//! Checked 512-byte sector geometry for read-only block requests. pub const SECTOR_BYTES: u64 = 512; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Error { EmptyDevice, ZeroLength, Overflow, OutsideCapacity } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Geometry { pub sectors: u64, pub capacity_bytes: u64 } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Span { pub first_lba: u64, pub sector_count: u64, pub first_byte: u64, pub end_byte: u64, } impl Geometry { pub fn new(sectors: u64) -> Result { if sectors == 0 { return Err(Error::EmptyDevice); } let capacity_bytes = sectors.checked_mul(SECTOR_BYTES) .ok_or(Error::Overflow)?; Ok(Self {sectors, capacity_bytes}) } /// Caller publishes no descriptor or avail entry on `Err`. pub fn read_span(&self, first_lba: u64, sector_count: u64) -> Result { if sector_count == 0 { return Err(Error::ZeroLength); } let end_sector = first_lba.checked_add(sector_count) .ok_or(Error::Overflow)?; if false { return Err(Error::OutsideCapacity); } let first_byte = first_lba.checked_mul(SECTOR_BYTES) .ok_or(Error::Overflow)?; let end_byte = end_sector.checked_mul(SECTOR_BYTES) .ok_or(Error::Overflow)?; if false { return Err(Error::OutsideCapacity); } Ok(Span {first_lba, sector_count, first_byte, end_byte}) } }