]>
Commit | Line | Data |
---|---|---|
3d6a91bc GKH |
1 | From 6dd0a3a7e0793dbeae1b951f091025d8cf896cb4 Mon Sep 17 00:00:00 2001 |
2 | From: Sarah Sharp <sarah.a.sharp@linux.intel.com> | |
3 | Date: Tue, 16 Nov 2010 15:58:52 -0800 | |
4 | Subject: xhci: Don't let the USB core disable SuperSpeed ports. | |
5 | ||
6 | From: Sarah Sharp <sarah.a.sharp@linux.intel.com> | |
7 | ||
8 | commit 6dd0a3a7e0793dbeae1b951f091025d8cf896cb4 upstream. | |
9 | ||
10 | Disabling SuperSpeed ports is a Very Bad Thing (TM). It disables | |
11 | SuperSpeed terminations, which means that devices will never connect at | |
12 | SuperSpeed on that port. For USB 2.0/1.1 ports, disabling the port meant | |
13 | that the USB core could always get a connect status change later. That's | |
14 | not true with USB 3.0 ports. | |
15 | ||
16 | Do not let the USB core disable SuperSpeed ports. We can't rely on the | |
17 | device speed in the port status registers, since that isn't valid until | |
18 | there's a USB device connected to the port. Instead, we use the port | |
19 | speed array that's created from the Extended Capabilities registers. | |
20 | ||
21 | Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> | |
22 | Tested-by: Don Zickus <dzickus@redhat.com> | |
23 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
24 | ||
25 | --- | |
26 | drivers/usb/host/xhci-hub.c | 7 +++++++ | |
27 | 1 file changed, 7 insertions(+) | |
28 | ||
29 | --- a/drivers/usb/host/xhci-hub.c | |
30 | +++ b/drivers/usb/host/xhci-hub.c | |
31 | @@ -132,6 +132,13 @@ static u32 xhci_port_state_to_neutral(u3 | |
32 | static void xhci_disable_port(struct xhci_hcd *xhci, u16 wIndex, | |
33 | u32 __iomem *addr, u32 port_status) | |
34 | { | |
35 | + /* Don't allow the USB core to disable SuperSpeed ports. */ | |
36 | + if (xhci->port_array[wIndex] == 0x03) { | |
37 | + xhci_dbg(xhci, "Ignoring request to disable " | |
38 | + "SuperSpeed port.\n"); | |
39 | + return; | |
40 | + } | |
41 | + | |
42 | /* Write 1 to disable the port */ | |
43 | xhci_writel(xhci, port_status | PORT_PE, addr); | |
44 | port_status = xhci_readl(xhci, addr); |