xhci: Return canceled URBs immediately when host is halted.
When the xHCI host controller is halted, it won't respond to commands placed on the command ring. So if an URB is cancelled after the first roothub is deallocated, it will try to place a stop endpoint command on the command ring, which will fail. The command watchdog timer will fire after five seconds, and the host controller will be marked as dying, and all URBs will be completed. Add a flag to the xHCI's internal state variable for when the host controller is halted. Immediately return the canceled URB if the host controller is halted. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
This commit is contained in:
parent
b320937972
commit
c6cc27c782
2 changed files with 9 additions and 2 deletions
|
@ -98,11 +98,15 @@ void xhci_quiesce(struct xhci_hcd *xhci)
|
|||
*/
|
||||
int xhci_halt(struct xhci_hcd *xhci)
|
||||
{
|
||||
int ret;
|
||||
xhci_dbg(xhci, "// Halt the HC\n");
|
||||
xhci_quiesce(xhci);
|
||||
|
||||
return handshake(xhci, &xhci->op_regs->status,
|
||||
ret = handshake(xhci, &xhci->op_regs->status,
|
||||
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
|
||||
if (!ret)
|
||||
xhci->xhc_state |= XHCI_STATE_HALTED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -129,6 +133,8 @@ int xhci_start(struct xhci_hcd *xhci)
|
|||
xhci_err(xhci, "Host took too long to start, "
|
||||
"waited %u microseconds.\n",
|
||||
XHCI_MAX_HALT_USEC);
|
||||
if (!ret)
|
||||
xhci->xhc_state &= ~XHCI_STATE_HALTED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1212,7 +1218,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
|||
if (ret || !urb->hcpriv)
|
||||
goto done;
|
||||
temp = xhci_readl(xhci, &xhci->op_regs->status);
|
||||
if (temp == 0xffffffff) {
|
||||
if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {
|
||||
xhci_dbg(xhci, "HW died, freeing TD.\n");
|
||||
urb_priv = urb->hcpriv;
|
||||
|
||||
|
|
|
@ -1260,6 +1260,7 @@ struct xhci_hcd {
|
|||
* There are no reports of xHCI host controllers that display this issue.
|
||||
*/
|
||||
#define XHCI_STATE_DYING (1 << 0)
|
||||
#define XHCI_STATE_HALTED (1 << 1)
|
||||
/* Statistics */
|
||||
int error_bitmask;
|
||||
unsigned int quirks;
|
||||
|
|
Reference in a new issue