Hi,
This is about USB mass storage devices.
The max_lun field in the scsi_host/us_data structure is the maximum
possible LUN value *plus 1*. It's initially set to 8 by scsi_host_alloc()
which is called by usb_stor_probe1().
usb_stor_scan_dwork() in drivers/usb/storage/usb.c contains this:
/* For bulk-only devices, determine the max LUN value */
if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) {
mutex_lock(&us->dev_mutex);
us->max_lun = usb_stor_Bulk_max_lun(us);
mutex_unlock(&us->dev_mutex);
}
scsi_scan_host(us_to_host(us));
usb_stor_Bulk_max_lun() in drivers/usb/storage/transport.c contains this:
usb_stor_dbg(us, "GetMaxLUN command result is %d, data is %d\n",
result, us->iobuf[0]);
/* if we have a successful request, return the result */
if (result > 0)
return us->iobuf[0];
/*
* Some devices don't like GetMaxLUN. They may STALL the control
* pipe, they may return a zero-length result, they may do nothing at
* all and timeout, or they may fail in even more bizarrely creative
* ways. In these cases the best approach is to use the default
* value: only one LUN.
*/
return 0;
The USB Mass Storage Class document specifies that Get Max LUN returns the
maximum LUN value (*not* plus 1). So for a single-LUN device or if
GetMaxLUN fails, usb_stor_Bulk_max_lun() returns 0. In view of that,
shouldn't the above code in usb_stor_scan_dwork() be changed to:
/* For bulk-only devices, determine the max LUN value */
if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) {
mutex_lock(&us->dev_mutex);
us->max_lun = usb_stor_Bulk_max_lun(us) + 1;
mutex_unlock(&us->dev_mutex);
}
scsi_scan_host(us_to_host(us));
[It looks like code in drivers/staging/keucr/usb.c has the same issue.]
Mark
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html