Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22efcf4a authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

[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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>

 drivers/usb/gadget/file_storage.c |   32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)
parent dabb5928
Loading
Loading
Loading
Loading
+13 −19
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/module.h>
@@ -669,7 +670,6 @@ struct fsg_dev {
	wait_queue_head_t	thread_wqh;
	int			thread_wakeup_needed;
	struct completion	thread_notifier;
	int			thread_pid;
	struct task_struct	*thread_task;
	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)
{
	unsigned long		flags;
	struct task_struct	*thread_task;

	/* Do nothing if a higher-priority exception is already in progress.
	 * 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) {
		fsg->exception_req_tag = fsg->ep0_req_tag;
		fsg->state = new_state;
		thread_task = fsg->thread_task;
		if (thread_task)
			send_sig_info(SIGUSR1, SEND_SIG_FORCED, thread_task);
		if (fsg->thread_task)
			send_sig_info(SIGUSR1, SEND_SIG_FORCED,
					fsg->thread_task);
	}
	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_;

	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
	 * to block everything but INT, TERM, KILL, and USR1. */
	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. */
	set_fs(get_ds());

	/* Wait for the gadget registration to finish up */
	wait_for_completion(&fsg->thread_notifier);

	/* The main loop */
	while (fsg->state != FSG_STATE_TERMINATED) {
		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_lock_irq(&fsg->lock);
	fsg->thread_task = NULL;
	flush_signals(current);
	spin_unlock_irq(&fsg->lock);

	/* In case we are exiting because of a signal, unregister the
	 * 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);
	}

	if ((rc = kernel_thread(fsg_main_thread, fsg, (CLONE_VM | CLONE_FS |
			CLONE_FILES))) < 0)
	fsg->thread_task = kthread_create(fsg_main_thread, fsg,
			"file-storage-gadget");
	if (IS_ERR(fsg->thread_task)) {
		rc = PTR_ERR(fsg->thread_task);
		goto out;
	fsg->thread_pid = rc;
	}

	INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
	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",
			mod_data.removable, mod_data.can_stall,
			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;

autoconf_fail:
@@ -4093,7 +4087,7 @@ static int __init fsg_init(void)
	set_bit(REGISTERED, &fsg->atomic_bitflags);

	/* Tell the thread to start working */
	complete(&fsg->thread_notifier);
	wake_up_process(fsg->thread_task);
	return 0;
}
module_init(fsg_init);