From 18f9e9d150fccfa747875df6f0a9f606740762b3 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 21 Dec 2018 15:14:18 +0100 Subject: PCI/IOV: Factor out sriov_add_vfs() Provide sriov_add_vfs() as a wrapper to scan for VFs that cleans up after itself. This is just a code simplification. No functional change. Signed-off-by: Sebastian Ott Signed-off-by: Bjorn Helgaas Reviewed-by: Christoph Hellwig --- drivers/pci/iov.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 9616eca3182f..408db232a328 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -252,6 +252,24 @@ int __weak pcibios_sriov_disable(struct pci_dev *pdev) return 0; } +static int 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; +} + static int sriov_enable(struct pci_dev *dev, int nr_virtfn) { int rc; @@ -337,21 +355,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 = 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); @@ -368,17 +380,23 @@ err_pcibios: return rc; } -static void sriov_disable(struct pci_dev *dev) +static void 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 void sriov_disable(struct pci_dev *dev) +{ 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); - + sriov_del_vfs(dev); iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); pci_cfg_access_lock(dev); pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); -- cgit v1.2.3 From aff68a5a621e2569d126b817d0d42f658df524bf Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 21 Dec 2018 15:14:19 +0100 Subject: PCI/IOV: Add flag so platforms can skip VF scanning Provide a flag to skip scanning for new VFs after SR-IOV enablement. This can be set by implementations for which the VFs are already reported by other means. Signed-off-by: Sebastian Ott Signed-off-by: Bjorn Helgaas Reviewed-by: Christoph Hellwig --- drivers/pci/iov.c | 6 ++++++ include/linux/pci.h | 1 + 2 files changed, 7 insertions(+) (limited to 'drivers/pci') diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 408db232a328..3aa115ed3a65 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -257,6 +257,9 @@ static int sriov_add_vfs(struct pci_dev *dev, u16 num_vfs) unsigned int i; int rc; + if (dev->no_vf_scan) + return 0; + for (i = 0; i < num_vfs; i++) { rc = pci_iov_add_virtfn(dev, i); if (rc) @@ -385,6 +388,9 @@ static void sriov_del_vfs(struct pci_dev *dev) struct pci_sriov *iov = dev->sriov; int i; + if (dev->no_vf_scan) + return; + for (i = 0; i < iov->num_VFs; i++) pci_iov_remove_virtfn(dev, i); } diff --git a/include/linux/pci.h b/include/linux/pci.h index 11c71c4ecf75..f9bc7651c406 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -405,6 +405,7 @@ struct pci_dev { unsigned int non_compliant_bars:1; /* Broken BARs; ignore them */ unsigned int is_probed:1; /* Device probing in progress */ unsigned int link_active_reporting:1;/* Device capable of reporting link active */ + unsigned int no_vf_scan:1; /* Don't scan for VFs after IOV enablement */ pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ -- cgit v1.2.3