HIFT; unsigned long baddr = addr & ~TITAN_HOSE_MASK; unsigned long last = baddr + size - 1; struct pci_controller *hose; struct vm_struct *area; unsigned long vaddr; unsigned long *ptes; unsigned long pfn; #ifdef CONFIG_VGA_HOSE /* * Adjust the address and hose, if necessary. */ if (pci_vga_hose && __is_mem_vga(addr)) { h = pci_vga_hose->index; addr += pci_vga_hose->mem_space->start; } #endif /* * Find the hose. */ for (hose = hose_head; hose; hose = hose->next) if (hose->index == h) break; if (!hose) return NULL; /* * Is it direct-mapped? */ if ((baddr >= __direct_map_base) && ((baddr + size - 1) < __direct_map_base + __direct_map_size)) { vaddr = addr - __direct_map_base + TITAN_MEM_BIAS; return (void __iomem *) vaddr; } /* * Check the scatter-gather arena. */ if (hose->sg_pci && baddr >= (unsigned long)hose->sg_pci->dma_base && last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size){ /* * Adjust the limits (mappings must be page aligned) */ baddr -= hose->sg_pci->dma_base; last -= hose->sg_pci->dma_base; baddr &= PAGE_MASK; size = PAGE_ALIGN(last) - baddr; /* * Map it */ area = get_vm_area(size, VM_IOREMAP); if (!area) { printk("ioremap failed... no vm_area...\n"); return NULL; } ptes = hose->sg_pci->ptes; for (vaddr = (unsigned long)area->addr; baddr <= last; baddr += PAGE_SIZE, vaddr += PAGE_SIZE) { pfn = ptes[baddr >> PAGE_SHIFT]; if (!(pfn & 1)) { printk("ioremap failed... pte not valid...\n"); vfree(area->addr); return NULL; } pfn >>= 1; /* make it a true pfn */ if (__alpha_remap_area_pages(vaddr, pfn << PAGE_SHIFT, PAGE_SIZE, 0)) { printk("FAILED to remap_area_pages...\n"); vfree(area->addr); return NULL; } } flush_tlb_all(); vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK); return (void __iomem *) vaddr; } /* Assume a legacy (read: VGA) address, and return appropriately. */ return (void __iomem *)(addr + TITAN_MEM_BIAS); } void titan_iounmap(volatile void __iomem *xaddr) { unsigned long addr = (unsigned long) xaddr; if (addr >= VMALLOC_START) vfree((void *)(PAGE_MASK & addr)); } int titan_is_mmio(const volatile void __iomem *xaddr) { unsigned long addr = (unsigned long) xaddr; if (addr >= VMALLOC_START) return 1; else return (addr & 0x100000000UL) == 0; } #ifndef CONFIG_ALPHA_GENERIC EXPORT_SYMBOL(titan_ioportmap); EXPORT_SYMBOL(titan_ioremap); EXPORT_SYMBOL(titan_iounmap); EXPORT_SYMBOL(titan_is_mmio); #endif