ACPI, APEI, PCIE AER, use general HEST table parsing in AER firmware_first setup
[safe/jmp/linux-2.6] / drivers / pci / probe.c
index 4b47b4b..f4adba2 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
-#include <acpi/acpi_hest.h>
 #include "pci.h"
 
 #define CARDBUS_LATENCY_TIMER  176     /* secondary latency timer */
@@ -89,6 +88,7 @@ static void release_pcibus_dev(struct device *dev)
 
        if (pci_bus->bridge)
                put_device(pci_bus->bridge);
+       pci_bus_remove_resources(pci_bus);
        kfree(pci_bus);
 }
 
@@ -311,7 +311,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
                dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
-                        "  bridge window [io  %04lx - %04lx] reg reading\n",
+                        "  bridge window [io  %#06lx-%#06lx] (disabled)\n",
                                 base, limit);
        }
 }
@@ -335,7 +335,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
                dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
-                       "  bridge window [mem 0x%08lx - 0x%08lx] reg reading\n",
+                       "  bridge window [mem %#010lx-%#010lx] (disabled)\n",
                                         base, limit + 0xfffff);
        }
 }
@@ -386,7 +386,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
                dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
        } else {
                dev_printk(KERN_DEBUG, &dev->dev,
-                    "  bridge window [mem 0x%08lx - %08lx pref] reg reading\n",
+                    "  bridge window [mem %#010lx-%#010lx pref] (disabled)\n",
                                         base, limit + 0xfffff);
        }
 }
@@ -394,6 +394,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
 void __devinit pci_read_bridge_bases(struct pci_bus *child)
 {
        struct pci_dev *dev = child->self;
+       struct resource *res;
        int i;
 
        if (pci_is_root_bus(child))     /* It's a host bus, nothing to read */
@@ -403,14 +404,25 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                 child->secondary, child->subordinate,
                 dev->transparent ? " (subtractive decode)" : "");
 
-       if (dev->transparent) {
-               for (i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
-                       child->resource[i] = child->parent->resource[i - 3];
-       }
+       pci_bus_remove_resources(child);
+       for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
+               child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
 
        pci_read_bridge_io(child);
        pci_read_bridge_mmio(child);
        pci_read_bridge_mmio_pref(child);
+
+       if (dev->transparent) {
+               pci_bus_for_each_resource(child->parent, res, i) {
+                       if (res) {
+                               pci_bus_add_resource(child, res,
+                                                    PCI_SUBTRACTIVE_DECODE);
+                               dev_printk(KERN_DEBUG, &dev->dev,
+                                          "  bridge window %pR (subtractive decode)\n",
+                                          res);
+                       }
+               }
+       }
 }
 
 static struct pci_bus * pci_alloc_bus(void)
@@ -423,6 +435,7 @@ static struct pci_bus * pci_alloc_bus(void)
                INIT_LIST_HEAD(&b->children);
                INIT_LIST_HEAD(&b->devices);
                INIT_LIST_HEAD(&b->slots);
+               INIT_LIST_HEAD(&b->resources);
                b->max_bus_speed = PCI_SPEED_UNKNOWN;
                b->cur_bus_speed = PCI_SPEED_UNKNOWN;
        }
@@ -659,16 +672,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
        int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
        u32 buses, i, j = 0;
        u16 bctl;
+       u8 primary, secondary, subordinate;
        int broken = 0;
 
        pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
+       primary = buses & 0xFF;
+       secondary = (buses >> 8) & 0xFF;
+       subordinate = (buses >> 16) & 0xFF;
 
-       dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n",
-               buses & 0xffffff, pass);
+       dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+               secondary, subordinate, pass);
 
        /* Check if setup is sensible at all */
        if (!pass &&
-           ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) {
+           (primary != bus->number || secondary <= bus->number)) {
                dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n");
                broken = 1;
        }
@@ -679,15 +696,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
        pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
                              bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
 
-       if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) {
-               unsigned int cmax, busnr;
+       if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
+           !is_cardbus && !broken) {
+               unsigned int cmax;
                /*
                 * Bus already configured by firmware, process it in the first
                 * pass and just note the configuration.
                 */
                if (pass)
                        goto out;
-               busnr = (buses >> 8) & 0xFF;
 
                /*
                 * If we already got to this bus through a different bridge,
@@ -696,13 +713,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
                 * However, we continue to descend down the hierarchy and
                 * scan remaining child buses.
                 */
-               child = pci_find_bus(pci_domain_nr(bus), busnr);
+               child = pci_find_bus(pci_domain_nr(bus), secondary);
                if (!child) {
-                       child = pci_add_new_bus(bus, dev, busnr);
+                       child = pci_add_new_bus(bus, dev, secondary);
                        if (!child)
                                goto out;
-                       child->primary = buses & 0xFF;
-                       child->subordinate = (buses >> 16) & 0xFF;
+                       child->primary = primary;
+                       child->subordinate = subordinate;
                        child->bridge_ctl = bctl;
                }
 
@@ -886,12 +903,6 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev)
                pdev->is_hotplug_bridge = 1;
 }
 
-static void set_pci_aer_firmware_first(struct pci_dev *pdev)
-{
-       if (acpi_hest_firmware_first_pci(pdev))
-               pdev->aer_firmware_first = 1;
-}
-
 #define LEGACY_IO_RESOURCE     (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
 /**
@@ -921,7 +932,6 @@ int pci_setup_device(struct pci_dev *dev)
        dev->multifunction = !!(hdr_type & 0x80);
        dev->error_state = pci_channel_io_normal;
        set_pcie_port_type(dev);
-       set_pci_aer_firmware_first(dev);
 
        list_for_each_entry(slot, &dev->bus->slots, list)
                if (PCI_SLOT(dev->devfn) == slot->number)
@@ -1422,6 +1432,7 @@ struct pci_bus * pci_create_bus(struct device *parent,
        if (error)
                goto dev_reg_err;
        b->bridge = get_device(dev);
+       device_enable_async_suspend(b->bridge);
 
        if (!parent)
                set_dev_node(b->bridge, pcibus_to_node(b));