Artemis Milestone 2g: Configure Endpoint command
Adds the xHCI Configure Endpoint command for the two bulk endpoints identified by the previous increment, and fixes control-transfer sequencing to match the spec: xHCI 1.2 section 4.3.5 requires Configure Endpoint before SET_CONFIGURATION is sent to the device, the reverse of the order this driver used through 2f (which happened to work against QEMU's lenient qemu-xhci emulation but wasn't spec-correct). New XHCI_TRB_TYPE_CONFIGURE_ENDPOINT_CMD, EP Context type constants for Bulk IN/OUT, and an XHCI_EP_ADDR_TO_DCI() macro (DCI = 2*EndpointNumber + Direction) in xhci.h. xhci_cmd_configure_endpoint() builds the Input Context (Slot + one EP Context per DCI up to the highest bulk endpoint in use) and submits the command via the existing next_action deferral mechanism, correlated on completion via a new XHCI_CONN_AWAIT_CONFIGURE_ENDPOINT connect_state, then chains into the existing SET_CONFIGURATION path. Two allocations had to grow beyond what Address Device sized them for: the Input Context (previously room for one EP Context only) and, less obviously, the Device Context that DCBAA[slot_id] itself points at -- the controller only touches DCIs named in a command's own Add/Drop flags, so growing that buffer required copying its existing Slot+EP0 content forward rather than zeroing it, to avoid handing the controller a blank EP0 out from under an endpoint this command isn't touching. Bulk Transfer Rings (bulk_in_ring/bulk_out_ring) are allocated and wired into the new EP Contexts but not yet exercised by an actual transfer -- CBW/CSW submission is next. Verified live via QMP hotplug, all three architectures, byte-identical: bulk endpoint identification -> configure endpoint command submitted -> configure endpoint succeeded -> the existing set configuration -> device configured chain, then a clean disconnect/disable-slot teardown afterward with the larger Device Context installed. FABRIC-2.md Section X Milestone 2g's endpoint identify+configure checklist item marked fully done. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R4VMX6VSKCten8nGgaMkq4
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
96d55fcd87
commit
92ce1f85dd
+50
-8
@@ -3451,11 +3451,8 @@ arch afterward, no wedge. `logs/20260825-073235/amd64/`, `logs/20260825-073417/a
|
||||
`logs/20260825-073728/riscv64/`.
|
||||
|
||||
**2g. Bulk-Only Transport (BOT) — the actual read/write path**
|
||||
- [~] Identify the device's bulk IN and bulk OUT endpoints — **identification done
|
||||
2026-08-25**, see writeup below; *configuring* them (a Configure Endpoint command,
|
||||
wiring their EP Contexts/DCIs so the controller will actually run transfers on them)
|
||||
is still open — this increment only reads the addresses out of the descriptor, it
|
||||
doesn't yet act on them
|
||||
- [x] Identify and configure the device's bulk IN and bulk OUT endpoints — **identification
|
||||
done 2026-08-25, configuration done 2026-08-25**, see writeups below
|
||||
- [ ] Implement CBW (Command Block Wrapper) construction and send, for a SCSI READ(10)
|
||||
- [ ] Implement CSW (Command Status Wrapper) receive and status check
|
||||
- [ ] Get one real SCSI READ(10) working end to end — first proof the whole stack works,
|
||||
@@ -3489,9 +3486,54 @@ individually-tracked instance — see the disconnect-teardown writeup above for
|
||||
matters), all three architectures, byte-identical results everywhere: `bulk IN
|
||||
endpoint=0x81`, `bulk OUT endpoint=0x02`, immediately followed by the existing `set
|
||||
configuration submitted` → `device configured` chain, unaffected. `logs/20260825-081058/amd64/`,
|
||||
`logs/20260825-081300/aarch64/`, `logs/20260825-081517/riscv64/`. *Configuring* these
|
||||
endpoints (a Configure Endpoint command, EP Context setup) is the next open item in this
|
||||
milestone — this increment only identifies them.
|
||||
`logs/20260825-081300/aarch64/`, `logs/20260825-081517/riscv64/`.
|
||||
|
||||
**Configure Endpoint command, done 2026-08-25.** Per xHCI 1.2 spec section 4.3.5, a Configure
|
||||
Endpoint command must be issued once enumeration has identified the endpoints a device's
|
||||
configuration actually uses, and *before* the USB SET_CONFIGURATION request is sent to the
|
||||
device — the reverse of the order this driver used through 2f (SET_CONFIGURATION issued with
|
||||
no endpoints ever configured). That earlier order happened to work against QEMU's lenient
|
||||
`qemu-xhci` emulation, but wasn't spec-correct; this increment fixes the sequencing as part of
|
||||
adding the command, chaining Configure Endpoint in between the bulk-endpoint-identification
|
||||
step and SET_CONFIGURATION via the same `next_action` deferral mechanism as every other
|
||||
control transfer/command in this driver (a new `XHCI_NEXT_ACTION_CONFIGURE_ENDPOINT` value,
|
||||
and a new `XHCI_CONN_AWAIT_CONFIGURE_ENDPOINT` connect-state to correlate the command's own
|
||||
Command Completion Event, same pattern as Enable Slot/Address Device/Disable Slot above).
|
||||
|
||||
Two things had to grow beyond what Address Device allocated, both realised only while writing
|
||||
this: the **Input Context** (Address Device's 96-byte allocation only ever held one EP
|
||||
Context; Configure Endpoint needs one EP Context per Device Context Index up to the highest
|
||||
DCI now in use — DCI = `2*EndpointNumber + Direction`, `XHCI_EP_ADDR_TO_DCI()`, new in
|
||||
`xhci.h` — so it's reallocated at a size covering the Slot Context plus every DCI from 1
|
||||
through the bulk endpoints' own, unused intermediate DCIs left zeroed since their Add flags
|
||||
are 0), and the **Device Context** that `DCBAA[slot_id]` itself points at (same reasoning,
|
||||
but with a sharper constraint: xHCI 1.2 spec section 4.6.6 has the controller touch only the
|
||||
DCIs actually named in a command's Add/Drop flags, so the *existing* Slot+EP0 content has to
|
||||
be copied into the newly, larger buffer rather than left zeroed — a freshly zeroed Device
|
||||
Context would hand the controller a blank EP0 out from under an endpoint this command isn't
|
||||
touching, corrupting live control-transfer state). The Slot Context written into the Input
|
||||
Context is itself copied from the live Device Context (Route String/Speed/Root Hub
|
||||
Port/Interrupter Target aren't retained anywhere else by this point in enumeration —
|
||||
`pending_connect_port_id` is cleared as soon as Address Device completes), with only Context
|
||||
Entries changed to the new highest DCI.
|
||||
|
||||
Max Burst Size is left at 0 (single-burst) in both bulk EP Contexts — SuperSpeed Endpoint
|
||||
Companion descriptor parsing isn't implemented, so this driver doesn't yet know a real
|
||||
device's burst capability; matches every device tested against so far under QEMU's emulation,
|
||||
flagged as a revisit point if a real high-throughput SS device needs it. Average TRB Length is
|
||||
a placeholder (1024, a scheduling hint per spec, not a correctness constraint) until real
|
||||
CBW/data/CSW transfer sizes are known — 2g's next items.
|
||||
|
||||
Verified live via QMP hotplug, all three architectures, byte-identical results: `xhci: bulk IN
|
||||
endpoint=0x81` / `bulk OUT endpoint=0x02` → `configure endpoint command submitted` →
|
||||
`configure endpoint succeeded` → the existing `set configuration submitted` → `device
|
||||
configured` chain, unaffected. Disconnect confirmed clean afterward on every arch, no wedge —
|
||||
`disable slot succeeded` still fires normally with the larger Device Context now installed.
|
||||
`logs/20260825-083142/amd64/`, `logs/20260825-083425/aarch64/`, `logs/20260825-083744/riscv64/`.
|
||||
Bulk Transfer Rings (`bulk_in_ring`/`bulk_out_ring`, same fixed-ring-plus-Link-TRB pattern as
|
||||
every other ring in this driver) are allocated and wired into the EP Contexts by this
|
||||
increment but not yet used for an actual transfer — CBW/CSW submission (2g's next items) is
|
||||
what exercises them for the first time.
|
||||
|
||||
**2h. Integration with the existing block subsystem**
|
||||
- [ ] Wire a working USB MSC device into `blk_subsys_attach_device()` (or
|
||||
|
||||
Reference in New Issue
Block a user