summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuen-Han Tsai <khtsai@google.com>2025-08-07 17:06:55 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-08-28 16:31:10 +0200
commit900fdc733f84d2b97c9f600a1e5e10e2aadc5c08 (patch)
tree35cd19978f1c283b9787a0550d93fe23964a4679
parent2f7fc6ec5a11a4235166f0446cb2e9143cd0639b (diff)
usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
commit 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 upstream. During a device-initiated disconnect, the End Transfer command resets the event filter, allowing a new xferNotReady event to be generated before the controller is fully halted. Processing this late event incorrectly triggers a Start Transfer, which prevents the controller from halting and results in a DSTS.DEVCTLHLT bit polling timeout. Ignore the late xferNotReady event if the controller is already in a disconnected state. Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver") Cc: stable <stable@kernel.org> Signed-off-by: Kuen-Han Tsai <khtsai@google.com> Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/20250807090700.2397190-1-khtsai@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/dwc3/gadget.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 37ae1dd3345d..fd23e2244049 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3707,6 +3707,15 @@ static void dwc3_gadget_endpoint_transfer_complete(struct dwc3_ep *dep,
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event)
{
+ /*
+ * During a device-initiated disconnect, a late xferNotReady event can
+ * be generated after the End Transfer command resets the event filter,
+ * but before the controller is halted. Ignore it to prevent a new
+ * transfer from starting.
+ */
+ if (!dep->dwc->connected)
+ return;
+
dwc3_gadget_endpoint_frame_from_event(dep, event);
/*