The generic OHCI and EHCI drivers provide remove callbacks, but do
not set DM_FLAG_ACTIVE_DMA. Their controllers can remain active
when U-Boot hands control to the operating system.

An active controller may continue DMA after the operating system
starts reusing U-Boot memory. In particular, OHCI may continue
accessing its HCCA.

Set DM_FLAG_ACTIVE_DMA on both drivers so their existing remove
callbacks stop the controllers during OS preparation.

Signed-off-by: khaliforce <[email protected]>
---
Changes in v2:
- Use DM_FLAG_ACTIVE_DMA as suggested by Neil Armstrong.

Retested on MangoPi MQ Pro with the downstream D1 port based on
U-Boot v2026.10 and Linux 6.1:
- Read a 64 GB FAT32 USB device in U-Boot.
- Verified a 4096-byte read against Linux using CRC32.
- Booted Linux without running "usb stop".
- Confirmed USB reads, Wi-Fi and SSH after the handoff.
- Observed no panic, Bad page or failed services.

Standalone builds pass for RISC-V64, ARM64 and ARM32 on upstream
main. RISC-V64 QEMU boots. Checkpatch reports no errors or warnings.

 drivers/usb/host/ehci-generic.c | 2 +-
 drivers/usb/host/ohci-generic.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-generic.c b/drivers/usb/host/ehci-generic.c
index 1ae3619ce25..57f1bcbd9c0 100644
--- a/drivers/usb/host/ehci-generic.c
+++ b/drivers/usb/host/ehci-generic.c
@@ -167,5 +167,5 @@ U_BOOT_DRIVER(ehci_generic) = {
        .remove = ehci_usb_remove,
        .ops    = &ehci_usb_ops,
        .priv_auto      = sizeof(struct generic_ehci),
-       .flags  = DM_FLAG_ALLOC_PRIV_DMA,
+       .flags  = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_ACTIVE_DMA,
 };
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index cc44226f5e0..7493750f8d1 100644
--- a/drivers/usb/host/ohci-generic.c
+++ b/drivers/usb/host/ohci-generic.c
@@ -110,5 +110,6 @@ U_BOOT_DRIVER(ohci_generic) = {
        .remove = ohci_usb_remove,
        .ops    = &ohci_usb_ops,
        .priv_auto      = sizeof(struct generic_ohci),
-       .flags  = DM_FLAG_ALLOC_PRIV_DMA,
+       /* Stop HCCA DMA before Linux reuses the controller memory. */
+       .flags  = DM_FLAG_ALLOC_PRIV_DMA | DM_FLAG_ACTIVE_DMA,
 };

Reply via email to