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 8953ded6954..a3cdb09734a 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -248,7 +248,7 @@ struct hc_driver {  	/* xHCI specific functions */  		/* Called by usb_alloc_dev to alloc HC device structures */  	int	(*alloc_dev)(struct usb_hcd *, struct usb_device *); -		/* Called by usb_release_dev to free HC device structures */ +		/* Called by usb_disconnect to free HC device structures */  	void	(*free_dev)(struct usb_hcd *, struct usb_device *);  	/* Bandwidth computation functions */ diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0e0a190bbd0..e198ff8a11c 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)  		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; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 32966ccdff6..1297e9b16a5 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)  	hcd = bus_to_hcd(udev->bus);  	usb_destroy_configuration(udev); -	/* 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_put_hcd(hcd);  	kfree(udev->product);  	kfree(udev->manufacturer);  |