Hi, On Wed, 8 Oct 2014 16:13:22 -0400 (EDT) Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > On Wed, 8 Oct 2014, Mark Knibbs wrote: > > > SCM-based USB-SCSI converters work with multi-LUN devices. I tested an MPL > > ... > > With Linux however, only the lower slot (LUN 0) is detected. It seems the > > us->max_lun field is zero for SCM converters. > > ... > > > I can think of several ways to fix this, and would like some input on which > > is the best/neatest: > > > > 1. Change usb_stor_Bulk_max_lun() to return 7 in the US_FL_SCM_MULT_TARG > > case (don't issue Get Max LUN to the USB device). > > > > 2. In usb_stor_scan_dwork(), don't call usb_stor_Bulk_max_lun() in the > > US_FL_SCM_MULT_TARG case, and one of: > > (a) In usb_stor_probe2(), set us->max_lun to 7 in the > > US_FL_SCM_MULT_TARG case > > (b) In get_transport(), set us->max_lun to 7 in the USB_PR_BULK case > > (c) In get_protocol(), set us->max_lun to 7 in the USB_SC_SCSI case > > Either way, usb_stor_Bulk_max_lun() shouldn't do anything for > SCM_MULT_TARG devices. Indeed, the value would be meaningless because > each target can have a different number of logical units. > > Since it isn't going to do anything for those devices, you might as > well avoid calling it, which means using approach 2. But instead of a, > b, or c, just do something simple like this in usb_stor_scan_dworkd(): > > /* For bulk-only devices, determine the max LUN value */ > if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { > if (us->fflags & US_FL_SCM_MULT_TARG) { > /* > * Multiple-target devices can have different numbers > * of LUNs on different targets. We will allow all > * of them to be probed. > */ > us->max_lun = 7; > } else { > mutex_lock(&us->dev_mutex); > us->max_lun = usb_stor_Bulk_max_lun(us); > mutex_unlock(&us->dev_mutex); > } > } Since setting max_lun to 0 in the US_FL_SINGLE_LUN case is done elsewhere, how about setting max_lun to 7 for US_FL_SCM_MULT_TARG next to that? So the above could could become: /* * Determine the max LUN value for bulk-only devices, except in * the US_FL_SINGLE_LUN and US_FL_SCM_MULT_TARG cases where max_lun * is set by usb_stor_probe2(). */ if (us->protocol == USB_PR_BULK && !(us->fflags & (US_FL_SINGLE_LUN | US_FL_SCM_MULT_TARG))) { mutex_lock(&us->dev_mutex); us->max_lun = usb_stor_Bulk_max_lun(us); mutex_unlock(&us->dev_mutex); } Then in usb_stor_probe2(): /* fix for single-lun devices */ if (us->fflags & US_FL_SINGLE_LUN) { us->max_lun = 0; } else if (us->fflags & US_FL_SCM_MULT_TARG) { /* * Multiple-target devices can have different numbers of * LUNs on different targets. Allow all to be probed. */ us->max_lun = 7; } That would also work if us->protocol != USB_PR_BULK. > Do you know that all SCM_MULT_TARG devices use the Bulk-only transport? Good question. It seems SCM converters support bulk-only and "CBC" (CBI with no command completion interrupt?); there's a comment in the Windows driver .INF file: ; DriverFlags field bitmap definition ; ... ; 0x00000010 => Force CBC Protocol ; 0x00000020 => Force BONLY Protocol An extract from lsusb -v output for a Belkin F5U015: bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk (Zip) iInterface 4 BONLY and CBC Interface Three entries for SCM-based converters in unusual-devs.h have USB_SC_SCSI, USB_PR_BULK though (as opposed to USB_SC_DEVICE, USB_PR_DEVICE): 04E6:000B, 04E6:000C, and 050D:0115. I don't have any of those so can't say whether USB_SC_SCSI/USB_PR_BULK is necessary for those quirk entries. So the answer to your question is probably yes. But it might be better to not rely on that. In get_transport() there is: switch (us->protocol) { case USB_PR_CB: us->transport_name = "Control/Bulk"; us->transport = usb_stor_CB_transport; us->transport_reset = usb_stor_CB_reset; us->max_lun = 7; break; Could a hacky way to get an SCM converter to work with multiple LUNs be to just change its useProtocol UNUSUAL_DEV entry to USB_PR_CB? That should force the kernel to use control/bulk protocol, and thus set max_lun to 7 with no other code change. By the way: is there any technical advantage to bulk-only vs control/bulk protocol? To digress slightly, I just built a kernel with USB_PR_CB instead of USB_PR_DEVICE for the SCM converter quirk. A couple of points on testing that: - Throughput is faster with CB than bulk-only. Using sg_rbuf to issue 512KB READ BUFFER commands gives 865,160 bytes/sec with bulk-only but 917,865 with CB; about 6% faster. Smaller transfer sizes have a much greater difference; CB was 100% faster for 1KB transfer size (BOT 128000, CB 256000) and 33% faster for 8KB transfers (BOT 511996, CB 682667). Does the CB protocol have less command overhead? - I had one single-LUN drive connected, but 8 block devices were created (one for each LUN). With the bulk-only protocol but max_lun set to 7, there were no bogus/phantom drives. I wonder if the SCM converters, when using Control/Bulk protocol, need target/LUN information in one of the reserved bytes of the ADSC setup packet (bytes 2, 3 or 5)... > > Could any other multiple-LUN-supporting devices be affected by this issue? > > Every multiple-target USB device will be affected. Right. Are there any others, other than USB-SCSI converters? Non-SCM USB-SCSI converters which support multiple targets include: - Adaptec USBXchange and USB2Xchange. Not supported in mainline kernel, though someone posted a patch a few years ago. - Second Wave SCUSBee. Also unsupported, and figuring out how it works might be tricky (wading through lots of PowerPC Mac OS driver code). - Ratoc U2SCX and U2SCX-LVD. Not supported in Linux either as far as I know. (I don't have one.) Any of those would need specific support in the kernel anyway I think, since (as far as I know) there isn't a standard way to access multiple targets. Mark -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html