|
@@ -476,3 +476,55 @@ titan_ioremap(unsigned long addr, unsigned long size)
|
|
|
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);
|