diff options
| -rw-r--r-- | drivers/usb/core/driver.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 85e0450a2bc7..08283d40616c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -400,8 +400,9 @@ static int usb_unbind_interface(struct device *dev) | |||
| 400 | { | 400 | { |
| 401 | struct usb_driver *driver = to_usb_driver(dev->driver); | 401 | struct usb_driver *driver = to_usb_driver(dev->driver); |
| 402 | struct usb_interface *intf = to_usb_interface(dev); | 402 | struct usb_interface *intf = to_usb_interface(dev); |
| 403 | struct usb_host_endpoint *ep, **eps = NULL; | ||
| 403 | struct usb_device *udev; | 404 | struct usb_device *udev; |
| 404 | int error, r, lpm_disable_error; | 405 | int i, j, error, r, lpm_disable_error; |
| 405 | 406 | ||
| 406 | intf->condition = USB_INTERFACE_UNBINDING; | 407 | intf->condition = USB_INTERFACE_UNBINDING; |
| 407 | 408 | ||
| @@ -425,6 +426,26 @@ static int usb_unbind_interface(struct device *dev) | |||
| 425 | driver->disconnect(intf); | 426 | driver->disconnect(intf); |
| 426 | usb_cancel_queued_reset(intf); | 427 | usb_cancel_queued_reset(intf); |
| 427 | 428 | ||
| 429 | /* Free streams */ | ||
| 430 | for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { | ||
| 431 | ep = &intf->cur_altsetting->endpoint[i]; | ||
| 432 | if (ep->streams == 0) | ||
| 433 | continue; | ||
| 434 | if (j == 0) { | ||
| 435 | eps = kmalloc(USB_MAXENDPOINTS * sizeof(void *), | ||
| 436 | GFP_KERNEL); | ||
| 437 | if (!eps) { | ||
| 438 | dev_warn(dev, "oom, leaking streams\n"); | ||
| 439 | break; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | eps[j++] = ep; | ||
| 443 | } | ||
| 444 | if (j) { | ||
| 445 | usb_free_streams(intf, eps, j, GFP_KERNEL); | ||
| 446 | kfree(eps); | ||
| 447 | } | ||
| 448 | |||
| 428 | /* Reset other interface state. | 449 | /* Reset other interface state. |
| 429 | * We cannot do a Set-Interface if the device is suspended or | 450 | * We cannot do a Set-Interface if the device is suspended or |
| 430 | * if it is prepared for a system sleep (since installing a new | 451 | * if it is prepared for a system sleep (since installing a new |
