aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2015-10-01 11:40:38 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-04 05:34:17 -0400
commitb50107bb83d027dfd36bb7efb90570559757d6ae (patch)
treebfdf003f25884dd1e25fea40f80fdb2eb66808be
parent7117522520b9101af7a0602d6b0d1e67d689fc6b (diff)
xhci: check xhci hardware for USB 3.1 support
Set the controller speed to HCD_USB31 to if host hardware supports USB 3.1 For PCI xhci controllers the USB 3.1 support is checked from SBRN bits in pci config space. Platform controllers will need to set xhci->sbrn == 0x31 to indicate USB 3.1 support before calling xhci_gen_setup(). Also make sure xhci driver works correctly with speed set to HCD_USB31 Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/xhci-hub.c24
-rw-r--r--drivers/usb/host/xhci-pci.c6
-rw-r--r--drivers/usb/host/xhci-ring.c10
-rw-r--r--drivers/usb/host/xhci.c13
4 files changed, 30 insertions, 23 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 483b5f8cb951..a4d429ce02a2 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -262,7 +262,7 @@ static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
262 struct usb_hub_descriptor *desc) 262 struct usb_hub_descriptor *desc)
263{ 263{
264 264
265 if (hcd->speed == HCD_USB3) 265 if (hcd->speed >= HCD_USB3)
266 xhci_usb3_hub_descriptor(hcd, xhci, desc); 266 xhci_usb3_hub_descriptor(hcd, xhci, desc);
267 else 267 else
268 xhci_usb2_hub_descriptor(hcd, xhci, desc); 268 xhci_usb2_hub_descriptor(hcd, xhci, desc);
@@ -351,7 +351,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
351 if (!xhci->devs[i]) 351 if (!xhci->devs[i])
352 continue; 352 continue;
353 speed = xhci->devs[i]->udev->speed; 353 speed = xhci->devs[i]->udev->speed;
354 if (((speed == USB_SPEED_SUPER) == (hcd->speed == HCD_USB3)) 354 if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3))
355 && xhci->devs[i]->fake_port == port) { 355 && xhci->devs[i]->fake_port == port) {
356 slot_id = i; 356 slot_id = i;
357 break; 357 break;
@@ -440,7 +440,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
440 u16 wIndex, __le32 __iomem *addr, u32 port_status) 440 u16 wIndex, __le32 __iomem *addr, u32 port_status)
441{ 441{
442 /* Don't allow the USB core to disable SuperSpeed ports. */ 442 /* Don't allow the USB core to disable SuperSpeed ports. */
443 if (hcd->speed == HCD_USB3) { 443 if (hcd->speed >= HCD_USB3) {
444 xhci_dbg(xhci, "Ignoring request to disable " 444 xhci_dbg(xhci, "Ignoring request to disable "
445 "SuperSpeed port.\n"); 445 "SuperSpeed port.\n");
446 return; 446 return;
@@ -508,7 +508,7 @@ static int xhci_get_ports(struct usb_hcd *hcd, __le32 __iomem ***port_array)
508 int max_ports; 508 int max_ports;
509 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 509 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
510 510
511 if (hcd->speed == HCD_USB3) { 511 if (hcd->speed >= HCD_USB3) {
512 max_ports = xhci->num_usb3_ports; 512 max_ports = xhci->num_usb3_ports;
513 *port_array = xhci->usb3_ports; 513 *port_array = xhci->usb3_ports;
514 } else { 514 } else {
@@ -691,7 +691,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
691 if ((raw_port_status & PORT_RC)) 691 if ((raw_port_status & PORT_RC))
692 status |= USB_PORT_STAT_C_RESET << 16; 692 status |= USB_PORT_STAT_C_RESET << 16;
693 /* USB3.0 only */ 693 /* USB3.0 only */
694 if (hcd->speed == HCD_USB3) { 694 if (hcd->speed >= HCD_USB3) {
695 /* Port link change with port in resume state should not be 695 /* Port link change with port in resume state should not be
696 * reported to usbcore, as this is an internal state to be 696 * reported to usbcore, as this is an internal state to be
697 * handled by xhci driver. Reporting PLC to usbcore may 697 * handled by xhci driver. Reporting PLC to usbcore may
@@ -707,7 +707,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
707 status |= USB_PORT_STAT_C_CONFIG_ERROR << 16; 707 status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
708 } 708 }
709 709
710 if (hcd->speed != HCD_USB3) { 710 if (hcd->speed < HCD_USB3) {
711 if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3 711 if ((raw_port_status & PORT_PLS_MASK) == XDEV_U3
712 && (raw_port_status & PORT_POWER)) 712 && (raw_port_status & PORT_POWER))
713 status |= USB_PORT_STAT_SUSPEND; 713 status |= USB_PORT_STAT_SUSPEND;
@@ -770,7 +770,7 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
770 && (raw_port_status & PORT_POWER) 770 && (raw_port_status & PORT_POWER)
771 && (bus_state->suspended_ports & (1 << wIndex))) { 771 && (bus_state->suspended_ports & (1 << wIndex))) {
772 bus_state->suspended_ports &= ~(1 << wIndex); 772 bus_state->suspended_ports &= ~(1 << wIndex);
773 if (hcd->speed != HCD_USB3) 773 if (hcd->speed < HCD_USB3)
774 bus_state->port_c_suspend |= 1 << wIndex; 774 bus_state->port_c_suspend |= 1 << wIndex;
775 } 775 }
776 if (raw_port_status & PORT_CONNECT) { 776 if (raw_port_status & PORT_CONNECT) {
@@ -784,13 +784,13 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,
784 if (raw_port_status & PORT_RESET) 784 if (raw_port_status & PORT_RESET)
785 status |= USB_PORT_STAT_RESET; 785 status |= USB_PORT_STAT_RESET;
786 if (raw_port_status & PORT_POWER) { 786 if (raw_port_status & PORT_POWER) {
787 if (hcd->speed == HCD_USB3) 787 if (hcd->speed >= HCD_USB3)
788 status |= USB_SS_PORT_STAT_POWER; 788 status |= USB_SS_PORT_STAT_POWER;
789 else 789 else
790 status |= USB_PORT_STAT_POWER; 790 status |= USB_PORT_STAT_POWER;
791 } 791 }
792 /* Update Port Link State */ 792 /* Update Port Link State */
793 if (hcd->speed == HCD_USB3) { 793 if (hcd->speed >= HCD_USB3) {
794 xhci_hub_report_usb3_link_state(xhci, &status, raw_port_status); 794 xhci_hub_report_usb3_link_state(xhci, &status, raw_port_status);
795 /* 795 /*
796 * Verify if all USB3 Ports Have entered U0 already. 796 * Verify if all USB3 Ports Have entered U0 already.
@@ -835,7 +835,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
835 * descriptor for the USB 3.0 roothub. If not, we stall the 835 * descriptor for the USB 3.0 roothub. If not, we stall the
836 * endpoint, like external hubs do. 836 * endpoint, like external hubs do.
837 */ 837 */
838 if (hcd->speed == HCD_USB3 && 838 if (hcd->speed >= HCD_USB3 &&
839 (wLength < USB_DT_SS_HUB_SIZE || 839 (wLength < USB_DT_SS_HUB_SIZE ||
840 wValue != (USB_DT_SS_HUB << 8))) { 840 wValue != (USB_DT_SS_HUB << 8))) {
841 xhci_dbg(xhci, "Wrong hub descriptor type for " 841 xhci_dbg(xhci, "Wrong hub descriptor type for "
@@ -1040,7 +1040,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
1040 temp = readl(port_array[wIndex]); 1040 temp = readl(port_array[wIndex]);
1041 break; 1041 break;
1042 case USB_PORT_FEAT_U1_TIMEOUT: 1042 case USB_PORT_FEAT_U1_TIMEOUT:
1043 if (hcd->speed != HCD_USB3) 1043 if (hcd->speed < HCD_USB3)
1044 goto error; 1044 goto error;
1045 temp = readl(port_array[wIndex] + PORTPMSC); 1045 temp = readl(port_array[wIndex] + PORTPMSC);
1046 temp &= ~PORT_U1_TIMEOUT_MASK; 1046 temp &= ~PORT_U1_TIMEOUT_MASK;
@@ -1048,7 +1048,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
1048 writel(temp, port_array[wIndex] + PORTPMSC); 1048 writel(temp, port_array[wIndex] + PORTPMSC);
1049 break; 1049 break;
1050 case USB_PORT_FEAT_U2_TIMEOUT: 1050 case USB_PORT_FEAT_U2_TIMEOUT:
1051 if (hcd->speed != HCD_USB3) 1051 if (hcd->speed < HCD_USB3)
1052 goto error; 1052 goto error;
1053 temp = readl(port_array[wIndex] + PORTPMSC); 1053 temp = readl(port_array[wIndex] + PORTPMSC);
1054 temp &= ~PORT_U2_TIMEOUT_MASK; 1054 temp &= ~PORT_U2_TIMEOUT_MASK;
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index c79d33676672..012d7f4c2901 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -200,15 +200,17 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
200 struct pci_dev *pdev = to_pci_dev(hcd->self.controller); 200 struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
201 int retval; 201 int retval;
202 202
203 xhci = hcd_to_xhci(hcd);
204 if (!xhci->sbrn)
205 pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
206
203 retval = xhci_gen_setup(hcd, xhci_pci_quirks); 207 retval = xhci_gen_setup(hcd, xhci_pci_quirks);
204 if (retval) 208 if (retval)
205 return retval; 209 return retval;
206 210
207 xhci = hcd_to_xhci(hcd);
208 if (!usb_hcd_is_primary_hcd(hcd)) 211 if (!usb_hcd_is_primary_hcd(hcd))
209 return 0; 212 return 0;
210 213
211 pci_read_config_byte(pdev, XHCI_SBRN_OFFSET, &xhci->sbrn);
212 xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn); 214 xhci_dbg(xhci, "Got SBRN %u\n", (unsigned int) xhci->sbrn);
213 215
214 /* Find any debug ports */ 216 /* Find any debug ports */
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0e5aa8751c05..48d2d40a53bd 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1453,7 +1453,7 @@ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
1453 * 1.1 ports are under the USB 2.0 hub. If the port speed 1453 * 1.1 ports are under the USB 2.0 hub. If the port speed
1454 * matches the device speed, it's a similar speed port. 1454 * matches the device speed, it's a similar speed port.
1455 */ 1455 */
1456 if ((port_speed == 0x03) == (hcd->speed == HCD_USB3)) 1456 if ((port_speed == 0x03) == (hcd->speed >= HCD_USB3))
1457 num_similar_speed_ports++; 1457 num_similar_speed_ports++;
1458 } 1458 }
1459 return num_similar_speed_ports; 1459 return num_similar_speed_ports;
@@ -1515,7 +1515,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
1515 1515
1516 /* Find the right roothub. */ 1516 /* Find the right roothub. */
1517 hcd = xhci_to_hcd(xhci); 1517 hcd = xhci_to_hcd(xhci);
1518 if ((major_revision == 0x03) != (hcd->speed == HCD_USB3)) 1518 if ((major_revision == 0x03) != (hcd->speed >= HCD_USB3))
1519 hcd = xhci->shared_hcd; 1519 hcd = xhci->shared_hcd;
1520 1520
1521 if (major_revision == 0) { 1521 if (major_revision == 0) {
@@ -1541,7 +1541,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
1541 * correct bus_state structure. 1541 * correct bus_state structure.
1542 */ 1542 */
1543 bus_state = &xhci->bus_state[hcd_index(hcd)]; 1543 bus_state = &xhci->bus_state[hcd_index(hcd)];
1544 if (hcd->speed == HCD_USB3) 1544 if (hcd->speed >= HCD_USB3)
1545 port_array = xhci->usb3_ports; 1545 port_array = xhci->usb3_ports;
1546 else 1546 else
1547 port_array = xhci->usb2_ports; 1547 port_array = xhci->usb2_ports;
@@ -1555,7 +1555,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
1555 usb_hcd_resume_root_hub(hcd); 1555 usb_hcd_resume_root_hub(hcd);
1556 } 1556 }
1557 1557
1558 if (hcd->speed == HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE) 1558 if (hcd->speed >= HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE)
1559 bus_state->port_remote_wakeup &= ~(1 << faked_port_index); 1559 bus_state->port_remote_wakeup &= ~(1 << faked_port_index);
1560 1560
1561 if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) { 1561 if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) {
@@ -1633,7 +1633,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
1633 goto cleanup; 1633 goto cleanup;
1634 } 1634 }
1635 1635
1636 if (hcd->speed != HCD_USB3) 1636 if (hcd->speed < HCD_USB3)
1637 xhci_test_and_clear_bit(xhci, port_array, faked_port_index, 1637 xhci_test_and_clear_bit(xhci, port_array, faked_port_index,
1638 PORT_PLC); 1638 PORT_PLC);
1639 1639
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0ba6c1cc90b4..49a41c7890c8 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3973,7 +3973,7 @@ int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
3973 __le32 __iomem *addr; 3973 __le32 __iomem *addr;
3974 int raw_port; 3974 int raw_port;
3975 3975
3976 if (hcd->speed != HCD_USB3) 3976 if (hcd->speed < HCD_USB3)
3977 addr = xhci->usb2_ports[port1 - 1]; 3977 addr = xhci->usb2_ports[port1 - 1];
3978 else 3978 else
3979 addr = xhci->usb3_ports[port1 - 1]; 3979 addr = xhci->usb3_ports[port1 - 1];
@@ -4124,7 +4124,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
4124 int hird, exit_latency; 4124 int hird, exit_latency;
4125 int ret; 4125 int ret;
4126 4126
4127 if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || 4127 if (hcd->speed >= HCD_USB3 || !xhci->hw_lpm_support ||
4128 !udev->lpm_capable) 4128 !udev->lpm_capable)
4129 return -EPERM; 4129 return -EPERM;
4130 4130
@@ -4241,7 +4241,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
4241 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 4241 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
4242 int portnum = udev->portnum - 1; 4242 int portnum = udev->portnum - 1;
4243 4243
4244 if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support || 4244 if (hcd->speed >= HCD_USB3 || !xhci->sw_lpm_support ||
4245 !udev->lpm_capable) 4245 !udev->lpm_capable)
4246 return 0; 4246 return 0;
4247 4247
@@ -4841,8 +4841,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
4841 /* XHCI controllers don't stop the ep queue on short packets :| */ 4841 /* XHCI controllers don't stop the ep queue on short packets :| */
4842 hcd->self.no_stop_on_short = 1; 4842 hcd->self.no_stop_on_short = 1;
4843 4843
4844 xhci = hcd_to_xhci(hcd);
4845
4844 if (usb_hcd_is_primary_hcd(hcd)) { 4846 if (usb_hcd_is_primary_hcd(hcd)) {
4845 xhci = hcd_to_xhci(hcd);
4846 xhci->main_hcd = hcd; 4847 xhci->main_hcd = hcd;
4847 /* Mark the first roothub as being USB 2.0. 4848 /* Mark the first roothub as being USB 2.0.
4848 * The xHCI driver will register the USB 3.0 roothub. 4849 * The xHCI driver will register the USB 3.0 roothub.
@@ -4856,6 +4857,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
4856 */ 4857 */
4857 hcd->has_tt = 1; 4858 hcd->has_tt = 1;
4858 } else { 4859 } else {
4860 if (xhci->sbrn == 0x31) {
4861 xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n");
4862 hcd->speed = HCD_USB31;
4863 }
4859 /* xHCI private pointer was set in xhci_pci_probe for the second 4864 /* xHCI private pointer was set in xhci_pci_probe for the second
4860 * registered roothub. 4865 * registered roothub.
4861 */ 4866 */