summaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb
diff options
context:
space:
mode:
authorBin Liu <b-liu@ti.com>2020-05-24 21:50:44 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-25 13:36:30 +0200
commit1b967691ecdcf512bc33c0783158f760e5c1a9cf (patch)
tree801bc67908158c9d87d8113febe1f9bbd02f09d8 /drivers/usb/musb
parentca681aa49200422a4144ee376a2079a9f717bf11 (diff)
downloadlinux-1b967691ecdcf512bc33c0783158f760e5c1a9cf.tar.gz
linux-1b967691ecdcf512bc33c0783158f760e5c1a9cf.tar.bz2
linux-1b967691ecdcf512bc33c0783158f760e5c1a9cf.zip
usb: musb: return -ESHUTDOWN in urb when three-strikes error happened
When a USB device attached to a hub got disconnected, MUSB controller generates RXCSR_RX_ERROR interrupt for the 3-strikes-out error. Currently the MUSB host driver returns -EPROTO in current URB, then the USB device driver could immediately resubmit the URB which causes MUSB generate RXCSR_RX_ERROR interrupt again. This circle causes interrupt storm then the hub never got a chance to report the USB device detach. To fix the interrupt storm, change the URB return code to -ESHUTDOWN for MUSB_RXCSR_H_ERROR interrupt, so that the USB device driver will not immediately resubmit the URB. Signed-off-by: Bin Liu <b-liu@ti.com> Link: https://lore.kernel.org/r/20200525025049.3400-2-b-liu@ti.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/musb')
-rw-r--r--drivers/usb/musb/musb_host.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 8736f4251a22..8b7d22a0c0fb 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1774,9 +1774,15 @@ void musb_host_rx(struct musb *musb, u8 epnum)
status = -EPIPE;
} else if (rx_csr & MUSB_RXCSR_H_ERROR) {
- musb_dbg(musb, "end %d RX proto error", epnum);
+ dev_err(musb->controller, "ep%d RX three-strikes error", epnum);
- status = -EPROTO;
+ /*
+ * The three-strikes error could only happen when the USB
+ * device is not accessible, for example detached or powered
+ * off. So return the fatal error -ESHUTDOWN so hopefully the
+ * USB device drivers won't immediately resubmit the same URB.
+ */
+ status = -ESHUTDOWN;
musb_writeb(epio, MUSB_RXINTERVAL, 0);
rx_csr &= ~MUSB_RXCSR_H_ERROR;