From 369a695bd949080933d013a48697d679d9b109e6 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 20 Feb 2020 21:09:10 -0700 Subject: [PATCH] Add timeout macro to simplify timeout logic --- tool/src/ec.rs | 32 ++++++++------------------------ tool/src/lib.rs | 19 ++++++++++++++----- tool/src/main.rs | 6 +++--- tool/src/pmc.rs | 40 ++++++++++++++++++++++++++++------------ tool/src/timeout.rs | 23 +++++++++++++++++++++++ 5 files changed, 76 insertions(+), 44 deletions(-) diff --git a/tool/src/ec.rs b/tool/src/ec.rs index d53ae75..74cdc39 100644 --- a/tool/src/ec.rs +++ b/tool/src/ec.rs @@ -1,8 +1,11 @@ use hwio::{Io, Pio}; -use crate::error::Error; -use crate::super_io::SuperIo; -use crate::timeout::Timeout; +use crate::{ + Error, + SuperIo, + Timeout, + timeout +}; #[derive(Clone, Copy, Debug)] #[repr(u8)] @@ -96,27 +99,8 @@ impl Ec { pub unsafe fn command(&mut self, cmd: EcCmd) -> Result<(), Error> { self.timeout.reset(); - while self.timeout.running() { - match self.command_start(cmd) { - Ok(()) => break, - Err(err) => match err { - Error::WouldBlock => (), - _ => return Err(err) - }, - } - } - - while self.timeout.running() { - match self.command_finish() { - Ok(ok) => return Ok(ok), - Err(err) => match err { - Error::WouldBlock => (), - _ => return Err(err) - }, - } - } - - Err(Error::Timeout) + timeout!(self.timeout, self.command_start(cmd))?; + timeout!(self.timeout, self.command_finish()) } /// Probe for EC diff --git a/tool/src/lib.rs b/tool/src/lib.rs index a1433c7..b0d5a2d 100644 --- a/tool/src/lib.rs +++ b/tool/src/lib.rs @@ -1,7 +1,16 @@ #![no_std] -pub mod ec; -pub mod error; -pub mod pmc; -pub mod super_io; -pub mod timeout; +pub use self::ec::Ec; +mod ec; + +pub use self::error::Error; +mod error; + +pub use self::pmc::Pmc; +mod pmc; + +pub use self::super_io::SuperIo; +mod super_io; + +pub use self::timeout::Timeout; +mod timeout; diff --git a/tool/src/main.rs b/tool/src/main.rs index adc1755..2298a7c 100644 --- a/tool/src/main.rs +++ b/tool/src/main.rs @@ -1,7 +1,7 @@ use ectool::{ - ec::Ec, - error::Error, - timeout::Timeout, + Ec, + Error, + Timeout, }; use std::{ io, diff --git a/tool/src/pmc.rs b/tool/src/pmc.rs index 743888e..1d755fc 100644 --- a/tool/src/pmc.rs +++ b/tool/src/pmc.rs @@ -1,17 +1,25 @@ use hwio::{Io, Pio}; -pub struct Pmc { +use crate::{ + Error, + Timeout, + timeout +}; + +pub struct Pmc { data: Pio, cmd: Pio, + timeout: T, } -impl Pmc { +impl Pmc { /// Create a new PMC instance. `base` identifies the data port. The command /// port will be `base + 4` - pub fn new(base: u16) -> Self { + pub fn new(base: u16, timeout: T) -> Self { Self { data: Pio::new(base), cmd: Pio::new(base + 4), + timeout, } } @@ -26,31 +34,39 @@ impl Pmc { } /// Write a command to the PMC. Returns None if unable to write - pub unsafe fn command(&mut self, data: u8) -> Option<()> { + pub unsafe fn command(&mut self, data: u8) -> Result<(), Error> { if self.can_write() { self.cmd.write(data); - Some(()) + Ok(()) } else { - None + Err(Error::WouldBlock) } } /// Read data from the PMC. Returns None if unable to read - pub unsafe fn read(&mut self) -> Option { + pub unsafe fn read(&mut self) -> Result { if self.can_read() { - Some(self.data.read()) + Ok(self.data.read()) } else { - None + Err(Error::WouldBlock) } } /// Write data to the PMC. Returns false if unable to write - pub unsafe fn write(&mut self, data: u8) -> Option<()> { + pub unsafe fn write(&mut self, data: u8) -> Result<(), Error> { if self.can_write() { self.data.write(data); - Some(()) + Ok(()) } else { - None + Err(Error::WouldBlock) } } + + pub unsafe fn acpi_read(&mut self, addr: u8) -> Result { + self.timeout.reset(); + + timeout!(self.timeout, self.command(0x80))?; + timeout!(self.timeout, self.write(addr))?; + timeout!(self.timeout, self.read()) + } } diff --git a/tool/src/timeout.rs b/tool/src/timeout.rs index a4ce933..8da4b39 100644 --- a/tool/src/timeout.rs +++ b/tool/src/timeout.rs @@ -1,3 +1,26 @@ +#[macro_export] +macro_rules! timeout { + ($t:expr, $f:expr) => {{ + let mut result = Err($crate::Error::Timeout); + while $t.running() { + match $f { + Ok(ok) => { + result = Ok(ok); + break; + }, + Err(err) => match err { + $crate::Error::WouldBlock => (), + _ => { + result = Err(err); + break; + } + }, + } + } + result + }}; +} + pub trait Timeout { fn reset(&mut self); fn running(&self) -> bool;