usb: xhci: fix xhci locking up during hcd remove
[cascardo/linux.git] / drivers / usb / host / xhci-ring.c
index f5397a5..d7fd5ef 100644 (file)
@@ -2026,8 +2026,13 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
                break;
        case COMP_DEV_ERR:
        case COMP_STALL:
+               frame->status = -EPROTO;
+               skip_td = true;
+               break;
        case COMP_TX_ERR:
                frame->status = -EPROTO;
+               if (event_trb != td->last_trb)
+                       return 0;
                skip_td = true;
                break;
        case COMP_STOP:
@@ -2640,7 +2645,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
                xhci_halt(xhci);
 hw_died:
                spin_unlock(&xhci->lock);
-               return -ESHUTDOWN;
+               return IRQ_HANDLED;
        }
 
        /*
@@ -3776,8 +3781,11 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
 {
        int reserved_trbs = xhci->cmd_ring_reserved_trbs;
        int ret;
-       if (xhci->xhc_state & XHCI_STATE_DYING)
+
+       if (xhci->xhc_state) {
+               xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n");
                return -ESHUTDOWN;
+       }
 
        if (!command_must_succeed)
                reserved_trbs++;