|
@@ -359,21 +359,19 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
|
|
xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
|
|
xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
|
|
&xhci->op_regs->cmd_ring);
|
|
&xhci->op_regs->cmd_ring);
|
|
|
|
|
|
- /* Section 4.6.1.2 of xHCI 1.0 spec says software should
|
|
|
|
- * time the completion od all xHCI commands, including
|
|
|
|
- * the Command Abort operation. If software doesn't see
|
|
|
|
- * CRR negated in a timely manner (e.g. longer than 5
|
|
|
|
- * seconds), then it should assume that the there are
|
|
|
|
- * larger problems with the xHC and assert HCRST.
|
|
|
|
|
|
+ /* Section 4.6.1.2 of xHCI 1.0 spec says software should also time the
|
|
|
|
+ * completion of the Command Abort operation. If CRR is not negated in 5
|
|
|
|
+ * seconds then driver handles it as if host died (-ENODEV).
|
|
|
|
+ * In the future we should distinguish between -ENODEV and -ETIMEDOUT
|
|
|
|
+ * and try to recover a -ETIMEDOUT with a host controller reset.
|
|
*/
|
|
*/
|
|
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
|
|
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
|
|
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
|
|
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
- xhci_err(xhci,
|
|
|
|
- "Stop command ring failed, maybe the host is dead\n");
|
|
|
|
- xhci->xhc_state |= XHCI_STATE_DYING;
|
|
|
|
|
|
+ xhci_err(xhci, "Abort failed to stop command ring: %d\n", ret);
|
|
xhci_halt(xhci);
|
|
xhci_halt(xhci);
|
|
- return -ESHUTDOWN;
|
|
|
|
|
|
+ xhci_hc_died(xhci);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
/*
|
|
/*
|
|
* Writing the CMD_RING_ABORT bit should cause a cmd completion event,
|
|
* Writing the CMD_RING_ABORT bit should cause a cmd completion event,
|
|
@@ -873,6 +871,40 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * host controller died, register read returns 0xffffffff
|
|
|
|
+ * Complete pending commands, mark them ABORTED.
|
|
|
|
+ * URBs need to be given back as usb core might be waiting with device locks
|
|
|
|
+ * held for the URBs to finish during device disconnect, blocking host remove.
|
|
|
|
+ *
|
|
|
|
+ * Call with xhci->lock held.
|
|
|
|
+ * lock is relased and re-acquired while giving back urb.
|
|
|
|
+ */
|
|
|
|
+void xhci_hc_died(struct xhci_hcd *xhci)
|
|
|
|
+{
|
|
|
|
+ int i, j;
|
|
|
|
+
|
|
|
|
+ if (xhci->xhc_state & XHCI_STATE_DYING)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ xhci_err(xhci, "xHCI host controller not responding, assume dead\n");
|
|
|
|
+ xhci->xhc_state |= XHCI_STATE_DYING;
|
|
|
|
+
|
|
|
|
+ xhci_cleanup_command_queue(xhci);
|
|
|
|
+
|
|
|
|
+ /* return any pending urbs, remove may be waiting for them */
|
|
|
|
+ for (i = 0; i <= HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
|
|
|
|
+ if (!xhci->devs[i])
|
|
|
|
+ continue;
|
|
|
|
+ for (j = 0; j < 31; j++)
|
|
|
|
+ xhci_kill_endpoint_urbs(xhci, i, j);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* inform usb core hc died if PCI remove isn't already handling it */
|
|
|
|
+ if (!(xhci->xhc_state & XHCI_STATE_REMOVING))
|
|
|
|
+ usb_hc_died(xhci_to_hcd(xhci));
|
|
|
|
+}
|
|
|
|
+
|
|
/* Watchdog timer function for when a stop endpoint command fails to complete.
|
|
/* Watchdog timer function for when a stop endpoint command fails to complete.
|
|
* In this case, we assume the host controller is broken or dying or dead. The
|
|
* In this case, we assume the host controller is broken or dying or dead. The
|
|
* host may still be completing some other events, so we have to be careful to
|
|
* host may still be completing some other events, so we have to be careful to
|
|
@@ -894,7 +926,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
|
|
{
|
|
{
|
|
struct xhci_hcd *xhci;
|
|
struct xhci_hcd *xhci;
|
|
struct xhci_virt_ep *ep;
|
|
struct xhci_virt_ep *ep;
|
|
- int ret, i, j;
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
ep = (struct xhci_virt_ep *) arg;
|
|
ep = (struct xhci_virt_ep *) arg;
|
|
@@ -911,52 +942,22 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
|
|
}
|
|
}
|
|
|
|
|
|
xhci_warn(xhci, "xHCI host not responding to stop endpoint command.\n");
|
|
xhci_warn(xhci, "xHCI host not responding to stop endpoint command.\n");
|
|
- xhci_warn(xhci, "Assuming host is dying, halting host.\n");
|
|
|
|
- /* Oops, HC is dead or dying or at least not responding to the stop
|
|
|
|
- * endpoint command.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- xhci->xhc_state |= XHCI_STATE_DYING;
|
|
|
|
ep->ep_state &= ~EP_STOP_CMD_PENDING;
|
|
ep->ep_state &= ~EP_STOP_CMD_PENDING;
|
|
|
|
|
|
- /* Disable interrupts from the host controller and start halting it */
|
|
|
|
- xhci_quiesce(xhci);
|
|
|
|
- spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
|
|
|
+ xhci_halt(xhci);
|
|
|
|
|
|
- ret = xhci_halt(xhci);
|
|
|
|
|
|
+ /*
|
|
|
|
+ * handle a stop endpoint cmd timeout as if host died (-ENODEV).
|
|
|
|
+ * In the future we could distinguish between -ENODEV and -ETIMEDOUT
|
|
|
|
+ * and try to recover a -ETIMEDOUT with a host controller reset
|
|
|
|
+ */
|
|
|
|
+ xhci_hc_died(xhci);
|
|
|
|
|
|
- spin_lock_irqsave(&xhci->lock, flags);
|
|
|
|
- if (ret < 0) {
|
|
|
|
- /* This is bad; the host is not responding to commands and it's
|
|
|
|
- * not allowing itself to be halted. At least interrupts are
|
|
|
|
- * disabled. If we call usb_hc_died(), it will attempt to
|
|
|
|
- * disconnect all device drivers under this host. Those
|
|
|
|
- * disconnect() methods will wait for all URBs to be unlinked,
|
|
|
|
- * so we must complete them.
|
|
|
|
- */
|
|
|
|
- xhci_warn(xhci, "Non-responsive xHCI host is not halting.\n");
|
|
|
|
- xhci_warn(xhci, "Completing active URBs anyway.\n");
|
|
|
|
- /* We could turn all TDs on the rings to no-ops. This won't
|
|
|
|
- * help if the host has cached part of the ring, and is slow if
|
|
|
|
- * we want to preserve the cycle bit. Skip it and hope the host
|
|
|
|
- * doesn't touch the memory.
|
|
|
|
- */
|
|
|
|
- }
|
|
|
|
- for (i = 0; i < MAX_HC_SLOTS; i++) {
|
|
|
|
- if (!xhci->devs[i])
|
|
|
|
- continue;
|
|
|
|
- for (j = 0; j < 31; j++)
|
|
|
|
- xhci_kill_endpoint_urbs(xhci, i, j);
|
|
|
|
- }
|
|
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
|
- xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
|
|
- "Calling usb_hc_died()");
|
|
|
|
- usb_hc_died(xhci_to_hcd(xhci));
|
|
|
|
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
|
"xHCI host controller is dead.");
|
|
"xHCI host controller is dead.");
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,
|
|
static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,
|
|
struct xhci_virt_device *dev,
|
|
struct xhci_virt_device *dev,
|
|
struct xhci_ring *ep_ring,
|
|
struct xhci_ring *ep_ring,
|
|
@@ -1291,7 +1292,6 @@ void xhci_cleanup_command_queue(struct xhci_hcd *xhci)
|
|
void xhci_handle_command_timeout(struct work_struct *work)
|
|
void xhci_handle_command_timeout(struct work_struct *work)
|
|
{
|
|
{
|
|
struct xhci_hcd *xhci;
|
|
struct xhci_hcd *xhci;
|
|
- int ret;
|
|
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
u64 hw_ring_state;
|
|
u64 hw_ring_state;
|
|
|
|
|
|
@@ -1312,22 +1312,17 @@ void xhci_handle_command_timeout(struct work_struct *work)
|
|
|
|
|
|
/* Make sure command ring is running before aborting it */
|
|
/* Make sure command ring is running before aborting it */
|
|
hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
|
|
hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
|
|
|
|
+ if (hw_ring_state == ~(u64)0) {
|
|
|
|
+ xhci_hc_died(xhci);
|
|
|
|
+ goto time_out_completed;
|
|
|
|
+ }
|
|
|
|
+
|
|
if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
|
|
if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
|
|
(hw_ring_state & CMD_RING_RUNNING)) {
|
|
(hw_ring_state & CMD_RING_RUNNING)) {
|
|
/* Prevent new doorbell, and start command abort */
|
|
/* Prevent new doorbell, and start command abort */
|
|
xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
|
|
xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
|
|
xhci_dbg(xhci, "Command timeout\n");
|
|
xhci_dbg(xhci, "Command timeout\n");
|
|
- ret = xhci_abort_cmd_ring(xhci, flags);
|
|
|
|
- if (unlikely(ret == -ESHUTDOWN)) {
|
|
|
|
- xhci_err(xhci, "Abort command ring failed\n");
|
|
|
|
- xhci_cleanup_command_queue(xhci);
|
|
|
|
- spin_unlock_irqrestore(&xhci->lock, flags);
|
|
|
|
- usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
|
|
|
|
- xhci_dbg(xhci, "xHCI host controller is dead.\n");
|
|
|
|
-
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ xhci_abort_cmd_ring(xhci, flags);
|
|
goto time_out_completed;
|
|
goto time_out_completed;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2695,7 +2690,8 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
|
|
spin_lock(&xhci->lock);
|
|
spin_lock(&xhci->lock);
|
|
/* Check if the xHC generated the interrupt, or the irq is shared */
|
|
/* Check if the xHC generated the interrupt, or the irq is shared */
|
|
status = readl(&xhci->op_regs->status);
|
|
status = readl(&xhci->op_regs->status);
|
|
- if (status == 0xffffffff) {
|
|
|
|
|
|
+ if (status == ~(u32)0) {
|
|
|
|
+ xhci_hc_died(xhci);
|
|
ret = IRQ_HANDLED;
|
|
ret = IRQ_HANDLED;
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|