diff options
| author | Gary Guo <gary@garyguo.net> | 2026-08-27 17:51:46 +0900 |
|---|---|---|
| committer | Alexandre Courbot <acourbot@nvidia.com> | 2026-09-07 11:54:49 +0900 |
| commit | 9aa6069d624ea877a17b7d0952c993d2eb07dc22 (patch) | |
| tree | 9078a6e065b2ea934513644db232998781b13b9a /rust/kernel | |
| parent | b05ff82081b7b90fdd70cc7d07b3da9d85184f88 (diff) | |
| download | linux-next-9aa6069d624ea877a17b7d0952c993d2eb07dc22.tar.gz linux-next-9aa6069d624ea877a17b7d0952c993d2eb07dc22.zip | |
rust: io: add static `cast()` method for views
Add a compile-time checked variant of `try_cast()` using the minimum size
and alignment information.
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260805-typed_register-v2-1-c3ca142220a0@garyguo.net
[ecourtney: fix the doc example type and doc grammar per v2 review]
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patch.msgid.link/20260827-pramin-split-v3-5-24b24d7afc52@nvidia.com
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Diffstat (limited to 'rust/kernel')
| -rw-r--r-- | rust/kernel/io.rs | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs index 7a0e0ebc6c85..de8ef8e2aec4 100644 --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@ -447,6 +447,45 @@ pub trait Io<'a>: IoBase<'a> { self.len() == 0 } + /// Convert into a different typed I/O view. + /// + /// The target type must be known (statically) to be of the same or smaller size to current + /// type, and the current view must be properly aligned for the target type. + /// + /// # Examples + /// + /// ```no_run + /// use kernel::io::{ + /// io_project, + /// Mmio, + /// Io, + /// Region, + /// }; + /// #[derive(FromBytes, IntoBytes)] + /// #[repr(C)] + /// struct MyStruct { field: u32, } + /// + /// # fn test(mmio: &Mmio<'_, Region<0x1000>>) { + /// // let mmio: Mmio<'_, Region<0x1000>>; + /// let whole: Mmio<'_, MyStruct> = mmio.cast(); + /// # } + /// ``` + #[inline] + fn cast<U>(self) -> <Self::Backend as IoBackend>::View<'a, U> + where + Self::Target: FromBytes + IntoBytes, + U: FromBytes + IntoBytes, + { + let view = self.as_view(); + let ptr = Self::Backend::as_ptr(view); + + const_assert!(size_of::<U>() <= Self::Target::MIN_SIZE); + const_assert!(align_of::<U>() <= Self::Target::MIN_ALIGN.as_usize()); + + // SAFETY: We have checked bounds and alignment, so this is a valid projection. + unsafe { Self::Backend::project_view(view, ptr.cast()) } + } + /// Try to convert into a different typed I/O view. /// /// A runtime check is performed to ensure that the target type is of same or smaller size to |
