|
@@ -136,6 +136,122 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_PCI_IOV
|
|
|
+static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
|
|
|
+ struct pci_dev *pdev,
|
|
|
+ int busno, int devfn)
|
|
|
+{
|
|
|
+ struct pci_dn *pdn;
|
|
|
+
|
|
|
+ /* Except PHB, we always have the parent */
|
|
|
+ if (!parent)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
|
|
|
+ if (!pdn) {
|
|
|
+ dev_warn(&pdev->dev, "%s: Out of memory!\n", __func__);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ pdn->phb = parent->phb;
|
|
|
+ pdn->parent = parent;
|
|
|
+ pdn->busno = busno;
|
|
|
+ pdn->devfn = devfn;
|
|
|
+#ifdef CONFIG_PPC_POWERNV
|
|
|
+ pdn->pe_number = IODA_INVALID_PE;
|
|
|
+#endif
|
|
|
+ INIT_LIST_HEAD(&pdn->child_list);
|
|
|
+ INIT_LIST_HEAD(&pdn->list);
|
|
|
+ list_add_tail(&pdn->list, &parent->child_list);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we already have PCI device instance, lets
|
|
|
+ * bind them.
|
|
|
+ */
|
|
|
+ if (pdev)
|
|
|
+ pdev->dev.archdata.pci_data = pdn;
|
|
|
+
|
|
|
+ return pdn;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
|
|
|
+{
|
|
|
+#ifdef CONFIG_PCI_IOV
|
|
|
+ struct pci_dn *parent, *pdn;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Only support IOV for now */
|
|
|
+ if (!pdev->is_physfn)
|
|
|
+ return pci_get_pdn(pdev);
|
|
|
+
|
|
|
+ /* Check if VFs have been populated */
|
|
|
+ pdn = pci_get_pdn(pdev);
|
|
|
+ if (!pdn || (pdn->flags & PCI_DN_FLAG_IOV_VF))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ pdn->flags |= PCI_DN_FLAG_IOV_VF;
|
|
|
+ parent = pci_bus_to_pdn(pdev->bus);
|
|
|
+ if (!parent)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
|
|
|
+ pdn = add_one_dev_pci_data(parent, NULL,
|
|
|
+ pci_iov_virtfn_bus(pdev, i),
|
|
|
+ pci_iov_virtfn_devfn(pdev, i));
|
|
|
+ if (!pdn) {
|
|
|
+ dev_warn(&pdev->dev, "%s: Cannot create firmware data for VF#%d\n",
|
|
|
+ __func__, i);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif /* CONFIG_PCI_IOV */
|
|
|
+
|
|
|
+ return pci_get_pdn(pdev);
|
|
|
+}
|
|
|
+
|
|
|
+void remove_dev_pci_data(struct pci_dev *pdev)
|
|
|
+{
|
|
|
+#ifdef CONFIG_PCI_IOV
|
|
|
+ struct pci_dn *parent;
|
|
|
+ struct pci_dn *pdn, *tmp;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Only support IOV PF for now */
|
|
|
+ if (!pdev->is_physfn)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* Check if VFs have been populated */
|
|
|
+ pdn = pci_get_pdn(pdev);
|
|
|
+ if (!pdn || !(pdn->flags & PCI_DN_FLAG_IOV_VF))
|
|
|
+ return;
|
|
|
+
|
|
|
+ pdn->flags &= ~PCI_DN_FLAG_IOV_VF;
|
|
|
+ parent = pci_bus_to_pdn(pdev->bus);
|
|
|
+ if (!parent)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We might introduce flag to pci_dn in future
|
|
|
+ * so that we can release VF's firmware data in
|
|
|
+ * a batch mode.
|
|
|
+ */
|
|
|
+ for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
|
|
|
+ list_for_each_entry_safe(pdn, tmp,
|
|
|
+ &parent->child_list, list) {
|
|
|
+ if (pdn->busno != pci_iov_virtfn_bus(pdev, i) ||
|
|
|
+ pdn->devfn != pci_iov_virtfn_devfn(pdev, i))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (!list_empty(&pdn->list))
|
|
|
+ list_del(&pdn->list);
|
|
|
+
|
|
|
+ kfree(pdn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif /* CONFIG_PCI_IOV */
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Traverse_func that inits the PCI fields of the device node.
|
|
|
* NOTE: this *must* be done before read/write config to the device.
|