vserver 1.9.5.x5
[linux-2.6.git] / arch / ppc64 / kernel / pmac_pci.c
index 9e1a069..a0df4e8 100644 (file)
 #define DBG(x...)
 #endif
 
-extern int pci_probe_only;
-extern int pci_read_irq_line(struct pci_dev *pci_dev);
-
 /* XXX Could be per-controller, but I don't think we risk anything by
  * assuming we won't have both UniNorth and Bandit */
 static int has_uninorth;
 static struct pci_controller *u3_agp;
-u8 pci_cache_line_size;
-struct pci_dev *k2_skiplist[2];
+struct device_node *k2_skiplist[2];
 
 static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
 {
@@ -150,16 +146,9 @@ static int __pmac macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
                                      int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       struct device_node *busdn;
        unsigned long addr;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
-       if (busdn == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       hose = busdn->phb;
+       hose = pci_bus_to_host(bus);
        if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -188,16 +177,9 @@ static int __pmac macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
                                       int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       struct device_node *busdn;
        unsigned long addr;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
-       if (busdn == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       hose = busdn->phb;
+       hose = pci_bus_to_host(bus);
        if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -236,14 +218,43 @@ static struct pci_ops macrisc_pci_ops =
  * implement self-view of the HT host yet
  */
 
-static int skip_k2_device(struct pci_bus *bus, unsigned int devfn)
+/*
+ * This function deals with some "special cases" devices.
+ *
+ *  0 -> No special case
+ *  1 -> Skip the device but act as if the access was successfull
+ *       (return 0xff's on reads, eventually, cache config space
+ *       accesses in a later version)
+ * -1 -> Hide the device (unsuccessful acess)
+ */
+static int u3_ht_skip_device(struct pci_controller *hose,
+                            struct pci_bus *bus, unsigned int devfn)
 {
+       struct device_node *busdn, *dn;
        int i;
 
+       /* 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
+        */
+       if (bus->self)
+               busdn = pci_device_to_OF_node(bus->self);
+       else
+               busdn = hose->arch_data;
+       for (dn = busdn->child; dn; dn = dn->sibling)
+               if (dn->devfn == devfn)
+                       break;
+       if (dn == NULL)
+               return -1;
+
+       /*
+        * When a device in K2 is powered down, we die on config
+        * cycle accesses. Fix that here.
+        */
        for (i=0; i<2; i++)
-               if (k2_skiplist[i] && k2_skiplist[i]->bus == bus &&
-                   k2_skiplist[i]->devfn == devfn)
+               if (k2_skiplist[i] == dn)
                        return 1;
+
        return 0;
 }
 
@@ -259,8 +270,7 @@ static unsigned long __pmac u3_ht_cfg_access(struct pci_controller* hose,
 {
        if (bus == hose->first_busno) {
                /* For now, we don't self probe U3 HT bridge */
-               if (PCI_FUNC(devfn) != 0 || PCI_SLOT(devfn) > 7 ||
-                   PCI_SLOT(devfn) < 1)
+               if (PCI_SLOT(devfn) == 0)
                        return 0;
                return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
        } else
@@ -271,39 +281,21 @@ 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, *dn;
        unsigned long addr;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
-       if (busdn == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       hose = busdn->phb;
-       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)
+       hose = pci_bus_to_host(bus);      
+       if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
-       /*
-        * When a device in K2 is powered down, we die on config
-        * cycle accesses. Fix that here. We may ultimately want
-        * to cache the config space for those instead of returning
-        * 0xffffffff's to make life easier to HW detection tools
-        */
-       if (skip_k2_device(bus, devfn)) {
+
+       switch (u3_ht_skip_device(hose, bus, devfn)) {
+       case 0:
+               break;
+       case 1:
                switch (len) {
                case 1:
                        *val = 0xff; break;
@@ -313,6 +305,8 @@ static int __pmac u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                        *val = 0xfffffffful; break;
                }
                return PCIBIOS_SUCCESSFUL;
+       default:
+               return PCIBIOS_DEVICE_NOT_FOUND;
        }
 
        /*
@@ -337,28 +331,24 @@ static int __pmac u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       struct device_node *busdn;
        unsigned long addr;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
-       if (busdn == NULL)
-               return PCIBIOS_DEVICE_NOT_FOUND;
-       hose = busdn->phb;
+       hose = pci_bus_to_host(bus);
        if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
-       /*
-        * When a device in K2 is powered down, we die on config
-        * cycle accesses. Fix that here.
-        */
-       if (skip_k2_device(bus, devfn))
+
+       switch (u3_ht_skip_device(hose, bus, devfn)) {
+       case 0:
+               break;
+       case 1:
                return PCIBIOS_SUCCESSFUL;
+       default:
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       }
 
        /*
         * Note: the caller has already checked that offset is
@@ -513,7 +503,7 @@ static void __init pmac_process_bridge_OF_ranges(struct pci_controller *hose,
        dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
        if (!dt_ranges)
                return;
-       /*      lc_ranges = (unsigned int *) alloc_bootmem(rlen);*/
+       /*      lc_ranges = alloc_bootmem(rlen);*/
        lc_ranges = static_lc_ranges;
        if (!lc_ranges)
                return; /* what can we do here ? */
@@ -623,15 +613,17 @@ static int __init add_bridge(struct device_node *dev)
                                       dev->full_name);
                }
 
-               hose = pci_alloc_pci_controller(phb_type_apple);
-               if (!hose)
-                       return -ENOMEM;
+       hose = alloc_bootmem(sizeof(struct pci_controller));
+       if (hose == NULL)
+               return -ENOMEM;
+               pci_setup_pci_controller(hose);
+
                hose->arch_data = dev;
                hose->first_busno = bus_range ? bus_range[0] : 0;
                hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
-       of_prop = (struct property *)alloc_bootmem(sizeof(struct property) +
-                       sizeof(hose->global_number));        
+       of_prop = alloc_bootmem(sizeof(struct property) +
+                               sizeof(hose->global_number));
        if (of_prop) {
                memset(of_prop, 0, sizeof(struct property));
                of_prop->name = "linux,pci-domain";
@@ -669,13 +661,8 @@ void __init pmac_pcibios_fixup(void)
 {
        struct pci_dev *dev = NULL;
 
-       while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
+       for_each_pci_dev(dev)
                pci_read_irq_line(dev);
-
-       pci_fix_bus_sysdata();
-
-       iommu_setup_u3();
-
 }
 
 static void __init pmac_fixup_phb_resources(void)
@@ -747,14 +734,9 @@ void __init pmac_pci_init(void)
 
        pmac_check_ht_link();
 
-       /* Tell pci.c to use the common resource allocation mecanism */
-       pci_probe_only = 0;
+       /* Tell pci.c to not use the common resource allocation mecanism */
+       pci_probe_only = 1;
        
-       /* HT don't do more than 64 bytes transfers. FIXME: Deal with
-        * the exception of U3/AGP (hook into pci_set_mwi)
-        */
-       pci_cache_line_size = 16; /* 64 bytes */
-
        /* Allow all IO */
        io_page_mask = -1;
 }
@@ -763,7 +745,7 @@ void __init pmac_pci_init(void)
  * Disable second function on K2-SATA, it's broken
  * and disable IO BARs on first one
  */
-void fixup_k2_sata(struct pci_dev* dev)
+static void fixup_k2_sata(struct pci_dev* dev)
 {
        int i;
        u16 cmd;