[IA64] remove use of asm/segment.h
[linux-2.6.git] / arch / ia64 / pci / pci.c
index 2a14877..0addeca 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <asm/machvec.h>
 #include <asm/page.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/sal.h>
@@ -157,6 +156,7 @@ alloc_pci_controller (int seg)
 
        memset(controller, 0, sizeof(*controller));
        controller->segment = seg;
+       controller->node = -1;
        return controller;
 }
 
@@ -288,6 +288,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 +296,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;
 
@@ -373,6 +380,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
        res->end = region->end + offset;
 }
 
+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)
 {
        struct pci_bus_region region;
@@ -386,7 +412,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 +425,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);