diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-10-09 19:19:25 +0400 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2014-03-05 03:38:03 +0400 |
commit | 8d4f70b2fa52ca80f74faebc2471f74ee374cf61 (patch) | |
tree | 0794531c519e89498617ae60f9222327761be06b | |
parent | 8f5d35441ff26b31e3812556ce468c76f1eb216b (diff) | |
download | linux-8d4f70b2fa52ca80f74faebc2471f74ee374cf61.tar.xz |
usb-core: Track if an endpoint has streams
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>
-rw-r--r-- | drivers/usb/core/hcd.c | 34 | ||||
-rw-r--r-- | include/linux/usb.h | 2 |
2 files changed, 28 insertions, 8 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 9b445f43f825..9c4e2922b04d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -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); diff --git a/include/linux/usb.h b/include/linux/usb.h index 9b73dd782c09..f1015cee5944 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -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 */ |