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.rs30
1 files changed, 20 insertions, 10 deletions
diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs
index 15147e4401b2..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,13 +76,12 @@ 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,
)?;
@@ -90,12 +92,20 @@ impl pci::Driver for SampleDriver {
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");
}
}