v0.13.3: broaden is_wedge_signature — fix dead-code wedge recovery
0.13.2's is_wedge_signature gated on opcode=SCSI_INQUIRY (0x12), but drive_has_disc issues TEST UNIT READY (0x00). Production wedge errors (E4000: 0x00/0xff/0x00) never matched → SCSI reset + USB reset escalation never fired. Drop the opcode gate. Status byte 0xFF is synthesised by our own execute() path on poll() timeout — it's the ground-truth wedge marker for any opcode. Linux-only; macOS/Windows use sense-key-based wedge detection.
This commit is contained in:
+10
-9
@@ -694,25 +694,26 @@ fn recover_then_probe(path: &Path, original: Error) -> Result<bool> {
|
||||
Err(original)
|
||||
}
|
||||
|
||||
/// Wedge signature: `Error::ScsiError` with INQUIRY opcode (0x12) and
|
||||
/// status byte 0xFF. 0xFF isn't a valid SCSI status — the kernel synthesises
|
||||
/// it when the device gives no answer, which is the real-world signature
|
||||
/// of a USB Mass Storage layer wedge.
|
||||
/// Wedge signature: `Error::ScsiError` with status byte 0xFF, for any
|
||||
/// opcode. 0xFF isn't a real SCSI status — our own `execute()` path
|
||||
/// synthesises it when poll() times out waiting for the kernel to
|
||||
/// deliver a response. That timeout is the ground-truth signature of
|
||||
/// the USB Mass Storage layer wedging; opcode-in-flight is incidental.
|
||||
fn is_wedge_signature(err: &Error) -> bool {
|
||||
matches!(
|
||||
err,
|
||||
Error::ScsiError {
|
||||
opcode: crate::scsi::SCSI_INQUIRY,
|
||||
status: WEDGE_STATUS_BYTE,
|
||||
..
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Synthesised SCSI status byte returned by the Linux SG driver when
|
||||
/// the kernel got no useful response from the device — the wedge
|
||||
/// signature. Real SCSI statuses are GOOD (0x00), CHECK_CONDITION (0x02),
|
||||
/// BUSY (0x08), etc.; 0xFF is reserved/invalid in the spec.
|
||||
/// Synthesised SCSI status byte returned by our own transport when
|
||||
/// poll() on the SG fd times out — the wedge signature. Real SCSI
|
||||
/// statuses are GOOD (0x00), CHECK_CONDITION (0x02), BUSY (0x08), etc.;
|
||||
/// 0xFF is reserved/invalid in the spec, so we can't collide with a
|
||||
/// real device response. Applies to any opcode (TUR, INQUIRY, READ, …).
|
||||
const WEDGE_STATUS_BYTE: u8 = 0xFF;
|
||||
|
||||
/// Settle time after `USBDEVFS_RESET` returns. The kernel re-enumerates
|
||||
|
||||
Reference in New Issue
Block a user