Move VF detection and device creation code to weak functions such that architectures can provide a different implementation. Signed-off-by: Sebastian Ott <sebott@xxxxxxxxxxxxx> --- drivers/pci/iov.c | 43 +++++++++++++++++++++++++++++++------------ include/linux/pci.h | 2 ++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9616eca3182f..1bfdb4deafd7 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -252,6 +252,33 @@ int __weak pcibios_sriov_disable(struct pci_dev *pdev) return 0; } +int __weak pcibios_sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) +{ + unsigned int i; + int rc; + + for (i = 0; i < num_vfs; i++) { + rc = pci_iov_add_virtfn(dev, i); + if (rc) + goto failed; + } + return 0; +failed: + while (i--) + pci_iov_remove_virtfn(dev, i); + + return rc; +} + +void __weak pcibios_sriov_del_vfs(struct pci_dev *dev) +{ + struct pci_sriov *iov = dev->sriov; + int i; + + for (i = 0; i < iov->num_VFs; i++) + pci_iov_remove_virtfn(dev, i); +} + static int sriov_enable(struct pci_dev *dev, int nr_virtfn) { int rc; @@ -337,21 +364,15 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) msleep(100); pci_cfg_access_unlock(dev); - for (i = 0; i < initial; i++) { - rc = pci_iov_add_virtfn(dev, i); - if (rc) - goto failed; - } + rc = pcibios_sriov_add_vfs(dev, initial); + if (rc) + goto err_pcibios; kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); iov->num_VFs = nr_virtfn; return 0; -failed: - while (i--) - pci_iov_remove_virtfn(dev, i); - err_pcibios: iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); pci_cfg_access_lock(dev); @@ -370,14 +391,12 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) static void sriov_disable(struct pci_dev *dev) { - int i; struct pci_sriov *iov = dev->sriov; if (!iov->num_VFs) return; - for (i = 0; i < iov->num_VFs; i++) - pci_iov_remove_virtfn(dev, i); + pcibios_sriov_del_vfs(dev); iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); pci_cfg_access_lock(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 11c71c4ecf75..84ca3bcdac76 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2001,6 +2001,8 @@ void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe); /* Arch may override these (weak) */ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs); int pcibios_sriov_disable(struct pci_dev *pdev); +int pcibios_sriov_add_vfs(struct pci_dev *dev, u16 num_vfs); +void pcibios_sriov_del_vfs(struct pci_dev *dev); resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno); #else static inline int pci_iov_virtfn_bus(struct pci_dev *dev, int id) -- 2.16.4