[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:
parent
ce2596df79
commit
3f13e66e21
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue