fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / ppc / kernel / pci.c
index 5b49655..5e723c4 100644 (file)
@@ -1,8 +1,7 @@
 /*
- * Common pmac/prep/chrp pci routines. -- Cort
+ * Common prep/chrp pci routines. -- Cort
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
@@ -21,6 +20,7 @@
 #include <asm/byteorder.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
+#include <asm/machdep.h>
 
 #undef DEBUG
 
@@ -33,6 +33,7 @@
 unsigned long isa_io_base     = 0;
 unsigned long isa_mem_base    = 0;
 unsigned long pci_dram_offset = 0;
+int pcibios_assign_bus_offset = 1;
 
 void pcibios_make_OF_bus_map(void);
 
@@ -43,63 +44,26 @@ static void update_bridge_base(struct pci_bus *bus, int i);
 static void pcibios_fixup_resources(struct pci_dev* dev);
 static void fixup_broken_pcnet32(struct pci_dev* dev);
 static int reparent_resources(struct resource *parent, struct resource *res);
-static void fixup_rev1_53c810(struct pci_dev* dev);
 static void fixup_cpc710_pci64(struct pci_dev* dev);
-#ifdef CONFIG_PPC_PMAC
-extern void pmac_pci_fixup_cardbus(struct pci_dev* dev);
-extern void pmac_pci_fixup_pciata(struct pci_dev* dev);
-extern void pmac_pci_fixup_k2_sata(struct pci_dev* dev);
-#endif
-#ifdef CONFIG_PPC_OF
-static u8* pci_to_OF_bus_map;
-#endif
 
-/* By default, we don't re-assign bus numbers. We do this only on
- * some pmacs
+/* By default, we don't re-assign bus numbers.
  */
-int pci_assign_all_busses;
+int pci_assign_all_buses;
 
 struct pci_controller* hose_head;
 struct pci_controller** hose_tail = &hose_head;
 
 static int pci_bus_count;
 
-struct pci_fixup pcibios_fixups[] = {
-       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_TRIDENT,  PCI_ANY_ID,                     fixup_broken_pcnet32 },
-       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_NCR,      PCI_DEVICE_ID_NCR_53C810,       fixup_rev1_53c810 },
-       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_IBM,      PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64},
-       { PCI_FIXUP_HEADER,     PCI_ANY_ID,             PCI_ANY_ID,                     pcibios_fixup_resources },
-#ifdef CONFIG_PPC_PMAC
-       /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */
-       { PCI_FIXUP_FINAL,      PCI_VENDOR_ID_TI,       PCI_ANY_ID,                     pmac_pci_fixup_cardbus },
-       { PCI_FIXUP_FINAL,      PCI_ANY_ID,             PCI_ANY_ID,                     pmac_pci_fixup_pciata },
-       { PCI_FIXUP_HEADER,     PCI_VENDOR_ID_SERVERWORKS, 0x0240,                      pmac_pci_fixup_k2_sata },
-#endif /* CONFIG_PPC_PMAC */
-       { 0 }
-};
-
-static void
-fixup_rev1_53c810(struct pci_dev* dev)
-{
-       /* rev 1 ncr53c810 chips don't set the class at all which means
-        * they don't get their resources remapped. Fix that here.
-        */
-
-       if ((dev->class == PCI_CLASS_NOT_DEFINED)) {
-               printk("NCR 53c810 rev 1 detected, setting PCI class.\n");
-               dev->class = PCI_CLASS_STORAGE_SCSI;
-       }
-}
-
 static void
 fixup_broken_pcnet32(struct pci_dev* dev)
 {
        if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
                dev->vendor = PCI_VENDOR_ID_AMD;
                pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-               pci_name_device(dev);
        }
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT,        PCI_ANY_ID,                     fixup_broken_pcnet32);
 
 static void
 fixup_cpc710_pci64(struct pci_dev* dev)
@@ -112,6 +76,7 @@ fixup_cpc710_pci64(struct pci_dev* dev)
        dev->resource[1].start = dev->resource[1].end = 0;
        dev->resource[1].flags = 0;
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,    PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64);
 
 static void
 pcibios_fixup_resources(struct pci_dev *dev)
@@ -128,9 +93,11 @@ pcibios_fixup_resources(struct pci_dev *dev)
                struct resource *res = dev->resource + i;
                if (!res->flags)
                        continue;
-               if (!res->start || res->end == 0xffffffff) {
-                       DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
-                           pci_name(dev), i, res->start, res->end);
+               if (res->end == 0xffffffff) {
+                       DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
+                               pci_name(dev), i,
+                               (unsigned long long)res->start,
+                               (unsigned long long)res->end);
                        res->end -= res->start;
                        res->start = 0;
                        res->flags |= IORESOURCE_UNSET;
@@ -158,9 +125,9 @@ pcibios_fixup_resources(struct pci_dev *dev)
        if (ppc_md.pcibios_fixup_resources)
                ppc_md.pcibios_fixup_resources(dev);
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID,           PCI_ANY_ID,                     pcibios_fixup_resources);
 
-void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                        struct resource *res)
 {
        unsigned long offset = 0;
@@ -173,6 +140,22 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
        region->start = res->start - offset;
        region->end = res->end - offset;
 }
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                            struct pci_bus_region *region)
+{
+       unsigned long offset = 0;
+       struct pci_controller *hose = dev->sysdata;
+
+       if (hose && res->flags & IORESOURCE_IO)
+               offset = (unsigned long)hose->io_base_virt - isa_io_base;
+       else if (hose && res->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+       res->start = region->start + offset;
+       res->end = region->end + offset;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 
 /*
  * We need to avoid collisions with `mirrored' VGA ports
@@ -187,19 +170,18 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
  * but we want to try to avoid allocating at 0x2900-0x2bff
  * which might have be mirrored at 0x0100-0x03ff..
  */
-void
-pcibios_align_resource(void *data, struct resource *res, unsigned long size,
-                      unsigned long align)
+void pcibios_align_resource(void *data, struct resource *res,
+                               resource_size_t size, resource_size_t align)
 {
        struct pci_dev *dev = data;
 
        if (res->flags & IORESOURCE_IO) {
-               unsigned long start = res->start;
+               resource_size_t start = res->start;
 
                if (size > 0x100) {
                        printk(KERN_ERR "PCI: I/O Region %s/%d too large"
-                              " (%ld bytes)\n", pci_name(dev),
-                              dev->resource - res, size);
+                              " (%lld bytes)\n", pci_name(dev),
+                              dev->resource - res, (unsigned long long)size);
                }
 
                if (start & 0x300) {
@@ -208,7 +190,7 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size,
                }
        }
 }
-
+EXPORT_SYMBOL(pcibios_align_resource);
 
 /*
  *  Handle resources of PCI devices.  If the world were perfect, we could
@@ -246,14 +228,12 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size,
 static void __init
 pcibios_allocate_bus_resources(struct list_head *bus_list)
 {
-       struct list_head *ln;
        struct pci_bus *bus;
        int i;
        struct resource *res, *pr;
 
        /* Depth-First Search on bus tree */
-       for (ln = bus_list->next; ln != bus_list; ln=ln->next) {
-               bus = pci_bus_b(ln);
+       list_for_each_entry(bus, bus_list, node) {
                for (i = 0; i < 4; ++i) {
                        if ((res = bus->resource[i]) == NULL || !res->flags
                            || res->start > res->end)
@@ -272,8 +252,9 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
                                }
                        }
 
-                       DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n",
-                           res->start, res->end, res->flags, pr);
+                       DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n",
+                               (unsigned long long)res->start,
+                               (unsigned long long)res->end, res->flags, pr);
                        if (pr) {
                                if (request_resource(pr, res) == 0)
                                        continue;
@@ -323,8 +304,9 @@ reparent_resources(struct resource *parent, struct resource *res)
        *pp = NULL;
        for (p = res->child; p != NULL; p = p->sibling) {
                p->parent = res;
-               DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n",
-                   p->name, p->start, p->end, res->name);
+               DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
+                       p->name, (unsigned long long)p->start,
+                       (unsigned long long)p->end, res->name);
        }
        return 0;
 }
@@ -347,6 +329,8 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i)
                return -1;
        }
        res = bus->resource[i];
+       if (res == NULL)
+               return -1;
        pr = NULL;
        for (j = 0; j < 4; j++) {
                struct resource *r = parent->resource[j];
@@ -377,13 +361,15 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i)
                try = conflict->start - 1;
        }
        if (request_resource(pr, res)) {
-               DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n",
-                   res->start, res->end);
+               DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n",
+                       (unsigned long long)res->start,
+                       (unsigned long long)res->end);
                return -1;              /* "can't happen" */
        }
        update_bridge_base(bus, i);
-       printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n",
-              bus->number, i, res->start, res->end);
+       printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n",
+               bus->number, i, (unsigned long long)res->start,
+               (unsigned long long)res->end);
        return 0;
 }
 
@@ -394,7 +380,6 @@ probe_resource(struct pci_bus *parent, struct resource *pr,
        struct pci_bus *bus;
        struct pci_dev *dev;
        struct resource *r;
-       struct list_head *ln;
        int i;
 
        for (r = pr->child; r != NULL; r = r->sibling) {
@@ -403,9 +388,7 @@ probe_resource(struct pci_bus *parent, struct resource *pr,
                        return 1;
                }
        }
-       for (ln = parent->children.next; ln != &parent->children;
-            ln = ln->next) {
-               bus = pci_bus_b(ln);
+       list_for_each_entry(bus, &parent->children, node) {
                for (i = 0; i < 4; ++i) {
                        if ((r = bus->resource[i]) == NULL)
                                continue;
@@ -419,13 +402,12 @@ probe_resource(struct pci_bus *parent, struct resource *pr,
                        }
                }
        }
-       for (ln = parent->devices.next; ln != &parent->devices; ln=ln->next) {
-               dev = pci_dev_b(ln);
+       list_for_each_entry(dev, &parent->devices, bus_list) {
                for (i = 0; i < 6; ++i) {
                        r = &dev->resource[i];
                        if (!r->flags || (r->flags & IORESOURCE_UNSET))
                                continue;
-                       if (pci_find_parent_resource(bus->self, r) != pr)
+                       if (pci_find_parent_resource(dev, r) != pr)
                                continue;
                        if (r->end >= res->start && res->end >= r->start) {
                                *conflict = r;
@@ -498,15 +480,17 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
 {
        struct resource *pr, *r = &dev->resource[idx];
 
-       DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n",
-           pci_name(dev), idx, r->start, r->end, r->flags);
+       DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n",
+           pci_name(dev), idx, (unsigned long long)r->start,
+           (unsigned long long)r->end, r->flags);
        pr = pci_find_parent_resource(dev, r);
        if (!pr || request_resource(pr, r) < 0) {
                printk(KERN_ERR "PCI: Cannot allocate resource region %d"
                       " of device %s\n", idx, pci_name(dev));
                if (pr)
-                       DBG("PCI:  parent is %p: %08lx-%08lx (f=%lx)\n",
-                           pr, pr->start, pr->end, pr->flags);
+                       DBG("PCI:  parent is %p: %016llx-%016llx (f=%lx)\n",
+                               pr, (unsigned long long)pr->start,
+                               (unsigned long long)pr->end, pr->flags);
                /* We'll assign a new address later */
                r->flags |= IORESOURCE_UNSET;
                r->end -= r->start;
@@ -522,7 +506,7 @@ pcibios_allocate_resources(int pass)
        u16 command;
        struct resource *r;
 
-       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
                pci_read_config_word(dev, PCI_COMMAND, &command);
                for (idx = 0; idx < 6; idx++) {
                        r = &dev->resource[idx];
@@ -540,11 +524,11 @@ pcibios_allocate_resources(int pass)
                if (pass)
                        continue;
                r = &dev->resource[PCI_ROM_RESOURCE];
-               if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+               if (r->flags & IORESOURCE_ROM_ENABLE) {
                        /* Turn the ROM off, leave the resource region, but keep it unregistered. */
                        u32 reg;
                        DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
-                       r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+                       r->flags &= ~IORESOURCE_ROM_ENABLE;
                        pci_read_config_dword(dev, dev->rom_base_reg, &reg);
                        pci_write_config_dword(dev, dev->rom_base_reg,
                                               reg & ~PCI_ROM_ADDRESS_ENABLE);
@@ -559,7 +543,7 @@ pcibios_assign_resources(void)
        int idx;
        struct resource *r;
 
-       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
                int class = dev->class >> 8;
 
                /* Don't touch classless devices and host bridges */
@@ -645,617 +629,15 @@ pcibios_alloc_controller(void)
        return hose;
 }
 
-#ifdef CONFIG_PPC_OF
-/*
- * Functions below are used on OpenFirmware machines.
- */
-static void __openfirmware
-make_one_node_map(struct device_node* node, u8 pci_bus)
-{
-       int *bus_range;
-       int len;
-
-       if (pci_bus >= pci_bus_count)
-               return;
-       bus_range = (int *) get_property(node, "bus-range", &len);
-       if (bus_range == NULL || len < 2 * sizeof(int)) {
-               printk(KERN_WARNING "Can't get bus-range for %s\n",
-                      node->full_name);
-               return;
-       }
-       pci_to_OF_bus_map[pci_bus] = bus_range[0];
-
-       for (node=node->child; node != 0;node = node->sibling) {
-               struct pci_dev* dev;
-               unsigned int *class_code, *reg;
-       
-               class_code = (unsigned int *) get_property(node, "class-code", 0);
-               if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
-                       (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
-                       continue;
-               reg = (unsigned int *)get_property(node, "reg", 0);
-               if (!reg)
-                       continue;
-               dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
-               if (!dev || !dev->subordinate)
-                       continue;
-               make_one_node_map(node, dev->subordinate->number);
-       }
-}
-       
-void __openfirmware
-pcibios_make_OF_bus_map(void)
-{
-       int i;
-       struct pci_controller* hose;
-       u8* of_prop_map;
-
-       pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
-       if (!pci_to_OF_bus_map) {
-               printk(KERN_ERR "Can't allocate OF bus map !\n");
-               return;
-       }
-
-       /* We fill the bus map with invalid values, that helps
-        * debugging.
-        */
-       for (i=0; i<pci_bus_count; i++)
-               pci_to_OF_bus_map[i] = 0xff;
-
-       /* For each hose, we begin searching bridges */
-       for(hose=hose_head; hose; hose=hose->next) {
-               struct device_node* node;       
-               node = (struct device_node *)hose->arch_data;
-               if (!node)
-                       continue;
-               make_one_node_map(node, hose->first_busno);
-       }
-       of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", 0);
-       if (of_prop_map)
-               memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
-#ifdef DEBUG
-       printk("PCI->OF bus map:\n");
-       for (i=0; i<pci_bus_count; i++) {
-               if (pci_to_OF_bus_map[i] == 0xff)
-                       continue;
-               printk("%d -> %d\n", i, pci_to_OF_bus_map[i]);
-       }
-#endif
-}
-
-typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
-
-static struct device_node* __openfirmware
-scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
-{
-       struct device_node* sub_node;
-
-       for (; node != 0;node = node->sibling) {
-               unsigned int *class_code;
-       
-               if (filter(node, data))
-                       return node;
-
-               /* For PCI<->PCI bridges or CardBus bridges, we go down
-                * Note: some OFs create a parent node "multifunc-device" as
-                * a fake root for all functions of a multi-function device,
-                * we go down them as well.
-                */
-               class_code = (unsigned int *) get_property(node, "class-code", 0);
-               if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
-                       (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
-                       strcmp(node->name, "multifunc-device"))
-                       continue;
-               sub_node = scan_OF_pci_childs(node->child, filter, data);
-               if (sub_node)
-                       return sub_node;
-       }
-       return NULL;
-}
-
-static int
-scan_OF_pci_childs_iterator(struct device_node* node, void* data)
-{
-       unsigned int *reg;
-       u8* fdata = (u8*)data;
-       
-       reg = (unsigned int *) get_property(node, "reg", 0);
-       if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
-               && ((reg[0] >> 16) & 0xff) == fdata[0])
-               return 1;
-       return 0;
-}
-
-static struct device_node* __openfirmware
-scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
-{
-       u8 filter_data[2] = {bus, dev_fn};
-
-       return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data);
-}
-
-/*
- * Scans the OF tree for a device node matching a PCI device
- */
-struct device_node *
-pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
-{
-       struct pci_controller *hose;
-       struct device_node *node;
-       int busnr;
-
-       if (!have_of)
-               return NULL;
-       
-       /* Lookup the hose */
-       busnr = bus->number;
-       hose = pci_bus_to_hose(busnr);
-       if (!hose)
-               return NULL;
-
-       /* Check it has an OF node associated */
-       node = (struct device_node *) hose->arch_data;
-       if (!node)
-               return NULL;
-
-       /* Fixup bus number according to what OF think it is. */
-#ifdef CONFIG_PPC_PMAC
-       /* The G5 need a special case here. Basically, we don't remap all
-        * busses on it so we don't create the pci-OF-map. However, we do
-        * remap the AGP bus and so have to deal with it. A future better
-        * fix has to be done by making the remapping per-host and always
-        * filling the pci_to_OF map. --BenH
-        */
-       if (_machine == _MACH_Pmac && busnr >= 0xf0)
-               busnr -= 0xf0;
-       else
-#endif
-       if (pci_to_OF_bus_map)
-               busnr = pci_to_OF_bus_map[busnr];
-       if (busnr == 0xff)
-               return NULL;
-       
-       /* Now, lookup childs of the hose */
-       return scan_OF_childs_for_device(node->child, busnr, devfn);
-}
-
-struct device_node*
-pci_device_to_OF_node(struct pci_dev *dev)
-{
-       return pci_busdev_to_OF_node(dev->bus, dev->devfn);
-}
-
-/* This routine is meant to be used early during boot, when the
- * PCI bus numbers have not yet been assigned, and you need to
- * issue PCI config cycles to an OF device.
- * It could also be used to "fix" RTAS config cycles if you want
- * to set pci_assign_all_busses to 1 and still use RTAS for PCI
- * config cycles.
- */
-struct pci_controller*
-pci_find_hose_for_OF_device(struct device_node* node)
-{
-       if (!have_of)
-               return NULL;
-       while(node) {
-               struct pci_controller* hose;
-               for (hose=hose_head;hose;hose=hose->next)
-                       if (hose->arch_data == node)
-                               return hose;
-               node=node->parent;
-       }
-       return NULL;
-}
-
-static int __openfirmware
-find_OF_pci_device_filter(struct device_node* node, void* data)
-{
-       return ((void *)node == data);
-}
-
-/*
- * Returns the PCI device matching a given OF node
- */
-int
-pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
-{
-       unsigned int *reg;
-       struct pci_controller* hose;
-       struct pci_dev* dev = NULL;
-       
-       if (!have_of)
-               return -ENODEV;
-       /* Make sure it's really a PCI device */
-       hose = pci_find_hose_for_OF_device(node);
-       if (!hose || !hose->arch_data)
-               return -ENODEV;
-       if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
-                       find_OF_pci_device_filter, (void *)node))
-               return -ENODEV;
-       reg = (unsigned int *) get_property(node, "reg", 0);
-       if (!reg)
-               return -ENODEV;
-       *bus = (reg[0] >> 16) & 0xff;
-       *devfn = ((reg[0] >> 8) & 0xff);
-
-       /* Ok, here we need some tweak. If we have already renumbered
-        * all busses, we can't rely on the OF bus number any more.
-        * the pci_to_OF_bus_map is not enough as several PCI busses
-        * may match the same OF bus number.
-        */
-       if (!pci_to_OF_bus_map)
-               return 0;
-       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               if (pci_to_OF_bus_map[dev->bus->number] != *bus)
-                       continue;
-               if (dev->devfn != *devfn)
-                       continue;
-               *bus = dev->bus->number;
-               return 0;
-       }
-       return -ENODEV;
-}
-
-void __init
-pci_process_bridge_OF_ranges(struct pci_controller *hose,
-                          struct device_node *dev, int primary)
-{
-       static unsigned int static_lc_ranges[256] __initdata;
-       unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
-       unsigned int size;
-       int rlen = 0, orig_rlen;
-       int memno = 0;
-       struct resource *res;
-       int np, na = prom_n_addr_cells(dev);
-       np = na + 5;
-
-       /* First we try to merge ranges to fix a problem with some pmacs
-        * that can have more than 3 ranges, fortunately using contiguous
-        * addresses -- BenH
-        */
-       dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
-       if (!dt_ranges)
-               return;
-       /* Sanity check, though hopefully that never happens */
-       if (rlen > sizeof(static_lc_ranges)) {
-               printk(KERN_WARNING "OF ranges property too large !\n");
-               rlen = sizeof(static_lc_ranges);
-       }
-       lc_ranges = static_lc_ranges;
-       memcpy(lc_ranges, dt_ranges, rlen);
-       orig_rlen = rlen;
-
-       /* Let's work on a copy of the "ranges" property instead of damaging
-        * the device-tree image in memory
-        */
-       ranges = lc_ranges;
-       prev = NULL;
-       while ((rlen -= np * sizeof(unsigned int)) >= 0) {
-               if (prev) {
-                       if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
-                               (prev[2] + prev[na+4]) == ranges[2] &&
-                               (prev[na+2] + prev[na+4]) == ranges[na+2]) {
-                               prev[na+4] += ranges[na+4];
-                               ranges[0] = 0;
-                               ranges += np;
-                               continue;
-                       }
-               }
-               prev = ranges;
-               ranges += np;
-       }
-
-       /*
-        * The ranges property is laid out as an array of elements,
-        * each of which comprises:
-        *   cells 0 - 2:       a PCI address
-        *   cells 3 or 3+4:    a CPU physical address
-        *                      (size depending on dev->n_addr_cells)
-        *   cells 4+5 or 5+6:  the size of the range
-        */
-       ranges = lc_ranges;
-       rlen = orig_rlen;
-       while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
-               res = NULL;
-               size = ranges[na+4];
-               switch (ranges[0] >> 24) {
-               case 1:         /* I/O space */
-                       if (ranges[2] != 0)
-                               break;
-                       hose->io_base_phys = ranges[na+2];
-                       /* limit I/O space to 16MB */
-                       if (size > 0x01000000)
-                               size = 0x01000000;
-                       hose->io_base_virt = ioremap(ranges[na+2], size);
-                       if (primary)
-                               isa_io_base = (unsigned long) hose->io_base_virt;
-                       res = &hose->io_resource;
-                       res->flags = IORESOURCE_IO;
-                       res->start = ranges[2];
-                       break;
-               case 2:         /* memory space */
-                       memno = 0;
-                       if (ranges[1] == 0 && ranges[2] == 0
-                           && ranges[na+4] <= (16 << 20)) {
-                               /* 1st 16MB, i.e. ISA memory area */
-                               if (primary)
-                                       isa_mem_base = ranges[na+2];
-                               memno = 1;
-                       }
-                       while (memno < 3 && hose->mem_resources[memno].flags)
-                               ++memno;
-                       if (memno == 0)
-                               hose->pci_mem_offset = ranges[na+2] - ranges[2];
-                       if (memno < 3) {
-                               res = &hose->mem_resources[memno];
-                               res->flags = IORESOURCE_MEM;
-                               res->start = ranges[na+2];
-                       }
-                       break;
-               }
-               if (res != NULL) {
-                       res->name = dev->full_name;
-                       res->end = res->start + size - 1;
-                       res->parent = NULL;
-                       res->sibling = NULL;
-                       res->child = NULL;
-               }
-               ranges += np;
-       }
-}
-
-/* We create the "pci-OF-bus-map" property now so it appears in the
- * /proc device tree
- */
-void __init
-pci_create_OF_bus_map(void)
-{
-       struct property* of_prop;
-       
-       of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256);
-       if (of_prop && find_path_device("/")) {
-               memset(of_prop, -1, sizeof(struct property) + 256);
-               of_prop->name = "pci-OF-bus-map";
-               of_prop->length = 256;
-               of_prop->value = (unsigned char *)&of_prop[1];
-               prom_add_property(find_path_device("/"), of_prop);
-       }
-}
-
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+void pcibios_make_OF_bus_map(void)
 {
-       struct pci_dev *pdev;
-       struct device_node *np;
-
-       pdev = to_pci_dev (dev);
-       np = pci_device_to_OF_node(pdev);
-       if (np == NULL || np->full_name == NULL)
-               return 0;
-       return sprintf(buf, "%s", np->full_name);
 }
-static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-
-#endif /* CONFIG_PPC_OF */
 
 /* Add sysfs properties */
 void pcibios_add_platform_entries(struct pci_dev *pdev)
 {
-#ifdef CONFIG_PPC_OF
-       device_create_file(&pdev->dev, &dev_attr_devspec);
-#endif /* CONFIG_PPC_OF */
-}
-
-
-#ifdef CONFIG_PPC_PMAC
-/*
- * This set of routines checks for PCI<->PCI bridges that have closed
- * IO resources and have child devices. It tries to re-open an IO
- * window on them.
- *
- * This is a _temporary_ fix to workaround a problem with Apple's OF
- * closing IO windows on P2P bridges when the OF drivers of cards
- * below this bridge don't claim any IO range (typically ATI or
- * Adaptec).
- *
- * A more complete fix would be to use drivers/pci/setup-bus.c, which
- * involves a working pcibios_fixup_pbus_ranges(), some more care about
- * ordering when creating the host bus resources, and maybe a few more
- * minor tweaks
- */
-
-/* Initialize bridges with base/limit values we have collected */
-static void __init
-do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
-{
-       struct pci_dev *bridge = bus->self;
-       struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
-       u32 l;
-       u16 w;
-       struct resource res;
-
-       res = *(bus->resource[0]);
-
-       DBG("Remapping Bus %d, bridge: %s\n", bus->number, bridge->slot_name);
-       res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
-       res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
-       DBG("  IO window: %08lx-%08lx\n", res.start, res.end);
-
-       /* Set up the top and bottom of the PCI I/O segment for this bus. */
-       pci_read_config_dword(bridge, PCI_IO_BASE, &l);
-       l &= 0xffff000f;
-       l |= (res.start >> 8) & 0x00f0;
-       l |= res.end & 0xf000;
-       pci_write_config_dword(bridge, PCI_IO_BASE, l);
-
-       if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
-               l = (res.start >> 16) | (res.end & 0xffff0000);
-               pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
-       }
-
-       pci_read_config_word(bridge, PCI_COMMAND, &w);
-       w |= PCI_COMMAND_IO;
-       pci_write_config_word(bridge, PCI_COMMAND, w);
-
-#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
-       if (enable_vga) {
-               pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
-               w |= PCI_BRIDGE_CTL_VGA;
-               pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
-       }
-#endif
-}
-
-/* This function is pretty basic and actually quite broken for the
- * general case, it's enough for us right now though. It's supposed
- * to tell us if we need to open an IO range at all or not and what
- * size.
- */
-static int __init
-check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
-{
-       struct list_head *ln;
-       int     i;
-       int     rc = 0;
-
-#define push_end(res, size) do { unsigned long __sz = (size) ; \
-       res->end = ((res->end + __sz) / (__sz + 1)) * (__sz + 1) + __sz; \
-    } while (0)
-
-       for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
-               struct pci_dev *dev = pci_dev_b(ln);
-               u16 class = dev->class >> 8;
-
-               if (class == PCI_CLASS_DISPLAY_VGA ||
-                   class == PCI_CLASS_NOT_DEFINED_VGA)
-                       *found_vga = 1;
-               if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
-                       rc |= check_for_io_childs(dev->subordinate, res, found_vga);
-               if (class == PCI_CLASS_BRIDGE_CARDBUS)
-                       push_end(res, 0xfff);
-
-               for (i=0; i<PCI_NUM_RESOURCES; i++) {
-                       struct resource *r;
-                       unsigned long r_size;
-
-                       if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
-                           && i >= PCI_BRIDGE_RESOURCES)
-                               continue;
-                       r = &dev->resource[i];
-                       r_size = r->end - r->start;
-                       if (r_size < 0xfff)
-                               r_size = 0xfff;
-                       if (r->flags & IORESOURCE_IO && (r_size) != 0) {
-                               rc = 1;
-                               push_end(res, r_size);
-                       }
-               }
-       }
-
-       return rc;
-}
-
-/* Here we scan all P2P bridges of a given level that have a closed
- * IO window. Note that the test for the presence of a VGA card should
- * be improved to take into account already configured P2P bridges,
- * currently, we don't see them and might end up configuring 2 bridges
- * with VGA pass through enabled
- */
-static void __init
-do_fixup_p2p_level(struct pci_bus *bus)
-{
-       struct list_head *ln;
-       int i, parent_io;
-       int has_vga = 0;
-
-       for (parent_io=0; parent_io<4; parent_io++)
-               if (bus->resource[parent_io]->flags & IORESOURCE_IO)
-                       break;
-       if (parent_io >= 4)
-               return;
-
-       for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
-               struct pci_bus *b = pci_bus_b(ln);
-               struct pci_dev *d = b->self;
-               struct pci_controller* hose = (struct pci_controller *)d->sysdata;
-               struct resource *res = b->resource[0];
-               struct resource tmp_res;
-               unsigned long max;
-               int found_vga = 0;
-
-               memset(&tmp_res, 0, sizeof(tmp_res));
-               tmp_res.start = bus->resource[parent_io]->start;
-
-               /* We don't let low addresses go through that closed P2P bridge, well,
-                * that may not be necessary but I feel safer that way
-                */
-               if (tmp_res.start == 0)
-                       tmp_res.start = 0x1000;
-       
-               if (!list_empty(&b->devices) && res && res->flags == 0 &&
-                   res != bus->resource[parent_io] &&
-                   (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
-                   check_for_io_childs(b, &tmp_res, &found_vga)) {
-                       u8 io_base_lo;
-
-                       printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
-
-                       if (found_vga) {
-                               if (has_vga) {
-                                       printk(KERN_WARNING "Skipping VGA, already active"
-                                           " on bus segment\n");
-                                       found_vga = 0;
-                               } else
-                                       has_vga = 1;
-                       }
-                       pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
-
-                       if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
-                               max = ((unsigned long) hose->io_base_virt
-                                       - isa_io_base) + 0xffffffff;
-                       else
-                               max = ((unsigned long) hose->io_base_virt
-                                       - isa_io_base) + 0xffff;
-
-                       *res = tmp_res;
-                       res->flags = IORESOURCE_IO;
-                       res->name = b->name;
-               
-                       /* Find a resource in the parent where we can allocate */
-                       for (i = 0 ; i < 4; i++) {
-                               struct resource *r = bus->resource[i];
-                               if (!r)
-                                       continue;
-                               if ((r->flags & IORESOURCE_IO) == 0)
-                                       continue;
-                               DBG("Trying to allocate from %08lx, size %08lx from parent"
-                                   " res %d: %08lx -> %08lx\n",
-                                       res->start, res->end, i, r->start, r->end);
-                       
-                               if (allocate_resource(r, res, res->end + 1, res->start, max,
-                                   res->end + 1, NULL, NULL) < 0) {
-                                       DBG("Failed !\n");
-                                       continue;
-                               }
-                               do_update_p2p_io_resource(b, found_vga);
-                               break;
-                       }
-               }
-               do_fixup_p2p_level(b);
-       }
-}
-
-static void
-pcibios_fixup_p2p_bridges(void)
-{
-       struct list_head *ln;
-
-       for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
-               struct pci_bus *b = pci_bus_b(ln);
-               do_fixup_p2p_level(b);
-       }
 }
 
-#endif /* CONFIG_PPC_PMAC */
 
 static int __init
 pcibios_init(void)
@@ -1268,13 +650,13 @@ pcibios_init(void)
 
        /* Scan all of the recorded PCI controllers.  */
        for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
-               if (pci_assign_all_busses)
+               if (pci_assign_all_buses)
                        hose->first_busno = next_busno;
                hose->last_busno = 0xff;
                bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
                hose->last_busno = bus->subordinate;
-               if (pci_assign_all_busses || next_busno <= hose->last_busno)
-                       next_busno = hose->last_busno+1;
+               if (pci_assign_all_buses || next_busno <= hose->last_busno)
+                       next_busno = hose->last_busno + pcibios_assign_bus_offset;
        }
        pci_bus_count = next_busno;
 
@@ -1282,7 +664,7 @@ pcibios_init(void)
         * numbers vs. kernel bus numbers since we may have to
         * remap them.
         */
-       if (pci_assign_all_busses && have_of)
+       if (pci_assign_all_buses && have_of)
                pcibios_make_OF_bus_map();
 
        /* Do machine dependent PCI interrupt routing */
@@ -1297,9 +679,6 @@ pcibios_init(void)
        pcibios_allocate_bus_resources(&pci_root_buses);
        pcibios_allocate_resources(0);
        pcibios_allocate_resources(1);
-#ifdef CONFIG_PPC_PMAC
-       pcibios_fixup_p2p_bridges();
-#endif /* CONFIG_PPC_PMAC */
        pcibios_assign_resources();
 
        /* Call machine dependent post-init code */
@@ -1452,7 +831,7 @@ pci_bus_to_hose(int bus)
        return NULL;
 }
 
-void*
+void __iomem *
 pci_bus_io_base(unsigned int bus)
 {
        struct pci_controller *hose;
@@ -1498,96 +877,147 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
        return res->start;
 }
 
-/*
- * Platform support for /proc/bus/pci/X/Y mmap()s,
- * modelled on the sparc64 implementation by Dave Miller.
- *  -- paulus.
- */
 
-/*
- * Adjust vm_pgoff of VMA such that it is the physical page offset
- * corresponding to the 32-bit pci bus offset for DEV requested by the user.
- *
- * Basically, the user finds the base address for his device which he wishes
- * to mmap.  They read the 32-bit value from the config space base register,
- * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
- * offset parameter of mmap on /proc/bus/pci/XXX for that device.
- *
- * Returns negative error code on failure, zero on success.
- */
-static __inline__ int
-__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
-                      enum pci_mmap_state mmap_state)
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+                                              resource_size_t *offset,
+                                              enum pci_mmap_state mmap_state)
 {
-       struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
-       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-       unsigned long size = vma->vm_end - vma->vm_start;
-       unsigned long base;
-       struct resource *res;
-       int i;
-       int ret = -EINVAL;
+       struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+       unsigned long io_offset = 0;
+       int i, res_bit;
 
        if (hose == 0)
-               return -EINVAL;         /* should never happen */
-       if (offset + size <= offset)
-               return -EINVAL;
+               return NULL;            /* should never happen */
 
+       /* If memory, add on the PCI bridge address offset */
        if (mmap_state == pci_mmap_mem) {
-               /* PCI memory space */
-               base = hose->pci_mem_offset;
-               for (i = 0; i < 3; ++i) {
-                       res = &hose->mem_resources[i];
-                       if (res->flags == 0)
-                               continue;
-                       if (offset >= res->start - base
-                           && offset + size - 1 <= res->end - base) {
-                               ret = 0;
-                               break;
-                       }
-               }
-               offset += hose->pci_mem_offset;
+#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
+               *offset += hose->pci_mem_offset;
+#endif
+               res_bit = IORESOURCE_MEM;
        } else {
-               /* PCI I/O space */
-               base = (unsigned long)hose->io_base_virt - isa_io_base;
-               res = &hose->io_resource;
-               if (offset >= res->start - base
-                   && offset + size - 1 <= res->end - base)
-                       ret = 0;
-               offset += hose->io_base_phys;
+               io_offset = hose->io_base_virt - ___IO_BASE;
+               *offset += io_offset;
+               res_bit = IORESOURCE_IO;
        }
 
-       vma->vm_pgoff = offset >> PAGE_SHIFT;
-       return ret;
-}
+       /*
+        * Check that the offset requested corresponds to one of the
+        * resources of the device.
+        */
+       for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+               struct resource *rp = &dev->resource[i];
+               int flags = rp->flags;
 
-/*
- * Set vm_flags of VMA, as appropriate for this architecture, for a pci device
- * mapping.
- */
-static __inline__ void
-__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
-                    enum pci_mmap_state mmap_state)
-{
-       vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
+               /* treat ROM as memory (should be already) */
+               if (i == PCI_ROM_RESOURCE)
+                       flags |= IORESOURCE_MEM;
+
+               /* Active and same type? */
+               if ((flags & res_bit) == 0)
+                       continue;
+
+               /* In the range of this resource? */
+               if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+                       continue;
+
+               /* found it! construct the final physical address */
+               if (mmap_state == pci_mmap_io)
+                       *offset += hose->io_base_phys - io_offset;
+               return rp;
+       }
+
+       return NULL;
 }
 
 /*
  * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
  * device mapping.
  */
-static __inline__ void
-__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
-                     enum pci_mmap_state mmap_state, int write_combine)
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+                                     pgprot_t protection,
+                                     enum pci_mmap_state mmap_state,
+                                     int write_combine)
 {
-       int prot = pgprot_val(vma->vm_page_prot);
+       unsigned long prot = pgprot_val(protection);
+
+       /* Write combine is always 0 on non-memory space mappings. On
+        * memory space, if the user didn't pass 1, we check for a
+        * "prefetchable" resource. This is a bit hackish, but we use
+        * this to workaround the inability of /sysfs to provide a write
+        * combine bit
+        */
+       if (mmap_state != pci_mmap_mem)
+               write_combine = 0;
+       else if (write_combine == 0) {
+               if (rp->flags & IORESOURCE_PREFETCH)
+                       write_combine = 1;
+       }
 
        /* XXX would be nice to have a way to ask for write-through */
        prot |= _PAGE_NO_CACHE;
-       if (!write_combine)
+       if (write_combine)
+               prot &= ~_PAGE_GUARDED;
+       else
                prot |= _PAGE_GUARDED;
-       vma->vm_page_prot = __pgprot(prot);
+
+       printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev),
+               (unsigned long long)rp->start, prot);
+
+       return __pgprot(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+                                 unsigned long pfn,
+                                 unsigned long size,
+                                 pgprot_t protection)
+{
+       struct pci_dev *pdev = NULL;
+       struct resource *found = NULL;
+       unsigned long prot = pgprot_val(protection);
+       unsigned long offset = pfn << PAGE_SHIFT;
+       int i;
+
+       if (page_is_ram(pfn))
+               return prot;
+
+       prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+       for_each_pci_dev(pdev) {
+               for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+                       struct resource *rp = &pdev->resource[i];
+                       int flags = rp->flags;
+
+                       /* Active and same type? */
+                       if ((flags & IORESOURCE_MEM) == 0)
+                               continue;
+                       /* In the range of this resource? */
+                       if (offset < (rp->start & PAGE_MASK) ||
+                           offset > rp->end)
+                               continue;
+                       found = rp;
+                       break;
+               }
+               if (found)
+                       break;
+       }
+       if (found) {
+               if (found->flags & IORESOURCE_PREFETCH)
+                       prot &= ~_PAGE_GUARDED;
+               pci_dev_put(pdev);
+       }
+
+       DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+
+       return __pgprot(prot);
 }
 
+
 /*
  * Perform the actual remap of the pages for a PCI device mapping, as
  * appropriate for this architecture.  The region in the process to map
@@ -1602,16 +1032,20 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                        enum pci_mmap_state mmap_state,
                        int write_combine)
 {
+       resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
+       struct resource *rp;
        int ret;
 
-       ret = __pci_mmap_make_offset(dev, vma, mmap_state);
-       if (ret < 0)
-               return ret;
+       rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+       if (rp == NULL)
+               return -EINVAL;
 
-       __pci_mmap_set_flags(dev, vma, mmap_state);
-       __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
+       vma->vm_pgoff = offset >> PAGE_SHIFT;
+       vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+                                                 vma->vm_page_prot,
+                                                 mmap_state, write_combine);
 
-       ret = remap_page_range(vma, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
+       ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
                               vma->vm_end - vma->vm_start, vma->vm_page_prot);
 
        return ret;
@@ -1675,17 +1109,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
        struct pci_controller* hose;
        long result = -EOPNOTSUPP;
 
-       /* Argh ! Please forgive me for that hack, but that's the
-        * simplest way to get existing XFree to not lockup on some
-        * G5 machines... So when something asks for bus 0 io base
-        * (bus 0 is HT root), we return the AGP one instead.
-        */
-#ifdef CONFIG_PPC_PMAC
-       if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4"))
-               if (bus == 0)
-                       bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
-
        hose = pci_bus_to_hose(bus);
        if (!hose)
                return -ENODEV;
@@ -1706,9 +1129,47 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
        return result;
 }
 
-void __init
-pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
-                 int flags, char *name)
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                         const struct resource *rsrc,
+                         resource_size_t *start, resource_size_t *end)
+{
+       struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+       resource_size_t offset = 0;
+
+       if (hose == NULL)
+               return;
+
+       if (rsrc->flags & IORESOURCE_IO)
+               offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+
+       /* We pass a fully fixed up address to userland for MMIO instead of
+        * a BAR value because X is lame and expects to be able to use that
+        * to pass to /dev/mem !
+        *
+        * That means that we'll have potentially 64 bits values where some
+        * userland apps only expect 32 (like X itself since it thinks only
+        * Sparc has 64 bits MMIO) but if we don't do that, we break it on
+        * 32 bits CHRPs :-(
+        *
+        * Hopefully, the sysfs insterface is immune to that gunk. Once X
+        * has been fixed (and the fix spread enough), we can re-enable the
+        * 2 lines below and pass down a BAR value to userland. In that case
+        * we'll also have to re-enable the matching code in
+        * __pci_mmap_make_offset().
+        *
+        * BenH.
+        */
+#if 0
+       else if (rsrc->flags & IORESOURCE_MEM)
+               offset = hose->pci_mem_offset;
+#endif
+
+       *start = rsrc->start - offset;
+       *end = rsrc->end - offset;
+}
+
+void __init pci_init_resource(struct resource *res, resource_size_t start,
+                             resource_size_t end, int flags, char *name)
 {
        res->start = start;
        res->end = end;
@@ -1719,6 +1180,53 @@ pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
        res->child = NULL;
 }
 
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+       unsigned long start = pci_resource_start(dev, bar);
+       unsigned long len = pci_resource_len(dev, bar);
+       unsigned long flags = pci_resource_flags(dev, bar);
+
+       if (!len)
+               return NULL;
+       if (max && len > max)
+               len = max;
+       if (flags & IORESOURCE_IO)
+               return ioport_map(start, len);
+       if (flags & IORESOURCE_MEM)
+               /* Not checking IORESOURCE_CACHEABLE because PPC does
+                * not currently distinguish between ioremap and
+                * ioremap_nocache.
+                */
+               return ioremap(start, len);
+       /* What? */
+       return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+       /* Nothing to do */
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
+
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+       struct pci_controller* hose = hose_head;
+
+       for (; hose; hose = hose->next) {
+               unsigned int size = hose->io_resource.end -
+                       hose->io_resource.start + 1;
+               if (address >= hose->io_base_phys &&
+                   address < (hose->io_base_phys + size)) {
+                       unsigned long base =
+                               (unsigned long)hose->io_base_virt - _IO_BASE;
+                       return base + (address - hose->io_base_phys);
+               }
+       }
+       return (unsigned int)-1;
+}
+EXPORT_SYMBOL(pci_address_to_pio);
+
 /*
  * Null PCI config access functions, for the case when we can't
  * find a hose.