Re: Multiple LUNs not detected with SCM USB-SCSI converter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux