USB Mass Storage BOT Debugging: CBW, CSW, Sense Data, and Recovery

Debug USB Mass Storage Bulk-Only Transport with CBW, CSW, SCSI sense data, stalls, reset recovery, and capture-based evidence before changing firmware.

USB Mass Storage BOT, CBW, CSW, sense data, USB debugging

USB mass-storage failures are often reported as a vague operating-system symptom: a drive does not mount, a logger appears briefly then disappears, a firmware-update device prompts for formatting, or a copy ends with an I/O error. The firmware and host stack, however, are usually exchanging a structured protocol. For a Bulk-Only Transport (BOT) device, the essential pattern is a Command Block Wrapper (CBW), an optional data phase, and a Command Status Wrapper (CSW), followed by SCSI sense handling when a command fails.

That pattern makes a capture far more useful than a generic “USB error” log. A good USB Mass Storage BOT debugging case answers which command was issued, what data direction and length were expected, whether the command tag survived the transaction, whether a CSW arrived, what status/residue it carried, whether REQUEST SENSE explained a failure, and whether the device and host recovered after a stall or reset.

Bus Scope helps keep that evidence in a readable inspection workflow. It does not make a capture prove an internal firmware state by itself. The aim is to identify the observed transaction boundary and give the firmware, driver, or platform owner the exact next question to verify.

The BOT transaction in one view

In the normal BOT flow, the host sends a CBW on a bulk OUT endpoint. The command may have no data phase, a host-to-device data phase, or a device-to-host data phase. The device then returns a CSW on a bulk IN endpoint to report status. The SCSI command bytes are carried inside the CBW, so a disk-mount problem may begin as a specific command such as inquiry, capacity read, read/write, mode sense, or test-unit-ready.

| BOT phase | Direction usually seen | Evidence to retain | Why it matters | | --- | --- | --- | | CBW | Host to device, bulk OUT | Signature, tag, transfer length, flags, LUN, command block | Defines the command and expected transaction shape | | Data phase | Depends on CBW flags/command | Endpoint, actual bytes, short/stalled/timeout outcome | Tests whether data matched the advertised direction and length | | CSW | Device to host, bulk IN | Signature, matching tag, residue, status | Tells the host whether the command passed, failed, or had a phase error | | REQUEST SENSE after failure | Host request then device data response | Failing command, sense key, ASC/ASCQ where decoded | Adds the device-reported reason for a failed SCSI command | | Recovery | Control plus bulk endpoint actions | Stalls, clear-halt/reset sequence, next CBW/CSW pair | Shows whether the device returned to a usable BOT state |

Do not review a CSW in isolation. A valid-looking status wrapper with the wrong tag or an impossible residue is not a clean completion. Likewise, a missing CSW may mean the device did not complete the observed command, but it does not tell you why until timing, endpoint status, host behaviour, and device logs are considered.

Decode the CBW before blaming the data phase

The CBW is the host's request contract. It contains a BOT signature, a host-selected command tag, expected transfer length, data direction flag, logical unit number, command-block length, and the SCSI command bytes. Start the investigation by comparing these fields with the traffic that follows rather than scanning only for a generic bulk-transfer error.

CBW field to compare Question to ask Common misleading shortcut
Command tag Does the later CSW return the same tag? “Any CSW after this CBW completes it”
Transfer length Does the data phase and CSW residue make sense for this command? “A short transfer is always a firmware crash”
Direction flag Did the host expect IN or OUT, and did traffic follow that direction? “The endpoint number alone describes the command direction”
LUN Is the host addressing the intended logical unit? “The device has only one storage personality”
Command-block length Is the parser/firmware handling the intended CDB length? “All SCSI commands use the same layout”
SCSI CDB bytes What operation was actually requested? “Mount failure means READ failed”

For example, a host may issue TEST UNIT READY, then receive a failed CSW, and then request sense data. That may be a normal way to learn that removable media is not ready; it is not equivalent to a corrupted write. Conversely, a capacity/read command with a mismatched data phase and a later phase error is a stronger protocol-level lead.

Use CBW tag, CSW tag, residue, and status together

The CSW closes the BOT transaction. Its tag should match the preceding CBW's tag. Its residue represents the amount of expected data not processed or transferred, and its status distinguishes successful command completion from command failure or phase error. The exact interpretation belongs to the command, transfer length, and sequence around it.

CSW result in a capture First interpretation Next check
Matching tag, pass status, plausible residue The observed BOT command completed successfully Confirm the host's next command and user-visible timing
Matching tag, failed status The device reported SCSI command failure Locate the following REQUEST SENSE and decode it
Matching tag, phase-error status Host/device BOT expectation may disagree Compare CBW direction/length, data phase, stalls, and recovery
Wrong tag The host cannot safely associate this status with the request Inspect transaction ordering, reset history, and firmware tag handling
No CSW before timeout The observed command did not reach a visible completion Check endpoint state, capture loss, device reset, and host retries
Implausible residue Data accounting may not agree with request/response Validate command semantics and inspect firmware transfer-state logic

This table deliberately avoids declaring a device faulty from one packet label. A host capture can itself omit transfers under load; a trace at a proxy/controller layer may not expose exactly the same sequence as a device-side trace. State the capture point and retain enough surrounding traffic to test the association.

Sense data often explains the operating-system symptom

A failed CSW is an invitation to look for the next SCSI conversation, not the end of the analysis. Many hosts issue REQUEST SENSE after command failure. Sense key and additional sense information can point to device-reported conditions such as not-ready, unit attention after a reset, illegal request, medium error, write protection, or an out-of-range address.

The most useful report pairs the original failing command with the sense response. “Sense reported an illegal request after this specific capacity/read command” is more actionable than “the drive failed.” It tells the firmware owner which CDB and state transition to reproduce.

User-visible symptom BOT/SCSI evidence worth preserving A careful next hypothesis
Disk appears but mount fails Capacity/mode commands, failed CSW, sense response Geometry, readiness, or command support should be checked
Copy fails at a repeatable offset Read/write CDB address, length, data phase, sense A media/address/firmware boundary may be involved
Device asks to be formatted Inquiry/capacity/read sequence and reported sense Host interpretation of storage metadata needs correlation
Device becomes read-only Write command, failed CSW, write-protect sense Reported protection state or firmware policy needs review
Device reappears after reconnect Reset, enumeration, BOT recovery, unit attention Recovery/state persistence needs investigation
Application reports generic I/O error Exact command/tag/status/residue/sense chain The OS symptom needs a protocol-specific owner

Sense data is evidence reported by the device; it should be compared with firmware logs and the actual media/configuration. Do not translate a sense key into a hardware defect without that correlation.

Separate a command failure from BOT reset recovery

Endpoint stalls and host recovery steps are important because BOT has defined error-recovery behaviour. Depending on the failure and host stack, a capture can show an endpoint halt, a clear-halt control request, a Mass Storage Reset request, enumeration activity, or a new CBW/CSW sequence. The order and exact host choices can vary with the stack and the error, so record the observed actions rather than forcing every trace into one assumed script.

Recovery observation What it can indicate What to verify next
Bulk IN or OUT endpoint stalls The transfer did not continue normally on that endpoint Which command/data phase preceded it and whether a clear halt follows
Host sends a class reset request Host is attempting BOT-level recovery Whether endpoints are cleared as required by the path and whether new CBWs succeed
Device re-enumerates A broader reset/disconnect occurred Power, cable, firmware reset, host controller, and timing evidence
New CBW gets a matching CSW after recovery Observed BOT flow resumed Whether the original command should be retried and state is coherent
Repeated reset/stall cycle Recovery did not stabilize the session Persisted state, command parsing, endpoint state machine, power/cable evidence

For reset-timeout patterns, compare USB UASP and BOT mass-storage reset timeout. UASP and BOT are different transports, so do not copy a UASP conclusion into a BOT case; the article is useful for the shared discipline of recording recovery sequence and timeout boundaries.

A capture workflow that remains useful to firmware and host teams

Capture enough context to include the relevant enumeration/configuration setup when possible, the first failing command, the sense follow-up, and recovery attempts. Preserve the endpoint addresses and host/device direction. If you export a smaller case, retain the original capture and document filter, time range, and transformation so another reviewer can reproduce the subset.

Use this workflow:

  1. Identify the device/session, capture interface, and symptom time.
  2. Locate the first CBW near the symptom and decode the SCSI CDB.
  3. Match its tag to the data phase and CSW; record expected versus observed length/direction.
  4. If the CSW failed, find REQUEST SENSE and preserve the response.
  5. If the flow stalled, document endpoint and the observed clear-halt/reset/re-enumeration sequence.
  6. Find the first post-recovery CBW and decide whether normal matching CSW flow resumed.
  7. Write observations, supported leads, and unproven causes separately before changing firmware.
Report section Good wording
Observed fact “CBW tag 0x… requested this command; the observed CSW had failed status and was followed by REQUEST SENSE.”
Bounded interpretation “The device-reported sense condition should be compared with the firmware/media state for this command.”
Unproven statement to avoid “The USB controller permanently corrupted the disk.”

This distinction makes the case easier to triage and protects against changing a state machine based on an over-read capture.

USB mass storage BOT QA checklist

Before sharing the trace or opening a firmware issue, confirm that the CBW and CSW are matched by tag, the intended data direction/length is noted, sense data follows the specific failing command, and recovery is described as an observed sequence. Include the capture point, operating system/controller, device firmware version where available, and whether the problem repeats with another port/cable/host.

Continue with USB endpoint STALL and bulk-transfer timeout debugging, USB control-transfer setup-packet debugging, the Bus Scope troubleshooting guide, or download Bus Scope for local inspection.

Frequently asked questions

Does a failed CSW mean the device is broken?

No. It means the device reported failure for that SCSI command. The sense response, command context, device state, media, and host behaviour determine whether the failure is expected, recoverable, or a firmware defect.

Why is the CBW/CSW tag so important?

The tag associates command completion with the request that started it. A wrong or missing association makes it unsafe for the host to treat a nearby status wrapper as the completion of a particular command.

Should I send only the failed bulk packet to the firmware team?

Usually not. Keep the CBW, data phase, CSW, sense response, and recovery context. A single packet often removes the only fields needed to distinguish a command failure, phase mismatch, timeout, or recovery problem.

How do you accept a USB Mass Storage BOT recovery?

Reproduce one command from CBW through its expected data phase and CSW, then continue far enough to show whether the host requests sense data or begins reset recovery. Record endpoint direction, CBW signature, tag, transfer length, flags, LUN, command descriptor block, actual data length, CSW signature/tag/residue/status, and the first request after failure. The tag and residue must be interpreted with the initiating command, not as isolated fields.

BOT boundary Evidence to retain Question it answers
Command start Complete CBW and endpoint Which SCSI operation and data direction were requested?
Data phase Bytes expected versus observed Did data length/direction match the command?
Command status CSW tag, residue, status Did the device complete, fail, or enter phase error?
Failure detail REQUEST SENSE response What condition did the device report?
Recovery Stall clear, BOT reset, endpoint recovery Did host and device return to synchronized state?
Retest Next successful command sequence Is recovery durable rather than accidental?

Acceptance requires more than a successful retry. The corrected trace should show consistent tags, valid residue semantics, the expected sense response when a command fails, and a bounded recovery that restores both bulk endpoints. Repeat after unplug/re-enumeration so stale host state cannot mask a firmware state-machine defect.

Keep the failed and corrected windows together in the Bus Scope session workflow. If recovery includes a reset or re-enumeration, compare the USB reset-loop guide before claiming the storage command alone caused the disconnect.

Add the storage medium state, capacity, write-protection policy, command timeout, and host driver version to the case. Repeat one harmless read before and after the failing command. That control shows whether the fix restores ordinary BOT traffic, not only the specific updater or test utility that triggered recovery.

Retain the successful control command and its matching CSW tag beside the failed sequence.

<!-- multilingual-related-reading:start -->

Related guides

Continue with the same-language pages below. They cover adjacent stages without changing the canonical owner of this topic:

<!-- multilingual-related-reading:end -->