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