Drive recovery, reset on open, simplified DiscStream

- SgIoTransport::reset() — open/close/TUR/escalate on every open
- Drive::read() — single read method with error recovery (min speed,
  sleep 30s, retry, phase 1/2/3 escalation)
- Removed read_timeout, read_sectors, read_range — one read() method
- DiscStream simplified — no on_error/on_success/Recovery, delegates
  all error handling to Drive::read()
- IsoStream no longer decrypts — streams return raw bytes, pipeline
  handles decryption
- reset() on all platforms (Linux real, Windows/macOS stubs)
- Watchdog thread removed — kernel handles USB timeouts
This commit is contained in:
MattJackson
2026-04-14 23:32:22 +00:00
parent d51e5c5a7f
commit cc84f954c2
7 changed files with 803 additions and 452 deletions
+18
View File
@@ -248,6 +248,24 @@ impl MacScsiTransport {
exclusive: true,
})
}
/// Reset the drive to a known good state.
/// On macOS, we open the device, release exclusive access, wait for
/// the system to reclaim it, then the next open() re-acquires.
/// IOKit's USB layer handles device-level resets internally when the
/// exclusive access is released and re-acquired.
///
/// NOTE: untested — macOS reset may need IOUSBDeviceInterface::ResetDevice()
/// for USB drives. This is a best-effort implementation.
pub fn reset(device: &Path) -> Result<()> {
// Opening and immediately dropping triggers release of exclusive access
// which forces IOKit to reset the device state.
if let Ok(transport) = Self::open(device) {
drop(transport); // Drop releases exclusive access + closes plugin
}
std::thread::sleep(std::time::Duration::from_secs(2));
Ok(())
}
}
impl Drop for MacScsiTransport {