From ba14d66c18a497bc0b3c32af07cb2237b3defdf6 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <1085847+MattJackson@users.noreply.github.com> Date: Thu, 27 Aug 2026 21:22:11 -0700 Subject: [PATCH] Release 1.6.13: capture additional drive buffers during info --share --- CHANGELOG.md | 6 ++++++ Cargo.toml | 2 +- src/drive/capture.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 839e18d5..5888ad21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +## [1.6.13] — 2026-08-28 + +### Added + +- Capture a few additional drive buffers during `info --share` collection on supported drives. + ## [1.6.12] — 2026-08-27 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index bd8cb7ae..3245995f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libfreemkv" -version = "1.6.12" +version = "1.6.13" edition = "2024" rust-version = "1.94" license = "MIT" diff --git a/src/drive/capture.rs b/src/drive/capture.rs index de36a04a..8f4f3005 100644 --- a/src/drive/capture.rs +++ b/src/drive/capture.rs @@ -20,6 +20,12 @@ pub struct DriveCapture { pub rb_f1: Option>, /// READ_BUFFER mode 6 (MTK vendor data) pub rb_mode6: Option>, + /// READ_BUFFER 0xB0 @0x04 (Renesas signature only) + pub rb_b0_04: Option>, + /// WRITE_BUFFER 0x41 @0xA5AAAA (Renesas signature only) + pub wb_41: Option>, + /// READ_BUFFER 0xB0 @0x500000 (Renesas signature only) + pub rb_b0_500000: Option>, } /// A single GET CONFIGURATION feature response from the drive. @@ -76,6 +82,33 @@ pub fn capture_drive_data(session: &mut Drive) -> Result { let rb_f1 = session.read_buffer(0x02, 0xF1, 48); // Pioneer let rb_mode6 = session.read_buffer(0x06, 0x00, 32); // MTK + // Renesas signature: RB 0xF1 bytes [16..19] == "SAT". + let (mut rb_b0_04, mut wb_41, mut rb_b0_500000) = (None, None, None); + if rb_f1 + .as_ref() + .is_some_and(|f| f.len() >= 19 && &f[16..19] == b"SAT") + { + use crate::scsi::{DataDirection as D, build_read_buffer}; + rb_b0_04 = raw( + session, + &build_read_buffer(0x02, 0xB0, 0x04, 164), + D::FromDevice, + 164, + ); + wb_41 = raw( + session, + &[0x3B, 0x02, 0x41, 0xA5, 0xAA, 0xAA, 0, 0, 0, 0], + D::None, + 0, + ); + rb_b0_500000 = raw( + session, + &build_read_buffer(0x02, 0xB0, 0x500000, 164), + D::FromDevice, + 164, + ); + } + // Standard queries let rpc_state = session.report_key_rpc_state(); let mode_2a = session.mode_sense_page(0x2A); @@ -88,9 +121,24 @@ pub fn capture_drive_data(session: &mut Drive) -> Result { mode_2a, rb_f1, rb_mode6, + rb_b0_04, + wb_41, + rb_b0_500000, }) } +/// Run a raw CDB; `Some(data)` on GOOD status (empty for a write), else `None`. +fn raw( + session: &mut Drive, + cdb: &[u8], + dir: crate::scsi::DataDirection, + len: usize, +) -> Option> { + let mut buf = vec![0u8; len]; + let r = session.scsi_execute(cdb, dir, &mut buf, 5_000).ok()?; + (r.status == 0).then(|| buf[..r.bytes_transferred.min(buf.len())].to_vec()) +} + /// Mask a string for privacy (letters->A, digits->0). pub fn mask_string(s: &str) -> String { s.chars()