From 97407570ede7a6adf42bf47520f48ace95132056 Mon Sep 17 00:00:00 2001 From: MattJackson <1085847+MattJackson@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:35:48 -0700 Subject: [PATCH] Clean pipeline: one open, one init, no double-init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed open_unlocked() — open() is the only entry - Removed redundant init() call from open_title() - init() called once in open(), handles everything - Each function does one thing: open→init→scan→read --- src/disc.rs | 4 +--- src/drive.rs | 18 ++++-------------- src/platform/mt1959.rs | 25 +++++++++++++++---------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/disc.rs b/src/disc.rs index 9ec00ea..1a26c7d 100644 --- a/src/disc.rs +++ b/src/disc.rs @@ -798,9 +798,7 @@ impl Disc { detail: format!("title index {} out of range (have {})", title_idx, self.titles.len()), })?; - if !session.is_unlocked() { - let _ = session.init(); - } + // init() already called by DriveSession::open(). No re-init needed. let speed_cdb = crate::scsi::build_set_cd_speed(0xFFFF); let mut dummy = [0u8; 0]; diff --git a/src/drive.rs b/src/drive.rs index a684605..241a9b1 100644 --- a/src/drive.rs +++ b/src/drive.rs @@ -30,10 +30,11 @@ pub struct DriveSession { } impl DriveSession { - /// Open a drive — identify, wait for disc, and unlock for raw reads. /// - /// This is the standard entry point. After `open()`, the drive is - /// ready for scanning and content reads. + /// This is the only entry point. After `open()`, the drive is + /// ready for scanning and content reads. init() handles everything: + /// unlock, firmware upload if needed, calibration, registers. + /// Called once per session. Non-fatal if init fails (BD works without it). pub fn open(device: &Path) -> Result { let mut session = Self::open_no_unlock(device)?; session.wait_ready()?; @@ -41,17 +42,6 @@ impl DriveSession { Ok(session) } - /// Open a drive and immediately init for raw reads. - /// - /// Use this when you need raw disc access without AACS (e.g. capture, - /// sector dumps). Skips AACS authentication — cannot be done after init. - pub fn open_unlocked(device: &Path) -> Result { - let mut session = Self::open_no_unlock(device)?; - session.wait_ready()?; - let _ = session.init(); - Ok(session) - } - /// Open a drive — identify only, no wait, no unlock. /// /// Low-level entry point. Caller is responsible for wait_ready() diff --git a/src/platform/mt1959.rs b/src/platform/mt1959.rs index 9bb7668..711ea13 100644 --- a/src/platform/mt1959.rs +++ b/src/platform/mt1959.rs @@ -463,11 +463,21 @@ impl Platform for Mt1959 { /// Phase 5: cmd 9 × 6 retries (status) fn init(&mut self, scsi: &mut dyn ScsiTransport) -> Result<()> { // Phase 1: Unlock + firmware upload (6 retries) + // + // Three unlock outcomes: + // Ok → warm drive, firmware loaded, skip to calibrate + // Err(other) → cold drive or SCSI error, try load_firmware let mut unlocked = false; for _attempt in 0..6 { match self.unlock(scsi) { Ok(_) => { unlocked = true; break; } + Err(Error::SignatureMismatch { .. }) => { + return Err(Error::UnlockFailed { + detail: "signature mismatch — wrong profile for this drive".into(), + }); + } Err(_) => { + // Cold boot or SCSI error — try uploading firmware if self.load_firmware(scsi).is_ok() { unlocked = true; break; @@ -493,17 +503,12 @@ impl Platform for Mt1959 { return Err(Error::ScsiError { opcode: 0x3C, status: 0xFF, sense_key: 0 }); } - // If fails: cmd 5 fallback (keepalive) - // In our context: this fetches a display string, not critical for reads - let _ = self.probe(scsi, 0x00, 0, 0x3FF); + // Phase 3: Read registers — non-fatal + // x86 retries 5×, but we do a single attempt each. Not required for reads. + let _ = self.read_register_a(scsi); + let _ = self.read_register_b(scsi); - for _attempt in 0..5 { - let a_ok = self.read_register_a(scsi).is_ok(); - let b_ok = self.read_register_b(scsi).is_ok(); - if a_ok && b_ok { break; } - } - - // Phase 5: Status — non-fatal, single attempt + // Phase 4: Status — non-fatal, single attempt // Some drives reject sub_cmd 0x13. Not required for reads. let _ = self.status(scsi);