diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-05-21 21:39:42 +0200 | 
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2012-05-21 21:39:42 +0200 | 
| commit | 0ad8c6a22d03a1598f7cc6585c65354dadca62ad (patch) | |
| tree | 1507deef3d55d5f3c71b2f76924fe1f6c6211905 /drivers/usb/core/hub.c | |
| parent | 8527f8e2934683e53405fbe876a4e6f4a0c46eb8 (diff) | |
| parent | 76e10d158efb6d4516018846f60c2ab5501900bc (diff) | |
Merge tag 'v3.4' with SCSI updates, needed for subsequent firewire-sbp2 changes
Linux 3.4
Diffstat (limited to 'drivers/usb/core/hub.c')
| -rw-r--r-- | drivers/usb/core/hub.c | 19 | 
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 28664eb7f555..ec6c97dadbe4 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)  {  	struct usb_device	*udev = *pdev;  	int			i; -	struct usb_hcd		*hcd = bus_to_hcd(udev->bus);  	/* mark the device as inactive, so any further urb submissions for  	 * this device (and any of its children) will fail immediately. @@ -1690,9 +1689,7 @@ void usb_disconnect(struct usb_device **pdev)  	 * so that the hardware is now fully quiesced.  	 */  	dev_dbg (&udev->dev, "unregistering device\n"); -	mutex_lock(hcd->bandwidth_mutex);  	usb_disable_device(udev, 0); -	mutex_unlock(hcd->bandwidth_mutex);  	usb_hcd_synchronize_unlinks(udev);  	usb_remove_ep_devs(&udev->ep0); @@ -3163,6 +3160,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,  	if (retval)  		goto fail; +	/* +	 * Some superspeed devices have finished the link training process +	 * and attached to a superspeed hub port, but the device descriptor +	 * got from those devices show they aren't superspeed devices. Warm +	 * reset the port attached by the devices can fix them. +	 */ +	if ((udev->speed == USB_SPEED_SUPER) && +			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) { +		dev_err(&udev->dev, "got a wrong device descriptor, " +				"warm reset device\n"); +		hub_port_reset(hub, port1, udev, +				HUB_BH_RESET_TIME, true); +		retval = -EINVAL; +		goto fail; +	} +  	if (udev->descriptor.bMaxPacketSize0 == 0xff ||  			udev->speed == USB_SPEED_SUPER)  		i = 512;  | 
