acm_rx_complete() pushes the received data into the RX buffer and
queues the request again, regardless of its completion status.
When an endpoint is disabled, the UDC gives back its queued requests
with an error status such as -ESHUTDOWN. This happens when the ACM
function is disabled on a bus reset or disconnect, or when the usbacm
console is stopped. Requeueing such a request from its completion
handler puts it back on the endpoint that is being flushed. With DWC3,
dwc3_remove_requests() then gives the same request back again and
again, usb_ep_disable() never returns, and gadget teardown stalls.
Return early for failed completions, as the fastboot and rockusb
functions already do. A failed request carries no valid data. It is
freed by acm_disable(), and acm_set_alt() queues a new one when the
data interface is enabled again. Successful completions are handled
as before.
Fixes: fc2b399ac03b ("usb: gadget: Add CDC ACM function")
Signed-off-by: Nizat Mikayilli <[email protected]>
---
Changes in v2:
- Use my real name as author and in Signed-off-by
drivers/usb/gadget/f_acm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index b6c11d97a62..2ea54dfbe69 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -293,6 +293,9 @@ static void acm_rx_complete(struct usb_ep *ep, struct
usb_request *req)
{
struct f_acm *f_acm = req->context;
+ if (req->status)
+ return;
+
buf_push(&f_acm->rx_buf, req->buf, req->actual);
/* Queue RX req again */
--
2.56.0