[PATCH] PATCH: usb-storage: move GetMaxLUN later in time

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>
This commit is contained in:
Alan Stern 2005-10-23 19:38:56 -07:00 коммит произвёл Greg Kroah-Hartman
Родитель 423e489d70
Коммит b876aef7f8
2 изменённых файлов: 14 добавлений и 17 удалений

Просмотреть файл

@ -923,6 +923,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
int result; int result;
/* issue the command */ /* issue the command */
us->iobuf[0] = 0;
result = usb_stor_control_msg(us, us->recv_ctrl_pipe, result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
US_BULK_GET_MAX_LUN, US_BULK_GET_MAX_LUN,
USB_DIR_IN | USB_TYPE_CLASS | USB_DIR_IN | USB_TYPE_CLASS |

Просмотреть файл

@ -747,25 +747,13 @@ static int usb_stor_acquire_resources(struct us_data *us)
return -ENOMEM; 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 /* Just before we start our control thread, initialize
* the device if it needs initialization */ * the device if it needs initialization */
if (us->unusual_dev->initFunction) if (us->unusual_dev->initFunction) {
us->unusual_dev->initFunction(us); p = us->unusual_dev->initFunction(us);
if (p)
up(&us->dev_semaphore); return p;
}
/* Start up our control thread */ /* Start up our control thread */
p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); 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 the device is still connected, perform the scanning */
if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { 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)); scsi_scan_host(us_to_host(us));
printk(KERN_DEBUG "usb-storage: device scan complete\n"); printk(KERN_DEBUG "usb-storage: device scan complete\n");