[PATCH] PATCH: usb-storage: use kthread API

This patch is originally from Alan Stern (as569).  It has been rediffed
against a current tree.

This patch converts usb-storage to use the kthread API for creating its
control and scanning threads.  The new code doesn't use kthread_stop
because the threads need (or will need in the future) to exit
asynchronously.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Alan Stern 2005-10-23 19:43:36 -07:00 committed by Greg Kroah-Hartman
parent ce2596df79
commit 3f13e66e21
2 changed files with 21 additions and 45 deletions

View File

@ -54,6 +54,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kthread.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
@ -310,22 +311,7 @@ static int usb_stor_control_thread(void * __us)
struct us_data *us = (struct us_data *)__us; struct us_data *us = (struct us_data *)__us;
struct Scsi_Host *host = us_to_host(us); struct Scsi_Host *host = us_to_host(us);
lock_kernel();
/*
* This thread doesn't need any user-level access,
* so get rid of all our resources.
*/
daemonize("usb-storage");
current->flags |= PF_NOFREEZE; current->flags |= PF_NOFREEZE;
unlock_kernel();
/* acquire a reference to the host, so it won't be deallocated
* until we're ready to exit */
scsi_host_get(host);
/* signal that we've started the thread */
complete(&(us->notify));
for(;;) { for(;;) {
US_DEBUGP("*** thread sleeping.\n"); US_DEBUGP("*** thread sleeping.\n");
@ -768,6 +754,7 @@ static int get_pipes(struct us_data *us)
static int usb_stor_acquire_resources(struct us_data *us) static int usb_stor_acquire_resources(struct us_data *us)
{ {
int p; int p;
struct task_struct *th;
us->current_urb = usb_alloc_urb(0, GFP_KERNEL); us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!us->current_urb) { if (!us->current_urb) {
@ -784,17 +771,19 @@ static int usb_stor_acquire_resources(struct us_data *us)
} }
/* Start up our control thread */ /* Start up our control thread */
p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); th = kthread_create(usb_stor_control_thread, us, "usb-storage");
if (p < 0) { if (IS_ERR(th)) {
printk(KERN_WARNING USB_STORAGE printk(KERN_WARNING USB_STORAGE
"Unable to start control thread\n"); "Unable to start control thread\n");
return p; return PTR_ERR(th);
} }
us->pid = p;
atomic_inc(&total_threads);
/* Wait for the thread to start */ /* Take a reference to the host for the control thread and
wait_for_completion(&(us->notify)); * count it among all the threads we have launched. Then
* start it up. */
scsi_host_get(us_to_host(us));
atomic_inc(&total_threads);
wake_up_process(th);
return 0; return 0;
} }
@ -890,21 +879,6 @@ static int usb_stor_scan_thread(void * __us)
{ {
struct us_data *us = (struct us_data *)__us; struct us_data *us = (struct us_data *)__us;
/*
* This thread doesn't need any user-level access,
* so get rid of all our resources.
*/
lock_kernel();
daemonize("usb-stor-scan");
unlock_kernel();
/* Acquire a reference to the host, so it won't be deallocated
* until we're ready to exit */
scsi_host_get(us_to_host(us));
/* Signal that we've started the thread */
complete(&(us->notify));
printk(KERN_DEBUG printk(KERN_DEBUG
"usb-storage: device found at %d\n", us->pusb_dev->devnum); "usb-storage: device found at %d\n", us->pusb_dev->devnum);
@ -949,6 +923,7 @@ static int storage_probe(struct usb_interface *intf,
struct us_data *us; struct us_data *us;
const int id_index = id - storage_usb_ids; const int id_index = id - storage_usb_ids;
int result; int result;
struct task_struct *th;
US_DEBUGP("USB Mass Storage device detected\n"); US_DEBUGP("USB Mass Storage device detected\n");
@ -1029,17 +1004,21 @@ static int storage_probe(struct usb_interface *intf,
} }
/* Start up the thread for delayed SCSI-device scanning */ /* Start up the thread for delayed SCSI-device scanning */
result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM); th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan");
if (result < 0) { if (IS_ERR(th)) {
printk(KERN_WARNING USB_STORAGE printk(KERN_WARNING USB_STORAGE
"Unable to start the device-scanning thread\n"); "Unable to start the device-scanning thread\n");
quiesce_and_remove_host(us); quiesce_and_remove_host(us);
result = PTR_ERR(th);
goto BadDevice; goto BadDevice;
} }
atomic_inc(&total_threads);
/* Wait for the thread to start */ /* Take a reference to the host for the scanning thread and
wait_for_completion(&(us->notify)); * count it among all the threads we have launched. Then
* start it up. */
scsi_host_get(us_to_host(us));
atomic_inc(&total_threads);
wake_up_process(th);
return 0; return 0;

View File

@ -161,9 +161,6 @@ struct us_data {
struct scsi_cmnd *srb; /* current srb */ struct scsi_cmnd *srb; /* current srb */
unsigned int tag; /* current dCBWTag */ unsigned int tag; /* current dCBWTag */
/* thread information */
int pid; /* control thread */
/* control and bulk communications data */ /* control and bulk communications data */
struct urb *current_urb; /* USB requests */ struct urb *current_urb; /* USB requests */
struct usb_ctrlrequest *cr; /* control requests */ struct usb_ctrlrequest *cr; /* control requests */