diff options
-rw-r--r-- | drivers/usb/core/hcd.h | 2 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 12 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 3 |
3 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 8953ded69541..a3cdb09734ab 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -248,7 +248,7 @@ struct hc_driver { | |||
248 | /* xHCI specific functions */ | 248 | /* xHCI specific functions */ |
249 | /* Called by usb_alloc_dev to alloc HC device structures */ | 249 | /* Called by usb_alloc_dev to alloc HC device structures */ |
250 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | 250 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); |
251 | /* Called by usb_release_dev to free HC device structures */ | 251 | /* Called by usb_disconnect to free HC device structures */ |
252 | void (*free_dev)(struct usb_hcd *, struct usb_device *); | 252 | void (*free_dev)(struct usb_hcd *, struct usb_device *); |
253 | 253 | ||
254 | /* Bandwidth computation functions */ | 254 | /* Bandwidth computation functions */ |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0e0a190bbd00..e198ff8a11c0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1524,6 +1524,15 @@ static void update_address(struct usb_device *udev, int devnum) | |||
1524 | udev->devnum = devnum; | 1524 | udev->devnum = devnum; |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | static void hub_free_dev(struct usb_device *udev) | ||
1528 | { | ||
1529 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1530 | |||
1531 | /* Root hubs aren't real devices, so don't free HCD resources */ | ||
1532 | if (hcd->driver->free_dev && udev->parent) | ||
1533 | hcd->driver->free_dev(hcd, udev); | ||
1534 | } | ||
1535 | |||
1527 | /** | 1536 | /** |
1528 | * usb_disconnect - disconnect a device (usbcore-internal) | 1537 | * usb_disconnect - disconnect a device (usbcore-internal) |
1529 | * @pdev: pointer to device being disconnected | 1538 | * @pdev: pointer to device being disconnected |
@@ -1592,6 +1601,8 @@ void usb_disconnect(struct usb_device **pdev) | |||
1592 | *pdev = NULL; | 1601 | *pdev = NULL; |
1593 | spin_unlock_irq(&device_state_lock); | 1602 | spin_unlock_irq(&device_state_lock); |
1594 | 1603 | ||
1604 | hub_free_dev(udev); | ||
1605 | |||
1595 | put_device(&udev->dev); | 1606 | put_device(&udev->dev); |
1596 | } | 1607 | } |
1597 | 1608 | ||
@@ -3166,6 +3177,7 @@ loop_disable: | |||
3166 | loop: | 3177 | loop: |
3167 | usb_ep0_reinit(udev); | 3178 | usb_ep0_reinit(udev); |
3168 | release_address(udev); | 3179 | release_address(udev); |
3180 | hub_free_dev(udev); | ||
3169 | usb_put_dev(udev); | 3181 | usb_put_dev(udev); |
3170 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | 3182 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) |
3171 | break; | 3183 | break; |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 32966ccdff63..1297e9b16a51 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -225,9 +225,6 @@ static void usb_release_dev(struct device *dev) | |||
225 | hcd = bus_to_hcd(udev->bus); | 225 | hcd = bus_to_hcd(udev->bus); |
226 | 226 | ||
227 | usb_destroy_configuration(udev); | 227 | usb_destroy_configuration(udev); |
228 | /* Root hubs aren't real devices, so don't free HCD resources */ | ||
229 | if (hcd->driver->free_dev && udev->parent) | ||
230 | hcd->driver->free_dev(hcd, udev); | ||
231 | usb_put_hcd(hcd); | 228 | usb_put_hcd(hcd); |
232 | kfree(udev->product); | 229 | kfree(udev->product); |
233 | kfree(udev->manufacturer); | 230 | kfree(udev->manufacturer); |