On real xHCI, USB keyboard and mouse input freezes because the interrupt-IN event-ring scan does not advance past events it did not arm.
controller/poll_interrupt_in/scan.rs:30-40 reads the event at the ring head, and if it is not the armed interrupt-IN transfer it returns Pending without advancing the dequeue pointer. Real xHCI puts Port Status Change Events (and other slots' transfer events) at the head on every connect/reset/link-state change; one of those sits at the head, the scan never dequeues it, has_event() keeps returning the same TRB, and all interrupt-IN polling wedges permanently.
The control-transfer waiter does this correctly (controller/wait_transfer_completion.rs:44-49 advances past and skips every non-matching event); the interrupt path just doesn't. This is the real "empty/stalled HID input" cause on real xHCI, not MSI-X or port power (both of which are handled correctly, including the USBLEGSUP SMM handoff and PORTSC.PP).
Widening: make scan mirror wait_transfer_completion and unconditionally advance past / handle non-matching events. This is the single highest-value real-HW input fix; on USB-only laptops with no PS/2 it is the difference between input and no input.
On real xHCI, USB keyboard and mouse input freezes because the interrupt-IN event-ring scan does not advance past events it did not arm.
controller/poll_interrupt_in/scan.rs:30-40 reads the event at the ring head, and if it is not the armed interrupt-IN transfer it returns Pending without advancing the dequeue pointer. Real xHCI puts Port Status Change Events (and other slots' transfer events) at the head on every connect/reset/link-state change; one of those sits at the head, the scan never dequeues it, has_event() keeps returning the same TRB, and all interrupt-IN polling wedges permanently.
The control-transfer waiter does this correctly (controller/wait_transfer_completion.rs:44-49 advances past and skips every non-matching event); the interrupt path just doesn't. This is the real "empty/stalled HID input" cause on real xHCI, not MSI-X or port power (both of which are handled correctly, including the USBLEGSUP SMM handoff and PORTSC.PP).
Widening: make scan mirror wait_transfer_completion and unconditionally advance past / handle non-matching events. This is the single highest-value real-HW input fix; on USB-only laptops with no PS/2 it is the difference between input and no input.