During the endpoint dequeue operation, it changes dequeued TRB as link
TRB, when the endpoint is disabled and re-enabled, the DMA fetches the
TRB before the link TRB, after it handles current TRB, the DMA pointer
will advance to the TRB after link TRB, but enqueue and dequene
variables don't know it due to no hardware interrupt at the time, when
the next TRB is added to link TRB position, the DMA will not handle
this TRB due to its pointer is already at the next TRB. See the trace
log like below:
file-storage-675 [001] d..1 86.585657: usb_ep_queue: ep0: req
00000000df9b3a4f length 0/0 sgs 0/0 stream 0 zsI status 0 --> 0
file-storage-675 [001] d..1 86.585663: cdns3_ep_queue: ep1out: req:
000000002ebce364, req buff
00000000f5bc96b4, length: 0/1024 zsi, status: -115, trb: [start:0, end:0: virt addr (null)], flags:0 SID: 0
file-storage-675 [001] d..1 86.585671: cdns3_prepare_trb: ep1out: trb
000000007f770303, dma buf: 0xbd195800, size: 1024, burst: 128 ctrl: 0x00000425 (C=1, T=0, ISP, IOC, Normal) SID:0 LAST_SID:0
file-storage-675 [001] d..1 86.585676: cdns3_ring:
Ring contents for ep1out:
Ring deq index: 0, trb:
000000007f770303 (virt), 0xc4003000 (dma)
Ring enq index: 1, trb:
0000000049c1ba21 (virt), 0xc400300c (dma)
free trbs: 38, CCS=1, PCS=1
@0x00000000c4003000
bd195800 80020400 00000425
@0x00000000c400300c
c4003018 80020400 00001811
@0x00000000c4003018
bcfcc000 0000001f 00000426
@0x00000000c4003024
bcfce800 0000001f 00000426
...
irq/144-
5b13000-698 [000] d... 87.619286: usb_gadget_giveback_request: ep1in: req
0000000031b832eb length 13/13 sgs 0/0 stream 0 zsI status 0 --> 0
file-storage-675 [001] d..1 87.619287: cdns3_ep_queue: ep1out: req:
000000002ebce364, req buff
00000000f5bc96b4, length: 0/1024 zsi, status: -115, trb: [start:0, end:0: virt addr 0x80020400c400300c], flags:0 SID: 0
file-storage-675 [001] d..1 87.619294: cdns3_prepare_trb: ep1out: trb
0000000049c1ba21, dma buf: 0xbd198000, size: 1024, burst: 128 ctrl: 0x00000425 (C=1, T=0, ISP, IOC, Normal) SID:0 LAST_SID:0
file-storage-675 [001] d..1 87.619297: cdns3_ring:
Ring contents for ep1out:
Ring deq index: 1, trb:
0000000049c1ba21 (virt), 0xc400300c (dma)
Ring enq index: 2, trb:
0000000059b34b67 (virt), 0xc4003018 (dma)
free trbs: 38, CCS=1, PCS=1
@0x00000000c4003000
bd195800 0000001f 00000427
@0x00000000c400300c
bd198000 80020400 00000425
@0x00000000c4003018
bcfcc000 0000001f 00000426
@0x00000000c4003024
bcfce800 0000001f 00000426
...
file-storage-675 [001] d..1 87.619305: cdns3_doorbell_epx: ep1out, ep_trbaddr
c4003018
file-storage-675 [001] .... 87.619308: usb_ep_queue: ep1out: req
000000002ebce364 length 0/1024 sgs 0/0 stream 0 zsI status -115 --> 0
irq/144-
5b13000-698 [000] d..1 87.619315: cdns3_epx_irq: IRQ for ep1out:
01000c80 TRBERR , ep_traddr:
c4003018 ep_last_sid:
00000000 use_streams: 0
irq/144-
5b13000-698 [000] d..1 87.619395: cdns3_usb_irq: IRQ
00000008 = Hot Reset
Fixes: f616c3bda47e ("usb: cdns3: Fix dequeue implementation")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Peter Chen <peter.chen@nxp.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>