From 9abfc14d7786ba34f84b0e0ec1fa824c3b4d532f Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Mon, 9 May 2016 09:04:13 +0200 Subject: [PATCH] usb: musb: host: don't start next rx urb if current one failed urb->status is set when endpoint csr RXSTALL, H_ERROR, DATAERROR or INCOMPRX bit is set. Those bits mean a broken pipe, so don't start next urb when any of these bits is set by checking urb->status. To minimize the risk of regression, only do so for RX, until we have a test case to understand the behavior of TX. The patch fixes system freeze issue caused by repeatedly invoking RX ISR while removing a usb uart device connected to a hub, in which case the hub has no chance to report the disconnect event due to the kernel is busy in processing the RX interrupt flooding. Reported-by: Max Uvarov Signed-off-by: Bin Liu --- drivers/usb/musb/musb_host.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4500610..446a0f4 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -424,7 +424,13 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, } } - if (qh != NULL && qh->is_ready) { + /* + * The pipe must be broken if current urb->status is set, so don't + * start next urb. + * TODO: to minimize the risk of regression, only check urb->status + * for RX, until we have a test case to understand the behavior of TX. + */ + if ((!status || !is_in) && qh != NULL && qh->is_ready) { dev_dbg(musb->controller, "... next ep%d %cX urb %p\n", hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); musb_start_urb(musb, is_in, qh); -- 2.1.4