As cleanup hook of all supported capabilities will be implemented in
follow-on changes, so to pre-call hook in vpci_deassign_device(), and
the capability specific clean open-code in there will be removed by
follow-on corresponding capability changes.

Since vpci_deassign_device() and vpci_init_capabilities() require
different cleanup actions, add a boolean parameter to cleanup hook
to distinguish them.

Signed-off-by: Jiqian Chen <jiqian.c...@amd.com>
---
cc: "Roger Pau Monné" <roger....@citrix.com>
---
v10->v11 changes:
new patch.
---
 xen/drivers/vpci/vpci.c | 25 ++++++++++++++++++++++++-
 xen/include/xen/vpci.h  |  2 +-
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index fd02718b47ea..120a919f08e3 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -280,7 +280,7 @@ static int vpci_init_capabilities(struct pci_dev *pdev)
 
             if ( capability->cleanup )
             {
-                rc = capability->cleanup(pdev);
+                rc = capability->cleanup(pdev, true);
                 if ( rc )
                 {
                     printk(XENLOG_ERR "%pd %pp: clean %s cap %u fail rc=%d\n",
@@ -321,6 +321,29 @@ void vpci_deassign_device(struct pci_dev *pdev)
                     &pdev->domain->vpci_dev_assigned_map);
 #endif
 
+    for ( i = 0; i < NUM_VPCI_INIT; i++ )
+    {
+        const vpci_capability_t *capability = &__start_vpci_array[i];
+        const unsigned int cap = capability->id;
+        unsigned int pos = 0;
+
+        if ( !capability->cleanup )
+            continue;
+
+        if ( !capability->is_ext )
+            pos = pci_find_cap_offset(pdev->sbdf, cap);
+        else if ( is_hardware_domain(pdev->domain) )
+            pos = pci_find_ext_capability(pdev->sbdf, cap);
+        if ( pos )
+        {
+            int rc = capability->cleanup(pdev, false);
+            if ( rc )
+                printk(XENLOG_ERR "%pd %pp: clean %s cap %u fail rc=%d\n",
+                       pdev->domain, &pdev->sbdf,
+                       capability->is_ext ? "extended" : "legacy", cap, rc);
+        }
+    }
+
     spin_lock(&pdev->vpci->lock);
     while ( !list_empty(&pdev->vpci->handlers) )
     {
diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
index 17cfecb0aabf..4b7b9298c4e8 100644
--- a/xen/include/xen/vpci.h
+++ b/xen/include/xen/vpci.h
@@ -17,7 +17,7 @@ typedef struct {
     unsigned int id;
     bool is_ext;
     int (* init)(struct pci_dev *pdev);
-    int (* cleanup)(const struct pci_dev *pdev);
+    int (* cleanup)(const struct pci_dev *pdev, bool hide);
 } vpci_capability_t;
 
 #define VPCI_ECAM_BDF(addr)     (((addr) & 0x0ffff000) >> 12)
-- 
2.34.1


Reply via email to