xhci: give command abortion one more chance before killing xhci
authorMathias Nyman <mathias.nyman@linux.intel.com>
Mon, 21 Sep 2015 14:46:10 +0000 (17:46 +0300)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 13 Oct 2015 02:46:10 +0000 (03:46 +0100)
commit a6809ffd1687b3a8c192960e69add559b9d32649 upstream.

We want to give the command abortion an additional try to stop
the command ring before we completely hose xhci.

Tested-by: Vincent Pelletier <plr.vincent@gmail.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: call handshake() rather than xhci_handshake()]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/usb/host/xhci-ring.c

index 26b498b..10240f2 100644 (file)
@@ -350,6 +350,15 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
        ret = handshake(xhci, &xhci->op_regs->cmd_ring,
                        CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
        if (ret < 0) {
        ret = handshake(xhci, &xhci->op_regs->cmd_ring,
                        CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
        if (ret < 0) {
+               /* we are about to kill xhci, give it one more chance */
+               xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
+                             &xhci->op_regs->cmd_ring);
+               udelay(1000);
+               ret = handshake(xhci, &xhci->op_regs->cmd_ring,
+                               CMD_RING_RUNNING, 0, 3 * 1000 * 1000);
+               if (ret == 0)
+                       return 0;
+
                xhci_err(xhci, "Stopped the command ring failed, "
                                "maybe the host is dead\n");
                xhci->xhc_state |= XHCI_STATE_DYING;
                xhci_err(xhci, "Stopped the command ring failed, "
                                "maybe the host is dead\n");
                xhci->xhc_state |= XHCI_STATE_DYING;