static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size, unsigned long flags) { pgd_t * dir; unsigned long end = address + size; phys_addr -= address; dir = pgd_offset(&init_mm, address); flush_cache_all(); if (address >= end) BUG(); do { pmd_t *pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; if (remap_area_pmd(pmd, address, end - address, phys_addr + address, flags)) return -ENOMEM; set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); flush_tlb_all(); return 0; }
int vmalloc_area_pages(unsigned long address, unsigned long size, pgprot_t prot) { pgd_t * dir; unsigned long end = address + size; dir = pgd_offset_k(address); flush_cache_all(); while (address < end) { pmd_t *pmd; pgd_t olddir = *dir; pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; if (alloc_area_pmd(pmd, address, end - address, prot)) return -ENOMEM; if (pgd_val(olddir) != pgd_val(*dir)) set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } flush_tlb_all(); return 0; }