[PATCH 1/1 v2]PCI: defer enablement of SRIOV BARS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



    	PCI: defer enablement of SRIOV BARS

    All the PCI BARs of a device are enabled when the device is enabled using
    pci_enable_device().  This unnecessarily enables SRIOV BARs of the device.

    On some platforms, which do not support SRIOV; as yet, the pci_enable_device()
    fails to enable the device if its SRIOV BARs are not allocated resources
    correctly.

    The following patch fixes the above problem. The SRIOV BARs are now enabled
    when IOV capability of the device is enabled in sriov_enable().

    NOTE: Note, there is subtle change in the pci_enable_device() API.  Any driver
    that depends on SRIOV BARS to be enabled in pci_enable_device() can fail.

    Changelog v2: Fixed a bug reported by Yinghai.The bug lead to ROM and
	BRIDGE BARs getting disabled.  Thanks for code snippets from Yinghai
	and Don Dutile.

   Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx

diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 9b4e88c..b0446dd 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -282,6 +282,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 	struct resource *res;
 	struct pci_dev *pdev;
 	struct pci_sriov *iov = dev->sriov;
+	int bars = 0;
 
 	if (!nr_virtfn)
 		return 0;
@@ -306,6 +307,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 
 	nres = 0;
 	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+		bars |= (1 << (i + PCI_IOV_RESOURCES));
 		res = dev->resource + PCI_IOV_RESOURCES + i;
 		if (res->parent)
 			nres++;
@@ -323,6 +325,11 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 		return -ENOMEM;
 	}
 
+	if (pci_enable_resources(dev, bars)) {
+		dev_err(&dev->dev, "SR-IOV: IOV BARS not allocated\n");
+		return -ENOMEM;
+	}
+
 	if (iov->link != dev->devfn) {
 		pdev = pci_get_slot(dev->bus, iov->link);
 		if (!pdev)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6f45a73..b548bec 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1126,9 +1126,14 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
 	if (atomic_add_return(1, &dev->enable_cnt) > 1)
 		return 0;		/* already enabled */
 
-	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+#ifdef CONFIG_PCI_IOV
+		if ((i >=  PCI_IOV_RESOURCES) && (i <= PCI_IOV_RESOURCE_END))
+			continue; /* skip sriov related resources */
+#endif
 		if (dev->resource[i].flags & flags)
 			bars |= (1 << i);
+	}
 
 	err = do_pci_enable_device(dev, bars);
 	if (err < 0)

--
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


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux