VFIO PCI variant drivers will use bind() to register their VFIO devices after PCI driver data is installed.
Adding bind() to pci::Driver lets VFIO variants reuse the PCI adapter's probe and remove paths. A following patch removes the duplicate vfio::pci::Adapter. Suggested-by: Zhi Wang <[email protected]> Signed-off-by: Simon Song <[email protected]> --- rust/kernel/pci.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs index adc7e92d44e..1951b3c8a5c 100644 --- a/rust/kernel/pci.rs +++ b/rust/kernel/pci.rs @@ -154,6 +154,13 @@ extern "C" fn probe_callback( let data = T::probe(pdev, info); pdev.as_ref().set_drvdata(data)?; + // SAFETY: `set_drvdata` installed the pinned `T::Data` above. + let data = unsafe { pdev.as_ref().drvdata_borrow::<T::Data<'_>>() }; + if let Err(error) = T::bind(pdev, data) { + // SAFETY: Failed bind leaves no callbacks borrowing the installed data. + drop(unsafe { pdev.as_ref().drvdata_obtain::<T::Data<'_>>() }); + return Err(error); + } Ok(0) }) } @@ -416,6 +423,15 @@ fn probe<'bound>( id_info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound; + /// Complete probe after the pinned driver data has been installed. + /// + /// Called with the PCI device lock held. On error, the data is dropped without calling + /// [`Self::unbind`]. Any callbacks started here must be stopped before returning an error. + fn bind<'bound>(dev: &Device<device::Core<'_>>, this: Pin<&Self::Data<'bound>>) -> Result { + let _ = (dev, this); + Ok(()) + } + /// PCI driver unbind. /// /// Called when a [`Device`] is unbound from its bound [`Driver`]. Implementing this callback -- 2.43.7
