Skip to contentSkip to conversation

New: usb: teach the usb subsystem about non-coherent dma

Bug 220090 [email protected] 2 participants 3 messages May 5, 2025 USB

lore
Share & tools
lore
#0 lore raw

https://bugzilla.kernel.org/show_bug.cgi?id=220090

            Bug ID: 220090
           Summary: usb: teach the usb subsystem about non-coherent dma
           Product: Drivers
           Version: 2.5
          Hardware: PPC-32
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P3
         Component: USB
          Assignee: [email protected]
          Reporter: [email protected]
        Regression: No

This is based on my findings attempting to bring the usb EHCI driver "ehci-hlwd" in wii-linux (https://wii-linux.org/) to mainline linux (6.14).

1) drivers/usb/core/buffer.c needs to use normal memory when the device uses dma and is not dma-coherent: !dev_is_dma_coherent(hcd->self.sysdev) Writing to uncached non-32-bit variables corrupts memory in the Nintendo Wii. Unfortunately linux puts private non-32-bit variables in dma memory (except ehci_qh), so regular memory is needed for non-coherent dma.

2) usb_hcd_map_urb_for_dma@drivers/usb/core/hcd.c needs to ignore URB_NO_TRANSFER_DMA_MAP when the device uses dma and is not dma-coherent. I did not check why it is needed, probably needs the sync that comes with map/unmap.

3) memset@arch/power/lib/copy_32.S (and machine_init@arch/powerpc/kernel/setup_32.c) needs to avoid alignment exceptions with uncached memory...
ehci_qh_alloc allocates zeroed dma memory, which triggers an alignment exception.
Removing the patch__memset_nocache code in machine_init fixes the alignment exception.
Maybe there needs to be a nocache version of memset?

?) no idea about the rest of the usb subsystem, but I expect changes are needed wherever it assumes that dma support implies the dma memory can be treated like normal cached memory.

--

Context:

wii-linux is currently stuck in an old version of the kernel, usb not working in more recent versions is one of the blockers.
I wanted to try making a rust driver for my Wii so I needed a recent kernel version and usb 2.0 working.
After trying to understand the hacky changes that come with the usb drivers, while trying to port the EHCI driver without hacks to a more recent version, I found a commit that breaks the strategy that I used.

Commit 461db2bdbf3c978e76dd10a04a63fa06bb29114f changed the conditions needed to trigger a sync for non-coherent dma memory.
Assuming that syncs are needed, I was able to adapt the code and got all the way to mainline (after disabling KUEP/KUAP) and here I am sharing my findings so stuff can be fixed.

--

Nintendo Wii memory:

MEM1 - 24MiB starting at address 0x00000000
MEM2 - 64MiB starting at address 0x10000000

The dma-coherent term is confusing but in this case it appears to imply uncached memory can be used like normal cached memory.

MEM1 and MEM2 are dma-coherent with 32-bit writes.
MEM1 corrupts memory with uncached 8-bit and 16-bit writes.
MEM2 corrupts memory with uncached 8-bit and 16-bit writes from the PowerPC cpu side.
MEM2 is fully dma-coherent from the ARM cpu side (inside the Hollywood SoC).

The corrupted memory is the 32-bit aligned value of the 8-bit or 16-bit write and also a surrounding 32-bit value (maybe more, did not check).

Devices that only perform 32-bit writes can use any memory for dma. Devices that perform non-32-bit writes, like usb, need to use MEM2 for dma.

I'm not sure if linux supports the concept of minimum address in dma allocations without using reserved memory, but the Nintendo Wii is a use case for that support.
I do not know if the Nintendo WiiU/Switch/Switch 2 work the same way, Nintendo has included backwards compatibility so it's plausible.

Signature · 4 lines
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.
maintainer
#1 lore raw
Quoted 2 lines · On Mon, May 05, 2025 at 03:45:51PM +0000, [email protected] wrote:

This is based on my findings attempting to bring the usb EHCI driver "ehci-hlwd" in wii-linux (https://wii-linux.org/) to mainline linux (6.14).

Great, please submit patches for this, BUT it looks like this:

Quoted 2 lines

Commit 461db2bdbf3c978e76dd10a04a63fa06bb29114f changed the conditions needed to trigger a sync for non-coherent dma memory.

Might be the real root of the problems. Please work with the dma developers to see if that's the cause, as all other platforms seem to work just fine with the ehci drivers that we know of, so perhaps this is just a dma subsystem setup issue somewhere for your platform?

thanks,

greg k-h

#2 lore raw

[Bug 220090] usb: teach the usb subsystem about non-coherent dma

In reply to [email protected]

https://bugzilla.kernel.org/show_bug.cgi?id=220090

--- Comment #1 from [email protected] ---

Quoted 2 lines · On Mon, May 05, 2025 at 03:45:51PM +0000, [email protected] wrote:

This is based on my findings attempting to bring the usb EHCI driver "ehci-hlwd" in wii-linux (https://wii-linux.org/) to mainline linux (6.14).

Great, please submit patches for this, BUT it looks like this:

Quoted 2 lines

Commit 461db2bdbf3c978e76dd10a04a63fa06bb29114f changed the conditions needed to trigger a sync for non-coherent dma memory.

Might be the real root of the problems. Please work with the dma developers to see if that's the cause, as all other platforms seem to work just fine with the ehci drivers that we know of, so perhaps this is just a dma subsystem setup issue somewhere for your platform?

thanks,

greg k-h

Signature · 4 lines
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.