usb-core: Free bulk streams on interface release
authorHans de Goede <hdegoede@redhat.com>
Wed, 9 Oct 2013 15:19:26 +0000 (17:19 +0200)
committerSarah Sharp <sarah.a.sharp@linux.intel.com>
Tue, 4 Mar 2014 23:38:03 +0000 (15:38 -0800)
Documentation/usb/bulk-streams.txt says:

All stream IDs will be deallocated when the driver releases the interface, to
ensure that drivers that don't support streams will be able to use the endpoint

This commit actually implements this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
drivers/usb/core/driver.c

index 85e0450a2bc72c693e2ea82eff109835d957a71d..08283d40616c462af6ca4663592239a722dc8f6b 100644 (file)
@@ -400,8 +400,9 @@ static int usb_unbind_interface(struct device *dev)
 {
        struct usb_driver *driver = to_usb_driver(dev->driver);
        struct usb_interface *intf = to_usb_interface(dev);
+       struct usb_host_endpoint *ep, **eps = NULL;
        struct usb_device *udev;
-       int error, r, lpm_disable_error;
+       int i, j, error, r, lpm_disable_error;
 
        intf->condition = USB_INTERFACE_UNBINDING;
 
@@ -425,6 +426,26 @@ static int usb_unbind_interface(struct device *dev)
        driver->disconnect(intf);
        usb_cancel_queued_reset(intf);
 
+       /* Free streams */
+       for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+               ep = &intf->cur_altsetting->endpoint[i];
+               if (ep->streams == 0)
+                       continue;
+               if (j == 0) {
+                       eps = kmalloc(USB_MAXENDPOINTS * sizeof(void *),
+                                     GFP_KERNEL);
+                       if (!eps) {
+                               dev_warn(dev, "oom, leaking streams\n");
+                               break;
+                       }
+               }
+               eps[j++] = ep;
+       }
+       if (j) {
+               usb_free_streams(intf, eps, j, GFP_KERNEL);
+               kfree(eps);
+       }
+
        /* Reset other interface state.
         * We cannot do a Set-Interface if the device is suspended or
         * if it is prepared for a system sleep (since installing a new