Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

storage: Fix bus scan and multi-LUN support for SCM eUSCSI devices

This patch does two things for SCM eUSCSI USB-SCSI converters:

1. SCM eUSCSI bridge devices are hard-wired to use SCSI ID 7. On connecting
the converter, access to that ID is attempted during the bus scan. Asking
the converter to issue INQUIRY commands to itself isn't very polite and
wastes time. Set this_id to 7 so __scsi_scan_target() skips it in the scan.

2. Enable multi-LUN support. eUSCSI devices don't support Get Max LUN
requests, returning an error (-32). [Different targets could have different
numbers of LUNs, so it wouldn't make sense to return a particular value in
response to Get Max LUN.]

usb_stor_scan_dwork() does 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);

It avoids calling usb_stor_Bulk_max_lun() if US_FL_SINGLE_LUN, but not for
US_FL_SCM_MULT_TARG. Since usb_stor_Bulk_max_lun() returns 0 in the error
case, us->max_lun was always set to 0.

[If the user doesn't want multi-LUN support (perhaps there are SCSI devices
which respond to commands on all LUNs?), the US_FL_SINGLE_LUN quirk can be
specified on the kernel command line.]

Signed-off-by: Mark Knibbs <markk@clara.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mark Knibbs and committed by
Greg Kroah-Hartman
646a3843 eab77694

+24 -12
+24 -12
drivers/usb/storage/usb.c
··· 884 884 dev_dbg(dev, "starting scan\n"); 885 885 886 886 /* For bulk-only devices, determine the max LUN value */ 887 - if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { 887 + if (us->protocol == USB_PR_BULK && 888 + !(us->fflags & US_FL_SINGLE_LUN) && 889 + !(us->fflags & US_FL_SCM_MULT_TARG)) { 888 890 mutex_lock(&us->dev_mutex); 889 891 us->max_lun = usb_stor_Bulk_max_lun(us); 890 892 mutex_unlock(&us->dev_mutex); ··· 985 983 usb_stor_dbg(us, "Transport: %s\n", us->transport_name); 986 984 usb_stor_dbg(us, "Protocol: %s\n", us->protocol_name); 987 985 986 + if (us->fflags & US_FL_SCM_MULT_TARG) { 987 + /* 988 + * SCM eUSCSI bridge devices can have different numbers 989 + * of LUNs on different targets; allow all to be probed. 990 + */ 991 + us->max_lun = 7; 992 + /* The eUSCSI itself has ID 7, so avoid scanning that */ 993 + us_to_host(us)->this_id = 7; 994 + /* max_id is 8 initially, so no need to set it here */ 995 + } else { 996 + /* In the normal case there is only a single target */ 997 + us_to_host(us)->max_id = 1; 998 + /* 999 + * Like Windows, we won't store the LUN bits in CDB[1] for 1000 + * SCSI-2 devices using the Bulk-Only transport (even though 1001 + * this violates the SCSI spec). 1002 + */ 1003 + if (us->transport == usb_stor_Bulk_transport) 1004 + us_to_host(us)->no_scsi2_lun_in_cdb = 1; 1005 + } 1006 + 988 1007 /* fix for single-lun devices */ 989 1008 if (us->fflags & US_FL_SINGLE_LUN) 990 1009 us->max_lun = 0; 991 - 992 - if (!(us->fflags & US_FL_SCM_MULT_TARG)) 993 - us_to_host(us)->max_id = 1; 994 - 995 - /* 996 - * Like Windows, we won't store the LUN bits in CDB[1] for SCSI-2 997 - * devices using the Bulk-Only transport (even though this violates 998 - * the SCSI spec). 999 - */ 1000 - if (us->transport == usb_stor_Bulk_transport) 1001 - us_to_host(us)->no_scsi2_lun_in_cdb = 1; 1002 1010 1003 1011 /* Find the endpoints and calculate pipe values */ 1004 1012 result = get_pipes(us);