aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/hub.c12
-rw-r--r--drivers/usb/core/usb.c3
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
1527static 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:
3166loop: 3177loop:
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);