From akpm@osdl.org Thu Apr 28 00:27:31 2005
Subject: [patch 05/20] acpi bridge hotadd: Prevent duplicate bus numbers when scanning PCI bridge
To: greg@kroah.com
Cc: akpm@osdl.org, rajesh.shah@intel.com
From: akpm@osdl.org
Date: Thu, 28 Apr 2005 00:25:47 -0700


From: Rajesh Shah <rajesh.shah@intel.com>

When hot-plugging a root bridge, as we try to assign bus numbers we may find
that the hotplugged hieratchy has more PCI to PCI bridges (i.e.  bus
requirements) than available.  Make sure we don't step over an existing bus
when that happens.  

Signed-off-by: Rajesh Shah <rajesh.shah@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/pci/probe.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

--- gregkh-2.6.orig/drivers/pci/probe.c	2005-05-03 22:28:11.000000000 -0700
+++ gregkh-2.6/drivers/pci/probe.c	2005-05-03 22:28:23.000000000 -0700
@@ -407,7 +407,7 @@
 {
 	struct pci_bus *child;
 	int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
-	u32 buses;
+	u32 buses, i;
 	u16 bctl;
 
 	pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -466,6 +466,10 @@
 		/* Clear errors */
 		pci_write_config_word(dev, PCI_STATUS, 0xffff);
 
+		/* Prevent assigning a bus number that already exists.
+		 * This can happen when a bridge is hot-plugged */
+		if (pci_find_bus(pci_domain_nr(bus), max+1))
+			return max;
 		child = pci_alloc_child_bus(bus, dev, ++max);
 		buses = (buses & 0xff000000)
 		      | ((unsigned int)(child->primary)     <<  0)
@@ -497,7 +501,11 @@
 			 * as cards with a PCI-to-PCI bridge can be
 			 * inserted later.
 			 */
-			max += CARDBUS_RESERVE_BUSNR;
+			for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
+				if (pci_find_bus(pci_domain_nr(bus),
+							max+i+1))
+					break;
+			max += i;
 		}
 		/*
 		 * Set the subordinate bus number to its real value.