To help debugging, add a kernel parameter, pci=sriov=[0|1], which enables or disables SRIOV. Signed-off-by: Prarit Bhargava <prarit@xxxxxxxxxx> Cc: ddutile@xxxxxxxxxx Cc: bhelgaas@xxxxxxxxxx --- Documentation/kernel-parameters.txt | 3 +++ drivers/pci/iov.c | 31 ++++++++++++++++++++++++++++++- drivers/pci/pci.c | 2 ++ drivers/pci/pci.h | 3 +++ 4 files changed, 38 insertions(+), 1 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 854ed5c..7ad2d32 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2032,6 +2032,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. on: Turn ECRC on. realloc reallocate PCI resources if allocations done by BIOS are erroneous. + sriov= [HW] + Format: [0|1] + Enable or disable SRIOV support in kernel. pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 42fae47..4a861df 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -408,6 +408,20 @@ static void sriov_disable(struct pci_dev *dev) iov->nr_virtfn = 0; } +unsigned int pci_sriov_enabled = 1; + +static int __init do_sriov_enable(char *str) +{ + get_option(&str, &pci_sriov_enabled); + if (!pci_sriov_enabled) + printk(KERN_INFO "SRIOV: Disabled\n"); + else + printk(KERN_INFO "SRIOV: Enabled\n"); + + return 1; +} +__setup("sriov=", do_sriov_enable); + static int sriov_init(struct pci_dev *dev, int pos) { int i; @@ -419,6 +433,12 @@ static int sriov_init(struct pci_dev *dev, int pos) struct resource *res; struct pci_dev *pdev; + if (!pci_sriov_enabled) { + rc = -EPERM; + /* in theory no flags should have been set ... */ + goto failed; + } + if (dev->pcie_type != PCI_EXP_TYPE_RC_END && dev->pcie_type != PCI_EXP_TYPE_ENDPOINT) return -ENODEV; @@ -614,7 +634,10 @@ resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno) struct resource tmp; enum pci_bar_type type; int reg = pci_iov_resource_bar(dev, resno, &type); - + + if (!pci_sriov_enabled) + return 0; + if (!reg) return 0; @@ -667,6 +690,9 @@ int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) { might_sleep(); + if (!pci_sriov_enabled) + return -EPERM; + if (!dev->is_physfn) return -ENODEV; @@ -682,6 +708,9 @@ void pci_disable_sriov(struct pci_dev *dev) { might_sleep(); + if (!pci_sriov_enabled) + return; + if (!dev->is_physfn) return; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e9651f0..c6f1d2f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3576,6 +3576,8 @@ static int __init pci_setup(char *str) pcie_bus_config = PCIE_BUS_PERFORMANCE; } else if (!strncmp(str, "pcie_bus_peer2peer", 18)) { pcie_bus_config = PCIE_BUS_PEER2PEER; + } else if (!strncmp(str, "sriov=", 6)) { + pci_sriov_enabled = memparse(str + 7, &str); } else { printk(KERN_ERR "PCI: Unknown option `%s'\n", str); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index b74084e..33f5fce 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -229,6 +229,9 @@ resource_size_t pci_specified_resource_alignment(struct pci_dev *dev); extern void pci_disable_bridge_window(struct pci_dev *dev); #endif +/* Use "pci=sriov=[0|1]" to enable or disable SRIOV */ +extern unsigned int pci_sriov_enabled; + /* Single Root I/O Virtualization */ struct pci_sriov { int pos; /* capability position */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html