From ceaa1da3698cebe9c51148fbabc191508048db48 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <1085847+MattJackson@users.noreply.github.com> Date: Wed, 1 Jul 2026 08:56:19 -0700 Subject: [PATCH] drive: apply drive-features for every disc, incl. DVD (fix riplock) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DVD ran the drive at ~0.4x stock speed: init() early-returned for DVD before any speed was set, and its only speed command was the sweep's lone legacy SET CD SPEED, which this BU40N ignores for DVD. BD/UHD got up to speed only via the firmware unlocker's calibration — a path a DVD can't take (it breaks stock CSS). Call the new unlock-crate drive-features capability at init() for ALL disc kinds, before the DVD stock-mode early-return, via a bridge shim. Stock MMC only (SET STREAMING + SET CD SPEED), no bus unlock, so CSS is undisturbed. --- src/drive/mod.rs | 10 +++++++++- src/unlock_bridge.rs | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/drive/mod.rs b/src/drive/mod.rs index e0c7f04..576b34f 100644 --- a/src/drive/mod.rs +++ b/src/drive/mod.rs @@ -411,8 +411,16 @@ impl Drive { pub fn init(&mut self) -> Result<()> { let t0 = std::time::Instant::now(); tracing::info!(target: "freemkv::drive", phase = "init", "begin"); + // Drive-level features (max read speed / riplock lift) — matched on the + // DRIVE, applied for ANY disc. STOCK MMC commands only (no firmware + // unlock), so this is safe for a CSS DVD that must stay in stock mode. + // Runs BEFORE the DVD early-return below so a DVD is no longer riplocked: + // previously only the BD/UHD path (which returns clear content via the + // firmware unlock + its speed calibration) got up to speed, and DVD fell + // through with just the legacy SET CD SPEED the drive ignores. + crate::unlock_bridge::apply_drive_features(self.scsi.as_mut(), &self.drive_id); if self.disc_is_dvd() { - tracing::info!(target: "freemkv::drive", phase = "init", dvd = true, elapsed_ms = t0.elapsed().as_millis() as u64, "end (stock-mode DVD, no unlock)"); + tracing::info!(target: "freemkv::drive", phase = "init", dvd = true, elapsed_ms = t0.elapsed().as_millis() as u64, "end (stock-mode DVD, drive features applied, no bus unlock)"); self.init_ran = true; return Ok(()); } diff --git a/src/unlock_bridge.rs b/src/unlock_bridge.rs index 87fa4d6..a6ef726 100644 --- a/src/unlock_bridge.rs +++ b/src/unlock_bridge.rs @@ -124,6 +124,26 @@ pub(crate) fn run_unlockers( Err(fu::UnlockError::NotApplicable) } +/// Apply drive-level feature tuning (max read speed / riplock lift) for the +/// installed drive, for ANY disc. This is the drive-features capability, kept +/// separate from bus removal: it issues only STOCK MMC commands (no firmware +/// unlock), so it is safe on a CSS DVD that must stay in stock mode. Each +/// unlocker's `apply_drive_features` is self-gating (a no-op unless it recognises +/// the drive), so we call every one; disc kind is irrelevant here, so we pass +/// `Unknown`. Best-effort — never returns an error to the caller (a slow drive +/// still rips). +pub(crate) fn apply_drive_features( + scsi: &mut dyn crate::scsi::ScsiTransport, + drive_id: &crate::identity::DriveId, +) { + let id = to_fu_drive_id(drive_id); + let ctx = fu::UnlockCtx::new(&id, fu::DiscKind::Unknown, &[]); + let mut adapter = ScsiAdapter(scsi); + for u in fu::all_unlockers() { + let _ = u.apply_drive_features(&mut adapter, &ctx); + } +} + #[cfg(test)] mod tests { use super::*;