[v3,2/2] PCI: assign bus numbers present in EA capability for bridges

Message ID 1548249481-24645-2-git-send-email-sundeep.lkml@gmail.com
State Not Applicable
Delegated to: Bjorn Helgaas
Headers show
Series
  • [v3,1/2] PCI: read fixed bus numbers in EA for type 1 functions
Related show

Commit Message

sundeep subbaraya Jan. 23, 2019, 1:18 p.m.
From: Subbaraya Sundeep <sbhatta@marvell.com>

As per the spec - ECN_Enhanced_Allocation_23_Oct_2014_Final
and section 6.9.1.2, bridges with EA capability work with fixed
secondary and subordinate bus numbers. Hence consider assigning
bus numbers to bridges from EA if the capability exists during
the scan.

Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
---
v3:
  removed function for reading fixed bus numbers
  instead those were captured in pci_ea_init
v2:
  None just added Sean

 drivers/pci/probe.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

Patch

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 257b9f6..9215e2e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1064,6 +1064,7 @@  static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 	u16 bctl;
 	u8 primary, secondary, subordinate;
 	int broken = 0;
+	int next_busnr;
 
 	/*
 	 * Make sure the bridge is powered on to be able to access config
@@ -1163,17 +1164,21 @@  static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 		/* Clear errors */
 		pci_write_config_word(dev, PCI_STATUS, 0xffff);
 
+		next_busnr = max + 1;
+		/* Fixed secondary bus number from EA capability */
+		if (dev->fixed_sec_busnr)
+			next_busnr = dev->fixed_sec_busnr;
 		/*
 		 * Prevent assigning a bus number that already exists.
 		 * This can happen when a bridge is hot-plugged, so in this
 		 * case we only re-scan this bus.
 		 */
-		child = pci_find_bus(pci_domain_nr(bus), max+1);
+		child = pci_find_bus(pci_domain_nr(bus), next_busnr);
 		if (!child) {
-			child = pci_add_new_bus(bus, dev, max+1);
+			child = pci_add_new_bus(bus, dev, next_busnr);
 			if (!child)
 				goto out;
-			pci_bus_insert_busn_res(child, max+1,
+			pci_bus_insert_busn_res(child, next_busnr,
 						bus->busn_res.end);
 		}
 		max++;
@@ -1234,7 +1239,13 @@  static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
 			max += i;
 		}
 
-		/* Set subordinate bus number to its real value */
+		/*
+		 * Set subordinate bus number to its real value.
+		 * If fixed subordinate bus number exists from EA
+		 * capability then use it.
+		 */
+		if (dev->fixed_sub_busnr)
+			max = dev->fixed_sub_busnr;
 		pci_bus_update_busn_res_end(child, max);
 		pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
 	}