|
@@ -1524,6 +1524,15 @@ static void update_address(struct usb_device *udev, int devnum)
|
|
|
udev->devnum = devnum;
|
|
|
}
|
|
|
|
|
|
+static void hub_free_dev(struct usb_device *udev)
|
|
|
+{
|
|
|
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
|
|
|
+
|
|
|
+ /* Root hubs aren't real devices, so don't free HCD resources */
|
|
|
+ if (hcd->driver->free_dev && udev->parent)
|
|
|
+ hcd->driver->free_dev(hcd, udev);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* usb_disconnect - disconnect a device (usbcore-internal)
|
|
|
* @pdev: pointer to device being disconnected
|
|
@@ -1592,6 +1601,8 @@ void usb_disconnect(struct usb_device **pdev)
|
|
|
*pdev = NULL;
|
|
|
spin_unlock_irq(&device_state_lock);
|
|
|
|
|
|
+ hub_free_dev(udev);
|
|
|
+
|
|
|
put_device(&udev->dev);
|
|
|
}
|
|
|
|
|
@@ -3166,6 +3177,7 @@ loop_disable:
|
|
|
loop:
|
|
|
usb_ep0_reinit(udev);
|
|
|
release_address(udev);
|
|
|
+ hub_free_dev(udev);
|
|
|
usb_put_dev(udev);
|
|
|
if ((status == -ENOTCONN) || (status == -ENOTSUPP))
|
|
|
break;
|