[PATCH v2 0/4] rust: samples: add an EDU PCI driver sample (MMIO + IRQ + DMA)

From: Maurice Hieronymus

Date: Sat Jun 20 2026 - 04:46:39 EST


The Rust sample drivers currently exercise PCI facilities in isolation:
rust_driver_pci covers MMIO and rust_dma covers DMA, but there is no
single in-tree example that combines memory-mapped I/O, interrupts and
DMA in one driver.

This series adds one. It targets QEMU's `edu` device -- a small,
well-documented educational PCI device that supports exactly these three
facilities and ships with any recent QEMU (`-device edu`), so the sample
runs without special hardware.

The sample maps BAR0 and runs a set of MMIO self-tests (identification,
liveness, factorial), allocates an MSI vector and registers an IRQ
handler, and performs a DMA round-trip -- each stage waiting on a
Completion that the IRQ handler signals.

Prerequisites, that had to be implemented:

- pci: make Vendor::from_raw() public, so a driver can match a device
whose vendor ID has no symbolic name in pci_ids.h (QEMU's 0x1234),
matching what C drivers already do.
- pci: add a managed enable_device() wrapping pcim_enable_device(), so
the enable count stays balanced across unbind/rebind.
- completion: add complete(), so a single Completion can be reused to
wait for consecutive events (e.g. back-to-back DMA transfers).

Tested with QEMU `-device edu`;

Signed-off-by: Maurice Hieronymus <mhi@xxxxxxxxxxx>
---
Changes in v2:
- pci: Vendor::from_raw(): collected Reviewed-by from Gary Guo;
wrapped code identifiers in the commit message in backticks (Gary).
- pci: enable_device(): collected Reviewed-by from Fiona Behrens;
made enable_device_mem() #[inline] and added a cross-reference to
enable_device() in its docs (Fiona).
- completion: complete(): tightened the doc comment per Gary's review
(emphasise "single", drop the internal-counter detail, drop the
complete_all comparison).
- samples/edu: take &EduDriverData instead of &Arc<EduDriverData> in
init()/test_irq()/test_dma() (Ewan Chorynski).
- samples/edu: simplify wait_until_compute_has_finished() to forward
read_poll_timeout()'s error via inspect_err() instead of returning a
hard-coded ETIMEDOUT (Ewan Chorynski / Miguel Ojeda).
- samples/edu: Rebased on rust/rust-next and adapt to the updated
pci::Bar / device::Core lifetimes and pci::Driver::Data<'bound>, and
obtain the BAR via into_devres().
- Link to v1: https://lore.kernel.org/r/20260614-b4-rust-pci-edu-driver-v1-0-e3f2471b595c@xxxxxxxxxxx

---
Maurice Hieronymus (4):
rust: pci: make Vendor::from_raw() public
rust: pci: add managed Device::enable_device()
rust: completion: add complete()
rust: samples: add EDU PCI driver sample

rust/kernel/pci.rs | 16 ++
rust/kernel/pci/id.rs | 2 +-
rust/kernel/sync/completion.rs | 11 ++
samples/rust/Kconfig | 11 ++
samples/rust/Makefile | 1 +
samples/rust/rust_driver_edu.rs | 378 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 418 insertions(+), 1 deletion(-)
---
base-commit: 43a393185e33e573a374c1d4f7ddf6481484ef8d
change-id: 20260614-b4-rust-pci-edu-driver-3e50db2dda0f

Best regards,
--
Maurice Hieronymus <mhi@xxxxxxxxxxx>