Hi,
On Wed, 8 Oct 2014 16:13:22 -0400 (EDT)
Alan Stern <[email protected]> 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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html