2.1.110 PCI patch for booting an NCR S40

Eric PAIRE (e.paire@opengroup.org)
Wed, 22 Jul 1998 17:08:05 +0200


Hi,

I had some difficulties to boot (even in uniprocessor) the NCR S40 with
linux-2.1.110, since it was not able to find the SCSI devices. After some
investigations, I discovered that this was a bug in the PCI bus parsing,
since there are 2 PCI busses connected to the processor bus. The code in
arch/i386/kernel/bios32.c supposes that all HOST-PCI bridges are visible
on PCI bus 0, which is not the case for the S40 (I guess that the problem
of Xintian Wu on his Compaq Proliant 7000 should be the same, since the
symptoms he described are more or less the same that the one I had).

The patch I developed scans potential additional PCI busses after the PCI
bus 0 has been completely scanned, and work perfectly on my quadri-pentium
S40.

Best regards,
-Eric
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Eric PAIRE
Email : e.paire@gr.opengroup.org | THE Open GROUP - Grenoble Research Institute
Phone : +33 (0) 476 63 48 71 | 2, avenue de Vignate
Fax : +33 (0) 476 51 05 32 | F-38610 Gieres FRANCE
------ Cut Here ------ Cut Here ------ Cut Here ------ Cut Here ------
--- linux/arch/i386/kernel/bios32.c.OLD Wed Jul 22 08:16:04 1998
+++ linux/arch/i386/kernel/bios32.c Wed Jul 22 08:16:35 1998
@@ -913,30 +913,36 @@
* In case there are peer host bridges, scan bus behind each of them.
* Although several sources claim that the host bridges should have
* header type 1 and be assigned a bus number as for PCI2PCI bridges,
- * the reality doesn't pass this test and the bus number is usually
- * hard-wired to 1.
+ * the reality doesn't pass this test and the bus number is last
+ * subordinate number of the last bus scanned + 1.
*/
__initfunc(void pcibios_fixup_peer_bridges(void))
{
struct pci_dev *dev;
- int cnt = 0;
+ struct pci_bus *b, *bus = &pci_root;
+ unsigned int l;

- for(dev=pci_root.devices; dev; dev=dev->sibling)
- if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
- DBG("PCI: Host bridge at %02x\n", dev->devfn);
- if (cnt) {
- struct pci_bus *b = kmalloc(sizeof(struct pci_bus), GFP_KERNEL);
- memset(b, 0, sizeof(*b));
- b->parent = &pci_root;
- b->next = pci_root.next;
- pci_root.next = b;
- b->self = dev;
- b->number = b->secondary = cnt;
- b->subordinate = 0xff;
- b->subordinate = pci_scan_bus(b);
+ for(;;) {
+ for(dev = bus->devices; dev; dev = dev->sibling)
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+ DBG("PCI: Host bridge at %02x:%02x\n", bus->number, dev->devfn);
+ bus->self = dev;
+ break;
}
- cnt++;
- }
+
+ pcibios_read_config_dword(bus->subordinate + 1, 0, PCI_VENDOR_ID, &l);
+ if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000)
+ break;
+
+ b = kmalloc(sizeof(struct pci_bus), GFP_ATOMIC);
+ memset(b, 0, sizeof(*b));
+ b->next = bus->next;
+ bus->next = b;
+ b->number = b->secondary = bus->subordinate + 1;
+ b->subordinate = 0xff;
+ b->subordinate = pci_scan_bus(b);
+ bus = b;
+ }
}

/*

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html