xhci: Make roothub functions deal with device removal.
authorSarah Sharp <sarah.a.sharp@linux.intel.com>
Fri, 29 Oct 2010 21:37:23 +0000 (14:37 -0700)
committerSarah Sharp <sarah.a.sharp@linux.intel.com>
Mon, 14 Mar 2011 01:23:44 +0000 (18:23 -0700)
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>
drivers/usb/host/xhci-hub.c

index 191ebc5..770f84c 100644 (file)
@@ -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(