* [PATCH] usb: ehci: Quiesce ASPEED EHCI before halting it on shutdown
@ 2026-10-16 8:53 Joe Wang
2026-10-16 9:07 ` sashiko-bot
2026-10-16 15:04 ` Alan Stern
0 siblings, 2 replies; 3+ messages in thread
From: Joe Wang @ 2026-10-16 8:53 UTC (permalink / raw)
To: Alan Stern, Greg Kroah-Hartman
Cc: linux-aspeed, linux-usb, linux-kernel, Joe Wang
On ASPEED EHCI controllers, clearing USBCMD.RS while both the periodic
and asynchronous schedules are enabled may leave the controller unable
to halt. If an asynchronous transaction is in progress when RS is
cleared, it may run past the end of the micro-frame. The controller then
clears its internal schedule buffer at the start of the next micro-frame
while it is already walking the periodic schedule, issues a DMA read
from address 0x0 and never sets USBSTS.HCHalted.
ehci_shutdown() calls ehci_silence_controller(), which halts the
controller without first turning off the schedules. For ASPEED
controllers, call ehci_quiesce() first to clear CMD_ASE/CMD_PSE and
wait for STS_ASS/STS_PSS to clear, as ehci_stop() and
ehci_bus_suspend() already do before halting. This is also the stop
sequence recommended by ASPEED.
Quiesce the controller after setting rh_state to EHCI_RH_STOPPING.
The asynchronous and periodic schedule-enable paths require
EHCI_RH_RUNNING, so this ordering prevents them from restarting the
schedules while the controller is being shut down.
Allow ehci_quiesce() to operate in EHCI_RH_STOPPING as well as
EHCI_RH_RUNNING. As documented for enum ehci_rh_state, both states
indicate that the controller may still be performing DMA, while
lower states indicate that it is not.
The controller-death path in ehci_irq() also sets EHCI_RH_STOPPING
and clears CMD_RUN, CMD_ASE and CMD_PSE. A quiesce call in that
state writes the command register with these bits still cleared
and polls the schedule status bits using the existing timeout
limits, without re-enabling the controller or its schedules.
Signed-off-by: Joe Wang <joe_wang@aspeedtech.com>
---
This issue was observed on a customer host platform using the AST2700
PCIe EHCI (ehci-pci), and the root cause was confirmed by the ASPEED
hardware team in RTL simulation. The stop sequence used here (clear
PSE/ASE, wait for PSS/ASS to clear, then clear RS) is their
recommended workaround and was confirmed to resolve the issue on that
platform. All ASPEED EHCI controllers share the same design, so the
workaround applies to every controller with is_aspeed set.
The quiesce is limited to ASPEED controllers to keep the change
minimal for other platforms.
Tested on AST2700 (ehci-platform): ehci_shutdown() and unbind/bind
(ehci_stop()) with a hub and USB mass storage under load, no
regressions.
---
drivers/usb/host/ehci-hcd.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 3c46bb18c7f3..d984987c8691 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -274,7 +274,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
{
u32 temp;
- if (ehci->rh_state != EHCI_RH_RUNNING)
+ if (ehci->rh_state < EHCI_RH_RUNNING)
return;
/* wait for any schedule enables/disables to take effect */
@@ -372,6 +372,14 @@ static void ehci_shutdown(struct usb_hcd *hcd)
ehci->enabled_hrtimer_events = 0;
spin_unlock_irq(&ehci->lock);
+ /*
+ * ASPEED EHCI may never halt if RS is cleared while both schedules
+ * are enabled, so turn them off first. rh_state is STOPPING at this
+ * point, which keeps them from being re-enabled.
+ */
+ if (ehci->is_aspeed)
+ ehci_quiesce(ehci);
+
ehci_silence_controller(ehci);
hrtimer_cancel(&ehci->hrtimer);
---
base-commit: 2f2f7eeef8b0a1a9b9ca998231419873ccae8d4e
change-id: 20261016-upstream_ehci_aspeed_shutdown-9ccffedb2a1c
Best regards,
--
Joe Wang <joe_wang@aspeedtech.com>
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] usb: ehci: Quiesce ASPEED EHCI before halting it on shutdown
2026-10-16 8:53 [PATCH] usb: ehci: Quiesce ASPEED EHCI before halting it on shutdown Joe Wang
@ 2026-10-16 9:07 ` sashiko-bot
2026-10-16 15:04 ` Alan Stern
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-10-16 9:07 UTC (permalink / raw)
To: Joe Wang; +Cc: linux-usb
> On ASPEED EHCI controllers, clearing USBCMD.RS while both the periodic
> and asynchronous schedules are enabled may leave the controller unable
> to halt. If an asynchronous transaction is in progress when RS is
> cleared, it may run past the end of the micro-frame. The controller then
> clears its internal schedule buffer at the start of the next micro-frame
> while it is already walking the periodic schedule, issues a DMA read
> from address 0x0 and never sets USBSTS.HCHalted.
>
> ehci_shutdown() calls ehci_silence_controller(), which halts the
> controller without first turning off the schedules. For ASPEED
> controllers, call ehci_quiesce() first to clear CMD_ASE/CMD_PSE and
> wait for STS_ASS/STS_PSS to clear, as ehci_stop() and
> ehci_bus_suspend() already do before halting. This is also the stop
> sequence recommended by ASPEED.
>
> [ ... ]
> state writes the command register with these bits still cleared
> and polls the schedule status bits using the existing timeout
> limits, without re-enabling the controller or its schedules.
>
> Signed-off-by: Joe Wang <joe_wang@aspeedtech.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261016-upstream_ehci_aspeed_shutdown-v1-1-8440c13b5652@aspeedtech.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] usb: ehci: Quiesce ASPEED EHCI before halting it on shutdown
2026-10-16 8:53 [PATCH] usb: ehci: Quiesce ASPEED EHCI before halting it on shutdown Joe Wang
2026-10-16 9:07 ` sashiko-bot
@ 2026-10-16 15:04 ` Alan Stern
1 sibling, 0 replies; 3+ messages in thread
From: Alan Stern @ 2026-10-16 15:04 UTC (permalink / raw)
To: Joe Wang; +Cc: Greg Kroah-Hartman, linux-aspeed, linux-usb, linux-kernel
On Fri, Oct 16, 2026 at 04:53:07PM +0800, Joe Wang wrote:
> On ASPEED EHCI controllers, clearing USBCMD.RS while both the periodic
> and asynchronous schedules are enabled may leave the controller unable
> to halt. If an asynchronous transaction is in progress when RS is
> cleared, it may run past the end of the micro-frame. The controller then
> clears its internal schedule buffer at the start of the next micro-frame
> while it is already walking the periodic schedule, issues a DMA read
> from address 0x0 and never sets USBSTS.HCHalted.
>
> ehci_shutdown() calls ehci_silence_controller(), which halts the
> controller without first turning off the schedules. For ASPEED
> controllers, call ehci_quiesce() first to clear CMD_ASE/CMD_PSE and
> wait for STS_ASS/STS_PSS to clear, as ehci_stop() and
> ehci_bus_suspend() already do before halting. This is also the stop
> sequence recommended by ASPEED.
>
> Quiesce the controller after setting rh_state to EHCI_RH_STOPPING.
> The asynchronous and periodic schedule-enable paths require
> EHCI_RH_RUNNING, so this ordering prevents them from restarting the
> schedules while the controller is being shut down.
>
> Allow ehci_quiesce() to operate in EHCI_RH_STOPPING as well as
> EHCI_RH_RUNNING. As documented for enum ehci_rh_state, both states
> indicate that the controller may still be performing DMA, while
> lower states indicate that it is not.
>
> The controller-death path in ehci_irq() also sets EHCI_RH_STOPPING
> and clears CMD_RUN, CMD_ASE and CMD_PSE. A quiesce call in that
> state writes the command register with these bits still cleared
> and polls the schedule status bits using the existing timeout
> limits, without re-enabling the controller or its schedules.
>
> Signed-off-by: Joe Wang <joe_wang@aspeedtech.com>
> ---
> This issue was observed on a customer host platform using the AST2700
> PCIe EHCI (ehci-pci), and the root cause was confirmed by the ASPEED
> hardware team in RTL simulation. The stop sequence used here (clear
> PSE/ASE, wait for PSS/ASS to clear, then clear RS) is their
> recommended workaround and was confirmed to resolve the issue on that
> platform. All ASPEED EHCI controllers share the same design, so the
> workaround applies to every controller with is_aspeed set.
>
> The quiesce is limited to ASPEED controllers to keep the change
> minimal for other platforms.
>
> Tested on AST2700 (ehci-platform): ehci_shutdown() and unbind/bind
> (ehci_stop()) with a hub and USB mass storage under load, no
> regressions.
Under what circumstances does ehci_shutdown() run without ehci_stop()
being called first? Is controller death the only possibility? If the
controller is dead, will quiescing work?
Is there any real reason not to do this on all types of EHCI controller,
not just ASPEED?
> ---
> drivers/usb/host/ehci-hcd.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 3c46bb18c7f3..d984987c8691 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -274,7 +274,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
> {
> u32 temp;
>
> - if (ehci->rh_state != EHCI_RH_RUNNING)
> + if (ehci->rh_state < EHCI_RH_RUNNING)
> return;
>
> /* wait for any schedule enables/disables to take effect */
> @@ -372,6 +372,14 @@ static void ehci_shutdown(struct usb_hcd *hcd)
> ehci->enabled_hrtimer_events = 0;
> spin_unlock_irq(&ehci->lock);
>
> + /*
> + * ASPEED EHCI may never halt if RS is cleared while both schedules
> + * are enabled, so turn them off first. rh_state is STOPPING at this
> + * point, which keeps them from being re-enabled.
> + */
> + if (ehci->is_aspeed)
> + ehci_quiesce(ehci);
Don't you want to check whether the controller has already been
quiesced?
Alan Stern
> +
> ehci_silence_controller(ehci);
>
> hrtimer_cancel(&ehci->hrtimer);
>
> ---
> base-commit: 2f2f7eeef8b0a1a9b9ca998231419873ccae8d4e
> change-id: 20261016-upstream_ehci_aspeed_shutdown-9ccffedb2a1c
>
> Best regards,
> --
> Joe Wang <joe_wang@aspeedtech.com>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-16 15:04 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16 8:53 [PATCH] usb: ehci: Quiesce ASPEED EHCI before halting it on shutdown Joe Wang
2026-10-16 9:07 ` sashiko-bot
2026-10-16 15:04 ` Alan Stern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox