diff options
Diffstat (limited to 'drivers')
-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 bbe2b924aae8..89613a744236 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 35cc8b9ba1f5..9cc0abae7923 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1554,6 +1554,15 @@ static inline void usb_stop_pm(struct usb_device *udev) | |||
1554 | 1554 | ||
1555 | #endif | 1555 | #endif |
1556 | 1556 | ||
1557 | static void hub_free_dev(struct usb_device *udev) | ||
1558 | { | ||
1559 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1560 | |||
1561 | /* Root hubs aren't real devices, so don't free HCD resources */ | ||
1562 | if (hcd->driver->free_dev && udev->parent) | ||
1563 | hcd->driver->free_dev(hcd, udev); | ||
1564 | } | ||
1565 | |||
1557 | /** | 1566 | /** |
1558 | * usb_disconnect - disconnect a device (usbcore-internal) | 1567 | * usb_disconnect - disconnect a device (usbcore-internal) |
1559 | * @pdev: pointer to device being disconnected | 1568 | * @pdev: pointer to device being disconnected |
@@ -1624,6 +1633,8 @@ void usb_disconnect(struct usb_device **pdev) | |||
1624 | 1633 | ||
1625 | usb_stop_pm(udev); | 1634 | usb_stop_pm(udev); |
1626 | 1635 | ||
1636 | hub_free_dev(udev); | ||
1637 | |||
1627 | put_device(&udev->dev); | 1638 | put_device(&udev->dev); |
1628 | } | 1639 | } |
1629 | 1640 | ||
@@ -3191,6 +3202,7 @@ loop_disable: | |||
3191 | loop: | 3202 | loop: |
3192 | usb_ep0_reinit(udev); | 3203 | usb_ep0_reinit(udev); |
3193 | release_address(udev); | 3204 | release_address(udev); |
3205 | hub_free_dev(udev); | ||
3194 | usb_put_dev(udev); | 3206 | usb_put_dev(udev); |
3195 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) | 3207 | if ((status == -ENOTCONN) || (status == -ENOTSUPP)) |
3196 | break; | 3208 | break; |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0daff0d968ba..ced0776b9ee9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -228,9 +228,6 @@ static void usb_release_dev(struct device *dev) | |||
228 | hcd = bus_to_hcd(udev->bus); | 228 | hcd = bus_to_hcd(udev->bus); |
229 | 229 | ||
230 | usb_destroy_configuration(udev); | 230 | usb_destroy_configuration(udev); |
231 | /* Root hubs aren't real devices, so don't free HCD resources */ | ||
232 | if (hcd->driver->free_dev && udev->parent) | ||
233 | hcd->driver->free_dev(hcd, udev); | ||
234 | usb_put_hcd(hcd); | 231 | usb_put_hcd(hcd); |
235 | kfree(udev->product); | 232 | kfree(udev->product); |
236 | kfree(udev->manufacturer); | 233 | kfree(udev->manufacturer); |