ld: public profile catalog API + emulation feature; clippy-clean

Expose the LibreDrive profile catalog as a curated public API on `ld`:
`ld::profiles()` returns the `Profiles` object (with `.get(drive_id)`) and
`ld::profile(filter)` finds one — the catalog of supported drives, queried
without unlocking. The unlock mechanism (firmware blobs, upload sequence, CDB
wire format) stays private; `LibreDrive` is pub(crate), reached only via
`all_unlockers()`.

The unlock-handshake wire format the bdemu test-emulator needs to impersonate a
drive (`UNLOCK_MARKER`, `is_unlock_read_buffer`) is behind a non-default
`emulation` feature; the `cdb` module compiles only under it. Rename the
`ScsiError` error variant to `Scsi` (matches css), gate the test-only
`load_bundled` and `SCSI_STATUS_CHECK_CONDITION`. Clippy-clean in both feature
configs; 86/89 tests pass.
This commit is contained in:
Matthew Jackson
2026-06-29 20:44:52 -07:00
parent 5ea0e2cc5a
commit 30f653f7f4
9 changed files with 109 additions and 51 deletions
+5 -5
View File
@@ -28,7 +28,7 @@ pub enum Error {
/// A SCSI command failed. `status == SCSI_STATUS_TRANSPORT_FAILURE` with
/// `sense: None` is a transport-layer fault; a CHECK CONDITION carries the
/// parsed [`ScsiSense`].
ScsiError {
Scsi {
/// CDB opcode that failed — diagnostic, carried for future logging.
opcode: u8,
status: u8,
@@ -54,14 +54,14 @@ impl Error {
Error::AacsVidRead => 7012,
Error::HandshakeRejected => 7013,
Error::VidUnavailable => 7014,
Error::ScsiError { .. } => 7099,
Error::Scsi { .. } => 7099,
}
}
/// The parsed sense for a CHECK CONDITION SCSI error, else `None`.
pub fn scsi_sense(&self) -> Option<ScsiSense> {
match self {
Error::ScsiError { sense, .. } => *sense,
Error::Scsi { sense, .. } => *sense,
_ => None,
}
}
@@ -70,7 +70,7 @@ impl Error {
pub fn is_scsi_transport_failure(&self) -> bool {
matches!(
self,
Error::ScsiError { status, sense: None, .. } if *status == SCSI_STATUS_TRANSPORT_FAILURE
Error::Scsi { status, sense: None, .. } if *status == SCSI_STATUS_TRANSPORT_FAILURE
)
}
}
@@ -79,7 +79,7 @@ impl Error {
/// at the transport level; sense parsed from the raw buffer when present).
impl From<crate::scsi::ScsiError> for Error {
fn from(e: crate::scsi::ScsiError) -> Self {
Error::ScsiError {
Error::Scsi {
opcode: 0,
status: e.status,
sense: e.sense.map(|s| ScsiSense::from_buf(&s)),