mirror of https://github.com/torvalds/linux.git
rust: dma: convert the read/write macros to return Result
We could do better here by having the macros return `Result`, so that we don't have to wrap these calls in a closure for validation which is confusing. Co-developed-by: Andreas Hindborg <a.hindborg@kernel.org> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org> Link: https://lore.kernel.org/rust-for-linux/87h63qhz4q.fsf@kernel.org/ Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org> Signed-off-by: Abdiel Janulgue <abdiel.janulgue@gmail.com> Link: https://lore.kernel.org/r/20250602085444.1925053-3-abdiel.janulgue@gmail.com [ Fix line length in dma_read!(). - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
parent
9863f77433
commit
fe58465905
|
|
@ -328,20 +328,24 @@ unsafe impl<T: AsBytes + FromBytes + Send> Send for CoherentAllocation<T> {}
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! dma_read {
|
macro_rules! dma_read {
|
||||||
($dma:expr, $idx: expr, $($field:tt)*) => {{
|
($dma:expr, $idx: expr, $($field:tt)*) => {{
|
||||||
|
(|| -> ::core::result::Result<_, $crate::error::Error> {
|
||||||
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
|
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
|
||||||
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
|
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
|
||||||
// dereferenced. The compiler also further validates the expression on whether `field`
|
// dereferenced. The compiler also further validates the expression on whether `field`
|
||||||
// is a member of `item` when expanded by the macro.
|
// is a member of `item` when expanded by the macro.
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr_field = ::core::ptr::addr_of!((*item) $($field)*);
|
let ptr_field = ::core::ptr::addr_of!((*item) $($field)*);
|
||||||
|
::core::result::Result::Ok(
|
||||||
$crate::dma::CoherentAllocation::field_read(&$dma, ptr_field)
|
$crate::dma::CoherentAllocation::field_read(&$dma, ptr_field)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
}};
|
}};
|
||||||
($dma:ident [ $idx:expr ] $($field:tt)* ) => {
|
($dma:ident [ $idx:expr ] $($field:tt)* ) => {
|
||||||
$crate::dma_read!($dma, $idx, $($field)*);
|
$crate::dma_read!($dma, $idx, $($field)*)
|
||||||
};
|
};
|
||||||
($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {
|
($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {
|
||||||
$crate::dma_read!($($dma).*, $idx, $($field)*);
|
$crate::dma_read!($($dma).*, $idx, $($field)*)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,17 +372,21 @@ macro_rules! dma_read {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! dma_write {
|
macro_rules! dma_write {
|
||||||
($dma:ident [ $idx:expr ] $($field:tt)*) => {{
|
($dma:ident [ $idx:expr ] $($field:tt)*) => {{
|
||||||
$crate::dma_write!($dma, $idx, $($field)*);
|
$crate::dma_write!($dma, $idx, $($field)*)
|
||||||
}};
|
}};
|
||||||
($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {{
|
($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {{
|
||||||
$crate::dma_write!($($dma).*, $idx, $($field)*);
|
$crate::dma_write!($($dma).*, $idx, $($field)*)
|
||||||
}};
|
}};
|
||||||
($dma:expr, $idx: expr, = $val:expr) => {
|
($dma:expr, $idx: expr, = $val:expr) => {
|
||||||
|
(|| -> ::core::result::Result<_, $crate::error::Error> {
|
||||||
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
|
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
|
||||||
// SAFETY: `item_from_index` ensures that `item` is always a valid item.
|
// SAFETY: `item_from_index` ensures that `item` is always a valid item.
|
||||||
unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) }
|
unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) }
|
||||||
|
::core::result::Result::Ok(())
|
||||||
|
})()
|
||||||
};
|
};
|
||||||
($dma:expr, $idx: expr, $(.$field:ident)* = $val:expr) => {
|
($dma:expr, $idx: expr, $(.$field:ident)* = $val:expr) => {
|
||||||
|
(|| -> ::core::result::Result<_, $crate::error::Error> {
|
||||||
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
|
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
|
||||||
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
|
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
|
||||||
// dereferenced. The compiler also further validates the expression on whether `field`
|
// dereferenced. The compiler also further validates the expression on whether `field`
|
||||||
|
|
@ -387,5 +395,7 @@ macro_rules! dma_write {
|
||||||
let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*);
|
let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*);
|
||||||
$crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val)
|
$crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val)
|
||||||
}
|
}
|
||||||
|
::core::result::Result::Ok(())
|
||||||
|
})()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,14 +54,10 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self
|
||||||
let ca: CoherentAllocation<MyStruct> =
|
let ca: CoherentAllocation<MyStruct> =
|
||||||
CoherentAllocation::alloc_coherent(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
|
CoherentAllocation::alloc_coherent(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
|
||||||
|
|
||||||
|| -> Result {
|
|
||||||
for (i, value) in TEST_VALUES.into_iter().enumerate() {
|
for (i, value) in TEST_VALUES.into_iter().enumerate() {
|
||||||
kernel::dma_write!(ca[i] = MyStruct::new(value.0, value.1));
|
kernel::dma_write!(ca[i] = MyStruct::new(value.0, value.1))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}()?;
|
|
||||||
|
|
||||||
let drvdata = KBox::new(
|
let drvdata = KBox::new(
|
||||||
Self {
|
Self {
|
||||||
pdev: pdev.into(),
|
pdev: pdev.into(),
|
||||||
|
|
@ -78,13 +74,19 @@ impl Drop for DmaSampleDriver {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n");
|
dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n");
|
||||||
|
|
||||||
let _ = || -> Result {
|
|
||||||
for (i, value) in TEST_VALUES.into_iter().enumerate() {
|
for (i, value) in TEST_VALUES.into_iter().enumerate() {
|
||||||
assert_eq!(kernel::dma_read!(self.ca[i].h), value.0);
|
let val0 = kernel::dma_read!(self.ca[i].h);
|
||||||
assert_eq!(kernel::dma_read!(self.ca[i].b), value.1);
|
let val1 = kernel::dma_read!(self.ca[i].b);
|
||||||
|
assert!(val0.is_ok());
|
||||||
|
assert!(val1.is_ok());
|
||||||
|
|
||||||
|
if let Ok(val0) = val0 {
|
||||||
|
assert_eq!(val0, value.0);
|
||||||
|
}
|
||||||
|
if let Ok(val1) = val1 {
|
||||||
|
assert_eq!(val1, value.1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue