From 589f189b860716bc1857683a0be81f36891299f1 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Fri, 22 Nov 2019 14:09:17 +0200 Subject: [PATCH] xhci: dump event ring and endpoint ring if TRB not found in TD After 5 cases of transfer event TRB not matching the queued TD we dump the event ring and current transfer ring. Error counter will continue running until it wraps around, this is a hack so we don't care Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 620846f30b4f..a1a9a408c479 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -201,6 +201,31 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) * @more_trbs_coming: Will you enqueue more TRBs before calling * prepare_transfer()? */ + +static int xhci_dump_ring(struct xhci_hcd *xhci, struct xhci_ring *ring) +{ + struct xhci_segment *seg; + dma_addr_t dma; + union xhci_trb *trb; + int i, j; + + seg = ring->first_seg; + + for (i = 0; i < ring->num_segs; i++) { + for (j = 0; j < TRBS_PER_SEGMENT; j++) { + trb = &seg->trbs[j]; + dma = seg->dma + j * sizeof(*trb); + xhci_err(xhci, "%pad: %s\n", &dma, + xhci_decode_trb(le32_to_cpu(trb->generic.field[0]), + le32_to_cpu(trb->generic.field[1]), + le32_to_cpu(trb->generic.field[2]), + le32_to_cpu(trb->generic.field[3]))); + } + seg = seg->next; + } + return 0; +} + static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool more_trbs_coming) { @@ -2318,6 +2343,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, u32 trb_comp_code; int td_num = 0; bool handling_skipped_tds = false; + static unsigned int err_cnt; slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; @@ -2579,6 +2605,12 @@ static int handle_tx_event(struct xhci_hcd *xhci, trb_in_td(xhci, ep_ring->deq_seg, ep_ring->dequeue, td->last_trb, ep_trb_dma, true); + if (err_cnt++ == 5) { + xhci_err(xhci, "EVENT RING:\n"); + xhci_dump_ring(xhci, xhci->event_ring); + xhci_err(xhci, "ENDPOINT RING:\n"); + xhci_dump_ring(xhci, ep_ring); + } return -ESHUTDOWN; } -- 2.17.1