aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/iov.c31
-rw-r--r--drivers/pci/pci.h1
2 files changed, 28 insertions, 4 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index a8752c2c2b53..2ae921f84bd3 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -46,6 +46,30 @@ static inline void pci_iov_set_numvfs(struct pci_dev *dev, int nr_virtfn)
46 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &iov->stride); 46 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &iov->stride);
47} 47}
48 48
49/*
50 * The PF consumes one bus number. NumVFs, First VF Offset, and VF Stride
51 * determine how many additional bus numbers will be consumed by VFs.
52 *
53 * Iterate over all valid NumVFs and calculate the maximum number of bus
54 * numbers that could ever be required.
55 */
56static inline u8 virtfn_max_buses(struct pci_dev *dev)
57{
58 struct pci_sriov *iov = dev->sriov;
59 int nr_virtfn;
60 u8 max = 0;
61 u8 busnr;
62
63 for (nr_virtfn = 1; nr_virtfn <= iov->total_VFs; nr_virtfn++) {
64 pci_iov_set_numvfs(dev, nr_virtfn);
65 busnr = virtfn_bus(dev, nr_virtfn - 1);
66 if (busnr > max)
67 max = busnr;
68 }
69
70 return max;
71}
72
49static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) 73static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
50{ 74{
51 struct pci_bus *child; 75 struct pci_bus *child;
@@ -427,6 +451,7 @@ found:
427 451
428 dev->sriov = iov; 452 dev->sriov = iov;
429 dev->is_physfn = 1; 453 dev->is_physfn = 1;
454 iov->max_VF_buses = virtfn_max_buses(dev);
430 455
431 return 0; 456 return 0;
432 457
@@ -556,15 +581,13 @@ void pci_restore_iov_state(struct pci_dev *dev)
556int pci_iov_bus_range(struct pci_bus *bus) 581int pci_iov_bus_range(struct pci_bus *bus)
557{ 582{
558 int max = 0; 583 int max = 0;
559 u8 busnr;
560 struct pci_dev *dev; 584 struct pci_dev *dev;
561 585
562 list_for_each_entry(dev, &bus->devices, bus_list) { 586 list_for_each_entry(dev, &bus->devices, bus_list) {
563 if (!dev->is_physfn) 587 if (!dev->is_physfn)
564 continue; 588 continue;
565 busnr = virtfn_bus(dev, dev->sriov->total_VFs - 1); 589 if (dev->sriov->max_VF_buses > max)
566 if (busnr > max) 590 max = dev->sriov->max_VF_buses;
567 max = busnr;
568 } 591 }
569 592
570 return max ? max - bus->number : 0; 593 return max ? max - bus->number : 0;
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 57329645dd01..bae593c04541 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -243,6 +243,7 @@ struct pci_sriov {
243 u16 stride; /* following VF stride */ 243 u16 stride; /* following VF stride */
244 u32 pgsz; /* page size for BAR alignment */ 244 u32 pgsz; /* page size for BAR alignment */
245 u8 link; /* Function Dependency Link */ 245 u8 link; /* Function Dependency Link */
246 u8 max_VF_buses; /* max buses consumed by VFs */
246 u16 driver_max_VFs; /* max num VFs driver supports */ 247 u16 driver_max_VFs; /* max num VFs driver supports */
247 struct pci_dev *dev; /* lowest numbered PF */ 248 struct pci_dev *dev; /* lowest numbered PF */
248 struct pci_dev *self; /* this PF */ 249 struct pci_dev *self; /* this PF */