[PATCH v2 2/2] samples: rust: add sample code for scatterlist bindings
From: Abdiel Janulgue
Date: Thu Jun 26 2025 - 16:33:30 EST
Add simple excercises to test the scatterlist bindings.
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@xxxxxxxxx>
---
samples/rust/rust_dma.rs | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs
index 874c2c964afa..c4d44e5a45b8 100644
--- a/samples/rust/rust_dma.rs
+++ b/samples/rust/rust_dma.rs
@@ -4,11 +4,15 @@
//!
//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
-use kernel::{bindings, device::Core, dma::CoherentAllocation, pci, prelude::*, types::ARef};
+use kernel::{
+ bindings, device::Core, dma::CoherentAllocation, page::*, pci, prelude::*, scatterlist::*,
+ types::ARef,
+};
struct DmaSampleDriver {
pdev: ARef<pci::Device>,
ca: CoherentAllocation<MyStruct>,
+ sgt: DeviceSGTable<PagesArray>,
}
const TEST_VALUES: [(u32, u32); 5] = [
@@ -34,6 +38,18 @@ unsafe impl kernel::transmute::AsBytes for MyStruct {}
// SAFETY: Instances of `MyStruct` have no uninitialized portions.
unsafe impl kernel::transmute::FromBytes for MyStruct {}
+struct PagesArray(KVec<Page>);
+
+impl SGTablePages for PagesArray {
+ fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a Page, usize, usize)> {
+ self.0.iter().map(|page| (page, kernel::page::PAGE_SIZE, 0))
+ }
+
+ fn entries(&self) -> usize {
+ self.0.len()
+ }
+}
+
kernel::pci_device_table!(
PCI_TABLE,
MODULE_PCI_TABLE,
@@ -62,10 +78,20 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self
Ok(())
}()?;
+ let mut pages = KVec::new();
+ for _ in TEST_VALUES.into_iter() {
+ let _ = pages.push(Page::alloc_page(GFP_KERNEL)?, GFP_KERNEL);
+ }
+
+ let sgt = SGTable::alloc_table(PagesArray(pages), GFP_KERNEL)?;
+ let sgt = sgt.dma_map(pdev.as_ref(), kernel::dma::DmaDataDirection::DmaToDevice)?;
+
let drvdata = KBox::new(
Self {
pdev: pdev.into(),
ca,
+ // Save object to excercise the destructor.
+ sgt,
},
GFP_KERNEL,
)?;
@@ -77,6 +103,7 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self
impl Drop for DmaSampleDriver {
fn drop(&mut self) {
dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n");
+ assert_eq!(self.sgt.iter().count(), TEST_VALUES.len());
let _ = || -> Result {
for (i, value) in TEST_VALUES.into_iter().enumerate() {
--
2.43.0