diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 2518c3250750..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, | |||
2049 | { | 2049 | { |
2050 | struct usb_hcd *hcd; | 2050 | struct usb_hcd *hcd; |
2051 | struct usb_device *dev; | 2051 | struct usb_device *dev; |
2052 | int i; | 2052 | int i, ret; |
2053 | 2053 | ||
2054 | dev = interface_to_usbdev(interface); | 2054 | dev = interface_to_usbdev(interface); |
2055 | hcd = bus_to_hcd(dev->bus); | 2055 | hcd = bus_to_hcd(dev->bus); |
@@ -2058,13 +2058,24 @@ int usb_alloc_streams(struct usb_interface *interface, | |||
2058 | if (dev->speed != USB_SPEED_SUPER) | 2058 | if (dev->speed != USB_SPEED_SUPER) |
2059 | return -EINVAL; | 2059 | return -EINVAL; |
2060 | 2060 | ||
2061 | /* Streams only apply to bulk endpoints. */ | 2061 | for (i = 0; i < num_eps; i++) { |
2062 | for (i = 0; i < num_eps; i++) | 2062 | /* Streams only apply to bulk endpoints. */ |
2063 | if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) | 2063 | if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) |
2064 | return -EINVAL; | 2064 | return -EINVAL; |
2065 | /* Re-alloc is not allowed */ | ||
2066 | if (eps[i]->streams) | ||
2067 | return -EINVAL; | ||
2068 | } | ||
2065 | 2069 | ||
2066 | return hcd->driver->alloc_streams(hcd, dev, eps, num_eps, | 2070 | ret = hcd->driver->alloc_streams(hcd, dev, eps, num_eps, |
2067 | num_streams, mem_flags); | 2071 | num_streams, mem_flags); |
2072 | if (ret < 0) | ||
2073 | return ret; | ||
2074 | |||
2075 | for (i = 0; i < num_eps; i++) | ||
2076 | eps[i]->streams = ret; | ||
2077 | |||
2078 | return ret; | ||
2068 | } | 2079 | } |
2069 | EXPORT_SYMBOL_GPL(usb_alloc_streams); | 2080 | EXPORT_SYMBOL_GPL(usb_alloc_streams); |
2070 | 2081 | ||
@@ -2078,8 +2089,7 @@ EXPORT_SYMBOL_GPL(usb_alloc_streams); | |||
2078 | * Reverts a group of bulk endpoints back to not using stream IDs. | 2089 | * Reverts a group of bulk endpoints back to not using stream IDs. |
2079 | * Can fail if we are given bad arguments, or HCD is broken. | 2090 | * Can fail if we are given bad arguments, or HCD is broken. |
2080 | * | 2091 | * |
2081 | * Return: On success, the number of allocated streams. On failure, a negative | 2092 | * Return: 0 on success. On failure, a negative error code. |
2082 | * error code. | ||
2083 | */ | 2093 | */ |
2084 | int usb_free_streams(struct usb_interface *interface, | 2094 | int usb_free_streams(struct usb_interface *interface, |
2085 | struct usb_host_endpoint **eps, unsigned int num_eps, | 2095 | struct usb_host_endpoint **eps, unsigned int num_eps, |
@@ -2087,19 +2097,26 @@ int usb_free_streams(struct usb_interface *interface, | |||
2087 | { | 2097 | { |
2088 | struct usb_hcd *hcd; | 2098 | struct usb_hcd *hcd; |
2089 | struct usb_device *dev; | 2099 | struct usb_device *dev; |
2090 | int i; | 2100 | int i, ret; |
2091 | 2101 | ||
2092 | dev = interface_to_usbdev(interface); | 2102 | dev = interface_to_usbdev(interface); |
2093 | hcd = bus_to_hcd(dev->bus); | 2103 | hcd = bus_to_hcd(dev->bus); |
2094 | if (dev->speed != USB_SPEED_SUPER) | 2104 | if (dev->speed != USB_SPEED_SUPER) |
2095 | return -EINVAL; | 2105 | return -EINVAL; |
2096 | 2106 | ||
2097 | /* Streams only apply to bulk endpoints. */ | 2107 | /* Double-free is not allowed */ |
2098 | for (i = 0; i < num_eps; i++) | 2108 | for (i = 0; i < num_eps; i++) |
2099 | if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc)) | 2109 | if (!eps[i] || !eps[i]->streams) |
2100 | return -EINVAL; | 2110 | return -EINVAL; |
2101 | 2111 | ||
2102 | return hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); | 2112 | ret = hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); |
2113 | if (ret < 0) | ||
2114 | return ret; | ||
2115 | |||
2116 | for (i = 0; i < num_eps; i++) | ||
2117 | eps[i]->streams = 0; | ||
2118 | |||
2119 | return ret; | ||
2103 | } | 2120 | } |
2104 | EXPORT_SYMBOL_GPL(usb_free_streams); | 2121 | EXPORT_SYMBOL_GPL(usb_free_streams); |
2105 | 2122 | ||