Skip to content

Commit fe58465

Browse files
xyn-ackDanilo Krummrich
authored andcommitted
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>
1 parent 9863f77 commit fe58465

2 files changed

Lines changed: 48 additions & 36 deletions

File tree

rust/kernel/dma.rs

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -328,20 +328,24 @@ unsafe impl<T: AsBytes + FromBytes + Send> Send for CoherentAllocation<T> {}
328328
#[macro_export]
329329
macro_rules! dma_read {
330330
($dma:expr, $idx: expr, $($field:tt)*) => {{
331-
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
332-
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
333-
// dereferenced. The compiler also further validates the expression on whether `field`
334-
// is a member of `item` when expanded by the macro.
335-
unsafe {
336-
let ptr_field = ::core::ptr::addr_of!((*item) $($field)*);
337-
$crate::dma::CoherentAllocation::field_read(&$dma, ptr_field)
338-
}
331+
(|| -> ::core::result::Result<_, $crate::error::Error> {
332+
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
333+
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
334+
// dereferenced. The compiler also further validates the expression on whether `field`
335+
// is a member of `item` when expanded by the macro.
336+
unsafe {
337+
let ptr_field = ::core::ptr::addr_of!((*item) $($field)*);
338+
::core::result::Result::Ok(
339+
$crate::dma::CoherentAllocation::field_read(&$dma, ptr_field)
340+
)
341+
}
342+
})()
339343
}};
340344
($dma:ident [ $idx:expr ] $($field:tt)* ) => {
341-
$crate::dma_read!($dma, $idx, $($field)*);
345+
$crate::dma_read!($dma, $idx, $($field)*)
342346
};
343347
($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {
344-
$crate::dma_read!($($dma).*, $idx, $($field)*);
348+
$crate::dma_read!($($dma).*, $idx, $($field)*)
345349
};
346350
}
347351

@@ -368,24 +372,30 @@ macro_rules! dma_read {
368372
#[macro_export]
369373
macro_rules! dma_write {
370374
($dma:ident [ $idx:expr ] $($field:tt)*) => {{
371-
$crate::dma_write!($dma, $idx, $($field)*);
375+
$crate::dma_write!($dma, $idx, $($field)*)
372376
}};
373377
($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {{
374-
$crate::dma_write!($($dma).*, $idx, $($field)*);
378+
$crate::dma_write!($($dma).*, $idx, $($field)*)
375379
}};
376380
($dma:expr, $idx: expr, = $val:expr) => {
377-
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
378-
// SAFETY: `item_from_index` ensures that `item` is always a valid item.
379-
unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) }
381+
(|| -> ::core::result::Result<_, $crate::error::Error> {
382+
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
383+
// SAFETY: `item_from_index` ensures that `item` is always a valid item.
384+
unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) }
385+
::core::result::Result::Ok(())
386+
})()
380387
};
381388
($dma:expr, $idx: expr, $(.$field:ident)* = $val:expr) => {
382-
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
383-
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
384-
// dereferenced. The compiler also further validates the expression on whether `field`
385-
// is a member of `item` when expanded by the macro.
386-
unsafe {
387-
let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*);
388-
$crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val)
389-
}
389+
(|| -> ::core::result::Result<_, $crate::error::Error> {
390+
let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?;
391+
// SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be
392+
// dereferenced. The compiler also further validates the expression on whether `field`
393+
// is a member of `item` when expanded by the macro.
394+
unsafe {
395+
let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*);
396+
$crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val)
397+
}
398+
::core::result::Result::Ok(())
399+
})()
390400
};
391401
}

samples/rust/rust_dma.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,9 @@ impl pci::Driver for DmaSampleDriver {
5454
let ca: CoherentAllocation<MyStruct> =
5555
CoherentAllocation::alloc_coherent(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
5656

57-
|| -> Result {
58-
for (i, value) in TEST_VALUES.into_iter().enumerate() {
59-
kernel::dma_write!(ca[i] = MyStruct::new(value.0, value.1));
60-
}
61-
62-
Ok(())
63-
}()?;
57+
for (i, value) in TEST_VALUES.into_iter().enumerate() {
58+
kernel::dma_write!(ca[i] = MyStruct::new(value.0, value.1))?;
59+
}
6460

6561
let drvdata = KBox::new(
6662
Self {
@@ -78,13 +74,19 @@ impl Drop for DmaSampleDriver {
7874
fn drop(&mut self) {
7975
dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n");
8076

81-
let _ = || -> Result {
82-
for (i, value) in TEST_VALUES.into_iter().enumerate() {
83-
assert_eq!(kernel::dma_read!(self.ca[i].h), value.0);
84-
assert_eq!(kernel::dma_read!(self.ca[i].b), value.1);
77+
for (i, value) in TEST_VALUES.into_iter().enumerate() {
78+
let val0 = kernel::dma_read!(self.ca[i].h);
79+
let val1 = kernel::dma_read!(self.ca[i].b);
80+
assert!(val0.is_ok());
81+
assert!(val1.is_ok());
82+
83+
if let Ok(val0) = val0 {
84+
assert_eq!(val0, value.0);
85+
}
86+
if let Ok(val1) = val1 {
87+
assert_eq!(val1, value.1);
8588
}
86-
Ok(())
87-
}();
89+
}
8890
}
8991
}
9092

0 commit comments

Comments
 (0)