On Wed, Jul 25, 2012 at 10:24:26PM -0700, Matthew Hall wrote: > On Wed, Jul 25, 2012 at 10:46:37AM -0700, Sarah Sharp wrote: > I think I'm in the same state as Gary only different. ;) I am getting weird > behavior with the quirk patch. The device popped up for about half a minute, > then went haywire and disappeared after the exfat FUSE FS tried to mount it > and begin reading the volume successfully for a short moment. I think now that your host is working, you're running into a separate bug that several other people have discovered. Your mass storage device stalls a lot of SCSI commands (which is fine), and that eventually hits a bug when the stall happens just before the end of a transfer ring segment boundary. The bug causes this message to appear: ERROR Transfer event TRB DMA ptr not part of current TD It's no wonder you hit an obscure filesystem error. The xHCI driver just happened to fall over when the superblock write occurred. Can you apply the attached patch, and trigger that error again? > I did not try the rate-limit yet, pending the outcome from the above topic. Please try the rate limiting patch anyway, as this bug is a separate issue. I just need to you confirm that it does slow down the warning messages, it won't fix anything. Sarah Sharp
>From 7f5dfb81daa76259eacd10b790c970270b7a7d3c Mon Sep 17 00:00:00 2001 From: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> Date: Wed, 25 Jul 2012 17:51:14 -0700 Subject: [PATCH] xhci: More debugging for TRB mismatch. Trying to figure out why the ring printing code isn't printing the second segment of all the rings. Also need more debugging to figure out why we're getting the message: ERROR Transfer event TRB DMA ptr not part of current TD Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-dbg.c | 12 ++++++++---- drivers/usb/host/xhci-mem.c | 2 ++ drivers/usb/host/xhci-ring.c | 4 ++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 4b436f5..80cc634 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -328,18 +328,16 @@ void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg) void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring) { + xhci_dbg(xhci, "Ring deq seg = %p (virt)\n", ring->deq_seg); xhci_dbg(xhci, "Ring deq = %p (virt), 0x%llx (dma)\n", ring->dequeue, (unsigned long long)xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue)); - xhci_dbg(xhci, "Ring deq updated %u times\n", - ring->deq_updates); + xhci_dbg(xhci, "Ring enq seg = %p (virt)\n", ring->enq_seg); xhci_dbg(xhci, "Ring enq = %p (virt), 0x%llx (dma)\n", ring->enqueue, (unsigned long long)xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue)); - xhci_dbg(xhci, "Ring enq updated %u times\n", - ring->enq_updates); } /** @@ -356,6 +354,12 @@ void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring) /* FIXME: Throw an error if any segment doesn't have a Link TRB */ struct xhci_segment *seg; struct xhci_segment *first_seg = ring->first_seg; + + xhci_dbg(xhci, "first_seg = 0x%llx (dma)\n", + (unsigned long long)ring->first_seg->dma); + xhci_dbg(xhci, "first_seg->next = 0x%llx (dma)\n", + (unsigned long long)ring->first_seg->next->dma); + xhci_debug_segment(xhci, first_seg); if (!ring->enq_updates && !ring->deq_updates) { diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 77689bd..3715b55 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -255,6 +255,8 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, cpu_to_le32(LINK_TOGGLE); } xhci_initialize_ring_info(ring, cycle_state); + xhci_debug_ring(xhci, ring); + xhci_dbg_ring_ptrs(xhci, ring); return ring; fail: diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8275645..5bbe6a6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2225,6 +2225,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not " "part of current TD\n"); + xhci_print_trb_offsets(xhci, + (union xhci_trb *) event); + xhci_debug_ring(xhci, ep_ring); + xhci_dbg_ring_ptrs(xhci, ep_ring); return -ESHUTDOWN; } -- 1.7.9