diff options
| author | Andrew Morton <akpm@osdl.org> | 2003-12-29 23:42:21 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-12-29 23:42:21 -0800 |
| commit | 313606d9d839efafcb5ca1ae193b61782f37b754 (patch) | |
| tree | e4c9f3f1073e8f6c34fe0a3924404e5215aedbf2 | |
| parent | 82b7e321fd71c4a8f9da2c5a63f3b4d7f5f8343f (diff) | |
[PATCH] dvb: Firmware_class update
From: Michael Hunold <hunold@linuxtv.org>
Use a kernel thread instead of schedule_work() when waiting for the firmware
upload to happen
| -rw-r--r-- | drivers/base/firmware_class.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index b186dba8d2d8..3fb7876157d0 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -415,18 +415,22 @@ struct firmware_work { void (*cont)(const struct firmware *fw, void *context); }; -static void +static int request_firmware_work_func(void *arg) { struct firmware_work *fw_work = arg; const struct firmware *fw; - if (!arg) - return; + if (!arg) { + WARN_ON(1); + return 0; + } + daemonize("%s/%s", "firmware", fw_work->name); request_firmware(&fw, fw_work->name, fw_work->device); fw_work->cont(fw, fw_work->context); release_firmware(fw); module_put(fw_work->module); kfree(fw_work); + return 0; } /** @@ -451,6 +455,8 @@ request_firmware_nowait( { struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), GFP_ATOMIC); + int ret; + if (!fw_work) return -ENOMEM; if (!try_module_get(module)) { @@ -465,9 +471,14 @@ request_firmware_nowait( .context = context, .cont = cont, }; - INIT_WORK(&fw_work->work, request_firmware_work_func, fw_work); - schedule_work(&fw_work->work); + ret = kernel_thread(request_firmware_work_func, fw_work, + CLONE_FS | CLONE_FILES); + + if (ret < 0) { + fw_work->cont(NULL, fw_work->context); + return ret; + } return 0; } |
