diff -urN z/arch/alpha/kernel/pci_iommu.c 2.4.5pre4aa1/arch/alpha/kernel/pci_iommu.c --- z/arch/alpha/kernel/pci_iommu.c Tue May 22 18:30:40 2001 +++ 2.4.5pre4aa1/arch/alpha/kernel/pci_iommu.c Tue May 22 18:10:06 2001 @@ -42,6 +42,25 @@ return (bytes + PAGE_SIZE - 1) >> PAGE_SHIFT; } +static void __init +iommu_arena_fixup(struct pci_iommu_arena * arena) +{ + unsigned long base, size; + + /* + * The Cypress chip has a quirk, it get confused by addresses + * above -1M so reserve the pagetables that maps pci addresses + * above -1M. + */ + base = arena->dma_base; + size = arena->size; + if (base + size > 0xfff00000) { + int i = (0xfff00000 - base) >> PAGE_SHIFT; + for (; i < (0x100000 >> PAGE_SHIFT); i++) + arena->ptes[i] = IOMMU_INVALID_PTE; + } +} + struct pci_iommu_arena * iommu_arena_new(struct pci_controller *hose, dma_addr_t base, unsigned long window_size, unsigned long align) @@ -70,6 +89,8 @@ /* Align allocations to a multiple of a page size. Not needed unless there are chip bugs. */ arena->align_entry = 1; + + iommu_arena_fixup(arena); return arena; }