`enable_device_mem()` wraps the unmanaged `pci_enable_device_mem()` and has no disable counterpart, so the enable count is leaked on driver unbind.
Replace it with: - `enable_device_managed()`, wrapping `pcim_enable_device()`, which registers a `pci_disable_device()` cleanup that runs on unbind; this is what drivers should normally call in `probe()`. - an unmanaged `enable_device()`/`disable_device()` pair, wrapping `pci_enable_device()`/`pci_disable_device()`, e.g. for runtime PM paths. Unlike `pci_enable_device_mem()`, both variants enable I/O and memory resources. Convert nova-core and the rust_driver_pci sample, the only users of `enable_device_mem()`, to `enable_device_managed()`; besides gaining the automatic cleanup they now also enables I/O resources. This is a prerequisite for the EDU PCI sample driver series [1], as requested by Danilo in its review [2]; that series will be rebased on top of this patch. Link: https://lore.kernel.org/r/[email protected] [1] Link: https://lore.kernel.org/rust-for-linux/[email protected]/ [2] Suggested-by: Danilo Krummrich <[email protected]> Signed-off-by: Maurice Hieronymus <[email protected]> --- Replace pci::Device::enable_device_mem() with a managed enable_device_managed() plus an unmanaged enable_device()/ disable_device() pair, and convert the two users (nova-core and the rust_driver_pci sample). Requested by Danilo [2] while reviewing the EDU PCI sample driver series [1]; that series will be rebased on top of this one. [1] https://lore.kernel.org/r/[email protected] [2] https://lore.kernel.org/rust-for-linux/[email protected] --- drivers/gpu/nova-core/driver.rs | 2 +- rust/kernel/pci.rs | 26 +++++++++++++++++++++++--- samples/rust/rust_driver_pci.rs | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/nova-core/driver.rs b/drivers/gpu/nova-core/driver.rs index 5738d4ac521b..b0711d98033b 100644 --- a/drivers/gpu/nova-core/driver.rs +++ b/drivers/gpu/nova-core/driver.rs @@ -75,7 +75,7 @@ fn probe<'bound>( pin_init::pin_init_scope(move || { dev_dbg!(pdev, "Probe Nova Core GPU driver.\n"); - pdev.enable_device_mem()?; + pdev.enable_device_managed()?; pdev.set_master(); Ok(try_pin_init!(NovaCore { diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index 5071cae6543f..a408b3412077 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -453,10 +453,30 @@ pub fn pci_class(&self) -> Class { } impl<'a> Device<device::Core<'a>> { - /// Enable memory resources for this device. - pub fn enable_device_mem(&self) -> Result { + /// Enable I/O and memory resources for this device. + /// + /// This function is unmanaged and does not perform any cleanup when the device is unbound. + /// For a managed function take a look at [`Device::enable_device_managed`]. + #[inline] + pub fn enable_device(&self) -> Result { + // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. + to_result(unsafe { bindings::pci_enable_device(self.as_raw()) }) + } + + /// Disable I/O and memory resources for this device. + /// + /// This function is the counterpart to [`Device::enable_device`]. + #[inline] + pub fn disable_device(&self) { + // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. + unsafe { bindings::pci_disable_device(self.as_raw()) } + } + + /// Enable I/O and memory resources for this device, with automatic cleanup. + #[inline] + pub fn enable_device_managed(&self) -> Result { // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. - to_result(unsafe { bindings::pci_enable_device_mem(self.as_raw()) }) + to_result(unsafe { bindings::pcim_enable_device(self.as_raw()) }) } /// Enable bus-mastering for this device. diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 1aa8197d8698..213ef14386ca 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -154,7 +154,7 @@ fn probe<'bound>( pdev.device_id() ); - pdev.enable_device_mem()?; + pdev.enable_device_managed()?; pdev.set_master(); let bar = pdev.iomap_region_sized::<{ regs::END }>(0, c"rust_driver_pci")?; --- base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482 change-id: 20260702-rust-pci-enable-device-managed-155eb5de8603 Best regards, -- Maurice Hieronymus <[email protected]>
