From: Joe Wang <joe_wang@aspeedtech.com>
To: Alan Stern <stern@rowland.harvard.edu>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <linux-aspeed@lists.ozlabs.org>, <linux-usb@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
Joe Wang <joe_wang@aspeedtech.com>
Subject: [PATCH v2] usb: ehci: Quiesce controller before halting it on shutdown
Date: Thu, 22 Oct 2026 09:21:11 +0800 [thread overview]
Message-ID: <20261022-upstream_ehci_aspeed_shutdown-v2-1-62712169bc07@aspeedtech.com> (raw)
ehci_shutdown() runs from the .shutdown callback during reboot,
poweroff and kexec, for example when LinuxBoot firmware boots the
final OS. The HCD is not removed in that path, so ehci_stop() is not
called and the controller may still be running. ehci_shutdown() then
halts it without first turning off the schedules, leaving a DMA master
running while the system shuts down.
On ASPEED EHCI controllers, clearing USBCMD.RS while both the periodic
and asynchronous schedules are enabled may also leave the controller
unable to halt. If an asynchronous transaction runs past the end of
the micro-frame after RS is cleared, the controller walks the periodic
schedule with a cleared internal buffer, reads from address 0x0 and
never sets USBSTS.HCHalted.
If the controller was running, call ehci_quiesce() before halting it,
as ehci_stop() and ehci_bus_suspend() already do. Do this after
rh_state is set to EHCI_RH_STOPPING, so that URB submissions and
hrtimer events cannot re-enable the schedules, and let ehci_quiesce()
accept that state: like EHCI_RH_RUNNING, it means the controller may
still be doing DMA. The controller-death path in ehci_irq() also sets
EHCI_RH_STOPPING, but it has already cleared CMD_RUN, CMD_ASE and
CMD_PSE, so a quiesce there cannot re-enable anything.
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.
When the controller is running, the added delay at shutdown is bounded
by the two existing 16-uframe handshakes in ehci_quiesce().
Tested on AST2700 (ehci-platform): reboot with a hub and USB mass
storage under load, ehci_shutdown() on already halted controllers,
and unbind/bind (ehci_stop()); no regressions.
---
Changes in v2:
- Apply to all EHCI controllers, not only ASPEED (Alan)
- Quiesce only if the controller was running (Alan)
- Link to v1: https://lore.kernel.org/r/20261016-upstream_ehci_aspeed_shutdown-v1-1-8440c13b5652@aspeedtech.com
---
drivers/usb/host/ehci-hcd.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 3c46bb18c7f3..d9d816eedc66 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 */
@@ -356,6 +356,7 @@ static void ehci_silence_controller(struct ehci_hcd *ehci)
static void ehci_shutdown(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ bool was_running;
/**
* Protect the system from crashing at system shutdown in cases where
@@ -367,11 +368,19 @@ static void ehci_shutdown(struct usb_hcd *hcd)
return;
spin_lock_irq(&ehci->lock);
+ was_running = ehci->rh_state == EHCI_RH_RUNNING;
ehci->shutdown = true;
ehci->rh_state = EHCI_RH_STOPPING;
ehci->enabled_hrtimer_events = 0;
spin_unlock_irq(&ehci->lock);
+ /*
+ * Turn off the schedules before halting. rh_state is STOPPING now,
+ * so they cannot be re-enabled.
+ */
+ if (was_running)
+ 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>
next reply other threads:[~2026-10-22 1:21 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 1:21 Joe Wang [this message]
2026-10-22 1:47 ` Alan Stern
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261022-upstream_ehci_aspeed_shutdown-v2-1-62712169bc07@aspeedtech.com \
--to=joe_wang@aspeedtech.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-aspeed@lists.ozlabs.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®