summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-pci.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2013-12-06 05:07:27 +0400
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2013-12-11 01:54:37 +0400
commit48fc7dbd52c0559647291f33a10ccdc6cdbe4c72 (patch)
tree4a2403420a69b2d40e38a53302771ec3d3eb6b66 /drivers/usb/host/xhci-pci.c
parent40fcd88b8d49fd911518190c985112097d3a8a17 (diff)
downloadlinux-48fc7dbd52c0559647291f33a10ccdc6cdbe4c72.tar.xz
usb: xhci: change enumeration scheme to 'new scheme' by default
Change the default enumeration scheme for xhci attached non-SuperSpeed devices from: Reset SetAddress [xhci address-device BSR = 0] GetDescriptor(8) GetDescriptor(18) ...to: Reset [xhci address-device BSR = 1] GetDescriptor(64) Reset SetAddress [xhci address-device BSR = 0] GetDescriptor(18) ...as some devices misbehave when encountering a SetAddress command prior to GetDescriptor. There are known legacy devices that require this scheme, but testing has found at least one USB3 device that fails enumeration when presented with this ordering. For now, follow the ehci case and enable 'new scheme' by default for non-SuperSpeed devices. To support this enumeration scheme on xhci the AddressDevice operation needs to be performed twice. The first instance of the command enables the HC's device and slot context info for the device, but omits sending the device a SetAddress command (BSR == block set address request). Then, after GetDescriptor completes, follow up with the full AddressDevice+SetAddress operation. As mentioned before, this ordering of events with USB3 devices causes an extra state transition to be exposed to xhci. Previously USB3 devices would transition directly from 'enabled' to 'addressed' and never need to underrun responses to 'get descriptor'. We do see the 64-byte descriptor fetch the correct data, but the following 18-byte descriptor read after the reset gets: bLength = 0 bDescriptorType = 0 bcdUSB = 0 bDeviceClass = 0 bDeviceSubClass = 0 bDeviceProtocol = 0 bMaxPacketSize0 = 9 instead of: bLength = 12 bDescriptorType = 1 bcdUSB = 300 bDeviceClass = 0 bDeviceSubClass = 0 bDeviceProtocol = 0 bMaxPacketSize0 = 9 which results in the discovery process looping until falling back to 'old scheme' enumeration. Acked-by: Alan Stern <stern@rowland.harvard.edu> Reported-by: David Moore <david.moore@gmail.com> Suggested-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci-pci.c')
-rw-r--r--drivers/usb/host/xhci-pci.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index b8dffd59eb25..4221dee924b5 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -331,6 +331,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
.address_device = xhci_address_device,
+ .enable_device = xhci_enable_device,
.update_hub_device = xhci_update_hub_device,
.reset_device = xhci_discover_or_reset_device,