* [PATCH] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
@ 2025-08-05 6:34 Kuen-Han Tsai
2025-08-05 23:28 ` Thinh Nguyen
0 siblings, 1 reply; 4+ messages in thread
From: Kuen-Han Tsai @ 2025-08-05 6:34 UTC (permalink / raw)
To: Thinh.Nguyen, gregkh; +Cc: linux-usb, linux-kernel, Kuen-Han Tsai, stable
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: 8f608e8ab628 ("usb: dwc3: gadget: remove unnecessary 'dwc' parameter")
Cc: stable <stable@kernel.org>
Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
---
Tracing:
# Stop active transfers by sending End Transfer commands
dwc3_gadget_ep_cmd: ep1out: cmd 'End Transfer' [20d08] params 00000000 00000000 00000000 --> status: Successful
dwc3_gadget_ep_cmd: ep1in: cmd 'End Transfer' [40d08] params 00000000 00000000 00000000 --> status: Successful
...
# Recieve an xferNotReady event on an ISOC IN endpoint
dwc3_event: event (35d010c6): ep1in: Transfer Not Ready [000035d0] (Not Active)
dwc3_gadget_ep_cmd: ep1in: cmd 'Start Transfer' [35d60406] params 00000000 ffffb620 00000000 --> status: Successful
dwc3_gadget_ep_cmd: ep2in: cmd 'End Transfer' [30d08] params 00000000 00000000 00000000 --> status: Timed Out
...
# Start polling DSTS.DEVCTRLHLT
dwc3_gadget_run_stop: start polling DWC3_DSTS_DEVCTRLHLT
...
# HALT timeout and print out the endpoint status for debugging
dwc3_gadget_run_stop: finish polling DWC3_DSTS_DEVCTRLHLT, is_on=0, reg=0
dwc3_gadget_ep_status: ep1out: mps 1024/2765 streams 16 burst 5 ring 64/56 flags E:swbp:>
dwc3_gadget_ep_status: ep1in: mps 1024/1024 streams 16 burst 2 ring 21/64 flags E:swBp:<
dwc3_gadget_ep_status: ep2out: mps 1024/2765 streams 16 burst 5 ring 56/48 flags e:swbp:>
---
drivers/usb/dwc3/gadget.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 25db36c63951..ad89cbeea761 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3777,6 +3777,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);
/*
--
2.50.1.565.gc32cd1483b-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
2025-08-05 6:34 [PATCH] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout Kuen-Han Tsai
@ 2025-08-05 23:28 ` Thinh Nguyen
2025-08-06 10:17 ` Kuen-Han Tsai
0 siblings, 1 reply; 4+ messages in thread
From: Thinh Nguyen @ 2025-08-05 23:28 UTC (permalink / raw)
To: Kuen-Han Tsai
Cc: Thinh Nguyen, gregkh@linuxfoundation.org,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, stable
On Tue, Aug 05, 2025, Kuen-Han Tsai wrote:
> 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: 8f608e8ab628 ("usb: dwc3: gadget: remove unnecessary 'dwc' parameter")
The Fixes should target since the beginning of the driver:
72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
> Cc: stable <stable@kernel.org>
> Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
> ---
> Tracing:
>
> # Stop active transfers by sending End Transfer commands
> dwc3_gadget_ep_cmd: ep1out: cmd 'End Transfer' [20d08] params 00000000 00000000 00000000 --> status: Successful
> dwc3_gadget_ep_cmd: ep1in: cmd 'End Transfer' [40d08] params 00000000 00000000 00000000 --> status: Successful
> ...
> # Recieve an xferNotReady event on an ISOC IN endpoint
> dwc3_event: event (35d010c6): ep1in: Transfer Not Ready [000035d0] (Not Active)
> dwc3_gadget_ep_cmd: ep1in: cmd 'Start Transfer' [35d60406] params 00000000 ffffb620 00000000 --> status: Successful
> dwc3_gadget_ep_cmd: ep2in: cmd 'End Transfer' [30d08] params 00000000 00000000 00000000 --> status: Timed Out
> ...
> # Start polling DSTS.DEVCTRLHLT
> dwc3_gadget_run_stop: start polling DWC3_DSTS_DEVCTRLHLT
> ...
> # HALT timeout and print out the endpoint status for debugging
> dwc3_gadget_run_stop: finish polling DWC3_DSTS_DEVCTRLHLT, is_on=0, reg=0
> dwc3_gadget_ep_status: ep1out: mps 1024/2765 streams 16 burst 5 ring 64/56 flags E:swbp:>
> dwc3_gadget_ep_status: ep1in: mps 1024/1024 streams 16 burst 2 ring 21/64 flags E:swBp:<
> dwc3_gadget_ep_status: ep2out: mps 1024/2765 streams 16 burst 5 ring 56/48 flags e:swbp:>
> ---
> drivers/usb/dwc3/gadget.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 25db36c63951..ad89cbeea761 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -3777,6 +3777,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)
Did you test this? This is supposed to be if (!dep->dwc->connected)
right?
BR,
Thinh
> + return;
> +
> dwc3_gadget_endpoint_frame_from_event(dep, event);
>
> /*
> --
> 2.50.1.565.gc32cd1483b-goog
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
2025-08-05 23:28 ` Thinh Nguyen
@ 2025-08-06 10:17 ` Kuen-Han Tsai
2025-08-07 0:55 ` Thinh Nguyen
0 siblings, 1 reply; 4+ messages in thread
From: Kuen-Han Tsai @ 2025-08-06 10:17 UTC (permalink / raw)
To: Thinh Nguyen
Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org,
linux-kernel@vger.kernel.org, stable
Hi Thinh,
Thank you for your review.
On Wed, Aug 6, 2025 at 7:28 AM Thinh Nguyen <Thinh.Nguyen@synopsys.com> wrote:
>
> On Tue, Aug 05, 2025, Kuen-Han Tsai wrote:
> > 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: 8f608e8ab628 ("usb: dwc3: gadget: remove unnecessary 'dwc' parameter")
>
> The Fixes should target since the beginning of the driver:
> 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
Commit 72246da40f37 doesn't have the dwc->connected member. Should we
change the Fixes tag to f09ddcfcb8c5 ("usb: dwc3: gadget: Prevent EP
queuing while stopping transfers")?
That's the commit where the "dwc->connected = false" logic was moved before
stopping active transfers within the pullup function.
>
> > Cc: stable <stable@kernel.org>
> > Signed-off-by: Kuen-Han Tsai <khtsai@google.com>
> > ---
> > Tracing:
> >
> > # Stop active transfers by sending End Transfer commands
> > dwc3_gadget_ep_cmd: ep1out: cmd 'End Transfer' [20d08] params 00000000 00000000 00000000 --> status: Successful
> > dwc3_gadget_ep_cmd: ep1in: cmd 'End Transfer' [40d08] params 00000000 00000000 00000000 --> status: Successful
> > ...
> > # Recieve an xferNotReady event on an ISOC IN endpoint
> > dwc3_event: event (35d010c6): ep1in: Transfer Not Ready [000035d0] (Not Active)
> > dwc3_gadget_ep_cmd: ep1in: cmd 'Start Transfer' [35d60406] params 00000000 ffffb620 00000000 --> status: Successful
> > dwc3_gadget_ep_cmd: ep2in: cmd 'End Transfer' [30d08] params 00000000 00000000 00000000 --> status: Timed Out
> > ...
> > # Start polling DSTS.DEVCTRLHLT
> > dwc3_gadget_run_stop: start polling DWC3_DSTS_DEVCTRLHLT
> > ...
> > # HALT timeout and print out the endpoint status for debugging
> > dwc3_gadget_run_stop: finish polling DWC3_DSTS_DEVCTRLHLT, is_on=0, reg=0
> > dwc3_gadget_ep_status: ep1out: mps 1024/2765 streams 16 burst 5 ring 64/56 flags E:swbp:>
> > dwc3_gadget_ep_status: ep1in: mps 1024/1024 streams 16 burst 2 ring 21/64 flags E:swBp:<
> > dwc3_gadget_ep_status: ep2out: mps 1024/2765 streams 16 burst 5 ring 56/48 flags e:swbp:>
> > ---
> > drivers/usb/dwc3/gadget.c | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> > index 25db36c63951..ad89cbeea761 100644
> > --- a/drivers/usb/dwc3/gadget.c
> > +++ b/drivers/usb/dwc3/gadget.c
> > @@ -3777,6 +3777,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)
>
> Did you test this? This is supposed to be if (!dep->dwc->connected)
> right?
>
You're absolutely right, I'll update your suggested change in the next
patch. Sorry for the mistake.
The code in my Android testing environment was correct and we've
verified that it resolves the halt problem.
Regards,
Kuen-Han
> > + return;
> > +
> > dwc3_gadget_endpoint_frame_from_event(dep, event);
> >
> > /*
> > --
> > 2.50.1.565.gc32cd1483b-goog
> >
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
2025-08-06 10:17 ` Kuen-Han Tsai
@ 2025-08-07 0:55 ` Thinh Nguyen
0 siblings, 0 replies; 4+ messages in thread
From: Thinh Nguyen @ 2025-08-07 0:55 UTC (permalink / raw)
To: Kuen-Han Tsai
Cc: Thinh Nguyen, gregkh@linuxfoundation.org,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, stable
On Wed, Aug 06, 2025, Kuen-Han Tsai wrote:
> Hi Thinh,
>
> Thank you for your review.
>
> On Wed, Aug 6, 2025 at 7:28 AM Thinh Nguyen <Thinh.Nguyen@synopsys.com> wrote:
> >
> > On Tue, Aug 05, 2025, Kuen-Han Tsai wrote:
> > > 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: 8f608e8ab628 ("usb: dwc3: gadget: remove unnecessary 'dwc' parameter")
> >
> > The Fixes should target since the beginning of the driver:
> > 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
>
> Commit 72246da40f37 doesn't have the dwc->connected member. Should we
> change the Fixes tag to f09ddcfcb8c5 ("usb: dwc3: gadget: Prevent EP
> queuing while stopping transfers")?
> That's the commit where the "dwc->connected = false" logic was moved before
> stopping active transfers within the pullup function.
>
The Fixes tag should point to where the issue first introduced that this
patch fixes, not necessarily where it can be backported to. You can give
hints to how far back you want the fix to be backported, but may not
have to.
Thanks,
Thinh
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-08-07 0:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-05 6:34 [PATCH] usb: dwc3: Ignore late xferNotReady event to prevent halt timeout Kuen-Han Tsai
2025-08-05 23:28 ` Thinh Nguyen
2025-08-06 10:17 ` Kuen-Han Tsai
2025-08-07 0:55 ` Thinh Nguyen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).