Skip to content

Commit dae5154

Browse files
author
Sebastian Andrzej Siewior
committed
usb/uas: use unique tags for all LUNs
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. Tag 1 is used for devices which do not adverise command queueing. This patch initilizes the queue before adding the scsi host like the other two user in tree. Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
1 parent 96c1eb9 commit dae5154

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

drivers/usb/storage/uas.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,17 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo)
684684
}
685685
}
686686

687+
static void uas_free_streams(struct uas_dev_info *devinfo)
688+
{
689+
struct usb_device *udev = devinfo->udev;
690+
struct usb_host_endpoint *eps[3];
691+
692+
eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
693+
eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
694+
eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
695+
usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
696+
}
697+
687698
/*
688699
* XXX: What I'd like to do here is register a SCSI host for each USB host in
689700
* the system. Follow usb-storage's design of registering a SCSI host for
@@ -713,18 +724,26 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
713724
shost->max_id = 1;
714725
shost->sg_tablesize = udev->bus->sg_tablesize;
715726

716-
result = scsi_add_host(shost, &intf->dev);
717-
if (result)
718-
goto free;
719-
shost->hostdata[0] = (unsigned long)devinfo;
720-
721727
devinfo->intf = intf;
722728
devinfo->udev = udev;
723729
uas_configure_endpoints(devinfo);
724730

731+
result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1);
732+
if (result)
733+
goto free;
734+
735+
result = scsi_add_host(shost, &intf->dev);
736+
if (result)
737+
goto deconfig_eps;
738+
739+
shost->hostdata[0] = (unsigned long)devinfo;
740+
725741
scsi_scan_host(shost);
726742
usb_set_intfdata(intf, shost);
727743
return result;
744+
745+
deconfig_eps:
746+
uas_free_streams(devinfo);
728747
free:
729748
kfree(devinfo);
730749
if (shost)
@@ -746,18 +765,11 @@ static int uas_post_reset(struct usb_interface *intf)
746765

747766
static void uas_disconnect(struct usb_interface *intf)
748767
{
749-
struct usb_device *udev = interface_to_usbdev(intf);
750-
struct usb_host_endpoint *eps[3];
751768
struct Scsi_Host *shost = usb_get_intfdata(intf);
752769
struct uas_dev_info *devinfo = (void *)shost->hostdata[0];
753770

754771
scsi_remove_host(shost);
755-
756-
eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
757-
eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
758-
eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
759-
usb_free_streams(intf, eps, 3, GFP_KERNEL);
760-
772+
uas_free_streams(devinfo);
761773
kfree(devinfo);
762774
}
763775

0 commit comments

Comments
 (0)