On 10/6/26 13:13, khaliforce wrote:
The generic OHCI and EHCI drivers provide remove callbacks, but do
not set DM_FLAG_OS_PREPARE. Consequently, 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 memory previously occupied by U-Boot. In particular,
OHCI may continue accessing its HCCA.
Set DM_FLAG_OS_PREPARE on both drivers so that their existing remove
callbacks stop the controllers during OS preparation.
So while they actually have the same behavior, the DM_FLAG_ACTIVE_DMA
is exactly what you want.
Neil
Signed-off-by: khaliforce <[email protected]>
---
Tested on a MangoPi MQ Pro with U-Boot v2026.10 and Linux 6.1:
- Started USB and accessed a 64 GB FAT32 USB storage device.
- Read 4096 bytes in U-Boot and verified that their CRC32 matched
the same data read under Linux.
- Booted Linux without manually running "usb stop".
- Confirmed USB storage access and Wi-Fi/SSH after the handoff.
- Observed no panic or Bad page errors in the kernel log.
The hardware test used the downstream D1/MangoPi port.
The standalone patch also builds on current upstream main for
RISC-V64, ARM64 and ARM32. 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..8075fb069f1 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_OS_PREPARE,
};
diff --git a/drivers/usb/host/ohci-generic.c b/drivers/usb/host/ohci-generic.c
index cc44226f5e0..6cc26e2d3c0 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_OS_PREPARE,
};