]> err.no Git - linux-2.6/blobdiff - arch/ia64/pci/pci.c
Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-ucb.git
[linux-2.6] / arch / ia64 / pci / pci.c
index e3fc4edea113a89855b8024acb4a8446b62e1674..f9472c50ab4298a072fd25cfca6743ff69122b91 100644 (file)
@@ -157,6 +157,7 @@ alloc_pci_controller (int seg)
 
        memset(controller, 0, sizeof(*controller));
        controller->segment = seg;
+       controller->node = -1;
        return controller;
 }
 
@@ -288,6 +289,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
        unsigned int windows = 0;
        struct pci_bus *pbus;
        char *name;
+       int pxm;
 
        controller = alloc_pci_controller(domain);
        if (!controller)
@@ -295,10 +297,16 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
 
        controller->acpi_handle = device->handle;
 
+       pxm = acpi_get_pxm(controller->acpi_handle);
+#ifdef CONFIG_NUMA
+       if (pxm >= 0)
+               controller->node = pxm_to_nid_map[pxm];
+#endif
+
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
                        &windows);
-       controller->window = kmalloc(sizeof(*controller->window) * windows,
-                       GFP_KERNEL);
+       controller->window = kmalloc_node(sizeof(*controller->window) * windows,
+                       GFP_KERNEL, controller->node);
        if (!controller->window)
                goto out2;
 
@@ -312,7 +320,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
                        &info);
 
-       pbus = pci_scan_bus(bus, &pci_root_ops, controller);
+       pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
        if (pbus)
                pcibios_setup_root_windows(pbus, controller);
 
@@ -372,6 +380,26 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
        res->start = region->start + offset;
        res->end = region->end + offset;
 }
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+{
+       unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+       struct resource *devr = &dev->resource[idx];
+
+       if (!dev->bus)
+               return 0;
+       for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+               struct resource *busr = dev->bus->resource[i];
+
+               if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+                       continue;
+               if ((devr->start) && (devr->start >= busr->start) &&
+                               (devr->end <= busr->end))
+                       return 1;
+       }
+       return 0;
+}
 
 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 {
@@ -386,7 +414,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
                region.start = dev->resource[i].start;
                region.end = dev->resource[i].end;
                pcibios_bus_to_resource(dev, &dev->resource[i], &region);
-               pci_claim_resource(dev, i);
+               if ((is_valid_resource(dev, i)))
+                       pci_claim_resource(dev, i);
        }
 }
 
@@ -398,6 +427,10 @@ pcibios_fixup_bus (struct pci_bus *b)
 {
        struct pci_dev *dev;
 
+       if (b->self) {
+               pci_read_bridge_bases(b);
+               pcibios_fixup_device_resources(b->self);
+       }
        list_for_each_entry(dev, &b->devices, bus_list)
                pcibios_fixup_device_resources(dev);
 
@@ -418,18 +451,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
        u16 cmd, old_cmd;
        int idx;
        struct resource *r;
+       unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
 
        if (!dev)
                return -EINVAL;
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        old_cmd = cmd;
-       for (idx=0; idx<6; idx++) {
+       for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
                /* Only set up the desired resources.  */
                if (!(mask & (1 << idx)))
                        continue;
 
                r = &dev->resource[idx];
+               if (!(r->flags & type_mask))
+                       continue;
+               if ((idx == PCI_ROM_RESOURCE) &&
+                               (!(r->flags & IORESOURCE_ROM_ENABLE)))
+                       continue;
                if (!r->start && r->end) {
                        printk(KERN_ERR
                               "PCI: Device %s not available because of resource collisions\n",
@@ -441,8 +480,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask)
                if (r->flags & IORESOURCE_MEM)
                        cmd |= PCI_COMMAND_MEMORY;
        }
-       if (dev->resource[PCI_ROM_RESOURCE].start)
-               cmd |= PCI_COMMAND_MEMORY;
        if (cmd != old_cmd) {
                printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
                pci_write_config_word(dev, PCI_COMMAND, cmd);