powerpc/eeh: EEH device for VF
authorWei Yang <weiyang@linux.vnet.ibm.com>
Thu, 3 Mar 2016 23:53:07 +0000 (10:53 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Tue, 8 Mar 2016 22:58:18 +0000 (09:58 +1100)
VFs and their corresponding pdn are created and released dynamically
when their PF's SRIOV capability is enabled and disabled. This creates
and releases EEH devices for VFs when creating and releasing their pdn
instances, which means EEH devices and pdn instances have same life
cycle. Also, VF's EEH device is identified by (struct eeh_dev::physfn).

Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>
Acked-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/include/asm/eeh.h
arch/powerpc/kernel/pci_dn.c

index 867c39b45df6ce4c1bd5a342ca314a888bb185bf..574ed49a4a0d38b59b4cb4a5dfeba1d0f0522107 100644 (file)
@@ -141,6 +141,7 @@ struct eeh_dev {
        struct pci_controller *phb;     /* Associated PHB               */
        struct pci_dn *pdn;             /* Associated PCI device node   */
        struct pci_dev *pdev;           /* Associated PCI device        */
+       struct pci_dev *physfn;         /* Associated SRIOV PF          */
        struct pci_bus *bus;            /* PCI bus for partial hotplug  */
 };
 
index b3b4df91b792cc59e533c7465b7543da37756de6..e23bdf786dab0f6bc654b8ed78d86b0a639e4baa 100644 (file)
@@ -179,6 +179,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
 {
 #ifdef CONFIG_PCI_IOV
        struct pci_dn *parent, *pdn;
+       struct eeh_dev *edev;
        int i;
 
        /* Only support IOV for now */
@@ -204,6 +205,12 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
                                 __func__, i);
                        return NULL;
                }
+
+               /* Create the EEH device for the VF */
+               eeh_dev_init(pdn, pci_bus_to_host(pdev->bus));
+               edev = pdn_to_eeh_dev(pdn);
+               BUG_ON(!edev);
+               edev->physfn = pdev;
        }
 #endif /* CONFIG_PCI_IOV */
 
@@ -215,6 +222,7 @@ void remove_dev_pci_data(struct pci_dev *pdev)
 #ifdef CONFIG_PCI_IOV
        struct pci_dn *parent;
        struct pci_dn *pdn, *tmp;
+       struct eeh_dev *edev;
        int i;
 
        /*
@@ -256,6 +264,13 @@ void remove_dev_pci_data(struct pci_dev *pdev)
                            pdn->devfn != pci_iov_virtfn_devfn(pdev, i))
                                continue;
 
+                       /* Release EEH device for the VF */
+                       edev = pdn_to_eeh_dev(pdn);
+                       if (edev) {
+                               pdn->edev = NULL;
+                               kfree(edev);
+                       }
+
                        if (!list_empty(&pdn->list))
                                list_del(&pdn->list);