[PATCH] PATCH: usb-storage: move GetMaxLUN later in time
authorAlan Stern <stern@rowland.harvard.edu>
Mon, 24 Oct 2005 02:38:56 +0000 (19:38 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 28 Oct 2005 23:47:50 +0000 (16:47 -0700)
This patch is originally from Alan Stern (as557).  It has been re-diffed
against a current tree, and I also corrected a minor merging error.

Some time ago we introduced a delay before device scanning, because many
devices do not like to receive SCSI commands right after enumeration.
Now it turns out there's a device that doesn't like to receive
Get-Max-LUN right after enumeration either.  Accordingly this patch
delays the Get-Max-LUN request until the beginning of the scanning
procedure.  This fixes Bugzilla entry #5010.

Three things are worth noting.  First, I removed the locking code from
usb_stor_acquire_resources.  It's not needed, because the locking is to
protect against disconnect events and acquire_resources is only called
during probe (so the disconnect routine can't be called).  Second, I
initialized to 0 the buffer used for the Get-Max-LUN response.  It's not
really necessary, but it will prevent random values from showing up in
the debugging log when the request fails.  Third, I added a test against
the SINGLE_LUN flag.  This will allow us to use the flag to indicate
Bulk-only devices that can't handle Get-Max-LUN.

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>
drivers/usb/storage/transport.c
drivers/usb/storage/usb.c

index c1ba530..e89e945 100644 (file)
@@ -923,6 +923,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
        int result;
 
        /* issue the command */
+       us->iobuf[0] = 0;
        result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
                                 US_BULK_GET_MAX_LUN, 
                                 USB_DIR_IN | USB_TYPE_CLASS | 
index 5164900..92ee079 100644 (file)
@@ -747,25 +747,13 @@ static int usb_stor_acquire_resources(struct us_data *us)
                return -ENOMEM;
        }
 
-       /* Lock the device while we carry out the next two operations */
-       down(&us->dev_semaphore);
-
-       /* For bulk-only devices, determine the max LUN value */
-       if (us->protocol == US_PR_BULK) {
-               p = usb_stor_Bulk_max_lun(us);
-               if (p < 0) {
-                       up(&us->dev_semaphore);
-                       return p;
-               }
-               us->max_lun = p;
-       }
-
        /* Just before we start our control thread, initialize
         * the device if it needs initialization */
-       if (us->unusual_dev->initFunction)
-               us->unusual_dev->initFunction(us);
-
-       up(&us->dev_semaphore);
+       if (us->unusual_dev->initFunction) {
+               p = us->unusual_dev->initFunction(us);
+               if (p)
+                       return p;
+       }
 
        /* Start up our control thread */
        p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
@@ -904,6 +892,14 @@ retry:
 
        /* If the device is still connected, perform the scanning */
        if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+
+               /* For bulk-only devices, determine the max LUN value */
+               if (us->protocol == US_PR_BULK &&
+                               !(us->flags & US_FL_SINGLE_LUN)) {
+                       down(&us->dev_semaphore);
+                       us->max_lun = usb_stor_Bulk_max_lun(us);
+                       up(&us->dev_semaphore);
+               }
                scsi_scan_host(us_to_host(us));
                printk(KERN_DEBUG "usb-storage: device scan complete\n");