Is this the same issue we were having with Linux not being able to see
bus 1?

  Stefan

----- Forwarded message from Matthew Wilcox <[EMAIL PROTECTED]> -----

Date: Sun, 9 Nov 2003 23:09:38 +0000
Subject: Re: PROBLEM: sym53c8xx is broken on HP LH 4 after Linux 2.2

On Sun, Nov 09, 2003 at 11:51:36AM -0500, Doug Ledford wrote:
> I can tell you what's going on here.  This is a 450NX based
> motherboard.  The 450NX chipset from Intel was the first chipset to
> have peer PCI busses.  For backwards compatibility, some machine
> makers hacked their PCI BIOS to have a fake bridge device on PCI bus 0
> that points to the same bus number as the peer bus.  This way if the
> OS didn't know about the peer bus registers it would still find the
> devices by scanning behind the bridge.
[..]
> In this case we are scanning behind this fake bridge and then also
> scanning based upon the peer bus registers in the chipset, and as a
> result we are finding the device twice.  In order to fix this problem
> you need to change the peer bus quirk code for the 450NX chipset to
> scan the list of bus 0 devices looking for a bridge that has the same
> config as the peer bus registers and if so delete the bridge from the
> list.  That will avoid double scanning and will avoid having the PCI
> code try and configure sub busses via a fake bridge when it should do
> all configurations via the 450NX peer bus registers.

Index: arch/i386/pci/fixup.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/i386/pci/fixup.c,v
retrieving revision 1.2
diff -u -p -r1.2 fixup.c
--- arch/i386/pci/fixup.c       12 Aug 2003 19:10:49 -0000      1.2
+++ arch/i386/pci/fixup.c       9 Nov 2003 23:07:17 -0000
@@ -6,27 +6,52 @@
 #include <linux/init.h>
 #include "pci.h"
 
+static void __devinit i450nx_scan_bus(struct pci_bus *parent, u8 busnr)
+{
+       struct list_head *tmp;
+
+       pci_scan_bus(busnr, &pci_root_ops, NULL);
+
+       list_for_each(tmp, &parent->children) {
+               u8 childnr;
+               struct pci_dev *dev = pci_dev_b(tmp);
+
+               if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
+                       continue;
+               pci_read_config_byte(dev, PCI_PRIMARY_BUS, &childnr);
+               if (childnr != busnr)
+                       continue;
+
+               printk(KERN_WARNING "PCI: Removing fake PCI bridge %s\n",
+                               pci_name(dev));
+               pci_remove_bus_device(dev);
+               break;
+       }
+}
 
 static void __devinit pci_fixup_i450nx(struct pci_dev *d)
 {
        /*
         * i450NX -- Find and scan all secondary buses on all PXB's.
+        * Some manufacturers added fake PCI-PCI bridges that also point
+        * to the peer busses.  Look for them and delete them.
         */
        int pxb, reg;
        u8 busno, suba, subb;
 
-       printk(KERN_WARNING "PCI: Searching for i450NX host bridges on %s\n", 
pci_name(d));
+       printk(KERN_NOTICE "PCI: Searching for i450NX host bridges on %s\n", 
pci_name(d));
        reg = 0xd0;
-       for(pxb=0; pxb<2; pxb++) {
+       for (pxb = 0; pxb < 2; pxb++) {
                pci_read_config_byte(d, reg++, &busno);
                pci_read_config_byte(d, reg++, &suba);
                pci_read_config_byte(d, reg++, &subb);
                DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
                if (busno)
-                       pci_scan_bus(busno, &pci_root_ops, NULL);       /* Bus A */
+                       i450nx_scan_bus(d->bus, busno);         /* Bus A */
                if (suba < subb)
-                       pci_scan_bus(suba+1, &pci_root_ops, NULL);      /* Bus B */
+                       i450nx_scan_bus(d->bus, suba+1);        /* Bus B */
        }
+
        pcibios_last_bus = -1;
 }
 
----- End forwarded message -----
  
-- 
     Stefan Reinauer, SUSE LINUX AG
Teamleader Architecture Development
_______________________________________________
Linuxbios mailing list
[EMAIL PROTECTED]
http://www.clustermatic.org/mailman/listinfo/linuxbios

Reply via email to