Hi, SCM-based USB-SCSI converters work with multi-LUN devices. I tested an MPL MCDISK-D dual PCMCIA SCSI device in a Windows XP VM (with SCM driver installed). Windows detected cards in both slots and added drive letters for them. With Linux however, only the lower slot (LUN 0) is detected. It seems the us->max_lun field is zero for SCM converters. SCM converters use the US_FL_SCM_MULT_TARG quirk. I first thought the problem might be this code in usb_stor_scan_dwork(): /* 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() returns 0 for an SCM converter; with usb-storage debugging enabled, I see this in the log: GetMaxLUN command result is -32, data is 0 So us->max_lun gets set to 0 which is presumably why LUNs > 0 are not scanned. I tried changing the above code to /* For bulk-only devices, determine the max LUN value */ if (us->protocol == USB_PR_BULK && !(us->fflags & (US_FL_SINGLE_LUN | US_FL_SCM_MULT_TARG))) { mutex_lock(&us->dev_mutex); ... But that change alone didn't seem to make any difference; with USB debugging enabled I got this log output: [ 205.823597] *** thread awakened [ 205.823605] Command INQUIRY (6 bytes) [ 205.823607] bytes: [ 205.823608] 12 00 00 00 24 00 [ 205.823620] Bulk Command S 0x43425355 T 0x12 L 36 F 128 Trg 3 LUN 0 CL 6 [ 205.823622] xfer 31 bytes [ 205.824455] Status code 0; transferred 31/31 [ 205.824459] -- transfer complete [ 205.824462] Bulk command transfer result=0 [ 205.824466] xfer 36 bytes, 1 entries [ 205.841459] Status code 0; transferred 36/36 [ 205.841463] -- transfer complete [ 205.841466] Bulk data transfer result 0x0 [ 205.841469] Attempting to get CSW... [ 205.841473] xfer 13 bytes [ 205.843450] Status code 0; transferred 13/13 [ 205.843454] -- transfer complete [ 205.843458] Bulk status result = 0 [ 205.843462] Bulk Status S 0x53425355 T 0x12 R 0 Stat 0x0 [ 205.843466] scsi cmd done, result=0x0 [ 205.843471] *** thread sleeping [ 205.843521] scsi 7:0:3:0: Direct-Access MPL MC-DISK-D-1S[0] 3.3 PQ: 0 ANSI: 2 [ 205.843581] *** thread awakened [ 205.843585] Bad LUN (3:1) [ 205.843589] scsi cmd done, result=0x40000 [ 205.843594] *** thread sleeping [ 205.843654] *** thread awakened [ 205.843657] Command INQUIRY (6 bytes) [ 205.843659] bytes: [ 205.843660] 12 00 00 00 24 00 [ 205.843666] Bulk Command S 0x43425355 T 0x13 L 36 F 128 Trg 4 LUN 0 CL 6 [ 205.843668] xfer 31 bytes Note the Bad LUN message. That's produced by this code in usb_stor_control_thread(): else if (us->srb->device->lun > us->max_lun) { usb_stor_dbg(us, "Bad LUN (%d:%llu)\n", us->srb->device->id, us->srb->device->lun); us->srb->result = DID_BAD_TARGET << 16; } So at that point, us->max_lun must be zero. What is us->max_lun initially set to? usb_stor_probe1() calls get_transport() then get_protocol(). get_transport() looks like this: /* Get the transport settings */ static void get_transport(struct us_data *us) { 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; case USB_PR_CBI: us->transport_name = "Control/Bulk/Interrupt"; us->transport = usb_stor_CB_transport; us->transport_reset = usb_stor_CB_reset; us->max_lun = 7; break; case USB_PR_BULK: us->transport_name = "Bulk"; us->transport = usb_stor_Bulk_transport; us->transport_reset = usb_stor_Bulk_reset; break; } } us->max_lun isn't set to 7 in the USB_PR_BULK case. Should it be? get_protocol() looks like this: /* Get the protocol settings */ static void get_protocol(struct us_data *us) { switch (us->subclass) { case USB_SC_RBC: us->protocol_name = "Reduced Block Commands (RBC)"; us->proto_handler = usb_stor_transparent_scsi_command; break; case USB_SC_8020: us->protocol_name = "8020i"; us->proto_handler = usb_stor_pad12_command; us->max_lun = 0; break; case USB_SC_QIC: us->protocol_name = "QIC-157"; us->proto_handler = usb_stor_pad12_command; us->max_lun = 0; break; case USB_SC_8070: us->protocol_name = "8070i"; us->proto_handler = usb_stor_pad12_command; us->max_lun = 0; break; case USB_SC_SCSI: us->protocol_name = "Transparent SCSI"; us->proto_handler = usb_stor_transparent_scsi_command; break; case USB_SC_UFI: us->protocol_name = "Uniform Floppy Interface (UFI)"; us->proto_handler = usb_stor_ufi_command; break; } } max_lun isn't set for the USB_SC_SCSI case (which the SCM converters use). 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 I compiled a kernel with option 2+(a) and it does detect LUNs > 0; here's part of lsscsi output with the modified kernel: [9:0:0:0]optical HP C1113M 1.19 /dev/sdg /dev/sg7 [9:0:3:0]disk MPL MC-DISK-D-1S[0] 3.3 /dev/sdh /dev/sg8 [9:0:3:1]disk MPL MC-DISK-D-1S[0] 3.3 - /dev/sg9 [9:0:3:2]disk MPL MC-DISK-D-1S[1] 3.3 - /dev/sg10 [9:0:3:3]disk MPL MC-DISK-D-1S[1] 3.3 /dev/sdi /dev/sg11 [9:0:3:4]disk MPL MC-DISK-D-1S[1] 3.3 /dev/sdj /dev/sg12 [9:0:3:5]disk MPL MC-DISK-D-1S[1] 3.3 /dev/sdk /dev/sg13 [9:0:3:6]disk MPL MC-DISK-D-1S[0] 3.3 /dev/sdl /dev/sg14 [9:0:3:7]disk MPL MC-DISK-D-1S[0] 3.3 /dev/sdm /dev/sg15 Could any other multiple-LUN-supporting devices be affected by this issue? Perhaps option 2+(c) might be better if so? [Also, looking at get_protocol(), should max_lun be set to 0 for the US_SC_RBC case?] 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