summaryrefslogtreecommitdiff
path: root/rust/kernel
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2026-08-27 17:51:46 +0900
committerAlexandre Courbot <acourbot@nvidia.com>2026-09-07 11:54:49 +0900
commit9aa6069d624ea877a17b7d0952c993d2eb07dc22 (patch)
tree9078a6e065b2ea934513644db232998781b13b9a /rust/kernel
parentb05ff82081b7b90fdd70cc7d07b3da9d85184f88 (diff)
downloadlinux-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.rs39
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