diff options
| author | Zhi Wang <zhiw@nvidia.com> | 2026-01-21 22:22:08 +0200 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2026-01-23 21:20:11 +0100 |
| commit | 121d87b28e1d9061d3aaa156c43a627d3cb5e620 (patch) | |
| tree | c0f45e4b093d2525dea5648ddd52105ae5f4ae99 /rust/kernel/io | |
| parent | 7043698aee6b6f61415ebb49b7e95fdfb9373a77 (diff) | |
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>
Diffstat (limited to 'rust/kernel/io')
| -rw-r--r-- | rust/kernel/io/mem.rs | 16 | ||||
| -rw-r--r-- | rust/kernel/io/poll.rs | 16 |
2 files changed, 20 insertions, 12 deletions
diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs index e4878c131c6d..620022cff401 100644 --- a/rust/kernel/io/mem.rs +++ b/rust/kernel/io/mem.rs @@ -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) } } } diff --git a/rust/kernel/io/poll.rs b/rust/kernel/io/poll.rs index b1a2570364f4..75d1b3e8596c 100644 --- a/rust/kernel/io/poll.rs +++ b/rust/kernel/io/poll.rs @@ -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), |
