Re: usb_stor_Bulk_max_lun() and scsi_host max_lun field mismatch

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

 



On Mon, 6 Oct 2014, Mark Knibbs wrote:

> Hi,
> 
> This is about USB mass storage devices.
> 
> The max_lun field in the scsi_host/us_data structure is the maximum
> possible LUN value *plus 1*.

You are confusing two different fields.  The max_lun field in scsi_host 
is different from the max_lun field in us_data.

The field in us_data is the maximum possible LUN value, _not_ plus 1.  
See 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;
		}

>  It's initially set to 8 by scsi_host_alloc()
> which is called by usb_stor_probe1().

scsi_host_alloc() doesn't touch anything in the us_data structure.

> usb_stor_scan_dwork() in drivers/usb/storage/usb.c contains this:
> 
>         /* 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() in drivers/usb/storage/transport.c contains this:
> 
>         usb_stor_dbg(us, "GetMaxLUN command result is %d, data is %d\n",
>                      result, us->iobuf[0]);
> 
>         /* if we have a successful request, return the result */
>         if (result > 0)
>                 return us->iobuf[0];
> 
>         /*
>          * Some devices don't like GetMaxLUN.  They may STALL the control
>          * pipe, they may return a zero-length result, they may do nothing at
>          * all and timeout, or they may fail in even more bizarrely creative
>          * ways.  In these cases the best approach is to use the default
>          * value: only one LUN.
>          */
>         return 0;
> 
> The USB Mass Storage Class document specifies that Get Max LUN returns the
> maximum LUN value (*not* plus 1). So for a single-LUN device or if
> GetMaxLUN fails, usb_stor_Bulk_max_lun() returns 0. In view of that,
> shouldn't the above code in usb_stor_scan_dwork() be changed to:
> 
>         /* 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) + 1;
>                 mutex_unlock(&us->dev_mutex);
>         }
>         scsi_scan_host(us_to_host(us));

No, it is correct as it stands.

Alan Stern

--
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