vserver 1.9.3
[linux-2.6.git] / arch / ppc64 / kernel / pmac_pci.c
index 1691957..9e1a069 100644 (file)
@@ -271,7 +271,7 @@ static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       struct device_node *busdn;
+       struct device_node *busdn, *dn;
        unsigned long addr;
 
        if (bus->self)
@@ -284,6 +284,16 @@ static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
        if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
+       /* We only allow config cycles to devices that are in OF device-tree
+        * as we are apparently having some weird things going on with some
+        * revs of K2 on recent G5s
+        */
+       for (dn = busdn->child; dn; dn = dn->sibling)
+               if (dn->devfn == devfn)
+                       break;
+       if (dn == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -419,7 +429,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
         * properties or figuring out the U3 address space decoding logic and
         * then read it's configuration register (if any).
         */
-       hose->io_base_phys = 0xf4000000 + 0x00400000;
+       hose->io_base_phys = 0xf4000000;
        hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
        isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt;
        hose->io_resource.name = np->full_name;
@@ -664,17 +674,15 @@ void __init pmac_pcibios_fixup(void)
 
        pci_fix_bus_sysdata();
 
-#ifdef CONFIG_PMAC_DART
-       iommu_setup_pmac();
-#endif /* CONFIG_PMAC_DART */
+       iommu_setup_u3();
 
 }
 
 static void __init pmac_fixup_phb_resources(void)
 {
-       struct pci_controller *hose;
+       struct pci_controller *hose, *tmp;
        
-       for (hose = hose_head; hose; hose = hose->next) {
+       list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
                unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
                hose->io_resource.start += offset;
                hose->io_resource.end += offset;
@@ -746,6 +754,9 @@ void __init pmac_pci_init(void)
         * the exception of U3/AGP (hook into pci_set_mwi)
         */
        pci_cache_line_size = 16; /* 64 bytes */
+
+       /* Allow all IO */
+       io_page_mask = -1;
 }
 
 /*
@@ -777,3 +788,4 @@ void fixup_k2_sata(struct pci_dev* dev)
                }
        }
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);