[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(-)
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
dabb592816
commit
22efcf4ade
@ -224,6 +224,7 @@
|
|||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kthread.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -669,7 +670,6 @@ struct fsg_dev {
|
|||||||
wait_queue_head_t thread_wqh;
|
wait_queue_head_t thread_wqh;
|
||||||
int thread_wakeup_needed;
|
int thread_wakeup_needed;
|
||||||
struct completion thread_notifier;
|
struct completion thread_notifier;
|
||||||
int thread_pid;
|
|
||||||
struct task_struct *thread_task;
|
struct task_struct *thread_task;
|
||||||
sigset_t thread_signal_mask;
|
sigset_t thread_signal_mask;
|
||||||
|
|
||||||
@ -1084,7 +1084,6 @@ static void wakeup_thread(struct fsg_dev *fsg)
|
|||||||
static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
|
static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct task_struct *thread_task;
|
|
||||||
|
|
||||||
/* Do nothing if a higher-priority exception is already in progress.
|
/* Do nothing if a higher-priority exception is already in progress.
|
||||||
* If a lower-or-equal priority exception is in progress, preempt it
|
* 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)
|
|||||||
if (fsg->state <= new_state) {
|
if (fsg->state <= new_state) {
|
||||||
fsg->exception_req_tag = fsg->ep0_req_tag;
|
fsg->exception_req_tag = fsg->ep0_req_tag;
|
||||||
fsg->state = new_state;
|
fsg->state = new_state;
|
||||||
thread_task = fsg->thread_task;
|
if (fsg->thread_task)
|
||||||
if (thread_task)
|
send_sig_info(SIGUSR1, SEND_SIG_FORCED,
|
||||||
send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
|
fsg->thread_task);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&fsg->lock, flags);
|
spin_unlock_irqrestore(&fsg->lock, flags);
|
||||||
}
|
}
|
||||||
@ -3383,11 +3382,6 @@ static int fsg_main_thread(void *fsg_)
|
|||||||
{
|
{
|
||||||
struct fsg_dev *fsg = (struct fsg_dev *) fsg_;
|
struct fsg_dev *fsg = (struct fsg_dev *) fsg_;
|
||||||
|
|
||||||
fsg->thread_task = current;
|
|
||||||
|
|
||||||
/* Release all our userspace resources */
|
|
||||||
daemonize("file-storage-gadget");
|
|
||||||
|
|
||||||
/* Allow the thread to be killed by a signal, but set the signal mask
|
/* Allow the thread to be killed by a signal, but set the signal mask
|
||||||
* to block everything but INT, TERM, KILL, and USR1. */
|
* to block everything but INT, TERM, KILL, and USR1. */
|
||||||
siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
|
siginitsetinv(&fsg->thread_signal_mask, sigmask(SIGINT) |
|
||||||
@ -3400,9 +3394,6 @@ static int fsg_main_thread(void *fsg_)
|
|||||||
* that expects a __user pointer and it will work okay. */
|
* that expects a __user pointer and it will work okay. */
|
||||||
set_fs(get_ds());
|
set_fs(get_ds());
|
||||||
|
|
||||||
/* Wait for the gadget registration to finish up */
|
|
||||||
wait_for_completion(&fsg->thread_notifier);
|
|
||||||
|
|
||||||
/* The main loop */
|
/* The main loop */
|
||||||
while (fsg->state != FSG_STATE_TERMINATED) {
|
while (fsg->state != FSG_STATE_TERMINATED) {
|
||||||
if (exception_in_progress(fsg) || signal_pending(current)) {
|
if (exception_in_progress(fsg) || signal_pending(current)) {
|
||||||
@ -3440,8 +3431,9 @@ static int fsg_main_thread(void *fsg_)
|
|||||||
spin_unlock_irq(&fsg->lock);
|
spin_unlock_irq(&fsg->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_irq(&fsg->lock);
|
||||||
fsg->thread_task = NULL;
|
fsg->thread_task = NULL;
|
||||||
flush_signals(current);
|
spin_unlock_irq(&fsg->lock);
|
||||||
|
|
||||||
/* In case we are exiting because of a signal, unregister the
|
/* In case we are exiting because of a signal, unregister the
|
||||||
* gadget driver and close the backing file. */
|
* gadget driver and close the backing file. */
|
||||||
@ -3959,10 +3951,12 @@ static int __init fsg_bind(struct usb_gadget *gadget)
|
|||||||
sprintf(&serial[i], "%02X", c);
|
sprintf(&serial[i], "%02X", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
|
fsg->thread_task = kthread_create(fsg_main_thread, fsg,
|
||||||
CLONE_FILES))) < 0)
|
"file-storage-gadget");
|
||||||
|
if (IS_ERR(fsg->thread_task)) {
|
||||||
|
rc = PTR_ERR(fsg->thread_task);
|
||||||
goto out;
|
goto out;
|
||||||
fsg->thread_pid = rc;
|
}
|
||||||
|
|
||||||
INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
|
INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
|
||||||
INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
|
INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
|
||||||
@ -3994,7 +3988,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
|
|||||||
DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
|
DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
|
||||||
mod_data.removable, mod_data.can_stall,
|
mod_data.removable, mod_data.can_stall,
|
||||||
mod_data.buflen);
|
mod_data.buflen);
|
||||||
DBG(fsg, "I/O thread pid: %d\n", fsg->thread_pid);
|
DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
autoconf_fail:
|
autoconf_fail:
|
||||||
@ -4093,7 +4087,7 @@ static int __init fsg_init(void)
|
|||||||
set_bit(REGISTERED, &fsg->atomic_bitflags);
|
set_bit(REGISTERED, &fsg->atomic_bitflags);
|
||||||
|
|
||||||
/* Tell the thread to start working */
|
/* Tell the thread to start working */
|
||||||
complete(&fsg->thread_notifier);
|
wake_up_process(fsg->thread_task);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
module_init(fsg_init);
|
module_init(fsg_init);
|
||||||
|
Reference in New Issue
Block a user