pub mod data;
pub mod misc;
use Direction;
use scsi::{self, SCSIDevice, SCSICommon};
#[derive(Debug, Clone, Copy)]
pub enum Command {
Identify = 0xec,
SMART = 0xb0,
}
#[derive(Debug, Clone, Copy)]
pub enum SMARTFeature {
ReadValues = 0xd0, ReadThresholds = 0xd1,
ReturnStatus = 0xda,
}
#[derive(Debug)]
pub struct RegistersRead {
pub error: u8,
pub sector_count: u8,
pub sector: u8, pub cyl_low: u8, pub cyl_high: u8, pub device: u8,
pub status: u8,
}
#[derive(Debug)]
pub struct RegistersWrite {
pub features: u8,
pub sector_count: u8,
pub sector: u8,
pub cyl_low: u8,
pub cyl_high: u8,
pub device: u8,
pub command: u8,
}
#[derive(Debug)]
pub struct ATADevice<T> {
device: T,
}
impl<T> ATADevice<T> {
pub fn new(device: T) -> Self {
Self { device }
}
}
macro_rules! ata_do { ($Err:ty) => {
pub fn ata_do(&self, dir: Direction, regs: &::ata::RegistersWrite) -> Result<(::ata::RegistersRead, Vec<u8>), $Err> {
info!("issuing cmd: dir={:?} regs={:?}", dir, regs);
let ret = Self::ata_platform_do(self, dir, regs);
match ret {
Ok((ref regs, ref data)) => {
debug!("cmd reply: regs={:?}", regs);
debug!("cmd data: {}", ::utils::hexdump_16be(&::utils::bytes_to_be_words(data)));
},
ref err => {
debug!("cmd error: {:?}", err);
},
}
ret
}
} }
#[cfg(target_os = "freebsd")]
mod freebsd;
#[cfg(target_os = "freebsd")]
pub use self::freebsd::*;
impl ATADevice<SCSIDevice> {
ata_do!(scsi::ATAError);
fn ata_platform_do(&self, dir: Direction, regs: &RegistersWrite) -> Result<(RegistersRead, Vec<u8>), scsi::ATAError> {
self.device.ata_pass_through_16(dir, regs)
}
pub fn unwrap(self) -> SCSIDevice {
self.device
}
}