Repository navigation
usb: keep EHCI/OHCI/UHCI DMA below 4 GiB, don't de-power unsupported devices - #113
Open
JiTianYu391 wants to merge 1 commit into
Open
JiTianYu391 wants to merge 1 commit into
JiTianYu391 wants to merge 1 commit into
Conversation
…rted devices The legacy host controllers use 32-bit DMA pointers, but their DMA helpers called alloc_frames(), which happily returns frames above 4 GiB on machines with enough RAM. The address was then silently truncated when written into PERIODICLISTBASE/ASYNCLISTADDR/QH/qTD links, so the controller walked the wrong memory and every transfer timed out. - buddy/frame: add buddy_alloc_below() and alloc_frames_dma32(). - ehci/ohci/uhci: allocate all DMA memory through alloc_frames_dma32(). - ehci: return -EOPNOTSUPP (not -EINVAL) for full/low-speed devices behind a high-speed hub; split transactions are not implemented. - hub: keep the port powered when the HCD merely does not support the device, and report failed port power-on instead of ignoring it. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On machines with enough RAM the EHCI controller never works: control transfers time out (`usb-ehci: Port 0 enumeration failed: -110`), and on real hardware the log shows `Control/Transfer DMA allocation failed` and `usb-hub: ... enumerate failed: -22`; the keyboard behind the hub then loses power.
Reproduction (QEMU, bare ISO, baseline = develop)
`-machine q35 -enable-kvm -m 16G -device usb-ehci -device usb-storage`
Instrumented `ehci_dma_alloc()` on the baseline:
```
DEBUG ehci dma size=4096 phys=0x47ff19000 # periodic list, > 4 GiB
DEBUG ehci dma size=96 phys=0x47ff18000 # first QH, > 4 GiB
usb-ehci: Port 0 enumeration failed: -110; waiting for reconnect.
```
With `-m 6G` all addresses stay below 4 GiB and nothing fails, which is why it depends on the machine.
Root cause
Fix
Verification
Same 16G setup after the fix: EHCI list/QH addresses written to the controller are all < 4 GiB (e.g. `P-LIST BASE = 0x7e4ca000`), the device enumerates and QEMU's `usb_msd_*` trace shows 36 SCSI commands completing (baseline: none). clang-tidy introduces no new warnings.
Not covered
Split transactions (full/low-speed devices behind a high-speed hub) and companion-controller handoff beyond the existing K-state release are still missing; those devices now fail with `-EOPNOTSUPP` without being powered off. QEMU has no high-speed hub model, so that path was not reproduced, only read from the code.
🤖 Generated with Claude Code