Changeset 445 for GPL/trunk/lib32/misc.c
- Timestamp:
- Jun 8, 2009, 11:51:32 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/lib32/misc.c
r305 r445 36 36 #include <linux\utsname.h> 37 37 #include <linux\module.h> 38 #include <linux/workqueue.h> 39 #include <linux/firmware.h> 38 40 #include <dbgos2.h> 39 41 #include <printfos2.h> … … 219 221 //****************************************************************************** 220 222 //****************************************************************************** 223 static void __x_queue_work(struct workqueue_struct *wq, struct work_struct *work) 224 { 225 unsigned long flags; 226 227 spin_lock_irqsave(&wq->lock, flags); 228 work->wq_data = wq; 229 list_add_tail(&work->entry, &wq->worklist); 230 wake_up(&wq->more_work); 231 spin_unlock_irqrestore(&wq->lock, flags); 232 } 233 //****************************************************************************** 234 //****************************************************************************** 235 int queue_work(struct workqueue_struct *wq, struct work_struct *work) 236 { 237 if (!test_and_set_bit(0, &work->pending)) { 238 __x_queue_work(wq, work); 239 return 1; 240 } 241 return 0; 242 } 243 //****************************************************************************** 244 //****************************************************************************** 245 void flush_workqueue(struct workqueue_struct *wq) 246 { 247 if (wq->task == current) { 248 run_workqueue(wq); 249 } else { 250 wait_queue_t wait; 251 252 init_waitqueue_entry(&wait, current); 253 set_current_state(TASK_UNINTERRUPTIBLE); 254 spin_lock_irq(&wq->lock); 255 add_wait_queue(&wq->work_done, &wait); 256 while (!list_empty(&wq->worklist)) { 257 spin_unlock_irq(&wq->lock); 258 schedule(); 259 spin_lock_irq(&wq->lock); 260 } 261 set_current_state(TASK_RUNNING); 262 remove_wait_queue(&wq->work_done, &wait); 263 spin_unlock_irq(&wq->lock); 264 } 265 } 266 //****************************************************************************** 267 //****************************************************************************** 268 static void run_workqueue(struct workqueue_struct *wq) 269 { 270 unsigned long flags; 271 272 spin_lock_irqsave(&wq->lock, flags); 273 while (!list_empty(&wq->worklist)) { 274 struct work_struct *work = list_entry(wq->worklist.next, 275 struct work_struct, entry); 276 void (*f) (void *) = work->func; 277 void *data = work->data; 278 279 list_del_init(wq->worklist.next); 280 spin_unlock_irqrestore(&wq->lock, flags); 281 clear_bit(0, &work->pending); 282 f(data); 283 spin_lock_irqsave(&wq->lock, flags); 284 wake_up(&wq->work_done); 285 } 286 spin_unlock_irqrestore(&wq->lock, flags); 287 } 288 //****************************************************************************** 289 //****************************************************************************** 290 struct workqueue_struct *create_workqueue(const char *name) 291 { 292 struct workqueue_struct *wq; 293 294 BUG_ON(strlen(name) > 10); 295 296 wq = kmalloc(sizeof(*wq), GFP_KERNEL); 297 if (!wq) 298 return NULL; 299 memset(wq, 0, sizeof(*wq)); 300 301 spin_lock_init(&wq->lock); 302 INIT_LIST_HEAD(&wq->worklist); 303 init_waitqueue_head(&wq->more_work); 304 init_waitqueue_head(&wq->work_done); 305 #ifndef TARGET_OS2 306 init_completion(&wq->thread_exited); 307 wq->name = name; 308 wq->task_pid = kernel_thread(xworker_thread, wq, 0); 309 if (wq->task_pid < 0) { 310 printk(KERN_ERR "snd: failed to start thread %s\n", name); 311 snd_compat_destroy_workqueue(wq); 312 wq = NULL; 313 } 314 wq->task = find_task_by_pid(wq->task_pid); 315 #endif 316 return wq; 317 } 318 //****************************************************************************** 319 //****************************************************************************** 320 void destroy_workqueue(struct workqueue_struct *wq) 321 { 322 #ifndef TARGET_OS2 323 snd_compat_flush_workqueue(wq); 324 kill_proc(wq->task_pid, SIGKILL, 1); 325 if (wq->task_pid >= 0) 326 wait_for_completion(&wq->thread_exited); 327 #endif 328 kfree(wq); 329 } 330 331 //****************************************************************************** 332 //****************************************************************************** 333 char *kstrdup(const char *s, unsigned int __nocast gfp_flags) 334 { 335 int len; 336 char *buf; 337 338 if (!s) return NULL; 339 340 len = strlen(s) + 1; 341 buf = kmalloc(len, gfp_flags); 342 if (buf) 343 memcpy(buf, s, len); 344 return buf; 345 } 346 //****************************************************************************** 347 //****************************************************************************** 348 int mod_firmware_load(const char *fn, char **fp) 349 { 350 return 0; 351 } 352 //****************************************************************************** 353 //****************************************************************************** 354 static int snd_try_load_firmware(const char *path, const char *name, 355 struct firmware *firmware) 356 { 357 char filename[30 + FIRMWARE_NAME_MAX]; 358 359 sprintf(filename, "%s/%s", path, name); 360 firmware->size = mod_firmware_load(filename, (char **)&firmware->data); 361 if (firmware->size) 362 printk(KERN_INFO "Loaded '%s'.", filename); 363 return firmware->size; 364 } 365 //****************************************************************************** 366 //****************************************************************************** 367 int request_firmware(const struct firmware **fw, const char *name, 368 struct device *device) 369 { 370 struct firmware *firmware; 371 372 *fw = NULL; 373 firmware = kmalloc(sizeof *firmware, GFP_KERNEL); 374 if (!firmware) 375 return -ENOMEM; 376 if (!snd_try_load_firmware("/lib/firmware", name, firmware) && 377 !snd_try_load_firmware("/lib/hotplug/firmware", name, firmware) && 378 !snd_try_load_firmware("/usr/lib/hotplug/firmware", name, firmware)) { 379 kfree(firmware); 380 return -EIO; 381 } 382 *fw = firmware; 383 return 0; 384 } 385 //****************************************************************************** 386 //****************************************************************************** 387 void release_firmware(const struct firmware *fw) 388 { 389 if (fw) { 390 vfree(fw->data); 391 kfree(fw); 392 } 393 } 394 //****************************************************************************** 395 //****************************************************************************** 396 void *memdup_user(void __user *src, size_t len) 397 { 398 void *p = kmalloc(len, GFP_KERNEL); 399 if (!p) 400 return ERR_PTR(-ENOMEM); 401 if (copy_from_user(p, src, len)) { 402 kfree(p); 403 return ERR_PTR(-EFAULT); 404 } 405 return p; 406 } 407 //****************************************************************************** 408 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.