diff options
author | Mathias Nyman <mathias.nyman@linux.intel.com> | 2019-06-18 17:27:48 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-06-25 06:34:44 +0300 |
commit | ee742005831ce1ab34cefe7e9a9183609735cadc (patch) | |
tree | ff61e28bd0a11a12d9f3c1087cfe32dc22dcb885 /drivers/usb/host | |
parent | 94207779337a5cf47dbb3218995c33a4041ebd12 (diff) | |
download | linux-ee742005831ce1ab34cefe7e9a9183609735cadc.tar.xz |
xhci: detect USB 3.2 capable host controllers correctly
commit ddd57980a0fde30f7b5d14b888a2cc84d01610e8 upstream.
USB 3.2 capability in a host can be detected from the
xHCI Supported Protocol Capability major and minor revision fields.
If major is 0x3 and minor 0x20 then the host is USB 3.2 capable.
For USB 3.2 capable hosts set the root hub lane count to 2.
The Major Revision and Minor Revision fields contain a BCD version number.
The value of the Major Revision field is JJh and the value of the Minor
Revision field is MNh for version JJ.M.N, where JJ = major revision number,
M - minor version number, N = sub-minor version number,
e.g. version 3.1 is represented with a value of 0310h.
Also fix the extra whitespace printed out when announcing regular
SuperSpeed hosts.
Cc: <stable@vger.kernel.org> # v4.18+
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/xhci.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 448e3f812833..6bc928b9e7a6 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5029,16 +5029,26 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) } else { /* * Some 3.1 hosts return sbrn 0x30, use xhci supported protocol - * minor revision instead of sbrn + * minor revision instead of sbrn. Minor revision is a two digit + * BCD containing minor and sub-minor numbers, only show minor. */ - minor_rev = xhci->usb3_rhub.min_rev; - if (minor_rev) { + minor_rev = xhci->usb3_rhub.min_rev / 0x10; + + switch (minor_rev) { + case 2: + hcd->speed = HCD_USB32; + hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; + hcd->self.root_hub->rx_lanes = 2; + hcd->self.root_hub->tx_lanes = 2; + break; + case 1: hcd->speed = HCD_USB31; hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; + break; } - xhci_info(xhci, "Host supports USB 3.%x %s SuperSpeed\n", + xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n", minor_rev, - minor_rev ? "Enhanced" : ""); + minor_rev ? "Enhanced " : ""); xhci->usb3_rhub.hcd = hcd; /* xHCI private pointer was set in xhci_pci_probe for the second |