feat: EP0 mouse/kbd polling, CC=12 investigation (Parallels xHCI)#239
Open
feat: EP0 mouse/kbd polling, CC=12 investigation (Parallels xHCI)#239
Conversation
Systematic investigation of CC=12 (Endpoint Not Enabled) on Parallels ARM64 virtual xHCI interrupt endpoints, with working EP0 GET_REPORT polling for both keyboard and mouse. ## Findings CC=12 on interrupt IN is a fundamental Parallels virtual xHC limitation: - Parallels proactively generates CC=12 Transfer Events after re-ConfigureEndpoint (before any TRBs are queued), signaling that interrupt IN transfers are not supported - This persists regardless of command sequence: BSR=0/1, bandwidth dance enabled/disabled, BEI flag, matching Linux byte-for-byte - EP0 control transfers work reliably; interrupt IN never completes - Linux keyboard/mouse works via Parallels Tools injection, not xHCI interrupt IN (Linux ftrace shows no interrupt TRB completions in trace) ## Working solution: EP0 GET_REPORT polling Both keyboard and mouse input work via EP0 GET_REPORT control transfers at 4 Hz (limited by Parallels virtual USB device timing, not our polling interval): - gr=N gk=N mr=N mk=N with ge=me=0 (zero errors) verified in testing - Ring recycling (StopEndpoint + SetTRDequeuePointer) for EP0 rings since Parallels does not follow Link TRBs on transfer rings ## Changes xhci.rs: - Mouse EP0 GET_REPORT polling: SET_PROTOCOL(boot) during init, then 4 Hz boot-protocol GET_REPORT via EP0 with ring recycling - EP0 ring recycling for keyboard (every ~84 polls) and mouse - Bandwidth dance (SKIP_BW_DANCE=false): matches Linux's xhci_check_bandwidth() sequence with 3x ConfigureEndpoint + 2x StopRing per slot — confirmed matching Linux ftrace byte-for-byte - BSR=0 confirmed correct (BSR=1 causes CC=19 Context State Error) - Added EP0_MOUSE_POLL_STATE, MOUSE_CTRL_DATA_BUF, queue_ep0_mouse_get_report() - Diagnostics: DIAG_DOORBELL_EP_STATE, DMA buffer address logging, endpoint state read after SET_CONFIG and at doorbell time - Polling interval: % 10 (20 Hz attempt; bottleneck is Parallels ~4 Hz) timer_interrupt.rs: - Heartbeat counters: mr= mk= me= for mouse EP0 polling status Co-Authored-By: Ryan Breen <ryan@ryanbreen.com> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.
Summary
Changes
kernel/src/drivers/usb/xhci.rsSET_PROTOCOL(boot)during device init, then 4 Hz GET_REPORT via EP0 control pipe with ring recyclingSKIP_BW_DANCE=false): matches Linux'sxhci_check_bandwidth()with 3× ConfigureEndpoint + 2× StopRing per slotDIAG_DOORBELL_EP_STATE, DMA buffer address logging, endpoint state diagnostics% 10(20 Hz attempt; bottleneck is Parallels' ~250ms USB device timing, effective rate stays 4 Hz)kernel/src/arch_impl/aarch64/timer_interrupt.rsmr= mk= me=counters for mouse EP0 polling statusTest plan
gr=N gk=N ge=0sustained at 4 Hz with zero errorsmr=N mk=N me=0sustained at 4 Hz with zero errors🤖 Generated with Claude Code