Acquiring the BAR temporarily to access is going to be a very common pattern, that typically takes two lines of code and introduces a short-lived local variable.
Add the Nova-local convenience with_bar!() macro, which uses Revocable::try_access_with() and converts its returned Option into the proper error as needed. Signed-off-by: Alexandre Courbot <acour...@nvidia.com> --- drivers/gpu/nova-core/gpu.rs | 3 +-- drivers/gpu/nova-core/nova_core.rs | 18 ++++++++++++++++++ drivers/gpu/nova-core/regs/macros.rs | 1 + 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index 64c38425098c19360a7c938f2b86a55ca3c48880..275b005d262e0a01a9ef1498836ef3c3019cb497 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -148,8 +148,7 @@ pub(crate) struct Spec { impl Spec { fn new(bar: &Devres<Bar0>) -> Result<Spec> { - let bar = bar.try_access().ok_or(ENXIO)?; - let boot0 = regs::NV_PMC_BOOT_0::read(&*bar); + let boot0 = with_bar!(bar, regs::NV_PMC_BOOT_0::read)?; Ok(Self { chipset: boot0.chipset()?, diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs index a91cd924054b49966937a8db6aab9cd0614f10de..0eecd612e34efc046dad852e6239de6ffa5fdd62 100644 --- a/drivers/gpu/nova-core/nova_core.rs +++ b/drivers/gpu/nova-core/nova_core.rs @@ -2,6 +2,24 @@ //! Nova Core GPU Driver +#[macro_use] +mod macros { + /// Convenience macro to run a closure while holding [`crate::driver::Bar0`]. + /// + /// If the bar cannot be acquired, then `ENXIO` is returned. + /// + /// If a `?` is present before the `bar` argument, then the `Result` returned by the closure is + /// merged into the `Result` of the macro itself to avoid having a `Result<Result<>>`. + macro_rules! with_bar { + ($bar:expr, $closure:expr) => { + $bar.try_access_with($closure).ok_or(ENXIO) + }; + (? $bar:expr, $closure:expr) => { + with_bar!($bar, $closure).and_then(|r| r) + }; + } +} + mod driver; mod firmware; mod gpu; diff --git a/drivers/gpu/nova-core/regs/macros.rs b/drivers/gpu/nova-core/regs/macros.rs index a08d4f2aa0a32b00e80dae4e6b2c79d072241734..7ecc70efb3cd723b673cd72915e72b8a4a009f06 100644 --- a/drivers/gpu/nova-core/regs/macros.rs +++ b/drivers/gpu/nova-core/regs/macros.rs @@ -68,6 +68,7 @@ /// /// // Flip the `start` switch for the CPU core which base address is at `CPU_BASE`. /// let cpuctl = CPU_CTL::read(&bar, CPU_BASE); +/// pr_info!("CPU CTL: {:#x}", cpuctl); /// cpuctl.set_start(true).write(&bar, CPU_BASE); /// ``` macro_rules! register { -- 2.49.0