Commit 7a7b562d authored by Hans de Goede's avatar Hans de Goede Committed by Sarah Sharp

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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
parent f7920884
...@@ -5131,7 +5131,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) ...@@ -5131,7 +5131,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
struct usb_hcd *hcd = bus_to_hcd(udev->bus); struct usb_hcd *hcd = bus_to_hcd(udev->bus);
struct usb_device_descriptor descriptor = udev->descriptor; struct usb_device_descriptor descriptor = udev->descriptor;
struct usb_host_bos *bos; struct usb_host_bos *bos;
int i, ret = 0; int i, j, ret = 0;
int port1 = udev->portnum; int port1 = udev->portnum;
if (udev->state == USB_STATE_NOTATTACHED || if (udev->state == USB_STATE_NOTATTACHED ||
...@@ -5257,6 +5257,9 @@ static int usb_reset_and_verify_device(struct usb_device *udev) ...@@ -5257,6 +5257,9 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
ret); ret);
goto re_enumerate; goto re_enumerate;
} }
/* Resetting also frees any allocated streams */
for (j = 0; j < intf->cur_altsetting->desc.bNumEndpoints; j++)
intf->cur_altsetting->endpoint[j].streams = 0;
} }
done: done:
......
...@@ -1293,8 +1293,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) ...@@ -1293,8 +1293,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
struct usb_interface *iface; struct usb_interface *iface;
struct usb_host_interface *alt; struct usb_host_interface *alt;
struct usb_hcd *hcd = bus_to_hcd(dev->bus); struct usb_hcd *hcd = bus_to_hcd(dev->bus);
int ret; int i, ret, manual = 0;
int manual = 0;
unsigned int epaddr; unsigned int epaddr;
unsigned int pipe; unsigned int pipe;
...@@ -1329,6 +1328,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) ...@@ -1329,6 +1328,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
mutex_unlock(hcd->bandwidth_mutex); mutex_unlock(hcd->bandwidth_mutex);
return -ENOMEM; return -ENOMEM;
} }
/* Changing alt-setting also frees any allocated streams */
for (i = 0; i < iface->cur_altsetting->desc.bNumEndpoints; i++)
iface->cur_altsetting->endpoint[i].streams = 0;
ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
if (ret < 0) { if (ret < 0) {
dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment