diff -u -r 50_iosapic_segment/arch/ia64/kernel/acpi.c 60_pci_tra/arch/ia64/kernel/acpi.c --- 50_iosapic_segment/arch/ia64/kernel/acpi.c Fri Jul 19 17:24:49 2002 +++ 60_pci_tra/arch/ia64/kernel/acpi.c Fri Jul 19 17:24:50 2002 @@ -166,6 +166,73 @@ kfree(buf->pointer); } +static void +acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *size, u64 *tra) +{ + int offset = 0; + acpi_resource_address16 *addr16; + acpi_resource_address32 *addr32; + acpi_resource_address64 *addr64; + + for (;;) { + acpi_resource *res = acpi_get_crs_next(buf, &offset); + if (!res) + return; + switch (res->id) { + case ACPI_RSTYPE_ADDRESS16: + addr16 = (acpi_resource_address16 *) &res->data; + + if (type == addr16->resource_type) { + *base = addr16->min_address_range; + *size = addr16->address_length; + *tra = addr16->address_translation_offset; + return; + } + break; + case ACPI_RSTYPE_ADDRESS32: + addr32 = (acpi_resource_address32 *) &res->data; + if (type == addr32->resource_type) { + *base = addr32->min_address_range; + *size = addr32->address_length; + *tra = addr32->address_translation_offset; + return; + } + break; + case ACPI_RSTYPE_ADDRESS64: + addr64 = (acpi_resource_address64 *) &res->data; + if (type == addr64->resource_type) { + *base = addr64->min_address_range; + *size = addr64->address_length; + *tra = addr64->address_translation_offset; + return; + } + break; + } + } +} + +acpi_status +acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra) +{ + acpi_status status; + acpi_buffer buf; + + *base = 0; + *length = 0; + *tra = 0; + + status = acpi_get_crs(obj, &buf); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n"); + return status; + } + + acpi_get_crs_addr(&buf, type, base, length, tra); + + acpi_dispose_crs(&buf); + + return AE_OK; +} #endif /* CONFIG_ACPI */ #ifdef CONFIG_ACPI_BOOT diff -u -r 50_iosapic_segment/arch/ia64/kernel/pci.c 60_pci_tra/arch/ia64/kernel/pci.c --- 50_iosapic_segment/arch/ia64/kernel/pci.c Fri Jul 19 17:24:49 2002 +++ 60_pci_tra/arch/ia64/kernel/pci.c Fri Jul 19 17:24:50 2002 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -214,6 +215,7 @@ pcibios_scan_root(void *handle, int seg, int bus) { struct pci_controller *controller; + u64 base, size, offset; printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus); @@ -222,6 +224,10 @@ return NULL; controller->acpi_handle = handle; + + acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset); + controller->mem_offset = offset; + return scan_root_bus(bus, pci_root_ops, controller); } @@ -267,6 +273,27 @@ subsys_initcall(pcibios_init); +static void __init +pcibios_fixup_resource(struct resource *res, u64 offset) +{ + res->start += offset; + res->end += offset; +} + +void __init +pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) +{ + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + if (!dev->resource[i].start) + continue; + if (dev->resource[i].flags & IORESOURCE_MEM) + pcibios_fixup_resource(&dev->resource[i], + PCI_CONTROLLER(dev)->mem_offset); + } +} + /* * Called after each bus is probed, but before its children * are examined. @@ -274,7 +301,10 @@ void __init pcibios_fixup_bus (struct pci_bus *b) { - return; + struct list_head *ln; + + for (ln = b->devices.next; ln != &b->devices; ln = ln->next) + pcibios_fixup_device_resources(pci_dev_b(ln), b); } void __init diff -u -r 50_iosapic_segment/include/asm-ia64/pci.h 60_pci_tra/include/asm-ia64/pci.h --- 50_iosapic_segment/include/asm-ia64/pci.h Fri Jul 19 17:24:49 2002 +++ 60_pci_tra/include/asm-ia64/pci.h Fri Jul 19 17:24:50 2002 @@ -99,6 +99,8 @@ struct pci_controller { void *acpi_handle; int segment; + + u64 mem_offset; }; #define PCI_CONTROLLER(dev) ((struct pci_controller *) dev->sysdata) diff -u -r 50_iosapic_segment/include/linux/acpi.h 60_pci_tra/include/linux/acpi.h --- 50_iosapic_segment/include/linux/acpi.h Fri Jul 19 17:24:49 2002 +++ 60_pci_tra/include/linux/acpi.h Fri Jul 19 17:30:06 2002 @@ -390,6 +390,7 @@ int acpi_init(void); int acpi_irq_to_vector(u32 irq); +acpi_status acpi_get_addr_space(acpi_handle, u8 type, u64 *base, u64 *length, u64 *tra); #endif /*CONFIG_ACPI_INTERPRETER*/