]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
usb-core: Track if an endpoint has streams
authorHans de Goede <hdegoede@redhat.com>
Wed, 9 Oct 2013 15:19:25 +0000 (17:19 +0200)
committerSarah Sharp <sarah.a.sharp@linux.intel.com>
Tue, 4 Mar 2014 23:38:03 +0000 (15:38 -0800)
This is a preparation patch for adding support for bulk streams to usbfs.

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

index 9b445f43f825879eaf8364a98f048d175c73d00b..9c4e2922b04d0f2c44b405f2074085896d75a7ce 100644 (file)
@@ -2049,7 +2049,7 @@ int usb_alloc_streams(struct usb_interface *interface,
 {
        struct usb_hcd *hcd;
        struct usb_device *dev;
-       int i;
+       int i, ret;
 
        dev = interface_to_usbdev(interface);
        hcd = bus_to_hcd(dev->bus);
@@ -2058,13 +2058,24 @@ int usb_alloc_streams(struct usb_interface *interface,
        if (dev->speed != USB_SPEED_SUPER)
                return -EINVAL;
 
-       /* Streams only apply to bulk endpoints. */
-       for (i = 0; i < num_eps; i++)
+       for (i = 0; i < num_eps; i++) {
+               /* Streams only apply to bulk endpoints. */
                if (!usb_endpoint_xfer_bulk(&eps[i]->desc))
                        return -EINVAL;
+               /* Re-alloc is not allowed */
+               if (eps[i]->streams)
+                       return -EINVAL;
+       }
 
-       return hcd->driver->alloc_streams(hcd, dev, eps, num_eps,
+       ret = hcd->driver->alloc_streams(hcd, dev, eps, num_eps,
                        num_streams, mem_flags);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < num_eps; i++)
+               eps[i]->streams = ret;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(usb_alloc_streams);
 
@@ -2086,19 +2097,26 @@ int usb_free_streams(struct usb_interface *interface,
 {
        struct usb_hcd *hcd;
        struct usb_device *dev;
-       int i;
+       int i, ret;
 
        dev = interface_to_usbdev(interface);
        hcd = bus_to_hcd(dev->bus);
        if (dev->speed != USB_SPEED_SUPER)
                return -EINVAL;
 
-       /* Streams only apply to bulk endpoints. */
+       /* Double-free is not allowed */
        for (i = 0; i < num_eps; i++)
-               if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc))
+               if (!eps[i] || !eps[i]->streams)
                        return -EINVAL;
 
-       return hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags);
+       ret = hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < num_eps; i++)
+               eps[i]->streams = 0;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(usb_free_streams);
 
index 9b73dd782c09580226f326a13d5caadf0704928a..f1015cee5944102c184fca56936c1f451010a20b 100644 (file)
@@ -57,6 +57,7 @@ struct ep_device;
  * @extra: descriptors following this endpoint in the configuration
  * @extralen: how many bytes of "extra" are valid
  * @enabled: URBs may be submitted to this endpoint
+ * @streams: number of USB-3 streams allocated on the endpoint
  *
  * USB requests are always queued to a given endpoint, identified by a
  * descriptor within an active interface in a given USB configuration.
@@ -71,6 +72,7 @@ struct usb_host_endpoint {
        unsigned char *extra;   /* Extra descriptors */
        int extralen;
        int enabled;
+       int streams;
 };
 
 /* host-side wrapper for one interface setting's parsed descriptors */