usb: musb: fix tx fifo flush handling
Here are a few changes in musb_h_tx_flush_fifo(). - It has been observed that sometimes (if not always) musb is unable to flush tx fifo during urb dequeue when disconnect a device. But it seems to be harmless, since the tx fifo flush is done again in musb_ep_program() when re-use the hw_ep. But the WARN() floods the console in the case when multiple tx urbs are queued, so change it to dev_WARN_ONCE(). - applications could queue up many tx urbs, then the 1ms delay could causes minutes of delay in device disconnect. So remove it to get better user experience. The 1ms delay does not help the flushing anyway. - cleanup the debug code - related to lastcsr. ---- Note: The tx fifo flush issue has been observed during device disconnect on AM335x. To reproduce the issue, ensure tx urb(s) are queued when unplug the usb device which is connected to AM335x usb host port. I found using a usb-ethernet device and running iperf (client on AM335x) has very high chance to trigger the problem. Better to turn on dev_dbg() in musb_cleanup_urb() with CPPI enabled to see the issue when aborting the tx channel. Signed-off-by: Bin Liu <b-liu@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
5e216d54b4
commit
68fe05e2a4
|
@ -112,22 +112,32 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
|
|||
struct musb *musb = ep->musb;
|
||||
void __iomem *epio = ep->regs;
|
||||
u16 csr;
|
||||
u16 lastcsr = 0;
|
||||
int retries = 1000;
|
||||
|
||||
csr = musb_readw(epio, MUSB_TXCSR);
|
||||
while (csr & MUSB_TXCSR_FIFONOTEMPTY) {
|
||||
if (csr != lastcsr)
|
||||
dev_dbg(musb->controller, "Host TX FIFONOTEMPTY csr: %02x\n", csr);
|
||||
lastcsr = csr;
|
||||
csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_TXPKTRDY;
|
||||
musb_writew(epio, MUSB_TXCSR, csr);
|
||||
csr = musb_readw(epio, MUSB_TXCSR);
|
||||
if (WARN(retries-- < 1,
|
||||
|
||||
/*
|
||||
* FIXME: sometimes the tx fifo flush failed, it has been
|
||||
* observed during device disconnect on AM335x.
|
||||
*
|
||||
* To reproduce the issue, ensure tx urb(s) are queued when
|
||||
* unplug the usb device which is connected to AM335x usb
|
||||
* host port.
|
||||
*
|
||||
* I found using a usb-ethernet device and running iperf
|
||||
* (client on AM335x) has very high chance to trigger it.
|
||||
*
|
||||
* Better to turn on dev_dbg() in musb_cleanup_urb() with
|
||||
* CPPI enabled to see the issue when aborting the tx channel.
|
||||
*/
|
||||
if (dev_WARN_ONCE(musb->controller, retries-- < 1,
|
||||
"Could not flush host TX%d fifo: csr: %04x\n",
|
||||
ep->epnum, csr))
|
||||
return;
|
||||
mdelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue