This is a preparation patch for adding support for bulk streams to usbfs.

Signed-off-by: Hans de Goede <hdego...@redhat.com>
---
 drivers/usb/core/hcd.c | 40 +++++++++++++++++++++++++++++++---------
 include/linux/usb.h    |  1 +
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 9da6635..d6eaa9f 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2045,7 +2045,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);
@@ -2054,13 +2054,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]->has_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]->has_streams = 1;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(usb_alloc_streams);
 
@@ -2083,19 +2094,30 @@ 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. */
-       for (i = 0; i < num_eps; i++)
-               if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc))
+       for (i = 0; i < num_eps; i++) {
+               /* Streams only apply to bulk endpoints. */
+               if (!usb_endpoint_xfer_bulk(&eps[i]->desc))
+                       return -EINVAL;
+               /* Double-free is not allowed */
+               if (!eps[i]->has_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;
+
+       for (i = 0; i < num_eps; i++)
+               eps[i]->has_streams = 0;
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(usb_free_streams);
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index f726c39..e769893 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -71,6 +71,7 @@ struct usb_host_endpoint {
        unsigned char *extra;   /* Extra descriptors */
        int extralen;
        int enabled;
+       int has_streams;
 };
 
 /* host-side wrapper for one interface setting's parsed descriptors */
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to