patch-2.1.123 linux/arch/i386/kernel/bios32.c

Next file: linux/arch/i386/kernel/io_apic.c
Previous file: linux/arch/i386/defconfig
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.122/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
@@ -1,7 +1,7 @@
 /*
  * bios32.c - Low-Level PCI Access
  *
- * $Id: bios32.c,v 1.45 1998/08/15 10:41:04 mj Exp $
+ * $Id: bios32.c,v 1.48 1998/09/26 08:06:55 mj Exp $
  *
  * Copyright 1993, 1994 Drew Eckhardt
  *      Visionary Computing
@@ -170,6 +170,7 @@
 #define PCI_PROBE_CONF2 4
 #define PCI_NO_SORT 0x100
 #define PCI_BIOS_SORT 0x200
+#define PCI_NO_CHECKS 0x400
 
 static unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
 
@@ -343,14 +344,21 @@
  * whether bus 00 contains a host bridge (this is similar to checking
  * techniques used in XFree86, but ours should be more reliable since we
  * attempt to make use of direct access hints provided by the PCI BIOS).
+ *
+ * This should be close to trivial, but it isn't, because there are buggy
+ * chipsets (yes, you guessed it, by Intel) that have no class ID.
  */
 __initfunc(int pci_sanity_check(struct pci_access *a))
 {
-	u16 dfn, class;
+	u16 dfn, x;
 
+	if (pci_probe & PCI_NO_CHECKS)
+		return 1;
 	for(dfn=0; dfn < 0x100; dfn++)
-		if (!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &class) &&
-		    class == PCI_CLASS_BRIDGE_HOST)
+		if ((!a->read_config_word(0, dfn, PCI_CLASS_DEVICE, &x) &&
+		     x == PCI_CLASS_BRIDGE_HOST) ||
+		    (!a->read_config_word(0, dfn, PCI_VENDOR_ID, &x) &&
+		     x == PCI_VENDOR_ID_INTEL))
 			return 1;
 	DBG("PCI: Sanity check failed\n");
 	return 0;
@@ -945,7 +953,7 @@
 __initfunc(void pcibios_fixup_peer_bridges(void))
 {
 	struct pci_bus *b = &pci_root;
-	int i, cnt=-1;
+	int i, n, cnt=-1;
 	struct pci_dev *d;
 
 #ifdef CONFIG_PCI_DIRECT
@@ -960,8 +968,8 @@
 	for(d=b->devices; d; d=d->sibling)
 		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
 			cnt++;
-	do {
-		int n = b->subordinate+1;
+	n = b->subordinate + 1;
+	while (n <= 0xff) {
 		int found = 0;
 		u16 l;
 		for(i=0; i<256; i += 8)
@@ -973,8 +981,9 @@
 				    l == PCI_CLASS_BRIDGE_HOST)
 					cnt++;
 			}
-		if (found && cnt > 0) {
-			cnt--;
+		if (cnt-- <= 0)
+			break;
+		if (found) {
 			printk("PCI: Discovered primary peer bus %02x\n", n);
 			b = kmalloc(sizeof(*b), GFP_KERNEL);
 			memset(b, 0, sizeof(*b));
@@ -983,9 +992,10 @@
 			b->number = b->secondary = n;
 			b->subordinate = 0xff;
 			b->subordinate = pci_scan_bus(b);
-			break;
+			n = b->subordinate;
 		}
-	} while (i < 256);
+		n++;
+	}
 }
 
 /*
@@ -1146,11 +1156,11 @@
 #endif
 #ifdef CONFIG_PCI_DIRECT
 	else if (!strcmp(str, "conf1")) {
-		pci_probe = PCI_PROBE_CONF1;
+		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
 		return NULL;
 	}
 	else if (!strcmp(str, "conf2")) {
-		pci_probe = PCI_PROBE_CONF2;
+		pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
 		return NULL;
 	}
 #endif

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