Commit 6ee86cac authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/virtualization'

  - Skip VF scanning on powerpc, which does this in firmware (Sebastian
    Ott)

* pci/virtualization:
  s390/pci: skip VF scanning
  PCI/IOV: Add flag so platforms can skip VF scanning
  PCI/IOV: Factor out sriov_add_vfs()
parents 54aed190 7dc20ab1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -651,6 +651,9 @@ int pcibios_add_device(struct pci_dev *pdev)
	struct resource *res;
	int i;

	if (pdev->is_physfn)
		pdev->no_vf_scan = 1;

	pdev->dev.groups = zpci_attr_groups;
	pdev->dev.dma_ops = &s390_pci_dma_ops;
	zpci_map_resources(pdev);
+36 −12
Original line number Diff line number Diff line
@@ -252,6 +252,27 @@ 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;

	if (dev->no_vf_scan)
		return 0;

	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 +358,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);
	rc = sriov_add_vfs(dev, initial);
	if (rc)
			goto failed;
	}
		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 +383,26 @@ err_pcibios:
	return rc;
}

static void sriov_disable(struct pci_dev *dev)
static void sriov_del_vfs(struct pci_dev *dev)
{
	int i;
	struct pci_sriov *iov = dev->sriov;
	int i;

	if (!iov->num_VFs)
	if (dev->no_vf_scan)
		return;

	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;

	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);
+1 −0
Original line number Diff line number Diff line
@@ -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 */