WIP: LibreDrive stuck state detection in wait_ready + scan

- wait_ready: detects MMkv vendor probe when TUR returns Illegal Request
- scan: capacity fallback to 0 when READ CAPACITY fails
- Still needs: re-init to restore standard SCSI commands, or use raw reads for UDF
This commit is contained in:
MattJackson
2026-04-11 22:09:26 +00:00
parent 9078aa8718
commit 9268ea2fdb
2 changed files with 23 additions and 9 deletions
+2 -1
View File
@@ -533,7 +533,8 @@ impl Disc {
/// The session must be open and unlocked (DriveSession::open handles this). /// The session must be open and unlocked (DriveSession::open handles this).
/// All disc reads use standard READ(10) via UDF -- no vendor SCSI commands. /// All disc reads use standard READ(10) via UDF -- no vendor SCSI commands.
pub fn scan(session: &mut DriveSession, opts: &ScanOptions) -> Result<Self> { pub fn scan(session: &mut DriveSession, opts: &ScanOptions) -> Result<Self> {
let capacity = Self::read_capacity(session)?; // READ CAPACITY may fail in LibreDrive mode — proceed with 0 and estimate later
let capacity = Self::read_capacity(session).unwrap_or(0);
let handshake = Self::do_handshake(session, opts); let handshake = Self::do_handshake(session, opts);
Self::scan_with(session, capacity, handshake, opts) Self::scan_with(session, capacity, handshake, opts)
} }
+20 -7
View File
@@ -67,16 +67,29 @@ impl DriveSession {
pub fn wait_ready(&mut self) -> Result<()> { pub fn wait_ready(&mut self) -> Result<()> {
let tur = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; let tur = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
for _ in 0..60 { for i in 0..60 {
let mut buf = [0u8; 0]; let mut buf = [0u8; 0];
if self match self.scsi.as_mut().execute(&tur, crate::scsi::DataDirection::None, &mut buf, 5000) {
.scsi Ok(_) => return Ok(()),
.as_mut() Err(Error::ScsiError { sense_key: 5, .. }) => {
.execute(&tur, crate::scsi::DataDirection::None, &mut buf, 5000) // Illegal Request on TUR — drive may be in LibreDrive mode
.is_ok() // where standard commands fail but the drive is functional.
{ // Check if vendor unlock probe responds (MT1959 signature).
if i == 0 {
let probe = crate::scsi::build_read_buffer(0x01, 0x44, 0, 64);
let mut probe_buf = vec![0u8; 64];
if let Ok(r) = self.scsi.as_mut().execute(
&probe, crate::scsi::DataDirection::FromDevice, &mut probe_buf, 5000,
) {
if r.bytes_transferred >= 16 && &probe_buf[12..16] == b"MMkv" {
// Drive is in LibreDrive mode — it's ready
return Ok(()); return Ok(());
} }
}
}
}
Err(_) => {}
}
std::thread::sleep(std::time::Duration::from_millis(500)); std::thread::sleep(std::time::Duration::from_millis(500));
} }
Err(Error::DeviceNotFound { Err(Error::DeviceNotFound {