diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 9957bd96d4bc..6e7dc6f93978 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) __le32 __iomem *addr; int raw_port; - if (hcd->speed != HCD_USB3) + if (hcd->speed < HCD_USB3) addr = xhci->usb2_ports[port1 - 1]; else addr = xhci->usb3_ports[port1 - 1]; @@ -4124,7 +4124,7 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd, int hird, exit_latency; int ret; - if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support || + if (hcd->speed >= HCD_USB3 || !xhci->hw_lpm_support || !udev->lpm_capable) return -EPERM; @@ -4241,7 +4241,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_hcd *xhci = hcd_to_xhci(hcd); int portnum = udev->portnum - 1; - if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support || + if (hcd->speed >= HCD_USB3 || !xhci->sw_lpm_support || !udev->lpm_capable) return 0; @@ -4841,8 +4841,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* XHCI controllers don't stop the ep queue on short packets :| */ hcd->self.no_stop_on_short = 1; + xhci = hcd_to_xhci(hcd); + if (usb_hcd_is_primary_hcd(hcd)) { - xhci = hcd_to_xhci(hcd); xhci->main_hcd = hcd; /* Mark the first roothub as being USB 2.0. * 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) */ hcd->has_tt = 1; } else { + if (xhci->sbrn == 0x31) { + xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n"); + hcd->speed = HCD_USB31; + } /* xHCI private pointer was set in xhci_pci_probe for the second * registered roothub. */ @@ -4875,6 +4880,8 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) xhci->hcc_params = readl(&xhci->cap_regs->hc_capbase); xhci->hci_version = HC_VERSION(xhci->hcc_params); xhci->hcc_params = readl(&xhci->cap_regs->hcc_params); + if (xhci->hci_version > 0x100) + xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2); xhci_print_registers(xhci); xhci->quirks = quirks; @@ -4906,6 +4913,16 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) !dma_set_mask(dev, DMA_BIT_MASK(64))) { xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); + } else { + /* + * This is to avoid error in cases where a 32-bit USB + * controller is used on a 64-bit capable system. + */ + retval = dma_set_mask(dev, DMA_BIT_MASK(32)); + if (retval) + return retval; + xhci_dbg(xhci, "Enabling 32-bit DMA addresses.\n"); + dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); } xhci_dbg(xhci, "Calling HCD init\n"); @@ -5020,7 +5037,7 @@ static int __init xhci_hcd_init(void) BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8); BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8); BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8); - BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 7*32/8); + BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 8*32/8); BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8); /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8); |