Add debugging to say exactly which command addresses are getting canceled, when we can't find a command that needed to be canceled, and add some debugging when commands or watchdog timers choose not to cancel a command due to not being the first command on the command ring. Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-ring.c | 37 ++++++++++++++++++++++++++++++++++++- 1 files changed, 36 insertions(+), 1 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 30a4c37..eda2d7fd 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -936,6 +936,8 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ep->stop_cmd_timer.expires = jiffies + XHCI_STOP_EP_CMD_TIMEOUT * HZ; add_timer(&ep->stop_cmd_timer); + xhci_dbg(xhci, "Restarting watchdog timer, pending = %u\n", + ep->stop_cmds_pending); spin_unlock_irqrestore(&xhci->lock, flags); return; } @@ -1276,17 +1278,35 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) break; } } + if (cur_cd->cmd_trb != cmd_trb) + xhci_err(xhci, "Could not find command to cancel %016llx, cmd ring deq = %016llx and enq = %016llx\n", + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->first_seg, + cur_cd->cmd_trb), + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->deq_seg, + xhci->cmd_ring->dequeue), + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->enq_seg, + xhci->cmd_ring->enqueue)); } static void xhci_cancel_cmd_in_cd_list(struct xhci_hcd *xhci) { struct xhci_cd *cur_cd, *next_cd; - if (list_empty(&xhci->cancel_cmd_list)) + if (list_empty(&xhci->cancel_cmd_list)) { + xhci_dbg(xhci, "No more commands to cancel\n"); return; + } list_for_each_entry_safe(cur_cd, next_cd, &xhci->cancel_cmd_list, cancel_cmd_list) { + xhci_dbg(xhci, "%s canceling command %016llx\n", + __func__, + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->first_seg, + cur_cd->cmd_trb)); xhci_cmd_to_noop(xhci, cur_cd); if (cur_cd->command) xhci_complete_cmd_in_cmd_wait_list(xhci, @@ -1313,6 +1333,11 @@ static int xhci_search_cmd_trb_in_cd_list(struct xhci_hcd *xhci, list_for_each_entry_safe(cur_cd, next_cd, &xhci->cancel_cmd_list, cancel_cmd_list) { if (cur_cd->cmd_trb == cmd_trb) { + xhci_dbg(xhci, "%s canceling command %016llx\n", + __func__, + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->first_seg, + cmd_trb)); xhci_cmd_to_noop(xhci, cur_cd); if (cur_cd->command) xhci_complete_cmd_in_cmd_wait_list(xhci, @@ -1323,6 +1348,10 @@ static int xhci_search_cmd_trb_in_cd_list(struct xhci_hcd *xhci, } } + xhci_dbg(xhci, "Dequeue of stopped command ring (%016llx) isn't a command to be canceled.\n", + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->first_seg, + cmd_trb)); return 0; } @@ -1338,6 +1367,12 @@ static int handle_stopped_cmd_ring(struct xhci_hcd *xhci, { int cur_trb_is_good = 0; + xhci_dbg(xhci, "Handle %s command ring, dequeue = %016llx.\n", + (cmd_trb_comp_code == COMP_CMD_STOP) ? + "stopped" : "aborted", + (unsigned long long) xhci_trb_virt_to_dma( + xhci->cmd_ring->deq_seg, + xhci->cmd_ring->dequeue)); /* Searching the cmd trb pointed by the command ring dequeue * pointer in command descriptor list. If it is found, free it. */ -- 1.7.9 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html