vserver 1.9.3
[linux-2.6.git] / arch / ppc / kernel / pci.c
index 5b49655..08cddde 100644 (file)
@@ -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);
 
@@ -45,11 +46,6 @@ 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
@@ -64,20 +60,6 @@ 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)
 {
@@ -90,6 +72,7 @@ fixup_rev1_53c810(struct pci_dev* dev)
                dev->class = PCI_CLASS_STORAGE_SCSI;
        }
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR,    PCI_DEVICE_ID_NCR_53C810,       fixup_rev1_53c810);
 
 static void
 fixup_broken_pcnet32(struct pci_dev* dev)
@@ -100,6 +83,7 @@ fixup_broken_pcnet32(struct pci_dev* dev)
                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 +96,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,7 +113,7 @@ pcibios_fixup_resources(struct pci_dev *dev)
                struct resource *res = dev->resource + i;
                if (!res->flags)
                        continue;
-               if (!res->start || res->end == 0xffffffff) {
+               if (res->end == 0xffffffff) {
                        DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n",
                            pci_name(dev), i, res->start, res->end);
                        res->end -= res->start;
@@ -158,9 +143,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 +158,7 @@ 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);
 
 /*
  * We need to avoid collisions with `mirrored' VGA ports
@@ -187,8 +173,7 @@ 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,
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size,
                       unsigned long align)
 {
        struct pci_dev *dev = data;
@@ -208,7 +193,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
@@ -347,6 +332,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];
@@ -425,7 +412,7 @@ probe_resource(struct pci_bus *parent, struct resource *pr,
                        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;
@@ -659,21 +646,21 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
                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];
+               printk(KERN_WARNING "Can't get bus-range for %s, "
+                      "assuming it starts at 0\n", node->full_name);
+               pci_to_OF_bus_map[pci_bus] = 0;
+       } else
+               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);
+               class_code = (unsigned int *) get_property(node, "class-code", NULL);
                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);
+               reg = (unsigned int *)get_property(node, "reg", NULL);
                if (!reg)
                        continue;
                dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
@@ -710,7 +697,7 @@ pcibios_make_OF_bus_map(void)
                        continue;
                make_one_node_map(node, hose->first_busno);
        }
-       of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", 0);
+       of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL);
        if (of_prop_map)
                memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
 #ifdef DEBUG
@@ -741,7 +728,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
                 * 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);
+               class_code = (unsigned int *) get_property(node, "class-code", NULL);
                if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
                        (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
                        strcmp(node->name, "multifunc-device"))
@@ -759,7 +746,7 @@ 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);
+       reg = (unsigned int *) get_property(node, "reg", NULL);
        if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
                && ((reg[0] >> 16) & 0xff) == fdata[0])
                return 1;
@@ -872,7 +859,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
        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);
+       reg = (unsigned int *) get_property(node, "reg", NULL);
        if (!reg)
                return -ENODEV;
        *bus = (reg[0] >> 16) & 0xff;
@@ -1073,6 +1060,8 @@ do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
        u16 w;
        struct resource res;
 
+       if (bus->resource[0] == NULL)
+               return;
        res = *(bus->resource[0]);
 
        DBG("Remapping Bus %d, bridge: %s\n", bus->number, bridge->slot_name);
@@ -1168,7 +1157,8 @@ do_fixup_p2p_level(struct pci_bus *bus)
        int has_vga = 0;
 
        for (parent_io=0; parent_io<4; parent_io++)
-               if (bus->resource[parent_io]->flags & IORESOURCE_IO)
+               if (bus->resource[parent_io]
+                   && bus->resource[parent_io]->flags & IORESOURCE_IO)
                        break;
        if (parent_io >= 4)
                return;
@@ -1274,7 +1264,7 @@ pcibios_init(void)
                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;
+                       next_busno = hose->last_busno + pcibios_assign_bus_offset;
        }
        pci_bus_count = next_busno;
 
@@ -1719,6 +1709,32 @@ 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)
+               return (void __iomem *) start;
+       /* What? */
+       return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+       /* Nothing to do */
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
+
+
 /*
  * Null PCI config access functions, for the case when we can't
  * find a hose.