diff options
-rw-r--r-- | drivers/pci/iov.c | 47 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 4 | ||||
-rw-r--r-- | drivers/pci/pci.h | 1 | ||||
-rw-r--r-- | include/linux/pci.h | 10 |
4 files changed, 60 insertions, 2 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index aeccc911abb8..f6781e42d00d 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -735,3 +735,50 @@ int pci_num_vf(struct pci_dev *dev) | |||
735 | return dev->sriov->nr_virtfn; | 735 | return dev->sriov->nr_virtfn; |
736 | } | 736 | } |
737 | EXPORT_SYMBOL_GPL(pci_num_vf); | 737 | EXPORT_SYMBOL_GPL(pci_num_vf); |
738 | |||
739 | /** | ||
740 | * pci_sriov_set_totalvfs -- reduce the TotalVFs available | ||
741 | * @dev: the PCI PF device | ||
742 | * numvfs: number that should be used for TotalVFs supported | ||
743 | * | ||
744 | * Should be called from PF driver's probe routine with | ||
745 | * device's mutex held. | ||
746 | * | ||
747 | * Returns 0 if PF is an SRIOV-capable device and | ||
748 | * value of numvfs valid. If not a PF with VFS, return -EINVAL; | ||
749 | * if VFs already enabled, return -EBUSY. | ||
750 | */ | ||
751 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) | ||
752 | { | ||
753 | if (!dev || !dev->is_physfn || (numvfs > dev->sriov->total)) | ||
754 | return -EINVAL; | ||
755 | |||
756 | /* Shouldn't change if VFs already enabled */ | ||
757 | if (dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE) | ||
758 | return -EBUSY; | ||
759 | else | ||
760 | dev->sriov->drvttl = numvfs; | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs); | ||
765 | |||
766 | /** | ||
767 | * pci_sriov_get_totalvfs -- get total VFs supported on this devic3 | ||
768 | * @dev: the PCI PF device | ||
769 | * | ||
770 | * For a PCIe device with SRIOV support, return the PCIe | ||
771 | * SRIOV capability value of TotalVFs or the value of drvttl | ||
772 | * if the driver reduced it. Otherwise, -EINVAL. | ||
773 | */ | ||
774 | int pci_sriov_get_totalvfs(struct pci_dev *dev) | ||
775 | { | ||
776 | if (!dev || !dev->is_physfn) | ||
777 | return -EINVAL; | ||
778 | |||
779 | if (dev->sriov->drvttl) | ||
780 | return dev->sriov->drvttl; | ||
781 | else | ||
782 | return dev->sriov->total; | ||
783 | } | ||
784 | EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs); | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 74508c63bd47..99b5f83d2468 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -411,7 +411,7 @@ static ssize_t sriov_totalvfs_show(struct device *dev, | |||
411 | { | 411 | { |
412 | struct pci_dev *pdev = to_pci_dev(dev); | 412 | struct pci_dev *pdev = to_pci_dev(dev); |
413 | 413 | ||
414 | return sprintf(buf, "%u\n", pdev->sriov->total); | 414 | return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev)); |
415 | } | 415 | } |
416 | 416 | ||
417 | 417 | ||
@@ -452,7 +452,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, | |||
452 | } | 452 | } |
453 | 453 | ||
454 | /* if enabling vf's ... */ | 454 | /* if enabling vf's ... */ |
455 | total = pdev->sriov->total; | 455 | total = pci_sriov_get_totalvfs(pdev); |
456 | /* Requested VFs to enable < totalvfs and none enabled already */ | 456 | /* Requested VFs to enable < totalvfs and none enabled already */ |
457 | if ((num_vfs > 0) && (num_vfs <= total)) { | 457 | if ((num_vfs > 0) && (num_vfs <= total)) { |
458 | if (pdev->sriov->nr_virtfn == 0) { | 458 | if (pdev->sriov->nr_virtfn == 0) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 6f6cd145bb7e..553bbba76eec 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -240,6 +240,7 @@ struct pci_sriov { | |||
240 | u16 stride; /* following VF stride */ | 240 | u16 stride; /* following VF stride */ |
241 | u32 pgsz; /* page size for BAR alignment */ | 241 | u32 pgsz; /* page size for BAR alignment */ |
242 | u8 link; /* Function Dependency Link */ | 242 | u8 link; /* Function Dependency Link */ |
243 | u16 drvttl; /* max num VFs driver supports */ | ||
243 | struct pci_dev *dev; /* lowest numbered PF */ | 244 | struct pci_dev *dev; /* lowest numbered PF */ |
244 | struct pci_dev *self; /* this PF */ | 245 | struct pci_dev *self; /* this PF */ |
245 | struct mutex lock; /* lock for VF bus */ | 246 | struct mutex lock; /* lock for VF bus */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7ef8fba319da..1ad824966e64 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1611,6 +1611,8 @@ extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn); | |||
1611 | extern void pci_disable_sriov(struct pci_dev *dev); | 1611 | extern void pci_disable_sriov(struct pci_dev *dev); |
1612 | extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); | 1612 | extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); |
1613 | extern int pci_num_vf(struct pci_dev *dev); | 1613 | extern int pci_num_vf(struct pci_dev *dev); |
1614 | extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs); | ||
1615 | extern int pci_sriov_get_totalvfs(struct pci_dev *dev); | ||
1614 | #else | 1616 | #else |
1615 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) | 1617 | static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) |
1616 | { | 1618 | { |
@@ -1627,6 +1629,14 @@ static inline int pci_num_vf(struct pci_dev *dev) | |||
1627 | { | 1629 | { |
1628 | return 0; | 1630 | return 0; |
1629 | } | 1631 | } |
1632 | static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) | ||
1633 | { | ||
1634 | return 0; | ||
1635 | } | ||
1636 | static inline int pci_sriov_get_totalvfs(struct pci_dev *dev) | ||
1637 | { | ||
1638 | return 0; | ||
1639 | } | ||
1630 | #endif | 1640 | #endif |
1631 | 1641 | ||
1632 | #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) | 1642 | #if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) |