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:
+2
-1
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-8
@@ -67,15 +67,28 @@ 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).
|
||||||
return Ok(());
|
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));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user