# Inventory: USB host transactions and compatibility policy

Status: complete
Type: inventory
Updated: 2026-07-30
Next Action: retain the passing executable inventory gate and fail future unclassified transaction drift
Campaign: 003-complete-bounded-hpt-slow-export-firmware-ticket
Parent: work/wp/completed/wp-implement-usb-command-class-compatibility-fallback-end-to-end.md
Project Map: work/maps/map-smi-firmware-stabilization-and-qualification.md

## Scope

This inventory covers every transaction the compiled Controller USB host path
can issue to a USB mass-storage drive, not only SCSI commands:

- root-port/HCD operations and USB signaling;
- USB standard device/interface/endpoint control requests;
- Mass Storage Bulk-Only Transport class-specific requests;
- bulk CBW, data, and CSW transfers plus reset recovery;
- every reachable SCSI command descriptor block; and
- compiled but unreachable/dormant request surfaces that must remain excluded
  or become covered if configuration changes.

The active generated configuration registers only the USB host Mass Storage
class. It does not register the external Hub, HID, CDC ACM, Video, Audio, or
Printer host classes. Legacy CB/CBI storage protocol support and OTG/HNP are
not enabled. The active storage transport is Bulk-Only Transport.

Static-audit raw search results are retained under the ignored path
`work/evidence/generated/`:

- `usb-all-requests-static-rg-20260730.txt`
- `usb-control-request-assignments-20260730.txt`
- `usb-hcd-port-operations-20260730.txt`
- `usb-scsi-static-rg-20260730.txt`

## Compatibility classes

| Class | Meaning | Required behavior |
| --- | --- | --- |
| Protocol-essential | Required to enumerate, address, configure, transport, mount, read, or write | Bounded retry/recovery where the specification permits; otherwise fail |
| Optional discovery | Provides information that can be safely defaulted or omitted | Accept only the protocol-defined unsupported response; use a documented conservative default |
| Optional lifecycle | Quiesce/eject/power-management aid | If explicitly unsupported, use the qualified fresh-powered-session barrier when durability matters |
| Durability barrier | Establishes that published data survived beyond the current device session | Normal success or qualified alternate barrier; never silently ignore |
| Recovery-only | Issued after stall, phase error, or failed command | Bounded recovery; failure is terminal for the current operation/session |
| Dormant | Compiled source or constants exist but no active call path/configuration reaches them | Keep excluded and add a build/static guard; inventory before enabling |

## Root-port and USB signaling inventory

| Operation | Reachability/use | Class | Compatibility policy |
| --- | --- | --- | --- |
| VBUS power on | Initial host operation and guarded compatibility recovery | Protocol-essential / durability | Require reported success plus attach and fresh-session verification |
| VBUS power down | Guarded durability fallback and diagnostic | Durability barrier | Require disconnect observation, stale-state clearing, minimum off interval, and no unchanged media generation |
| Root-port status read | Enumeration, change processing, diagnostics | Protocol-essential | Poll only to a bounded deadline; impossible/SE0/SE1/overcurrent states terminate with attribution |
| Root-port enable | Device insertion | Protocol-essential | One bounded attempt followed by reset/re-enumeration policy |
| Root-port reset | Enumeration and recovery | Recovery-only | Enforce USB reset/recovery timing and one bounded retry |
| Root-port disable | HCD capability; not used in normal storage workflow | Dormant/recovery | Do not add to compatibility path without a lifecycle test |
| Root-port suspend/resume | HCD capability; no active storage call path | Dormant | Static guard; separately review remote-wakeup and resume timing before enabling |
| Transfer request/abort | All control and bulk traffic; timeout cleanup | Protocol-essential/recovery | Every transfer has a finite deadline; abort must leave endpoint/session state attributable |
| Full-/high-speed negotiation | Electrical/HCD enumeration | Protocol-essential | Support a high-speed-capable device falling back to controller-supported speed; fail invalid persistent line states |

External-hub class requests and hub interrupt transfers are excluded because
the generated firmware does not register the Hub host class. Directly attached
drives through the controller root port are the supported topology. Enabling
external hubs requires a new inventory covering hub descriptors, per-port
power/reset/status/change features, transaction translators, and compound
device timing.

## USB standard control-request inventory

| Request | Active trigger | Class | Compatibility policy |
| --- | --- | --- | --- |
| `GET_DESCRIPTOR(Device)` | Initial short descriptor and full device descriptor | Protocol-essential | Require valid lengths, EP0 maximum packet size, descriptor type, and bounded retry; malformed data fails |
| `SET_ADDRESS` | Enumeration | Protocol-essential | Require successful status stage and post-address recovery delay; failure resets/re-enumerates once |
| `GET_DESCRIPTOR(Configuration)` | Configuration header and full descriptor tree | Protocol-essential | Validate total length, interface/endpoint bounds, descriptor progress, and exact transfer length |
| `SET_CONFIGURATION(nonzero)` | Activate selected mass-storage configuration | Protocol-essential | Failure is terminal after bounded reset/re-enumeration |
| `SET_CONFIGURATION(0)` | Configuration deactivation/removal path | Recovery/lifecycle | Best-effort during confirmed removal; must not preserve stale class/FileX state if device no longer responds |
| `CLEAR_FEATURE(ENDPOINT_HALT)` | BOT reset recovery and endpoint reset | Recovery-only | Apply to the correct bulk endpoint, reset data toggle, require recovery completion |
| `GET_STATUS(Endpoint)` | BOT CSW/stall diagnosis | Recovery-only | Short/malformed/stalled result cannot be treated as healthy transport |
| `SET_INTERFACE` | USBX API exists but storage path does not select an alternate setting | Dormant | Static guard; inventory alternate-setting compatibility before any future call |
| `GET_DESCRIPTOR(String)` | API compiled but neither storage stack nor application calls it | Dormant | Product compatibility must not depend on strings; keep out of required enumeration |
| OTG `SET_FEATURE` / device `GET_STATUS` | Source compiled conditionally; OTG/HNP disabled | Dormant | Must remain disabled for this fixed-host product |
| Other standard requests (`GET_CONFIGURATION`, `GET_INTERFACE`, `SET_DESCRIPTOR`, `SYNCH_FRAME`) | No active call path | Dormant | Static guard and future review before enabling |

Descriptor parsing, not only request success, is part of compatibility.
Dynamic endpoint discovery must accept valid bulk endpoint numbers and order,
reject duplicate/missing/zero-max-packet endpoints, and avoid hard-coded
endpoint addresses.

## Mass Storage Bulk-Only Transport inventory

| Transaction | Active trigger | Class | Compatibility policy |
| --- | --- | --- | --- |
| `GET_MAX_LUN` (`bRequest=0xFE`) | Storage initialization | Optional discovery | A control stall means one LUN as required by BOT; malformed/short data also defaults to LUN 0 but must be recorded; cap impossible values and mount only supported media slots |
| Bulk-Only Mass Storage Reset (`bRequest=0xFF`) | BOT phase/stall/REQUEST SENSE recovery | Recovery-only | Require successful class reset followed by `CLEAR_FEATURE(HALT)` on both bulk endpoints and data-toggle reset; one bounded recovery sequence |
| CBW bulk OUT | Every SCSI command | Protocol-essential | Validate 31-byte transfer, signature, unique tag, legal CDB length, LUN bounds, direction, and transfer length |
| Data bulk IN/OUT | Commands with payload | Protocol-essential | Exact-length policy per command; short data allowed only where explicitly defined; no generic short-transfer success |
| CSW bulk IN | Every BOT command | Protocol-essential | Validate 13-byte length, signature, matching tag, residue, and status; phase error forces BOT reset recovery |
| `REQUEST SENSE` after failed CSW | Failed SCSI command | Recovery-only | Sense transfer/format must be valid; missing or malformed sense is not an unsupported-command classification |
| Endpoint stall handling | Data or CSW stall | Recovery-only | Follow BOT reset recovery order; prevent infinite stall/clear/reset loops |

## Reachable SCSI command inventory

The USBX names `READ16` and `WRITE16` are misleading: their opcode values are
`0x28` and `0x2A`, therefore the active commands are SCSI `READ(10)` and
`WRITE(10)`.

| Opcode | Command and active use | Class | `ILLEGAL REQUEST` and compatibility policy |
| ---: | --- | --- | --- |
| `0x00` | `TEST UNIT READY` during mount/readiness checks | Protocol-essential | Do not ignore. Retry only documented transient states such as Unit Attention or becoming-ready Not Ready, with delay/deadline; medium absent and permanent states terminate |
| `0x03` | `REQUEST SENSE` automatically after command-failed CSW | Recovery-only | Must succeed with valid fixed/descriptor sense before interpreting a command failure; failure triggers bounded BOT recovery then terminates |
| `0x12` | Standard `INQUIRY`, EVPD=0, 36 bytes, during LUN initialization | Protocol-essential discovery | A mass-storage interface that cannot return minimally valid standard inquiry cannot be safely classified; fail. Do not require VPD pages or vendor/product strings |
| `0x23` | `READ FORMAT CAPACITIES`, currently issued inside capacity lookup and again by initialization | Optional discovery | `ILLEGAL REQUEST` may be ignored. Remove redundant invocation or make it a single recorded optional probe; never let its data override valid `READ CAPACITY(10)` |
| `0x25` | `READ CAPACITY(10)` for logical block size and capacity | Protocol-essential | Do not guess 512 bytes after command failure. Require valid response, supported logical sector size, non-overflowing bounds, and representative last-sector read |
| `0x28` | `READ(10)` for MBR/VBR, FAT/FileX, readback, WAV/update/PID/HPT workflows | Protocol-essential | Any command failure is fatal to the current operation after sense-based transient recovery; verify exact data length and LBA/count bounds |
| `0x2A` | `WRITE(10)` for FAT/FileX data and metadata | Protocol-essential | Any command failure is fatal; do not retry an ambiguous completed write blindly; use FileX/session recovery and post-failure filesystem disposition |
| `0x35` | `SYNCHRONIZE CACHE(10)` from `FX_DRIVER_FLUSH` | Durability barrier | Completed BOT command with valid sense key `ILLEGAL REQUEST`, regardless of ASC/ASCQ, means unsupported for this session and selects fresh-powered-session verification. Timeout, transport failure, malformed sense, or any other sense remains fatal |
| `0x1B` | `START STOP UNIT`, application sends START=0 to quiesce before VBUS/removal-ready success | Optional lifecycle/durability aid | Completed command with valid `ILLEGAL REQUEST` means unsupported; continue only through fresh-powered-session verification. Replace the current 50 immediate retries with sense-aware bounded policy and delay |

## Dormant SCSI surfaces

The following constants or source helpers exist but are not reachable in the
active BOT/FileX/application call graph:

- `FORMAT UNIT (0x04)`;
- `MODE SENSE(6) (0x1A)`;
- `VERIFY(10) (0x2F)`;
- `MODE SELECT(10) (0x55)`;
- `MODE SENSE(10) (0x5A)`;
- opcodes named `READ32/WRITE32` by USBX but representing
  `READ(12)/WRITE(12)` (`0xA8/0xAA`);
- media-protection and recovery-mode-sense helpers; and
- legacy CB/CBI command transport.

They must not be used to claim present compatibility coverage. Add a static
source/configuration check so enabling one forces an inventory and test update.
If future capacity exceeds `READ CAPACITY(10)` representation, add and review
`SERVICE ACTION IN(16)/READ CAPACITY(16)` rather than silently truncating.

## Findings and implementation disposition

1. **Resolved — capacity guessing.** Repeated `READ CAPACITY(10)` failure now
   fails closed; it cannot silently become guessed 512-byte media success.
2. **Resolved — redundant READ FORMAT CAPACITIES.** The repeated probe was
   removed from the capacity retry loop.
3. **Resolved — INQUIRY validation.** Standard INQUIRY now requires transport
   success, command/sense success, and the complete expected data phase.
4. **Resolved — START STOP retries.** Recovery is bounded to three attempts
   with delay; a completed `ILLEGAL REQUEST` is classified as unsupported
   optional lifecycle behavior.
5. **Resolved — READ/WRITE retries.** READ retries only explicit transient
   readiness states; WRITE is issued once and ambiguous writes are not replayed.
6. **Open — GET_MAX_LUN attribution.** Defaulting a stall to LUN 0 is
   compatible, but malformed/short/transport failures should be distinguishable
   in telemetry.
7. **Open — BOT recovery terminal proof.** Reset, halt clearing, REQUEST SENSE,
   and re-enumeration must not form an unbounded recovery loop.
8. **Resolved — fresh-session handoff.** Blocking VBUS remount waits now
   service the deferred FileX handoff. A/B hardware runs reached a fresh
   generation and acceptance mask `15`.
9. **Resolved — executable static audit.**
   `script/check-usb-transaction-inventory.ps1` enumerates enabled host
   classes, control/class requests, HCD operations, and SCSI opcode assignments
   and fails on unclassified drift.

## 2026-07-30 compatibility timing evidence

- A completed SYNCHRONIZE CACHE `ILLEGAL REQUEST` is correctly classified.
- A 5-second passive delay before the fresh-powered-session barrier was too
  short for `USB08_8G`: the renamed file was not immediately visible after
  remount, although it appeared after a later controller reboot.
- A 30-second passive delay passed image and PID publication with exact
  post-cycle verification on Controller B and Controller A.
- The 30-second interval is not yet the final policy. The next qualification
  should test 10 seconds, then 15 seconds only if necessary, and select the
  shortest repeatedly passing bounded interval.
- TEST UNIT READY, reads, or host-bus inactivity cannot be treated as proof
  that an unsupported device cache is physically persistent.

## Required verification matrix

For every active transaction above, tests must cover:

- nominal success;
- control or bulk stall where legal;
- timeout/no response;
- short and malformed response;
- disconnect during setup, data, and status phases;
- BOT CSW command-failed and phase-error statuses;
- valid and malformed REQUEST SENSE;
- bounded recovery exhaustion;
- session-state cleanup and fresh generation after reconnect; and
- attribution in compact telemetry without relying on device strings.

Protocol-specific cases:

- descriptor lengths, endpoint order/address, max-packet sizes, full/high-speed
  operation, SET_ADDRESS/SET_CONFIGURATION timing;
- GET_MAX_LUN success, defined stall-to-zero behavior, short data, and
  excessive LUN values;
- BOT reset plus both endpoint halt clears and data-toggle reset;
- SCSI transient readiness versus permanent sense;
- exact READ/WRITE length, boundary, and residue behavior;
- SYNCHRONIZE CACHE and START STOP UNIT unsupported compatibility paths; and
- compliant sync path versus fresh-powered-session durability proof.

Target telemetry must be correlated with a USB protocol analyzer or a
fault-injection transport shim for cases that cannot be produced reliably by
available drives. Laboratory specimens validate examples; fault injection
validates the complete unknown-drive policy space.

## Completion criteria

- Historical planning item: Every reachable root-port operation is classified and bounded.
- Historical planning item: Every reachable USB standard request is classified and tested.
- Historical planning item: Every reachable Mass Storage class request and BOT phase is classified
      and tested.
- Historical planning item: Every reachable SCSI opcode is classified and tested.
- Historical planning item: Dormant transactions are guarded so configuration/source drift fails the
      audit.
- Historical planning item: All nine implementation findings are resolved or explicitly rejected by
      reviewed decision.
- Historical planning item: Static inventory check and runtime opcode/request telemetry agree on both
      controllers.
- Historical planning item: No unclassified request can be issued by the release build.
