[RFC 9/9] UAS: Free streams during USB disconnect.

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

 



When a USB device is disconnected (or a driver is unbound from a
device), the USB core will automatically cancel any URBs, and possibly
clean up any host controller state associated with the device.  This may
include setting the alternate interface setting back to alt setting 0.

Unfortunately, the xHCI needs any bulk stream rings to be freed before
the next alt setting is installed, and the USB core has no idea which
endpoints has stream rings allocated.  Instead, the UAS driver needs to
set the soft_unbind flag, which tells the USB core that it will cancel
any pending URBs and clean up any extra state (including the stream
rings).

Make the UAS disconnect method go through the same process as the
pre_reset method to quiesce all command submission, wait for all URBs to
be killed, and free the stream rings.

Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
Cc: Matthew Wilcox <willy@xxxxxxxxxxxxxxx>
---
 drivers/usb/storage/uas.c |   11 ++++-------
 1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index e3c5426..600edbc 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1078,18 +1078,13 @@ 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];
 
+	/* Clean up any pending commands and free streams */
+	uas_pre_reset(intf);
 	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);
-
 	cleanup_srcu_struct(devinfo->srcu);
 	kfree(devinfo->srcu);
 	kfree(devinfo->anchors);
@@ -1107,6 +1102,8 @@ static struct usb_driver uas_driver = {
 	.pre_reset = uas_pre_reset,
 	.post_reset = uas_post_reset,
 	.id_table = uas_usb_ids,
+	/* UAS needs to free URBs and streams before USB core disables eps */
+	.soft_unbind = 1,
 };
 
 static int uas_init(void)
-- 
1.7.5.4

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