summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorUttkarsh Aggarwal <quic_uaggarwa@quicinc.com>2023-12-22 15:17:04 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-01-04 15:57:45 +0100
commite9d40b215e38480fd94c66b06d79045717a59e9c (patch)
tree3309f5199c3a871c12a8652fe3b58a62c7836439 /drivers/usb
parent738ec5ab7acca7ee5856e36a5a6a0c41201fe88f (diff)
downloadlinux-e9d40b215e38480fd94c66b06d79045717a59e9c.tar.gz
linux-e9d40b215e38480fd94c66b06d79045717a59e9c.tar.bz2
linux-e9d40b215e38480fd94c66b06d79045717a59e9c.zip
usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart
Current implementation blocks the running operations when Plug-out and Plug-In is performed continuously, process gets stuck in dwc3_thread_interrupt(). Code Flow: CPU1 ->Gadget_start ->dwc3_interrupt ->dwc3_thread_interrupt ->dwc3_process_event_buf ->dwc3_process_event_entry ->dwc3_endpoint_interrupt ->dwc3_ep0_interrupt ->dwc3_ep0_inspect_setup ->dwc3_ep0_stall_and_restart By this time if pending_list is not empty, it will get the next request on the given list and calls dwc3_gadget_giveback which will unmap request and call its complete() callback to notify upper layers that it has completed. Currently dwc3_gadget_giveback status is set to -ECONNRESET, whereas it should be -ESHUTDOWN based on condition if not dwc->connected is true. Cc: <stable@vger.kernel.org> Fixes: d742220b3577 ("usb: dwc3: ep0: giveback requests on stall_and_restart") Signed-off-by: Uttkarsh Aggarwal <quic_uaggarwa@quicinc.com> Link: https://lore.kernel.org/r/20231222094704.20276-1-quic_uaggarwa@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/dwc3/ep0.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index b94243237293..6ae8a36f21cf 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -238,7 +238,10 @@ void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
struct dwc3_request *req;
req = next_request(&dep->pending_list);
- dwc3_gadget_giveback(dep, req, -ECONNRESET);
+ if (!dwc->connected)
+ dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
+ else
+ dwc3_gadget_giveback(dep, req, -ECONNRESET);
}
dwc->eps[0]->trb_enqueue = 0;