Commit 1a869403 authored by Longfang Liu's avatar Longfang Liu Committed by JiangShui
Browse files

xhci:fix USB xhci controller issue

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7DZ8S


CVE: NA

----------------------------------------------------------------------

When the current HiSilicon USB xhci controller formats the faulty
U disk, it will trigger a controller exception error. This will
cause errors in the control logic of the xhci controller and
driver software. In the end, all USB devices on the xhci controller
cannot be used.

By introducing a noop command operation, restore the logic of the
xhci controller and driver software, and restore all USB devices
on the xhci controller to normal.

Signed-off-by: default avatarLongfang Liu <liulongfang@huawei.com>
parent 195117a2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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)