diff options
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8d7fcbbe6ad..5c72c431bab 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -40,7 +40,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); /* TODO: copied from ehci-hcd.c - can this be refactored? */ /* - * handshake - spin reading hc until handshake completes or fails + * xhci_handshake - spin reading hc until handshake completes or fails * @ptr: address of hc register to be read * @mask: bits to look at in result of read * @done: value of those bits when handshake succeeds @@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); * handshake done). There are two failure modes: "usec" have passed (major * hardware flakeout), or the register reads as all-ones (hardware removed). */ -int handshake(struct xhci_hcd *xhci, void __iomem *ptr, +int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, u32 mask, u32 done, int usec) { u32 result; @@ -103,7 +103,7 @@ int xhci_halt(struct xhci_hcd *xhci) xhci_dbg(xhci, "// Halt the HC\n"); xhci_quiesce(xhci); - ret = handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (!ret) { xhci->xhc_state |= XHCI_STATE_HALTED; @@ -132,7 +132,7 @@ static int xhci_start(struct xhci_hcd *xhci) * Wait for the HCHalted Status bit to be 0 to indicate the host is * running. */ - ret = handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, 0, XHCI_MAX_HALT_USEC); if (ret == -ETIMEDOUT) xhci_err(xhci, "Host took too long to start, " @@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci) command |= CMD_RESET; xhci_writel(xhci, command, &xhci->op_regs->command); - ret = handshake(xhci, &xhci->op_regs->command, + ret = xhci_handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 10 * 1000 * 1000); if (ret) return ret; @@ -177,7 +177,7 @@ int xhci_reset(struct xhci_hcd *xhci) * xHCI cannot write to any doorbells or operational registers other * than status until the "Controller Not Ready" flag is cleared. */ - ret = handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 10 * 1000 * 1000); for (i = 0; i < 2; ++i) { @@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void) if (strstr(dmi_product_name, "Z420") || strstr(dmi_product_name, "Z620") || - strstr(dmi_product_name, "Z820")) + strstr(dmi_product_name, "Z820") || + strstr(dmi_product_name, "Z1 Workstation")) return true; return false; @@ -879,6 +880,10 @@ int xhci_suspend(struct xhci_hcd *xhci) struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 command; + if (hcd->state != HC_STATE_SUSPENDED || + xhci->shared_hcd->state != HC_STATE_SUSPENDED) + return -EINVAL; + spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); @@ -889,7 +894,7 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command &= ~CMD_RUN; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); spin_unlock_irq(&xhci->lock); @@ -904,7 +909,8 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CSS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { + if (xhci_handshake(xhci, &xhci->op_regs->status, + STS_SAVE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC save state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; @@ -966,7 +972,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CRS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(xhci, &xhci->op_regs->status, STS_RESTORE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); @@ -1034,7 +1040,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_RUN; xhci_writel(xhci, command, &xhci->op_regs->command); - handshake(xhci, &xhci->op_regs->status, STS_HALT, + xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, 0, 250 * 1000); /* step 5: walk topology and initialize portsc, @@ -1626,7 +1632,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct xhci_hcd *xhci; struct xhci_container_ctx *in_ctx, *out_ctx; unsigned int ep_index; - struct xhci_ep_ctx *ep_ctx; struct xhci_slot_ctx *slot_ctx; struct xhci_input_control_ctx *ctrl_ctx; u32 added_ctxs; @@ -1662,7 +1667,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, out_ctx = virt_dev->out_ctx; ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ep_index = xhci_get_endpoint_index(&ep->desc); - ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); /* If this endpoint is already in use, and the upper layers are trying * to add it again without dropping it, reject the addition. @@ -1816,6 +1820,8 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, case COMP_EBADSLT: dev_warn(&udev->dev, "WARN: slot not enabled for" "evaluate context command.\n"); + ret = -EINVAL; + break; case COMP_CTX_STATE: dev_warn(&udev->dev, "WARN: invalid context state for " "evaluate context command.\n"); @@ -2253,7 +2259,7 @@ static bool xhci_is_async_ep(unsigned int ep_type) static bool xhci_is_sync_in_ep(unsigned int ep_type) { - return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP); + return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP); } static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw) @@ -3873,7 +3879,8 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, spin_lock_irqsave(&xhci->lock, flags); /* Check L1 Status */ - ret = handshake(xhci, pm_addr, PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); + ret = xhci_handshake(xhci, pm_addr, + PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); if (ret != -ETIMEDOUT) { /* enter L1 successfully */ temp = xhci_readl(xhci, addr); @@ -4020,7 +4027,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) static unsigned long long xhci_service_interval_to_ns( struct usb_endpoint_descriptor *desc) { - return (1 << (desc->bInterval - 1)) * 125 * 1000; + return (1ULL << (desc->bInterval - 1)) * 125 * 1000; } static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, @@ -4141,7 +4148,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev, (xhci_service_interval_to_ns(desc) > timeout_ns)) timeout_ns = xhci_service_interval_to_ns(desc); - u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000; + u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL; if (u2_del_ns > timeout_ns) timeout_ns = u2_del_ns; |