xhci: define the new default speed ID for SuperSpeedPlus used by xhci hw
authorMathias Nyman <mathias.nyman@linux.intel.com>
Thu, 1 Oct 2015 15:40:36 +0000 (18:40 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 4 Oct 2015 09:34:17 +0000 (10:34 +0100)
USB 3.1 capable xhci controllers use a new default speed ID "5" in the
PORTSC register to represent a 10Gbps connection speed of a SuperSpeedPlus
device

Make sure the xhci driver can handle the returned SuperSpeedPlus speed ID
properly

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.h

index a7a0c64d17ab773b81c5af518e8df6e4cfe2dfed..483b5f8cb9510efc437379d4c9c0f2cd6d881b79 100644 (file)
@@ -713,7 +713,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
                        status |= USB_PORT_STAT_SUSPEND;
        }
        if ((raw_port_status & PORT_PLS_MASK) == XDEV_RESUME &&
-                       !DEV_SUPERSPEED(raw_port_status)) {
+               !DEV_SUPERSPEED_ANY(raw_port_status)) {
                if ((raw_port_status & PORT_RESET) ||
                                !(raw_port_status & PORT_PE))
                        return 0xffffffff;
@@ -1311,14 +1311,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
                u32 temp;
 
                temp = readl(port_array[port_index]);
-               if (DEV_SUPERSPEED(temp))
+               if (DEV_SUPERSPEED_ANY(temp))
                        temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
                else
                        temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
                if (test_bit(port_index, &bus_state->bus_suspended) &&
                    (temp & PORT_PLS_MASK)) {
                        set_bit(port_index, &port_was_suspended);
-                       if (!DEV_SUPERSPEED(temp)) {
+                       if (!DEV_SUPERSPEED_ANY(temp)) {
                                xhci_set_link_state(xhci, port_array,
                                                port_index, XDEV_RESUME);
                                need_usb2_u3_exit = true;
index 43291f93afeb59a90a3b39cbb045a26b3bd1ad5b..0e5aa8751c0547cdba1a89752f3cfd81f957ca67 100644 (file)
@@ -1567,7 +1567,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
                        goto cleanup;
                }
 
-               if (DEV_SUPERSPEED(temp)) {
+               if (DEV_SUPERSPEED_ANY(temp)) {
                        xhci_dbg(xhci, "remote wake SS port %d\n", port_id);
                        /* Set a flag to say the port signaled remote wakeup,
                         * so we can tell the difference between the end of
@@ -1595,7 +1595,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
        }
 
        if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_U0 &&
-                       DEV_SUPERSPEED(temp)) {
+                       DEV_SUPERSPEED_ANY(temp)) {
                xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
                /* We've just brought the device into U0 through either the
                 * Resume state after a device remote wakeup, or through the
@@ -1625,7 +1625,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
         * RExit to a disconnect state).  If so, let the the driver know it's
         * out of the RExit state.
         */
-       if (!DEV_SUPERSPEED(temp) &&
+       if (!DEV_SUPERSPEED_ANY(temp) &&
                        test_and_clear_bit(faked_port_index,
                                &bus_state->rexit_ports)) {
                complete(&bus_state->rexit_done[faked_port_index]);
index cd4a6e795329d0be186fa95edd76180037b31eec..e2c76e2108176850a049d31998e19fd7bdde8f01 100644 (file)
@@ -327,11 +327,15 @@ struct xhci_op_regs {
 #define        XDEV_LS                 (0x2 << 10)
 #define        XDEV_HS                 (0x3 << 10)
 #define        XDEV_SS                 (0x4 << 10)
+#define        XDEV_SSP                (0x5 << 10)
 #define DEV_UNDEFSPEED(p)      (((p) & DEV_SPEED_MASK) == (0x0<<10))
 #define DEV_FULLSPEED(p)       (((p) & DEV_SPEED_MASK) == XDEV_FS)
 #define DEV_LOWSPEED(p)                (((p) & DEV_SPEED_MASK) == XDEV_LS)
 #define DEV_HIGHSPEED(p)       (((p) & DEV_SPEED_MASK) == XDEV_HS)
 #define DEV_SUPERSPEED(p)      (((p) & DEV_SPEED_MASK) == XDEV_SS)
+#define DEV_SUPERSPEEDPLUS(p)  (((p) & DEV_SPEED_MASK) == XDEV_SSP)
+#define DEV_SUPERSPEED_ANY(p)  (((p) & DEV_SPEED_MASK) >= XDEV_SS)
+
 /* Bits 20:23 in the Slot Context are the speed for the device */
 #define        SLOT_SPEED_FS           (XDEV_FS << 10)
 #define        SLOT_SPEED_LS           (XDEV_LS << 10)