Skip to main content

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}