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 Sat Jul 20 16:34:49 2002 +++ 60_pci_tra/arch/ia64/kernel/acpi.c Sat Jul 20 16:35:33 2002 @@ -169,6 +169,73 @@ kfree(buf->pointer); } +static void +acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, 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; + *length = 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; + *length = 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; + *length = 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 Sat Jul 20 16:33:47 2002 +++ 60_pci_tra/arch/ia64/kernel/pci.c Sat Jul 20 16:35:33 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); } @@ -266,6 +272,27 @@ return; } +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. @@ -273,7 +300,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/arch/ia64/kernel/setup.c 60_pci_tra/arch/ia64/kernel/setup.c --- 50_iosapic_segment/arch/ia64/kernel/setup.c Sat Jul 20 16:31:07 2002 +++ 60_pci_tra/arch/ia64/kernel/setup.c Sat Jul 20 16:35:33 2002 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -295,6 +296,7 @@ efi_init(); + iomem_resource.end = ~0UL; /* FIXME probably belongs elsewhere */ find_memory(); #if 0 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 Sat Jul 20 16:33:47 2002 +++ 60_pci_tra/include/asm-ia64/pci.h Sat Jul 20 16:35:33 2002 @@ -86,6 +86,8 @@ void *acpi_handle; int segment; + u64 mem_offset; + void *platform_data; }; diff -u -r 50_iosapic_segment/include/linux/acpi.h 60_pci_tra/include/linux/acpi.h --- 50_iosapic_segment/include/linux/acpi.h Sat Jul 20 16:33:00 2002 +++ 60_pci_tra/include/linux/acpi.h Sat Jul 20 16:35:33 2002 @@ -378,6 +378,8 @@ 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*/