mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
rust: io: separate generic I/O helpers from MMIO implementation
The previous Io<SIZE> type combined both the generic I/O access helpers and MMIO implementation details in a single struct. This coupling prevented reusing the I/O helpers for other backends, such as PCI configuration space. Establish a clean separation between the I/O interface and concrete backends by separating generic I/O helpers from MMIO implementation. Introduce a new trait hierarchy to handle different access capabilities: - IoCapable<T>: A marker trait indicating that a backend supports I/O operations of a certain type (u8, u16, u32, or u64). - Io trait: Defines fallible (try_read8, try_write8, etc.) and infallibile (read8, write8, etc.) I/O methods with runtime bounds checking and compile-time bounds checking. - IoKnownSize trait: The marker trait for types support infallible I/O methods. Move the MMIO-specific logic into a dedicated Mmio<SIZE> type that implements the Io traits. Rename IoRaw to MmioRaw and update consumers to use the new types. Cc: Alexandre Courbot <acourbot@nvidia.com> Cc: Alice Ryhl <aliceryhl@google.com> Cc: Bjorn Helgaas <helgaas@kernel.org> Cc: Gary Guo <gary@garyguo.net> Cc: Danilo Krummrich <dakr@kernel.org> Cc: John Hubbard <jhubbard@nvidia.com> Signed-off-by: Zhi Wang <zhiw@nvidia.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260121202212.4438-3-zhiw@nvidia.com [ Add #[expect(unused)] to define_{read,write}!(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
committed by
Danilo Krummrich
parent
7043698aee
commit
121d87b28e
@@ -11,6 +11,7 @@ use kernel::bits::bit_u32;
|
||||
use kernel::device::Bound;
|
||||
use kernel::device::Device;
|
||||
use kernel::devres::Devres;
|
||||
use kernel::io::Io;
|
||||
use kernel::prelude::*;
|
||||
|
||||
use crate::driver::IoMem;
|
||||
|
||||
@@ -12,7 +12,10 @@ use core::{
|
||||
|
||||
use kernel::{
|
||||
device,
|
||||
io::poll::read_poll_timeout,
|
||||
io::{
|
||||
poll::read_poll_timeout,
|
||||
Io, //
|
||||
},
|
||||
prelude::*,
|
||||
time::{
|
||||
delay::fsleep,
|
||||
|
||||
@@ -369,16 +369,18 @@ macro_rules! register {
|
||||
|
||||
/// Read the register from its address in `io`.
|
||||
#[inline(always)]
|
||||
pub(crate) fn read<const SIZE: usize, T>(io: &T) -> Self where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
pub(crate) fn read<T, I>(io: &T) -> Self where
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
{
|
||||
Self(io.read32($offset))
|
||||
}
|
||||
|
||||
/// Write the value contained in `self` to the register address in `io`.
|
||||
#[inline(always)]
|
||||
pub(crate) fn write<const SIZE: usize, T>(self, io: &T) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
pub(crate) fn write<T, I>(self, io: &T) where
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
{
|
||||
io.write32(self.0, $offset)
|
||||
}
|
||||
@@ -386,11 +388,12 @@ macro_rules! register {
|
||||
/// Read the register from its address in `io` and run `f` on its value to obtain a new
|
||||
/// value to write back.
|
||||
#[inline(always)]
|
||||
pub(crate) fn update<const SIZE: usize, T, F>(
|
||||
pub(crate) fn update<T, I, F>(
|
||||
io: &T,
|
||||
f: F,
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
F: ::core::ops::FnOnce(Self) -> Self,
|
||||
{
|
||||
let reg = f(Self::read(io));
|
||||
@@ -408,12 +411,13 @@ macro_rules! register {
|
||||
/// Read the register from `io`, using the base address provided by `base` and adding
|
||||
/// the register's offset to it.
|
||||
#[inline(always)]
|
||||
pub(crate) fn read<const SIZE: usize, T, B>(
|
||||
pub(crate) fn read<T, I, B>(
|
||||
io: &T,
|
||||
#[allow(unused_variables)]
|
||||
base: &B,
|
||||
) -> Self where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
{
|
||||
const OFFSET: usize = $name::OFFSET;
|
||||
@@ -428,13 +432,14 @@ macro_rules! register {
|
||||
/// Write the value contained in `self` to `io`, using the base address provided by
|
||||
/// `base` and adding the register's offset to it.
|
||||
#[inline(always)]
|
||||
pub(crate) fn write<const SIZE: usize, T, B>(
|
||||
pub(crate) fn write<T, I, B>(
|
||||
self,
|
||||
io: &T,
|
||||
#[allow(unused_variables)]
|
||||
base: &B,
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
{
|
||||
const OFFSET: usize = $name::OFFSET;
|
||||
@@ -449,12 +454,13 @@ macro_rules! register {
|
||||
/// the register's offset to it, then run `f` on its value to obtain a new value to
|
||||
/// write back.
|
||||
#[inline(always)]
|
||||
pub(crate) fn update<const SIZE: usize, T, B, F>(
|
||||
pub(crate) fn update<T, I, B, F>(
|
||||
io: &T,
|
||||
base: &B,
|
||||
f: F,
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
F: ::core::ops::FnOnce(Self) -> Self,
|
||||
{
|
||||
@@ -474,11 +480,12 @@ macro_rules! register {
|
||||
|
||||
/// Read the array register at index `idx` from its address in `io`.
|
||||
#[inline(always)]
|
||||
pub(crate) fn read<const SIZE: usize, T>(
|
||||
pub(crate) fn read<T, I>(
|
||||
io: &T,
|
||||
idx: usize,
|
||||
) -> Self where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
{
|
||||
build_assert!(idx < Self::SIZE);
|
||||
|
||||
@@ -490,12 +497,13 @@ macro_rules! register {
|
||||
|
||||
/// Write the value contained in `self` to the array register with index `idx` in `io`.
|
||||
#[inline(always)]
|
||||
pub(crate) fn write<const SIZE: usize, T>(
|
||||
pub(crate) fn write<T, I>(
|
||||
self,
|
||||
io: &T,
|
||||
idx: usize
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
{
|
||||
build_assert!(idx < Self::SIZE);
|
||||
|
||||
@@ -507,12 +515,13 @@ macro_rules! register {
|
||||
/// Read the array register at index `idx` in `io` and run `f` on its value to obtain a
|
||||
/// new value to write back.
|
||||
#[inline(always)]
|
||||
pub(crate) fn update<const SIZE: usize, T, F>(
|
||||
pub(crate) fn update<T, I, F>(
|
||||
io: &T,
|
||||
idx: usize,
|
||||
f: F,
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
F: ::core::ops::FnOnce(Self) -> Self,
|
||||
{
|
||||
let reg = f(Self::read(io, idx));
|
||||
@@ -524,11 +533,12 @@ macro_rules! register {
|
||||
/// The validity of `idx` is checked at run-time, and `EINVAL` is returned is the
|
||||
/// access was out-of-bounds.
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_read<const SIZE: usize, T>(
|
||||
pub(crate) fn try_read<T, I>(
|
||||
io: &T,
|
||||
idx: usize,
|
||||
) -> ::kernel::error::Result<Self> where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
{
|
||||
if idx < Self::SIZE {
|
||||
Ok(Self::read(io, idx))
|
||||
@@ -542,12 +552,13 @@ macro_rules! register {
|
||||
/// The validity of `idx` is checked at run-time, and `EINVAL` is returned is the
|
||||
/// access was out-of-bounds.
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_write<const SIZE: usize, T>(
|
||||
pub(crate) fn try_write<T, I>(
|
||||
self,
|
||||
io: &T,
|
||||
idx: usize,
|
||||
) -> ::kernel::error::Result where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
{
|
||||
if idx < Self::SIZE {
|
||||
Ok(self.write(io, idx))
|
||||
@@ -562,12 +573,13 @@ macro_rules! register {
|
||||
/// The validity of `idx` is checked at run-time, and `EINVAL` is returned is the
|
||||
/// access was out-of-bounds.
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_update<const SIZE: usize, T, F>(
|
||||
pub(crate) fn try_update<T, I, F>(
|
||||
io: &T,
|
||||
idx: usize,
|
||||
f: F,
|
||||
) -> ::kernel::error::Result where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
F: ::core::ops::FnOnce(Self) -> Self,
|
||||
{
|
||||
if idx < Self::SIZE {
|
||||
@@ -593,13 +605,14 @@ macro_rules! register {
|
||||
/// Read the array register at index `idx` from `io`, using the base address provided
|
||||
/// by `base` and adding the register's offset to it.
|
||||
#[inline(always)]
|
||||
pub(crate) fn read<const SIZE: usize, T, B>(
|
||||
pub(crate) fn read<T, I, B>(
|
||||
io: &T,
|
||||
#[allow(unused_variables)]
|
||||
base: &B,
|
||||
idx: usize,
|
||||
) -> Self where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
{
|
||||
build_assert!(idx < Self::SIZE);
|
||||
@@ -614,14 +627,15 @@ macro_rules! register {
|
||||
/// Write the value contained in `self` to `io`, using the base address provided by
|
||||
/// `base` and adding the offset of array register `idx` to it.
|
||||
#[inline(always)]
|
||||
pub(crate) fn write<const SIZE: usize, T, B>(
|
||||
pub(crate) fn write<T, I, B>(
|
||||
self,
|
||||
io: &T,
|
||||
#[allow(unused_variables)]
|
||||
base: &B,
|
||||
idx: usize
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
{
|
||||
build_assert!(idx < Self::SIZE);
|
||||
@@ -636,13 +650,14 @@ macro_rules! register {
|
||||
/// by `base` and adding the register's offset to it, then run `f` on its value to
|
||||
/// obtain a new value to write back.
|
||||
#[inline(always)]
|
||||
pub(crate) fn update<const SIZE: usize, T, B, F>(
|
||||
pub(crate) fn update<T, I, B, F>(
|
||||
io: &T,
|
||||
base: &B,
|
||||
idx: usize,
|
||||
f: F,
|
||||
) where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
F: ::core::ops::FnOnce(Self) -> Self,
|
||||
{
|
||||
@@ -656,12 +671,13 @@ macro_rules! register {
|
||||
/// The validity of `idx` is checked at run-time, and `EINVAL` is returned is the
|
||||
/// access was out-of-bounds.
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_read<const SIZE: usize, T, B>(
|
||||
pub(crate) fn try_read<T, I, B>(
|
||||
io: &T,
|
||||
base: &B,
|
||||
idx: usize,
|
||||
) -> ::kernel::error::Result<Self> where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
{
|
||||
if idx < Self::SIZE {
|
||||
@@ -677,13 +693,14 @@ macro_rules! register {
|
||||
/// The validity of `idx` is checked at run-time, and `EINVAL` is returned is the
|
||||
/// access was out-of-bounds.
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_write<const SIZE: usize, T, B>(
|
||||
pub(crate) fn try_write<T, I, B>(
|
||||
self,
|
||||
io: &T,
|
||||
base: &B,
|
||||
idx: usize,
|
||||
) -> ::kernel::error::Result where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
{
|
||||
if idx < Self::SIZE {
|
||||
@@ -700,13 +717,14 @@ macro_rules! register {
|
||||
/// The validity of `idx` is checked at run-time, and `EINVAL` is returned is the
|
||||
/// access was out-of-bounds.
|
||||
#[inline(always)]
|
||||
pub(crate) fn try_update<const SIZE: usize, T, B, F>(
|
||||
pub(crate) fn try_update<T, I, B, F>(
|
||||
io: &T,
|
||||
base: &B,
|
||||
idx: usize,
|
||||
f: F,
|
||||
) -> ::kernel::error::Result where
|
||||
T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
|
||||
T: ::core::ops::Deref<Target = I>,
|
||||
I: ::kernel::io::IoKnownSize + ::kernel::io::IoCapable<u32>,
|
||||
B: crate::regs::macros::RegisterBase<$base>,
|
||||
F: ::core::ops::FnOnce(Self) -> Self,
|
||||
{
|
||||
|
||||
@@ -6,6 +6,7 @@ use core::convert::TryFrom;
|
||||
|
||||
use kernel::{
|
||||
device,
|
||||
io::Io,
|
||||
prelude::*,
|
||||
ptr::{
|
||||
Alignable,
|
||||
|
||||
@@ -26,7 +26,10 @@ use kernel::{
|
||||
clk::Clk,
|
||||
device::{Bound, Core, Device},
|
||||
devres,
|
||||
io::mem::IoMem,
|
||||
io::{
|
||||
mem::IoMem,
|
||||
Io, //
|
||||
},
|
||||
of, platform,
|
||||
prelude::*,
|
||||
pwm, time,
|
||||
|
||||
+13
-6
@@ -74,14 +74,17 @@ struct Inner<T: Send> {
|
||||
/// devres::Devres,
|
||||
/// io::{
|
||||
/// Io,
|
||||
/// IoRaw,
|
||||
/// PhysAddr,
|
||||
/// IoKnownSize,
|
||||
/// Mmio,
|
||||
/// MmioRaw,
|
||||
/// PhysAddr, //
|
||||
/// },
|
||||
/// prelude::*,
|
||||
/// };
|
||||
/// use core::ops::Deref;
|
||||
///
|
||||
/// // See also [`pci::Bar`] for a real example.
|
||||
/// struct IoMem<const SIZE: usize>(IoRaw<SIZE>);
|
||||
/// struct IoMem<const SIZE: usize>(MmioRaw<SIZE>);
|
||||
///
|
||||
/// impl<const SIZE: usize> IoMem<SIZE> {
|
||||
/// /// # Safety
|
||||
@@ -96,7 +99,7 @@ struct Inner<T: Send> {
|
||||
/// return Err(ENOMEM);
|
||||
/// }
|
||||
///
|
||||
/// Ok(IoMem(IoRaw::new(addr as usize, SIZE)?))
|
||||
/// Ok(IoMem(MmioRaw::new(addr as usize, SIZE)?))
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
@@ -108,11 +111,11 @@ struct Inner<T: Send> {
|
||||
/// }
|
||||
///
|
||||
/// impl<const SIZE: usize> Deref for IoMem<SIZE> {
|
||||
/// type Target = Io<SIZE>;
|
||||
/// type Target = Mmio<SIZE>;
|
||||
///
|
||||
/// fn deref(&self) -> &Self::Target {
|
||||
/// // SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
|
||||
/// unsafe { Io::from_raw(&self.0) }
|
||||
/// unsafe { Mmio::from_raw(&self.0) }
|
||||
/// }
|
||||
/// }
|
||||
/// # fn no_run(dev: &Device<Bound>) -> Result<(), Error> {
|
||||
@@ -258,6 +261,10 @@ impl<T: Send> Devres<T> {
|
||||
/// use kernel::{
|
||||
/// device::Core,
|
||||
/// devres::Devres,
|
||||
/// io::{
|
||||
/// Io,
|
||||
/// IoKnownSize, //
|
||||
/// },
|
||||
/// pci, //
|
||||
/// };
|
||||
///
|
||||
|
||||
+335
-73
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,8 @@ use crate::{
|
||||
Region,
|
||||
Resource, //
|
||||
},
|
||||
Io,
|
||||
IoRaw, //
|
||||
Mmio,
|
||||
MmioRaw, //
|
||||
},
|
||||
prelude::*,
|
||||
};
|
||||
@@ -212,7 +212,7 @@ impl<const SIZE: usize> ExclusiveIoMem<SIZE> {
|
||||
}
|
||||
|
||||
impl<const SIZE: usize> Deref for ExclusiveIoMem<SIZE> {
|
||||
type Target = Io<SIZE>;
|
||||
type Target = Mmio<SIZE>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.iomem
|
||||
@@ -226,10 +226,10 @@ impl<const SIZE: usize> Deref for ExclusiveIoMem<SIZE> {
|
||||
///
|
||||
/// # Invariants
|
||||
///
|
||||
/// [`IoMem`] always holds an [`IoRaw`] instance that holds a valid pointer to the
|
||||
/// [`IoMem`] always holds an [`MmioRaw`] instance that holds a valid pointer to the
|
||||
/// start of the I/O memory mapped region.
|
||||
pub struct IoMem<const SIZE: usize = 0> {
|
||||
io: IoRaw<SIZE>,
|
||||
io: MmioRaw<SIZE>,
|
||||
}
|
||||
|
||||
impl<const SIZE: usize> IoMem<SIZE> {
|
||||
@@ -264,7 +264,7 @@ impl<const SIZE: usize> IoMem<SIZE> {
|
||||
return Err(ENOMEM);
|
||||
}
|
||||
|
||||
let io = IoRaw::new(addr as usize, size)?;
|
||||
let io = MmioRaw::new(addr as usize, size)?;
|
||||
let io = IoMem { io };
|
||||
|
||||
Ok(io)
|
||||
@@ -287,10 +287,10 @@ impl<const SIZE: usize> Drop for IoMem<SIZE> {
|
||||
}
|
||||
|
||||
impl<const SIZE: usize> Deref for IoMem<SIZE> {
|
||||
type Target = Io<SIZE>;
|
||||
type Target = Mmio<SIZE>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY: Safe as by the invariant of `IoMem`.
|
||||
unsafe { Io::from_raw(&self.io) }
|
||||
unsafe { Mmio::from_raw(&self.io) }
|
||||
}
|
||||
}
|
||||
|
||||
+12
-4
@@ -45,12 +45,16 @@ use crate::{
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use kernel::io::{Io, poll::read_poll_timeout};
|
||||
/// use kernel::io::{
|
||||
/// Io,
|
||||
/// Mmio,
|
||||
/// poll::read_poll_timeout, //
|
||||
/// };
|
||||
/// use kernel::time::Delta;
|
||||
///
|
||||
/// const HW_READY: u16 = 0x01;
|
||||
///
|
||||
/// fn wait_for_hardware<const SIZE: usize>(io: &Io<SIZE>) -> Result {
|
||||
/// fn wait_for_hardware<const SIZE: usize>(io: &Mmio<SIZE>) -> Result {
|
||||
/// read_poll_timeout(
|
||||
/// // The `op` closure reads the value of a specific status register.
|
||||
/// || io.try_read16(0x1000),
|
||||
@@ -128,12 +132,16 @@ where
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use kernel::io::{poll::read_poll_timeout_atomic, Io};
|
||||
/// use kernel::io::{
|
||||
/// Io,
|
||||
/// Mmio,
|
||||
/// poll::read_poll_timeout_atomic, //
|
||||
/// };
|
||||
/// use kernel::time::Delta;
|
||||
///
|
||||
/// const HW_READY: u16 = 0x01;
|
||||
///
|
||||
/// fn wait_for_hardware<const SIZE: usize>(io: &Io<SIZE>) -> Result {
|
||||
/// fn wait_for_hardware<const SIZE: usize>(io: &Mmio<SIZE>) -> Result {
|
||||
/// read_poll_timeout_atomic(
|
||||
/// // The `op` closure reads the value of a specific status register.
|
||||
/// || io.try_read16(0x1000),
|
||||
|
||||
@@ -8,8 +8,8 @@ use crate::{
|
||||
device,
|
||||
devres::Devres,
|
||||
io::{
|
||||
Io,
|
||||
IoRaw, //
|
||||
Mmio,
|
||||
MmioRaw, //
|
||||
},
|
||||
prelude::*,
|
||||
sync::aref::ARef, //
|
||||
@@ -27,7 +27,7 @@ use core::ops::Deref;
|
||||
/// memory mapped PCI BAR and its size.
|
||||
pub struct Bar<const SIZE: usize = 0> {
|
||||
pdev: ARef<Device>,
|
||||
io: IoRaw<SIZE>,
|
||||
io: MmioRaw<SIZE>,
|
||||
num: i32,
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<const SIZE: usize> Bar<SIZE> {
|
||||
return Err(ENOMEM);
|
||||
}
|
||||
|
||||
let io = match IoRaw::new(ioptr, len as usize) {
|
||||
let io = match MmioRaw::new(ioptr, len as usize) {
|
||||
Ok(io) => io,
|
||||
Err(err) => {
|
||||
// SAFETY:
|
||||
@@ -117,11 +117,11 @@ impl<const SIZE: usize> Drop for Bar<SIZE> {
|
||||
}
|
||||
|
||||
impl<const SIZE: usize> Deref for Bar<SIZE> {
|
||||
type Target = Io<SIZE>;
|
||||
type Target = Mmio<SIZE>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
// SAFETY: By the type invariant of `Self`, the MMIO range in `self.io` is properly mapped.
|
||||
unsafe { Io::from_raw(&self.io) }
|
||||
unsafe { Mmio::from_raw(&self.io) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
use kernel::{
|
||||
device::Core,
|
||||
devres::Devres,
|
||||
io::Io,
|
||||
pci,
|
||||
prelude::*,
|
||||
sync::aref::ARef, //
|
||||
|
||||
Reference in New Issue
Block a user