usb-storage: enable multi-LUN scanning when needed
authorAlan Stern <stern@rowland.harvard.edu>
Thu, 30 Jan 2014 15:43:22 +0000 (10:43 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Feb 2014 20:59:15 +0000 (12:59 -0800)
People sometimes create their own custom-configured kernels and forget
to enable CONFIG_SCSI_MULTI_LUN.  This causes problems when they plug
in a USB storage device (such as a card reader) with more than one
LUN.

Fortunately, we can tell fairly easily when a storage device claims to
have more than one LUN.  When that happens, this patch asks the SCSI
layer to probe all the LUNs automatically, regardless of the config
setting.

The patch also updates the Kconfig help text for usb-storage,
explaining that CONFIG_SCSI_MULTI_LUN may be necessary.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Thomas Raschbacher <lordvan@lordvan.com>
CC: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
CC: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/storage/Kconfig
drivers/usb/storage/scsiglue.c

index 8470e1b114f2bff5538d9f4134e4f6222ab47500..1dd0604d1911d683015bedfe28ab86cdd42e8db4 100644 (file)
@@ -18,7 +18,9 @@ config USB_STORAGE
 
          This option depends on 'SCSI' support being enabled, but you
          probably also need 'SCSI device support: SCSI disk support'
-         (BLK_DEV_SD) for most USB storage devices.
+         (BLK_DEV_SD) for most USB storage devices.  Some devices also
+         will require 'Probe all LUNs on each SCSI device'
+         (SCSI_MULTI_LUN).
 
          To compile this driver as a module, choose M here: the
          module will be called usb-storage.
index 18509e6c21ab84e7d3133f7a0e428ba462d2a24b..9d38ddc8da492178afc8c2bebdbb8cb62cadc85f 100644 (file)
@@ -78,6 +78,8 @@ static const char* host_info(struct Scsi_Host *host)
 
 static int slave_alloc (struct scsi_device *sdev)
 {
+       struct us_data *us = host_to_us(sdev->host);
+
        /*
         * Set the INQUIRY transfer length to 36.  We don't use any of
         * the extra data and many devices choke if asked for more or
@@ -102,6 +104,10 @@ static int slave_alloc (struct scsi_device *sdev)
         */
        blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
 
+       /* Tell the SCSI layer if we know there is more than one LUN */
+       if (us->protocol == USB_PR_BULK && us->max_lun > 0)
+               sdev->sdev_bflags |= BLIST_FORCELUN;
+
        return 0;
 }