if (!dev->msi_enabled && pcibios_disable_irq)
                pcibios_disable_irq(dev);
 }
+
+struct pci_bus *pci_scan_bus_with_sysdata(int busno)
+{
+       struct pci_bus *bus = NULL;
+       struct pci_sysdata *sd;
+
+       /*
+        * Allocate per-root-bus (not per bus) arch-specific data.
+        * TODO: leak; this memory is never freed.
+        * It's arguable whether it's worth the trouble to care.
+        */
+       sd = kzalloc(sizeof(*sd), GFP_KERNEL);
+       if (!sd) {
+               printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno);
+               return NULL;
+       }
+       sd->node = -1;
+       bus = pci_scan_bus(busno, &pci_root_ops, sd);
+       if (!bus)
+               kfree(sd);
+
+       return bus;
+}
 
                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 */
+                       pci_scan_bus_with_sysdata(busno);       /* Bus A */
                if (suba < subb)
-                       pci_scan_bus(suba+1, &pci_root_ops, NULL);      /* Bus B */
+                       pci_scan_bus_with_sysdata(suba+1);      /* Bus B */
        }
        pcibios_last_bus = -1;
 }
        u8 busno;
        pci_read_config_byte(d, 0x4a, &busno);
        printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", pci_name(d), busno);
-       pci_scan_bus(busno, &pci_root_ops, NULL);
+       pci_scan_bus_with_sysdata(busno);
        pcibios_last_bus = -1;
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, pci_fixup_i450gx);
 
        for(i = 1; i < 256; i++) {
                if (!busmap[i] || pci_find_bus(0, i))
                        continue;
-               if (pci_scan_bus(i, &pci_root_ops, NULL))
-                       printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+               if (pci_scan_bus_with_sysdata(i))
+                       printk(KERN_INFO "PCI: Discovered primary peer "
+                              "bus %02x [IRQ]\n", i);
        }
        pcibios_last_bus = -1;
 }
 
                            l != 0x0000 && l != 0xffff) {
                                DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
                                printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
-                               pci_scan_bus(n, &pci_root_ops, NULL);
+                               pci_scan_bus_with_sysdata(n);
                                break;
                        }
                }
 
                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(QUADLOCAL2BUS(quad,busno), &pci_root_ops, NULL);   /* Bus A */
-               if (suba < subb)
-                       pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), &pci_root_ops, NULL);  /* Bus B */
+               if (busno) {
+                       /* Bus A */
+                       pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, busno));
+               }
+               if (suba < subb) {
+                       /* Bus B */
+                       pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, suba+1));
+               }
        }
        pcibios_last_bus = -1;
 }
                                continue;
                        printk("Scanning PCI bus %d for quad %d\n", 
                                QUADLOCAL2BUS(quad,0), quad);
-                       pci_scan_bus(QUADLOCAL2BUS(quad,0), 
-                               &pci_root_ops, NULL);
+                       pci_scan_bus_with_sysdata(QUADLOCAL2BUS(quad, 0));
                }
        return 0;
 }
 
                "bridge B (PIIX4) bus: %u\n", pci_bus1, pci_bus0);
 
        raw_pci_ops = &pci_direct_conf1;
-       pci_scan_bus(pci_bus0, &pci_root_ops, NULL);
-       pci_scan_bus(pci_bus1, &pci_root_ops, NULL);
+       pci_scan_bus_with_sysdata(pci_bus0);
+       pci_scan_bus_with_sysdata(pci_bus1);
        pci_fixup_irqs(visws_swizzle, visws_map_irq);
        pcibios_resource_survey();
        return 0;
 
        int             node;           /* NUMA node */
 };
 
+/* scan a bus after allocating a pci_sysdata for it */
+extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
+
 #include <linux/mm.h>          /* for struct page */
 
 /* Can be used to override the logic in pci_scan_bus for skipping
 
        void*           iommu;          /* IOMMU private data */
 };
 
+extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
+
 #ifdef CONFIG_CALGARY_IOMMU
 static inline void* pci_iommu(struct pci_bus *bus)
 {