Artemis Milestone 2g: TEST UNIT READY unit-init sequence -- READ(10) now PASSes
Roots out the CSW status FAILED left unexplained in the prior increment: a freshly attached SCSI target's standing UNIT ATTENTION condition, which a bare READ(10) with no retry can never clear. xhci_bot_send_test_unit_ready() sends SCSI TEST UNIT READY (SPC-4 6.33) ahead of the real command; the CSW handler now tags command kind (bot_cmd_kind) to distinguish a TUR completion from a READ10 completion, chains TUR PASS into the real READ(10), and bounded-retries TUR on FAILED/PHASE ERROR (bot_tur_retries, capped at XHCI_BOT_TUR_MAX_RETRIES). xhci_bot_read_block() is the new intended entry point tying lba/num_blocks/block_size + the TUR-first sequencing together. Verified live via a temporary probe (hot-attached disk/usb-thumbdrive-test.img through the running instance's QMP socket), captured on amd64: full chain CBW(TUR) -> FAILED -> retry -> PASS -> CBW(READ10) -> Data-In -> CSW PASS. Probe reverted after capture; all three architectures re-verified clean, probe-free boot to ok>. FABRIC-2.md Section X 2g updated with the writeup. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXjAPTEKrgY2Mrk25KoLDn
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
c54ea24aaf
commit
65effbd1ba
+53
-5
@@ -3460,11 +3460,10 @@ arch afterward, no wedge. `logs/20260825-073235/amd64/`, `logs/20260825-073417/a
|
||||
split between this item and "identify/configure endpoints" above didn't leave a
|
||||
separate line for it, but it's new work, not folded silently into either neighbor —
|
||||
see writeup)
|
||||
- [ ] Get one real SCSI READ(10) working end to end — first proof the whole stack works,
|
||||
before write. **Partially exercised, not satisfied**: the CBW→Data-In→CSW mechanism
|
||||
itself is confirmed working (see writeup below), but the SCSI command itself returns
|
||||
CSW status FAILED against the current test fixture -- this item stays open until a
|
||||
READ(10) actually returns PASS with real data, not just a well-formed CSW
|
||||
- [x] Get one real SCSI READ(10) working end to end — first proof the whole stack works,
|
||||
before write. **Done 2026-08-25**: the earlier CSW status FAILED was exactly the
|
||||
UNIT ATTENTION condition flagged (not root-caused) in the prior writeup — a TEST UNIT
|
||||
READY unit-init sequence ahead of READ(10) was the fix, see writeup below
|
||||
- [ ] Implement CBW/data/CSW for SCSI WRITE(10) — this is where the earlier "read/write,
|
||||
unquestionable" requirement actually gets satisfied
|
||||
- [ ] Implement basic error/stall recovery (CSW failure status, endpoint stall clear) — at
|
||||
@@ -3650,6 +3649,55 @@ the SET_CONFIGURATION completion handler) was removed after capture; only
|
||||
Re-verified probe-free afterward, all three architectures, clean boots with no BOT activity:
|
||||
`logs/20260825-092701/amd64/`, `logs/20260825-092842/aarch64/`, `logs/20260825-093048/riscv64/`.
|
||||
|
||||
**TEST UNIT READY unit-init sequence, done 2026-08-25 — READ(10) now returns PASS.** Root-causes
|
||||
the CSW status FAILED flagged but not chased down in the previous increment: SBC-3/SPC-4 give a
|
||||
freshly attached SCSI target's first command a standing UNIT ATTENTION (media-change/reset
|
||||
notice), cleared once any command is issued and answered — a bare READ(10) with no retry, which
|
||||
is all the previous probe sent, was always going to eat that condition rather than clear it.
|
||||
`xhci_bot_send_test_unit_ready()` builds and sends the CBW for SCSI TEST UNIT READY (SPC-4
|
||||
section 6.33, opcode `0x00`, 6-byte all-zero CDB, no data stage) — mirrors
|
||||
`xhci_bot_send_read10()`'s CBW-build shape but sets `dCBWDataTransferLength = 0` /
|
||||
`bot_expected_data_len = 0`, which the existing `XHCI_XFER_CBW_SENT` completion handler now
|
||||
checks to skip straight to CSW receive rather than a Data-In stage that would never arrive (BOT
|
||||
spec section 6.3: zero-length command means no data phase).
|
||||
|
||||
A new `bot_cmd_kind` field (`BOT_CMD_NONE`/`BOT_CMD_TEST_UNIT_READY`/`BOT_CMD_READ10`) tags which
|
||||
SCSI command a given CBW→CSW round trip actually is, since `XHCI_XFER_CSW_RECEIVED` alone can't
|
||||
tell a TUR completion from a READ10 completion — both take the identical CBW→(Data-In)→CSW
|
||||
shape. The CSW-receive handler now branches on it: a TUR CSW PASS chains into the real READ(10)
|
||||
(`XHCI_NEXT_ACTION_BOT_SEND_READ10`, same deferred-dispatch pattern as every other chained
|
||||
request in this driver); a TUR FAILED/PHASE ERROR retries TUR itself
|
||||
(`XHCI_NEXT_ACTION_BOT_SEND_TUR`), bounded by a new `bot_tur_retries` counter against
|
||||
`XHCI_BOT_TUR_MAX_RETRIES` (3) so a target that's never going to clear UNIT ATTENTION can't spin
|
||||
the driver forever; a READ10 CSW completion is unchanged (terminal, logged only — 2h's problem
|
||||
per the prior increment's own doc comment, still true).
|
||||
|
||||
`xhci_bot_read_block()` is the new intended entry point tying this together — latches
|
||||
lba/num_blocks/block_size, resets the retry counter, and kicks off with TUR rather than a bare
|
||||
READ10, so callers get the UNIT ATTENTION handling for free instead of reimplementing it.
|
||||
`xhci_bot_send_read10()` itself is unchanged in behavior, just now also reachable via this
|
||||
chain (low-level primitive, most callers should prefer `xhci_bot_read_block()`).
|
||||
|
||||
Verified live via a temporary probe (written, run once, log captured, then reverted per this
|
||||
project's own probe convention) hot-attaching `disk/usb-thumbdrive-test.img` through the running
|
||||
instance's QMP socket (`blockdev-add` + `device_add usb-storage,bus=xhci0.0`) rather than at
|
||||
QEMU launch — exercises the same live-hotplug path 2e/2f's own writeups already use, and avoids
|
||||
needing the `-device usb-storage` flag added to any of the three `qemu` Makefile targets. Full
|
||||
chain, byte-identical to the design: `device configured` → `CBW (TEST UNIT READY) submitted` →
|
||||
`CSW status = FAILED` → `unit not ready -- retrying TEST UNIT READY` → `CBW (TEST UNIT READY)
|
||||
submitted` → `CSW status = PASS` → `unit ready -- issuing READ10` → `CBW (READ10) submitted` →
|
||||
`BOT Data-In read submitted` → `BOT Data-In read completed` → `CSW status = PASS`, data
|
||||
residue 0 throughout. Captured on amd64 only this increment (`logs/20260825-112924/amd64/`) —
|
||||
unlike 2g's own writeups, the other two architectures were not separately hotplug-verified with
|
||||
the probe active, since the mechanism itself (CBW/CSW dispatch, deferred `next_action` chaining)
|
||||
is architecture-independent code already proven identical across all three arches by every
|
||||
earlier BOT increment; only the probe-removed acceptance boot was re-run on all three. The probe
|
||||
(`XHCI_NEXT_ACTION_BOT_PROBE_READ_BLOCK` and its trigger in the SET_CONFIGURATION completion
|
||||
handler) was removed after capture; only `xhci_bot_send_test_unit_ready()`/
|
||||
`xhci_bot_read_block()` and their Transfer Event handling remain. Re-verified probe-free
|
||||
afterward, all three architectures, clean boots with no BOT activity: `logs/20260825-113813/amd64/`,
|
||||
`logs/20260825-114114/aarch64/`, `logs/20260825-114321/riscv64/`.
|
||||
|
||||
**2h. Integration with the existing block subsystem**
|
||||
- [ ] Wire a working USB MSC device into `blk_subsys_attach_device()` (or
|
||||
`blk_subsys_add_raw_device()`, whichever fits — confirm which, since USB is
|
||||
|
||||
Reference in New Issue
Block a user