Commit 8effc395 authored by Alexander Duyck's avatar Alexander Duyck Committed by Bjorn Helgaas

PCI/IOV: Add pci_sriov_configure_simple()

SR-IOV (Single Root I/O Virtualization) is an optional PCIe capability (see
PCIe r4.0, sec 9).  A PCIe Function with the SR-IOV capability is referred
to as a PF (Physical Function).  If SR-IOV is enabled on the PF, several
VFs (Virtual Functions) may be created.  The VFs can be individually
assigned to virtual machines, which allows them to share a single hardware
device while being isolated from each other.

Some SR-IOV devices have resources such as queues and interrupts that must
be set up in the PF before enabling the VFs, so they require a PF driver to
do that.

Other SR-IOV devices don't require any PF setup before enabling VFs.  Add a
pci_sriov_configure_simple() interface so PF drivers for such devices can
use it without repeating the VF-enabling code.
Tested-by: default avatarMark Rustad <mark.d.rustad@intel.com>
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
[bhelgaas: changelog, comment]
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarGreg Rose <gvrose8192@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>:wq
parent 60cc43fc
...@@ -833,3 +833,39 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev) ...@@ -833,3 +833,39 @@ int pci_sriov_get_totalvfs(struct pci_dev *dev)
return dev->sriov->total_VFs; return dev->sriov->total_VFs;
} }
EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs); EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs);
/**
* pci_sriov_configure_simple - helper to configure SR-IOV
* @dev: the PCI device
* @nr_virtfn: number of virtual functions to enable, 0 to disable
*
* Enable or disable SR-IOV for devices that don't require any PF setup
* before enabling SR-IOV. Return value is negative on error, or number of
* VFs allocated on success.
*/
int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn)
{
int rc;
might_sleep();
if (!dev->is_physfn)
return -ENODEV;
if (pci_vfs_assigned(dev)) {
pci_warn(dev, "Cannot modify SR-IOV while VFs are assigned\n");
return -EPERM;
}
if (nr_virtfn == 0) {
sriov_disable(dev);
return 0;
}
rc = sriov_enable(dev, nr_virtfn);
if (rc < 0)
return rc;
return nr_virtfn;
}
EXPORT_SYMBOL_GPL(pci_sriov_configure_simple);
...@@ -1954,6 +1954,7 @@ int pci_num_vf(struct pci_dev *dev); ...@@ -1954,6 +1954,7 @@ int pci_num_vf(struct pci_dev *dev);
int pci_vfs_assigned(struct pci_dev *dev); int pci_vfs_assigned(struct pci_dev *dev);
int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
int pci_sriov_get_totalvfs(struct pci_dev *dev); int pci_sriov_get_totalvfs(struct pci_dev *dev);
int pci_sriov_configure_simple(struct pci_dev *dev, int nr_virtfn);
resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno); resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno);
void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe); void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe);
...@@ -1986,6 +1987,7 @@ static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) ...@@ -1986,6 +1987,7 @@ static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
{ return 0; } { return 0; }
static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
{ return 0; } { return 0; }
#define pci_sriov_configure_simple NULL
static inline resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno) static inline resource_size_t pci_iov_resource_size(struct pci_dev *dev, int resno)
{ return 0; } { return 0; }
static inline void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe) { } static inline void pci_vf_drivers_autoprobe(struct pci_dev *dev, bool probe) { }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment