Commit 33be1265 authored by Mathias Nyman's avatar Mathias Nyman Committed by Greg Kroah-Hartman

xhci: always handle "Command Ring Stopped" events

Fix "Command completion event does not match command" errors by always
handling the command ring stopped events.

The command ring stopped event is generated as a result of aborting
or stopping the command ring with a register write. It is not caused
by a command in the command queue, and thus won't have a matching command
in the comman list.

Solve it by handling the command ring stopped event before checking for a
matching command.

In most command time out cases we abort the command ring, and get
a command ring stopped event. The events command pointer will point at
the current command ring dequeue, which in most cases matches the timed
out command in the command list, and no error messages are seen.

If we instead get a command aborted event before the command ring stopped
event, the abort event will increse the command ring dequeue pointer, and
the following command ring stopped events command pointer will point at the
next, not yet queued command. This case triggered the error message
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
CC: <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent add12505
...@@ -1334,12 +1334,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, ...@@ -1334,12 +1334,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list);
if (cmd->command_trb != xhci->cmd_ring->dequeue) {
xhci_err(xhci,
"Command completion event does not match command\n");
return;
}
del_timer(&xhci->cmd_timer); del_timer(&xhci->cmd_timer);
trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event); trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
...@@ -1351,6 +1345,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, ...@@ -1351,6 +1345,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_stopped_cmd_ring(xhci, cmd); xhci_handle_stopped_cmd_ring(xhci, cmd);
return; return;
} }
if (cmd->command_trb != xhci->cmd_ring->dequeue) {
xhci_err(xhci,
"Command completion event does not match command\n");
return;
}
/* /*
* Host aborted the command ring, check if the current command was * Host aborted the command ring, check if the current command was
* supposed to be aborted, otherwise continue normally. * supposed to be aborted, otherwise continue normally.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment