Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: Clear host_endpoint->streams when implicitly freeing streams

If streams are still allocated on device-reset or set-interface then the hcd
code implictly frees the streams. Clear host_endpoint->streams in this case
so that if a driver later tries to re-allocate them it won't run afoul of the
device already having streams check in usb_alloc_streams().

Note normally streams still being allocated at reset / set-intf would be a
driver bug, but this can happen without it being a driver bug on reset-resume.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>

authored by

Hans de Goede and committed by
Sarah Sharp
7a7b562d f7920884

+9 -3
+4 -1
drivers/usb/core/hub.c
··· 5131 5131 struct usb_hcd *hcd = bus_to_hcd(udev->bus); 5132 5132 struct usb_device_descriptor descriptor = udev->descriptor; 5133 5133 struct usb_host_bos *bos; 5134 - int i, ret = 0; 5134 + int i, j, ret = 0; 5135 5135 int port1 = udev->portnum; 5136 5136 5137 5137 if (udev->state == USB_STATE_NOTATTACHED || ··· 5257 5257 ret); 5258 5258 goto re_enumerate; 5259 5259 } 5260 + /* Resetting also frees any allocated streams */ 5261 + for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++) 5262 + intf->cur_altsetting->endpoint[j].streams = 0; 5260 5263 } 5261 5264 5262 5265 done:
+5 -2
drivers/usb/core/message.c
··· 1293 1293 struct usb_interface *iface; 1294 1294 struct usb_host_interface *alt; 1295 1295 struct usb_hcd *hcd = bus_to_hcd(dev->bus); 1296 - int ret; 1297 - int manual = 0; 1296 + int i, ret, manual = 0; 1298 1297 unsigned int epaddr; 1299 1298 unsigned int pipe; 1300 1299 ··· 1328 1329 mutex_unlock(hcd->bandwidth_mutex); 1329 1330 return -ENOMEM; 1330 1331 } 1332 + /* Changing alt-setting also frees any allocated streams */ 1333 + for (i = 0; i < iface->cur_altsetting->desc.bNumEndpoints; i++) 1334 + iface->cur_altsetting->endpoint[i].streams = 0; 1335 + 1331 1336 ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); 1332 1337 if (ret < 0) { 1333 1338 dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",