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

Reply via email to