This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / sparc64 / mm / generic.c
index 6be13eb..149dc1b 100644 (file)
 #include <asm/page.h>
 #include <asm/tlbflush.h>
 
-/* Remap IO memory, the same way as remap_pfn_range(), but use
+static inline void forget_pte(pte_t page)
+{
+       if (!pte_none(page)) {
+               printk("forget_pte: old mapping existed!\n");
+               BUG();
+       }
+}
+
+/* Remap IO memory, the same way as remap_page_range(), but use
  * the obio memory space.
  *
  * They use a pgprot that sets PAGE_IO and does not check the
@@ -35,6 +43,7 @@ static inline void io_remap_pte_range(pte_t * pte, unsigned long address, unsign
        if (end > PMD_SIZE)
                end = PMD_SIZE;
        do {
+               pte_t oldpage;
                pte_t entry;
                unsigned long curend = address + PAGE_SIZE;
                
@@ -66,8 +75,10 @@ static inline void io_remap_pte_range(pte_t * pte, unsigned long address, unsign
                if (offset & 0x1UL)
                        pte_val(entry) &= ~(_PAGE_E);
                do {
-                       BUG_ON(!pte_none(*pte));
+                       oldpage = *pte;
+                       pte_clear(pte);
                        set_pte(pte, entry);
+                       forget_pte(oldpage);
                        address += PAGE_SIZE;
                        pte++;
                } while (address < curend);
@@ -121,8 +132,8 @@ int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned
                from = (from + PGDIR_SIZE) & PGDIR_MASK;
                dir++;
        }
-       flush_tlb_range(vma, beg, end);
        spin_unlock(&mm->page_table_lock);
 
+       flush_tlb_range(vma, beg, end);
        return error;
 }