summaryrefslogtreecommitdiff
path: root/samples/rust/rust_driver_pci.rs
diff options
context:
space:
mode:
Diffstat (limited to 'samples/rust/rust_driver_pci.rs')
-rw-r--r--samples/rust/rust_driver_pci.rs35
1 files changed, 22 insertions, 13 deletions
diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs
index 2bb260aebc9e..606946ff4d7f 100644
--- a/samples/rust/rust_driver_pci.rs
+++ b/samples/rust/rust_driver_pci.rs
@@ -18,16 +18,19 @@ impl Regs {
type Bar0 = pci::Bar<{ Regs::END }>;
-#[derive(Debug)]
+#[derive(Copy, Clone, Debug)]
struct TestIndex(u8);
impl TestIndex {
const NO_EVENTFD: Self = Self(0);
}
+#[pin_data(PinnedDrop)]
struct SampleDriver {
pdev: ARef<pci::Device>,
+ #[pin]
bar: Devres<Bar0>,
+ index: TestIndex,
}
kernel::pci_device_table!(
@@ -73,30 +76,36 @@ impl pci::Driver for SampleDriver {
pdev.enable_device_mem()?;
pdev.set_master();
- let bar = pdev.iomap_region_sized::<{ Regs::END }>(0, c_str!("rust_driver_pci"))?;
-
- let drvdata = KBox::new(
- Self {
+ let drvdata = KBox::pin_init(
+ try_pin_init!(Self {
pdev: pdev.into(),
- bar,
- },
+ bar <- pdev.iomap_region_sized::<{ Regs::END }>(0, c_str!("rust_driver_pci")),
+ index: *info,
+ }),
GFP_KERNEL,
)?;
- let bar = drvdata.bar.try_access().ok_or(ENXIO)?;
-
+ let bar = drvdata.bar.access(pdev.as_ref())?;
dev_info!(
pdev.as_ref(),
"pci-testdev data-match count: {}\n",
- Self::testdev(info, &bar)?
+ Self::testdev(info, bar)?
);
- Ok(drvdata.into())
+ Ok(drvdata)
+ }
+
+ fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
+ if let Ok(bar) = this.bar.access(pdev.as_ref()) {
+ // Reset pci-testdev by writing a new test index.
+ bar.write8(this.index.0, Regs::TEST);
+ }
}
}
-impl Drop for SampleDriver {
- fn drop(&mut self) {
+#[pinned_drop]
+impl PinnedDrop for SampleDriver {
+ fn drop(self: Pin<&mut Self>) {
dev_dbg!(self.pdev.as_ref(), "Remove Rust PCI driver sample.\n");
}
}