On Sat, 2013-04-20 at 02:49 -0700, Jeff Kirsher wrote: > From: Alexander Duyck <alexander.h.duyck@xxxxxxxxx> > > This function is meant to add a helper function that will determine if a PF > has any VFs that are currently assigned to a guest. We currently have been > implementing this function per driver, and going forward I would like to avoid > that by making this function generic and using this helper. > > Signed-off-by: Alexander Duyck <alexander.h.duyck@xxxxxxxxx> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@xxxxxxxxx> Adding linux-pci mailing list and Bjorn to the CC. Bjorn- David Miller needs a signoff by PCI maintainer. > --- > drivers/pci/iov.c | 41 +++++++++++++++++++++++++++++++++++++++++ > include/linux/pci.h | 5 +++++ > 2 files changed, 46 insertions(+) > > diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c > index ee599f2..fd99720 100644 > --- a/drivers/pci/iov.c > +++ b/drivers/pci/iov.c > @@ -729,6 +729,47 @@ int pci_num_vf(struct pci_dev *dev) > EXPORT_SYMBOL_GPL(pci_num_vf); > > /** > + * pci_vfs_assigned - returns number of VFs are assigned to a guest > + * @dev: the PCI device > + * > + * Returns number of VFs belonging to this device that are assigned to a guest. > + * If device is not a physical function returns -ENODEV. > + */ > +int pci_vfs_assigned(struct pci_dev *dev) > +{ > + struct pci_dev *vfdev; > + unsigned int vfs_assigned = 0; > + unsigned short dev_id; > + > + /* only search if we are a PF */ > + if (!dev->is_physfn) > + return -ENODEV; > + > + /* > + * determine the device ID for the VFs, the vendor ID will be the > + * same as the PF so there is no need to check for that one > + */ > + pci_read_config_word(dev, dev->sriov->pos + PCI_SRIOV_VF_DID, &dev_id); > + > + /* loop through all the VFs to see if we own any that are assigned */ > + vfdev = pci_get_device(dev->vendor, dev_id, NULL); > + while (vfdev) { > + /* > + * It is considered assigned if it is a virtual function with > + * our dev as the physical function and the assigned bit is set > + */ > + if (vfdev->is_virtfn && (vfdev->physfn == dev) && > + (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)) > + vfs_assigned++; > + > + vfdev = pci_get_device(dev->vendor, dev_id, vfdev); > + } > + > + return vfs_assigned; > +} > +EXPORT_SYMBOL_GPL(pci_vfs_assigned); > + > +/** > * pci_sriov_set_totalvfs -- reduce the TotalVFs available > * @dev: the PCI PF device > * @numvfs: number that should be used for TotalVFs supported > diff --git a/include/linux/pci.h b/include/linux/pci.h > index 2461033a..03b4d3c 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -1643,6 +1643,7 @@ extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); > extern void pci_disable_sriov(struct pci_dev *dev); > extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); > extern int pci_num_vf(struct pci_dev *dev); > +extern int pci_vfs_assigned(struct pci_dev *dev); > extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); > extern int pci_sriov_get_totalvfs(struct pci_dev *dev); > #else > @@ -1661,6 +1662,10 @@ static inline int pci_num_vf(struct pci_dev *dev) > { > return 0; > } > +static inline int pci_vfs_assigned(struct pci_dev *dev) > +{ > + return 0; > +} > static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) > { > return 0;
Attachment:
signature.asc
Description: This is a digitally signed message part