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:34:41 +0200
commit2e61dd38d051f8c666b55778147d5ff4f1eba27f (patch)
treeab9a78f6aaa23878ac522d51f9b2f2e499f37b8c
parent36b93b34f392227dd7830ece4889cea1f33b1d5f (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 74968f93d4a3..dff03f0826ab 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3779,6 +3779,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);
/*