diff --git a/src/disc/mod.rs b/src/disc/mod.rs index 5e04bee..040f2b7 100644 --- a/src/disc/mod.rs +++ b/src/disc/mod.rs @@ -533,7 +533,8 @@ impl Disc { /// The session must be open and unlocked (DriveSession::open handles this). /// All disc reads use standard READ(10) via UDF -- no vendor SCSI commands. pub fn scan(session: &mut DriveSession, opts: &ScanOptions) -> Result { - 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); Self::scan_with(session, capacity, handshake, opts) } diff --git a/src/drive/mod.rs b/src/drive/mod.rs index 149b91f..f5c6313 100644 --- a/src/drive/mod.rs +++ b/src/drive/mod.rs @@ -67,15 +67,28 @@ impl DriveSession { pub fn wait_ready(&mut self) -> Result<()> { let tur = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; - for _ in 0..60 { + for i in 0..60 { let mut buf = [0u8; 0]; - if self - .scsi - .as_mut() - .execute(&tur, crate::scsi::DataDirection::None, &mut buf, 5000) - .is_ok() - { - return Ok(()); + match self.scsi.as_mut().execute(&tur, crate::scsi::DataDirection::None, &mut buf, 5000) { + Ok(_) => return Ok(()), + Err(Error::ScsiError { sense_key: 5, .. }) => { + // Illegal Request on TUR — drive may be in LibreDrive mode + // 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(()); + } + } + } + } + Err(_) => {} } std::thread::sleep(std::time::Duration::from_millis(500)); }