diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 9f6600e6f22f6510077b031418e46e037777557f..5115e994c663934fc2da18dc93ac1ab6c68733e6 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -376,6 +376,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (xhci->quirks & XHCI_RESET_ON_RESUME) xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "QUIRK: Resetting on resume"); + + if (pdev->vendor == PCI_VENDOR_ID_HUAWEI && + (pdev->device == 0xa23c || pdev->device == 0xa23d)) + xhci->quirks |= XHCI_USB3_NOOP; } #ifdef CONFIG_ACPI diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fa3a7ac15f82575f3cffb9e44e39b91c4bee5e05..1aa4a73d650f221d90241139c212a2fe4a526150 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1492,7 +1492,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, * Check whether the completion event is for our internal kept * command. */ - if (!cmd_dequeue_dma || cmd_dma != (u64)cmd_dequeue_dma) { + if (!cmd_dequeue_dma || ((cmd_dma != (u64)cmd_dequeue_dma) && + !((xhci->quirks & XHCI_USB3_NOOP) && (cmd_comp_code == + COMP_COMMAND_RING_STOPPED)))) { xhci_warn(xhci, "ERROR mismatched command completion event\n"); return; @@ -1525,6 +1527,8 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, if (cmd_comp_code == COMP_COMMAND_ABORTED) { xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; if (cmd->status == COMP_COMMAND_ABORTED) { + if (xhci->quirks & XHCI_USB3_NOOP) + trb_to_noop(cmd->command_trb, TRB_CMD_NOOP); if (xhci->current_cmd == cmd) xhci->current_cmd = NULL; goto event_handled; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 5f68e880e0ca4c7fb75c0ba20bf6db406df0be71..18671a416c02934c1f975362690f227765d94a44 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1835,6 +1835,7 @@ struct xhci_hcd { #define XHCI_STATE_HALTED (1 << 1) #define XHCI_STATE_REMOVING (1 << 2) unsigned long long quirks; +#define XHCI_USB3_NOOP BIT_ULL(63) #define XHCI_LINK_TRB_QUIRK BIT_ULL(0) #define XHCI_RESET_EP_QUIRK BIT_ULL(1) #define XHCI_NEC_HOST BIT_ULL(2)