patch-2.1.28 linux/drivers/pci/pci.c

Next file: linux/drivers/scsi/AM53C974.c
Previous file: linux/drivers/net/slip.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.27/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
@@ -917,29 +917,47 @@
 			pcibios_write_config_word(bus->number, devfn,
 						  PCI_STATUS, 0xffff);
 			/*
-			 * Configure the bus numbers for this bridge:
+			 * Read the existing primary/secondary/subordinate bus
+			 * number configuration to determine if the PCI bridge
+			 * has already been configured by the system.  If so,
+			 * do not modify the configuration, merely note it.
 			 */
 			pcibios_read_config_dword(bus->number, devfn, 0x18,
 						  &buses);
-			buses &= 0xff000000;
-			buses |= (((unsigned int)(child->primary)     <<  0) |
-				  ((unsigned int)(child->secondary)   <<  8) |
-				  ((unsigned int)(child->subordinate) << 16));
-			pcibios_write_config_dword(bus->number, devfn, 0x18,
-						   buses);
-			/*
-			 * Now we can scan all subordinate buses:
-			 */
-			max = scan_bus(child, mem_startp);
-			/*
-			 * Set the subordinate bus number to its real
-			 * value:
-			 */
-			child->subordinate = max;
-			buses = (buses & 0xff00ffff)
-			  | ((unsigned int)(child->subordinate) << 16);
-			pcibios_write_config_dword(bus->number, devfn, 0x18,
-						   buses);
+			if ((buses & 0xFFFFFF) != 0)
+			  {
+			    child->primary = buses & 0xFF;
+			    child->secondary = (buses >> 8) & 0xFF;
+			    child->subordinate = (buses >> 16) & 0xFF;
+			    child->number = child->secondary;
+			    max = scan_bus(child, mem_startp);
+			  }
+			else
+			  {
+			    /*
+			     * Configure the bus numbers for this bridge:
+			     */
+			    buses &= 0xff000000;
+			    buses |=
+			      (((unsigned int)(child->primary)     <<  0) |
+			       ((unsigned int)(child->secondary)   <<  8) |
+			       ((unsigned int)(child->subordinate) << 16));
+			    pcibios_write_config_dword(bus->number, devfn, 0x18,
+						       buses);
+			    /*
+			     * Now we can scan all subordinate buses:
+			     */
+			    max = scan_bus(child, mem_startp);
+			    /*
+			     * Set the subordinate bus number to its real
+			     * value:
+			     */
+			    child->subordinate = max;
+			    buses = (buses & 0xff00ffff)
+			      | ((unsigned int)(child->subordinate) << 16);
+			    pcibios_write_config_dword(bus->number, devfn, 0x18,
+						       buses);
+			  }
 			pcibios_write_config_word(bus->number, devfn,
 						  PCI_COMMAND, cr);
 		}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov