Commit adc625da authored by Matthew Dharm's avatar Matthew Dharm Committed by Greg Kroah-Hartman

[PATCH] USB Storage: GetMaxLUN tightening

This patch started life from Alan Stern as as274, and has been heavily
modified.  It narrows the case where a clear_halt() is issued after a
failed GetMaxLUN command to only a STALL case.

Since the only legimate responses to a GetMaxLUN are STALL or data,
anything else is now considered a fatal error and we give up on the device.
Signed-off-by: default avatarMatthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent bd504645
......@@ -908,26 +908,29 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
USB_RECIP_INTERFACE,
0, us->ifnum, us->iobuf, 1, HZ);
US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
result, us->iobuf[0]);
/* if we have a successful request, return the result */
if (result == 1)
return us->iobuf[0];
/*
* Some devices (i.e. Iomega Zip100) need this -- apparently
* the bulk pipes get STALLed when the GetMaxLUN request is
* processed. This is, in theory, harmless to all other devices
* (regardless of if they stall or not).
*/
if (result < 0) {
if (result == -EPIPE) {
usb_stor_clear_halt(us, us->recv_bulk_pipe);
usb_stor_clear_halt(us, us->send_bulk_pipe);
/* return the default -- no LUNs */
return 0;
}
US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
result, us->iobuf[0]);
/* if we have a successful request, return the result */
if (result == 1)
return us->iobuf[0];
/* return the default -- no LUNs */
return 0;
/* An answer or a STALL are the only valid responses. If we get
* something else, return an indication of error */
return -1;
}
int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
......
......@@ -754,8 +754,14 @@ static int usb_stor_acquire_resources(struct us_data *us)
down(&us->dev_semaphore);
/* For bulk-only devices, determine the max LUN value */
if (us->protocol == US_PR_BULK)
us->max_lun = usb_stor_Bulk_max_lun(us);
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment