I observed that on a device with multiple LUNs UAS was re-using the same tag number for requests which were issued at the same time to both LUNs. This patch uses scsi_init_shared_tag_map() to use unique tags for all LUNs. With this patch I haven't seen the same tag number during the init sequence anymore. Devices which do not adverise command queueing I saw only tag 1. This patch initilizes the queue before adding the host like the other two user in tree. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> --- * James Bottomley | 2011-12-16 22:47:39 [+0100]: >Well, no, what you want to do is use a shared tag map at the block >level. That will manage a joint tag space for N queues without your >having to partition it arbitrarily. see scsi_host_find_tag() and >scsi_init_shared_tag_map(). James, thank you for the two hints. This patch implements one of them. drivers/usb/storage/uas.c | 38 +++++++++++++++++++++++++------------- 1 files changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 09f55f9..4a8c062 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -690,6 +690,17 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) } } +static void uas_free_streams(struct uas_dev_info *devinfo) +{ + struct usb_device *udev = devinfo->udev; + struct usb_host_endpoint *eps[3]; + + eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); + eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); + eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); + usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); +} + /* * XXX: What I'd like to do here is register a SCSI host for each USB host in * the system. Follow usb-storage's design of registering a SCSI host for @@ -719,18 +730,26 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) shost->max_id = 1; shost->sg_tablesize = udev->bus->sg_tablesize; - result = scsi_add_host(shost, &intf->dev); - if (result) - goto free; - shost->hostdata[0] = (unsigned long)devinfo; - devinfo->intf = intf; devinfo->udev = udev; uas_configure_endpoints(devinfo); + result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1); + if (result) + goto free; + + result = scsi_add_host(shost, &intf->dev); + if (result) + goto deconfig_eps; + + shost->hostdata[0] = (unsigned long)devinfo; + scsi_scan_host(shost); usb_set_intfdata(intf, shost); return result; + +deconfig_eps: + uas_free_streams(devinfo); free: kfree(devinfo); if (shost) @@ -752,18 +771,11 @@ static int uas_post_reset(struct usb_interface *intf) static void uas_disconnect(struct usb_interface *intf) { - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_endpoint *eps[3]; struct Scsi_Host *shost = usb_get_intfdata(intf); struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); - - eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); - eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); - eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); - usb_free_streams(intf, eps, 3, GFP_KERNEL); - + uas_free_streams(devinfo); kfree(devinfo); } -- 1.7.7.3 -- 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