libcdio_rs/mmc/set_cd_speed.rs
1// Copyright (C) 2026 Shiva Kiran Koninty <shiva@skran.xyz>
2//
3// This file is part of libcdio-rs.
4//
5// libcdio-rs is free software: you can redistribute it and/or
6// modify it under the terms of the GNU General Public License as
7// published by the Free Software Foundation, either version 3 of the
8// License, or (at your option) any later version.
9//
10// libcdio-rs is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13// General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with libcdio-rs. If not, see <https://www.gnu.org/licenses/>.
17
18//! Routines based on MMC `SET CD SPEED`.
19
20use displaydoc::Display;
21use thiserror::Error;
22
23use crate::{
24 Mmc,
25 mmc::{Cdb, MmcCommand, MmcDirection, MmcError},
26};
27
28/// Routines based on MMC `SET CD SPEED`.
29impl Mmc {
30 /// Set the read and write speeds of the drive, in kilo bytes per second.
31 pub fn set_cd_speed(
32 &self,
33 rotation_mode: RotationMode,
34 read_speed: u16,
35 write_speed: u16,
36 ) -> Result<(), MmcSetCdSpeedError> {
37 let mut cdb = Cdb::default();
38 cdb[0] = MmcCommand::SetCdSpeed as u8;
39 cdb[1] = rotation_mode as u8;
40 cdb[2..4].copy_from_slice(&read_speed.to_be_bytes());
41 cdb[4..6].copy_from_slice(&write_speed.to_be_bytes());
42
43 self.run_command(Some(MmcDirection::Write), &mut [], cdb)?;
44
45 Ok(())
46 }
47}
48
49/// Rotation mode used by the drive.
50#[repr(u8)]
51#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
52pub enum RotationMode {
53 /// Constant Angular Velocity: Maintains a fixed rotation rate.
54 /// Provides faster seek times.
55 #[default]
56 Cav = 0b00,
57
58 /// Constant Linear Velocity: Variable rotation rate.
59 /// Provides consistent data rates.
60 Clv = 0b01,
61}
62
63/// error from a `SET CD SPEED` command.
64#[derive(Debug, Display, Error)]
65pub struct MmcSetCdSpeedError {
66 #[from]
67 pub source: MmcError,
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test_log::test(test)]
75 #[ignore = "requires a drive with mmc"]
76 fn set_cd_speed() {
77 Mmc::new()
78 .unwrap()
79 .set_cd_speed(RotationMode::Cav, 0xffff, 0xffff)
80 .unwrap();
81 }
82}