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. Greg, please apply. Matt Signed-off-by: Alan Stern <[EMAIL PROTECTED]> Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]> Index: usb-2.6/drivers/usb/storage/usb.h =================================================================== --- usb-2.6.orig/drivers/usb/storage/usb.h +++ usb-2.6/drivers/usb/storage/usb.h @@ -160,9 +160,6 @@ struct us_data { struct scsi_cmnd *srb; /* current srb */ unsigned int tag; /* current dCBWTag */ - /* thread information */ - int pid; /* control thread */ - /* control and bulk communications data */ struct urb *current_urb; /* USB requests */ struct usb_ctrlrequest *cr; /* control requests */ Index: usb-2.6/drivers/usb/storage/usb.c =================================================================== --- usb-2.6.orig/drivers/usb/storage/usb.c +++ usb-2.6/drivers/usb/storage/usb.c @@ -54,6 +54,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/kthread.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> @@ -310,22 +311,7 @@ static int usb_stor_control_thread(void struct us_data *us = (struct us_data *)__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; - 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(;;) { US_DEBUGP("*** thread sleeping.\n"); @@ -762,6 +748,7 @@ static int get_pipes(struct us_data *us) static int usb_stor_acquire_resources(struct us_data *us) { int p; + struct task_struct *th; us->current_urb = usb_alloc_urb(0, GFP_KERNEL); if (!us->current_urb) { @@ -790,17 +777,19 @@ static int usb_stor_acquire_resources(st up(&us->dev_semaphore); /* Start up our control thread */ - p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); - if (p < 0) { + th = kthread_create(usb_stor_control_thread, us, "usb-storage"); + if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "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 */ - wait_for_completion(&(us->notify)); + /* Take a reference to the host for the control thread and + * 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; } @@ -894,21 +883,6 @@ static int usb_stor_scan_thread(void * _ { 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 "usb-storage: device found at %d\n", us->pusb_dev->devnum); @@ -945,6 +919,7 @@ static int storage_probe(struct usb_inte struct us_data *us; const int id_index = id - storage_usb_ids; int result; + struct task_struct *th; US_DEBUGP("USB Mass Storage device detected\n"); @@ -1025,17 +1000,21 @@ static int storage_probe(struct usb_inte } /* Start up the thread for delayed SCSI-device scanning */ - result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM); - if (result < 0) { + th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); + if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "Unable to start the device-scanning thread\n"); quiesce_and_remove_host(us); + result = PTR_ERR(th); goto BadDevice; } - atomic_inc(&total_threads); - /* Wait for the thread to start */ - wait_for_completion(&(us->notify)); + /* Take a reference to the host for the scanning thread and + * 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; -- Matthew Dharm Home: [EMAIL PROTECTED] Maintainer, Linux USB Mass Storage Driver NYET! The evil stops here! -- Pitr User Friendly, 6/22/1998
pgp5Lv29GG9MR.pgp
Description: PGP signature