summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-10-29 21:37:23 (GMT)
committerSarah Sharp <sarah.a.sharp@linux.intel.com>2011-03-14 01:23:44 (GMT)
commitf9de8151877b4f01cc8e124b0e213a6c6c78d970 (patch)
treefa1fb7231c83430c098f20511ab99909fe1c2544 /drivers/usb
parentd30b2a208108a0b0fdeae7006b8824d9be16ca96 (diff)
downloadlinux-f9de8151877b4f01cc8e124b0e213a6c6c78d970.tar.xz
xhci: Make roothub functions deal with device removal.
Return early in the roothub control and status functions if the xHCI host controller is not electrically present in the system (register reads return all "fs"). This issue only shows up when the xHCI driver registers two roothubs and the host controller is removed from the system. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-hub.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 191ebc5..770f84c 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -418,6 +418,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
wIndex--;
status = 0;
temp = xhci_readl(xhci, port_array[wIndex]);
+ if (temp == 0xffffffff) {
+ retval = -ENODEV;
+ break;
+ }
xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp);
/* FIXME - should we return a port status value like the USB
@@ -492,6 +496,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
goto error;
wIndex--;
temp = xhci_readl(xhci, port_array[wIndex]);
+ if (temp == 0xffffffff) {
+ retval = -ENODEV;
+ break;
+ }
temp = xhci_port_state_to_neutral(temp);
/* FIXME: What new port features do we need to support? */
switch (wValue) {
@@ -562,6 +570,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
goto error;
wIndex--;
temp = xhci_readl(xhci, port_array[wIndex]);
+ if (temp == 0xffffffff) {
+ retval = -ENODEV;
+ break;
+ }
/* FIXME: What new port features do we need to support? */
temp = xhci_port_state_to_neutral(temp);
switch (wValue) {
@@ -677,6 +689,10 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
/* For each port, did anything change? If so, set that bit in buf. */
for (i = 0; i < ports; i++) {
temp = xhci_readl(xhci, port_array[i]);
+ if (temp == 0xffffffff) {
+ retval = -ENODEV;
+ break;
+ }
if ((temp & mask) != 0 ||
(bus_state->port_c_suspend & 1 << i) ||
(bus_state->resume_done[i] && time_after_eq(