diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-10-23 22:43:36 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-10-28 19:47:50 -0400 |
commit | 3f13e66e219238e025ff561d69826da9342c3f4a (patch) | |
tree | ff0fd93b0119975d45f2a55f49d2c897b0fc1ec0 /drivers/usb/storage | |
parent | ce2596df79ddbac605a290f4c7cf011cb40524fc (diff) |
[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>
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/usb.c | 63 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 3 |
2 files changed, 21 insertions, 45 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index c1a902691bc6..3847ebed2aa4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/module.h> | 54 | #include <linux/module.h> |
55 | #include <linux/init.h> | 55 | #include <linux/init.h> |
56 | #include <linux/slab.h> | 56 | #include <linux/slab.h> |
57 | #include <linux/kthread.h> | ||
57 | 58 | ||
58 | #include <scsi/scsi.h> | 59 | #include <scsi/scsi.h> |
59 | #include <scsi/scsi_cmnd.h> | 60 | #include <scsi/scsi_cmnd.h> |
@@ -310,22 +311,7 @@ static int usb_stor_control_thread(void * __us) | |||
310 | struct us_data *us = (struct us_data *)__us; | 311 | struct us_data *us = (struct us_data *)__us; |
311 | struct Scsi_Host *host = us_to_host(us); | 312 | struct Scsi_Host *host = us_to_host(us); |
312 | 313 | ||
313 | lock_kernel(); | ||
314 | |||
315 | /* | ||
316 | * This thread doesn't need any user-level access, | ||
317 | * so get rid of all our resources. | ||
318 | */ | ||
319 | daemonize("usb-storage"); | ||
320 | current->flags |= PF_NOFREEZE; | 314 | current->flags |= PF_NOFREEZE; |
321 | unlock_kernel(); | ||
322 | |||
323 | /* acquire a reference to the host, so it won't be deallocated | ||
324 | * until we're ready to exit */ | ||
325 | scsi_host_get(host); | ||
326 | |||
327 | /* signal that we've started the thread */ | ||
328 | complete(&(us->notify)); | ||
329 | 315 | ||
330 | for(;;) { | 316 | for(;;) { |
331 | US_DEBUGP("*** thread sleeping.\n"); | 317 | US_DEBUGP("*** thread sleeping.\n"); |
@@ -768,6 +754,7 @@ static int get_pipes(struct us_data *us) | |||
768 | static int usb_stor_acquire_resources(struct us_data *us) | 754 | static int usb_stor_acquire_resources(struct us_data *us) |
769 | { | 755 | { |
770 | int p; | 756 | int p; |
757 | struct task_struct *th; | ||
771 | 758 | ||
772 | us->current_urb = usb_alloc_urb(0, GFP_KERNEL); | 759 | us->current_urb = usb_alloc_urb(0, GFP_KERNEL); |
773 | if (!us->current_urb) { | 760 | if (!us->current_urb) { |
@@ -784,17 +771,19 @@ static int usb_stor_acquire_resources(struct us_data *us) | |||
784 | } | 771 | } |
785 | 772 | ||
786 | /* Start up our control thread */ | 773 | /* Start up our control thread */ |
787 | p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); | 774 | th = kthread_create(usb_stor_control_thread, us, "usb-storage"); |
788 | if (p < 0) { | 775 | if (IS_ERR(th)) { |
789 | printk(KERN_WARNING USB_STORAGE | 776 | printk(KERN_WARNING USB_STORAGE |
790 | "Unable to start control thread\n"); | 777 | "Unable to start control thread\n"); |
791 | return p; | 778 | return PTR_ERR(th); |
792 | } | 779 | } |
793 | us->pid = p; | ||
794 | atomic_inc(&total_threads); | ||
795 | 780 | ||
796 | /* Wait for the thread to start */ | 781 | /* Take a reference to the host for the control thread and |
797 | wait_for_completion(&(us->notify)); | 782 | * count it among all the threads we have launched. Then |
783 | * start it up. */ | ||
784 | scsi_host_get(us_to_host(us)); | ||
785 | atomic_inc(&total_threads); | ||
786 | wake_up_process(th); | ||
798 | 787 | ||
799 | return 0; | 788 | return 0; |
800 | } | 789 | } |
@@ -890,21 +879,6 @@ static int usb_stor_scan_thread(void * __us) | |||
890 | { | 879 | { |
891 | struct us_data *us = (struct us_data *)__us; | 880 | struct us_data *us = (struct us_data *)__us; |
892 | 881 | ||
893 | /* | ||
894 | * This thread doesn't need any user-level access, | ||
895 | * so get rid of all our resources. | ||
896 | */ | ||
897 | lock_kernel(); | ||
898 | daemonize("usb-stor-scan"); | ||
899 | unlock_kernel(); | ||
900 | |||
901 | /* Acquire a reference to the host, so it won't be deallocated | ||
902 | * until we're ready to exit */ | ||
903 | scsi_host_get(us_to_host(us)); | ||
904 | |||
905 | /* Signal that we've started the thread */ | ||
906 | complete(&(us->notify)); | ||
907 | |||
908 | printk(KERN_DEBUG | 882 | printk(KERN_DEBUG |
909 | "usb-storage: device found at %d\n", us->pusb_dev->devnum); | 883 | "usb-storage: device found at %d\n", us->pusb_dev->devnum); |
910 | 884 | ||
@@ -949,6 +923,7 @@ static int storage_probe(struct usb_interface *intf, | |||
949 | struct us_data *us; | 923 | struct us_data *us; |
950 | const int id_index = id - storage_usb_ids; | 924 | const int id_index = id - storage_usb_ids; |
951 | int result; | 925 | int result; |
926 | struct task_struct *th; | ||
952 | 927 | ||
953 | US_DEBUGP("USB Mass Storage device detected\n"); | 928 | US_DEBUGP("USB Mass Storage device detected\n"); |
954 | 929 | ||
@@ -1029,17 +1004,21 @@ static int storage_probe(struct usb_interface *intf, | |||
1029 | } | 1004 | } |
1030 | 1005 | ||
1031 | /* Start up the thread for delayed SCSI-device scanning */ | 1006 | /* Start up the thread for delayed SCSI-device scanning */ |
1032 | result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM); | 1007 | th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); |
1033 | if (result < 0) { | 1008 | if (IS_ERR(th)) { |
1034 | printk(KERN_WARNING USB_STORAGE | 1009 | printk(KERN_WARNING USB_STORAGE |
1035 | "Unable to start the device-scanning thread\n"); | 1010 | "Unable to start the device-scanning thread\n"); |
1036 | quiesce_and_remove_host(us); | 1011 | quiesce_and_remove_host(us); |
1012 | result = PTR_ERR(th); | ||
1037 | goto BadDevice; | 1013 | goto BadDevice; |
1038 | } | 1014 | } |
1039 | atomic_inc(&total_threads); | ||
1040 | 1015 | ||
1041 | /* Wait for the thread to start */ | 1016 | /* Take a reference to the host for the scanning thread and |
1042 | wait_for_completion(&(us->notify)); | 1017 | * count it among all the threads we have launched. Then |
1018 | * start it up. */ | ||
1019 | scsi_host_get(us_to_host(us)); | ||
1020 | atomic_inc(&total_threads); | ||
1021 | wake_up_process(th); | ||
1043 | 1022 | ||
1044 | return 0; | 1023 | return 0; |
1045 | 1024 | ||
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index dfa4dc71dd3e..98b09711a739 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -161,9 +161,6 @@ struct us_data { | |||
161 | struct scsi_cmnd *srb; /* current srb */ | 161 | struct scsi_cmnd *srb; /* current srb */ |
162 | unsigned int tag; /* current dCBWTag */ | 162 | unsigned int tag; /* current dCBWTag */ |
163 | 163 | ||
164 | /* thread information */ | ||
165 | int pid; /* control thread */ | ||
166 | |||
167 | /* control and bulk communications data */ | 164 | /* control and bulk communications data */ |
168 | struct urb *current_urb; /* USB requests */ | 165 | struct urb *current_urb; /* USB requests */ |
169 | struct usb_ctrlrequest *cr; /* control requests */ | 166 | struct usb_ctrlrequest *cr; /* control requests */ |