diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-09-26 16:12:02 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 19:47:42 -0400 |
commit | 22efcf4adec4262e0f49e6225f6cd070e4a85d20 (patch) | |
tree | 416d2fbb46995ad9483e1dee758ee818292e2ed9 /drivers/usb/gadget | |
parent | dabb592816444fcba1a771e27d4f72a2b8218374 (diff) |
[PATCH] USB: File-Storage gadget: use the kthread API
This patch (as566) converts the File-Storage gadget over to the kthread
API. The new code doesn't use kthread_stop because the control thread
needs to terminate asynchronously when it receives a signal.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/gadget/file_storage.c | 32 +++++++++++++-------------------
1 file changed, 13 insertions(+), 19 deletions(-)
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index a41d9d4baee3..241c570e541c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -224,6 +224,7 @@ | |||
224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
227 | #include <linux/kthread.h> | ||
227 | #include <linux/limits.h> | 228 | #include <linux/limits.h> |
228 | #include <linux/list.h> | 229 | #include <linux/list.h> |
229 | #include <linux/module.h> | 230 | #include <linux/module.h> |
@@ -669,7 +670,6 @@ struct fsg_dev { | |||
669 | wait_queue_head_t thread_wqh; | 670 | wait_queue_head_t thread_wqh; |
670 | int thread_wakeup_needed; | 671 | int thread_wakeup_needed; |
671 | struct completion thread_notifier; | 672 | struct completion thread_notifier; |
672 | int thread_pid; | ||
673 | struct task_struct *thread_task; | 673 | struct task_struct *thread_task; |
674 | sigset_t thread_signal_mask; | 674 | sigset_t thread_signal_mask; |
675 | 675 | ||
@@ -1084,7 +1084,6 @@ static void wakeup_thread(struct fsg_dev *fsg) | |||
1084 | static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) | 1084 | static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) |
1085 | { | 1085 | { |
1086 | unsigned long flags; | 1086 | unsigned long flags; |
1087 | struct task_struct *thread_task; | ||
1088 | 1087 | ||
1089 | /* Do nothing if a higher-priority exception is already in progress. | 1088 | /* Do nothing if a higher-priority exception is already in progress. |
1090 | * If a lower-or-equal priority exception is in progress, preempt it | 1089 | * If a lower-or-equal priority exception is in progress, preempt it |
@@ -1093,9 +1092,9 @@ static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) | |||
1093 | if (fsg->state <= new_state) { | 1092 | if (fsg->state <= new_state) { |
1094 | fsg->exception_req_tag = fsg->ep0_req_tag; | 1093 | fsg->exception_req_tag = fsg->ep0_req_tag; |
1095 | fsg->state = new_state; | 1094 | fsg->state = new_state; |
1096 | thread_task = fsg->thread_task; | 1095 | if (fsg->thread_task) |
1097 | if (thread_task) | 1096 | send_sig_info(SIGUSR1, SEND_SIG_FORCED, |
1098 | send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task); | 1097 | fsg->thread_task); |
1099 | } | 1098 | } |
1100 | spin_unlock_irqrestore(&fsg->lock, flags); | 1099 | spin_unlock_irqrestore(&fsg->lock, flags); |
1101 | } | 1100 | } |
@@ -3383,11 +3382,6 @@ static int fsg_main_thread(void *fsg_) | |||
3383 | { | 3382 | { |
3384 | struct fsg_dev *fsg = (struct fsg_dev *) fsg_; | 3383 | struct fsg_dev *fsg = (struct fsg_dev *) fsg_; |
3385 | 3384 | ||
3386 | fsg->thread_task = current; | ||
3387 | |||
3388 | /* Release all our userspace resources */ | ||
3389 | daemonize("file-storage-gadget"); | ||
3390 | |||
3391 | /* Allow the thread to be killed by a signal, but set the signal mask | 3385 | /* Allow the thread to be killed by a signal, but set the signal mask |
3392 | * to block everything but INT, TERM, KILL, and USR1. */ | 3386 | * to block everything but INT, TERM, KILL, and USR1. */ |
3393 | siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | | 3387 | siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) | |
@@ -3400,9 +3394,6 @@ static int fsg_main_thread(void *fsg_) | |||
3400 | * that expects a __user pointer and it will work okay. */ | 3394 | * that expects a __user pointer and it will work okay. */ |
3401 | set_fs(get_ds()); | 3395 | set_fs(get_ds()); |
3402 | 3396 | ||
3403 | /* Wait for the gadget registration to finish up */ | ||
3404 | wait_for_completion(&fsg->thread_notifier); | ||
3405 | |||
3406 | /* The main loop */ | 3397 | /* The main loop */ |
3407 | while (fsg->state != FSG_STATE_TERMINATED) { | 3398 | while (fsg->state != FSG_STATE_TERMINATED) { |
3408 | if (exception_in_progress(fsg) || signal_pending(current)) { | 3399 | if (exception_in_progress(fsg) || signal_pending(current)) { |
@@ -3440,8 +3431,9 @@ static int fsg_main_thread(void *fsg_) | |||
3440 | spin_unlock_irq(&fsg->lock); | 3431 | spin_unlock_irq(&fsg->lock); |
3441 | } | 3432 | } |
3442 | 3433 | ||
3434 | spin_lock_irq(&fsg->lock); | ||
3443 | fsg->thread_task = NULL; | 3435 | fsg->thread_task = NULL; |
3444 | flush_signals(current); | 3436 | spin_unlock_irq(&fsg->lock); |
3445 | 3437 | ||
3446 | /* In case we are exiting because of a signal, unregister the | 3438 | /* In case we are exiting because of a signal, unregister the |
3447 | * gadget driver and close the backing file. */ | 3439 | * gadget driver and close the backing file. */ |
@@ -3959,10 +3951,12 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3959 | sprintf(&serial[i], "%02X", c); | 3951 | sprintf(&serial[i], "%02X", c); |
3960 | } | 3952 | } |
3961 | 3953 | ||
3962 | if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS | | 3954 | fsg->thread_task = kthread_create(fsg_main_thread, fsg, |
3963 | CLONE_FILES))) < 0) | 3955 | "file-storage-gadget"); |
3956 | if (IS_ERR(fsg->thread_task)) { | ||
3957 | rc = PTR_ERR(fsg->thread_task); | ||
3964 | goto out; | 3958 | goto out; |
3965 | fsg->thread_pid = rc; | 3959 | } |
3966 | 3960 | ||
3967 | INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); | 3961 | INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); |
3968 | INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); | 3962 | INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); |
@@ -3994,7 +3988,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3994 | DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", | 3988 | DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", |
3995 | mod_data.removable, mod_data.can_stall, | 3989 | mod_data.removable, mod_data.can_stall, |
3996 | mod_data.buflen); | 3990 | mod_data.buflen); |
3997 | DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid); | 3991 | DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); |
3998 | return 0; | 3992 | return 0; |
3999 | 3993 | ||
4000 | autoconf_fail: | 3994 | autoconf_fail: |
@@ -4093,7 +4087,7 @@ static int __init fsg_init(void) | |||
4093 | set_bit(REGISTERED, &fsg->atomic_bitflags); | 4087 | set_bit(REGISTERED, &fsg->atomic_bitflags); |
4094 | 4088 | ||
4095 | /* Tell the thread to start working */ | 4089 | /* Tell the thread to start working */ |
4096 | complete(&fsg->thread_notifier); | 4090 | wake_up_process(fsg->thread_task); |
4097 | return 0; | 4091 | return 0; |
4098 | } | 4092 | } |
4099 | module_init(fsg_init); | 4093 | module_init(fsg_init); |