aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2016-06-01 11:09:08 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-01 17:55:01 -0400
commit3425aa03f484d45dc21e0e791c2f6c74ea656421 (patch)
treeb22cfe0e98d6a6a85e24bfe7b6e5ce93b56fff9a /drivers/usb
parent27a41a83ec54d0edfcaf079310244e7f013a7701 (diff)
xhci: Fix handling timeouted commands on hosts in weird states.
If commands timeout we mark them for abortion, then stop the command ring, and turn the commands to no-ops and finally restart the command ring. If the host is working properly the no-op commands will finish and pending completions are called. If we notice the host is failing, driver clears the command ring and completes, deletes and frees all pending commands. There are two separate cases reported where host is believed to work properly but is not. In the first case we successfully stop the ring but no abort or stop command ring event is ever sent and host locks up. The second case is if a host is removed, command times out and driver believes the ring is stopped, and assumes it will be restarted, but actually ends up timing out on the same command forever. If one of the pending commands has the xhci->mutex held it will block xhci_stop() in the remove codepath which otherwise would cleanup pending commands. Add a check that clears all pending commands in case host is removed, or we are stuck timing out on the same command. Also restart the command timeout timer when stopping the command ring to ensure we recive an ring stop/abort event. Cc: stable <stable@vger.kernel.org> Tested-by: Joe Lawrence <joe.lawrence@stratus.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-ring.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 1287339f11bb..d7d502578d79 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -290,6 +290,14 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
290 290
291 temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); 291 temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
292 xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; 292 xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
293
294 /*
295 * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
296 * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
297 * but the completion event in never sent. Use the cmd timeout timer to
298 * handle those cases. Use twice the time to cover the bit polling retry
299 */
300 mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT));
293 xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, 301 xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
294 &xhci->op_regs->cmd_ring); 302 &xhci->op_regs->cmd_ring);
295 303
@@ -314,6 +322,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
314 322
315 xhci_err(xhci, "Stopped the command ring failed, " 323 xhci_err(xhci, "Stopped the command ring failed, "
316 "maybe the host is dead\n"); 324 "maybe the host is dead\n");
325 del_timer(&xhci->cmd_timer);
317 xhci->xhc_state |= XHCI_STATE_DYING; 326 xhci->xhc_state |= XHCI_STATE_DYING;
318 xhci_quiesce(xhci); 327 xhci_quiesce(xhci);
319 xhci_halt(xhci); 328 xhci_halt(xhci);
@@ -1246,22 +1255,21 @@ void xhci_handle_command_timeout(unsigned long data)
1246 int ret; 1255 int ret;
1247 unsigned long flags; 1256 unsigned long flags;
1248 u64 hw_ring_state; 1257 u64 hw_ring_state;
1249 struct xhci_command *cur_cmd = NULL; 1258 bool second_timeout = false;
1250 xhci = (struct xhci_hcd *) data; 1259 xhci = (struct xhci_hcd *) data;
1251 1260
1252 /* mark this command to be cancelled */ 1261 /* mark this command to be cancelled */
1253 spin_lock_irqsave(&xhci->lock, flags); 1262 spin_lock_irqsave(&xhci->lock, flags);
1254 if (xhci->current_cmd) { 1263 if (xhci->current_cmd) {
1255 cur_cmd = xhci->current_cmd; 1264 if (xhci->current_cmd->status == COMP_CMD_ABORT)
1256 cur_cmd->status = COMP_CMD_ABORT; 1265 second_timeout = true;
1266 xhci->current_cmd->status = COMP_CMD_ABORT;
1257 } 1267 }
1258 1268
1259
1260 /* Make sure command ring is running before aborting it */ 1269 /* Make sure command ring is running before aborting it */
1261 hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); 1270 hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
1262 if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && 1271 if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
1263 (hw_ring_state & CMD_RING_RUNNING)) { 1272 (hw_ring_state & CMD_RING_RUNNING)) {
1264
1265 spin_unlock_irqrestore(&xhci->lock, flags); 1273 spin_unlock_irqrestore(&xhci->lock, flags);
1266 xhci_dbg(xhci, "Command timeout\n"); 1274 xhci_dbg(xhci, "Command timeout\n");
1267 ret = xhci_abort_cmd_ring(xhci); 1275 ret = xhci_abort_cmd_ring(xhci);
@@ -1273,6 +1281,15 @@ void xhci_handle_command_timeout(unsigned long data)
1273 } 1281 }
1274 return; 1282 return;
1275 } 1283 }
1284
1285 /* command ring failed to restart, or host removed. Bail out */
1286 if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
1287 spin_unlock_irqrestore(&xhci->lock, flags);
1288 xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
1289 xhci_cleanup_command_queue(xhci);
1290 return;
1291 }
1292
1276 /* command timeout on stopped ring, ring can't be aborted */ 1293 /* command timeout on stopped ring, ring can't be aborted */
1277 xhci_dbg(xhci, "Command timeout on stopped ring\n"); 1294 xhci_dbg(xhci, "Command timeout on stopped ring\n");
1278 xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd); 1295 xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd);