aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2016-08-16 03:18:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-08-16 03:42:47 -0400
commit33be126510974e2eb9679f1ca9bca4f67ee4c4c7 (patch)
tree88f953a57e7d69c64fdccbb56d5c77293a1e0b54 /drivers/usb
parentadd125054b8727103631dce116361668436ef6a7 (diff)
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: Mathias Nyman <mathias.nyman@linux.intel.com> CC: <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-ring.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 918e0c739b79..fe5b70be61ba 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1334,12 +1334,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
1334 1334
1335 cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); 1335 cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list);
1336 1336
1337 if (cmd->command_trb != xhci->cmd_ring->dequeue) {
1338 xhci_err(xhci,
1339 "Command completion event does not match command\n");
1340 return;
1341 }
1342
1343 del_timer(&xhci->cmd_timer); 1337 del_timer(&xhci->cmd_timer);
1344 1338
1345 trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event); 1339 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 xhci_handle_stopped_cmd_ring(xhci, cmd); 1345 xhci_handle_stopped_cmd_ring(xhci, cmd);
1352 return; 1346 return;
1353 } 1347 }
1348
1349 if (cmd->command_trb != xhci->cmd_ring->dequeue) {
1350 xhci_err(xhci,
1351 "Command completion event does not match command\n");
1352 return;
1353 }
1354
1354 /* 1355 /*
1355 * Host aborted the command ring, check if the current command was 1356 * Host aborted the command ring, check if the current command was
1356 * supposed to be aborted, otherwise continue normally. 1357 * supposed to be aborted, otherwise continue normally.