From: "Randy.Dunlap" This patch introduces a new interface function for mapping bus/device memory: io_remap_pfn_range. This accepts the same parameters as remap_pfn_range and io_remap_page_range but should be used in any situation where the caller is not simply remapping ordinary RAM. For example, when mapping device registers the new function should be used. The distinction between remapping device memory and ordinary RAM is critical for the Xen hypervisor. This patch series also cleans up the remaining users of io_remap_page_range (in particular, the several sparc-specific sections in various drivers that use a special form of io_remap_page_range: an extra argument for SPARC arch.) by converting them to use io_remap_pfn_range(), where io_remap_pfn_range() supports passing as part of the pfn argument. The sparc32 & sparc64 code needs live testing. (from Keir:) I have audited the drivers/ and sound/ directories. Most uses of remap_pfn_range are okay, but there are a small handful that are remapping device memory (mostly AGP and DRM drivers). Of particular driver is the HPET driver, whose mmap function is broken even for native (non-Xen) builds. If nothing else, vmalloc_to_phys should be used instead of __pa to convert an ioremapped virtual address to a valid physical address. The fix in this patch is to remember the original bus address as probed at boot time and to pass this to io_remap_pfn_range. io_remap_pfn_range(): add io_remap_pfn_range() for all arches; add MK_IOSPACE_PFN(), GET_IOSPACE(), and GET_PFN() for all arches but primarily for sparc32/64's extended IO space, sparc: kill the hack of using low bit of to mean write_combine or set side-effect (_PAGE_E) bit; (DaveM suggested that I kill it;) future: convert remaining callers of io_remap_page_range() to io_remap_pfn_range() and deprecate io_remap_page_range(); Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton --- 25-akpm/arch/sparc/kernel/sparc_ksyms.c | 1 25-akpm/arch/sparc/mm/generic.c | 34 +++++++++++++++++++ 25-akpm/arch/sparc64/kernel/pci.c | 15 +++----- 25-akpm/arch/sparc64/kernel/sparc64_ksyms.c | 6 ++- 25-akpm/arch/sparc64/mm/generic.c | 50 ++++++++++++++++++++++------ 25-akpm/include/asm-alpha/pgtable.h | 7 +++ 25-akpm/include/asm-arm/pgtable.h | 7 +++ 25-akpm/include/asm-arm26/pgtable.h | 7 +++ 25-akpm/include/asm-frv/pgtable.h | 7 +++ 25-akpm/include/asm-h8300/pgtable.h | 7 +++ 25-akpm/include/asm-i386/pgtable.h | 7 +++ 25-akpm/include/asm-ia64/pgtable.h | 7 +++ 25-akpm/include/asm-m32r/pgtable.h | 7 +++ 25-akpm/include/asm-m68k/pgtable.h | 7 +++ 25-akpm/include/asm-m68knommu/pgtable.h | 7 +++ 25-akpm/include/asm-mips/pgtable.h | 18 +++++++++- 25-akpm/include/asm-parisc/pgtable.h | 7 +++ 25-akpm/include/asm-ppc/pgtable.h | 16 ++++++++ 25-akpm/include/asm-ppc64/pgtable.h | 7 +++ 25-akpm/include/asm-sh/pgtable.h | 7 +++ 25-akpm/include/asm-sh64/pgtable.h | 8 ++++ 25-akpm/include/asm-sparc/pgtable.h | 14 +++++++ 25-akpm/include/asm-sparc64/pgtable.h | 12 ++++++ 25-akpm/include/asm-x86_64/pgtable.h | 7 +++ 24 files changed, 251 insertions(+), 21 deletions(-) diff -puN arch/sparc64/kernel/pci.c~io_remap_pfn_range-add-for-all-arch-es arch/sparc64/kernel/pci.c --- 25/arch/sparc64/kernel/pci.c~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/arch/sparc64/kernel/pci.c 2005-03-18 13:49:15.000000000 -0800 @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -734,12 +735,10 @@ static void __pci_mmap_set_flags(struct static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state) { - /* Our io_remap_page_range takes care of this, do nothing. */ + /* Our io_remap_page_range/io_remap_pfn_range takes care of this, + do nothing. */ } -extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset, - unsigned long size, pgprot_t prot, int space); - /* Perform the actual remap of the pages for a PCI device mapping, as appropriate * for this architecture. The region in the process to map is described by vm_start * and vm_end members of VMA, the base physical address is found in vm_pgoff. @@ -761,10 +760,10 @@ int pci_mmap_page_range(struct pci_dev * __pci_mmap_set_flags(dev, vma, mmap_state); __pci_mmap_set_pgprot(dev, vma, mmap_state); - ret = io_remap_page_range(vma, vma->vm_start, - (vma->vm_pgoff << PAGE_SHIFT | - (write_combine ? 0x1UL : 0x0UL)), - vma->vm_end - vma->vm_start, vma->vm_page_prot, 0); + ret = io_remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); if (ret) return ret; diff -puN arch/sparc64/kernel/sparc64_ksyms.c~io_remap_pfn_range-add-for-all-arch-es arch/sparc64/kernel/sparc64_ksyms.c --- 25/arch/sparc64/kernel/sparc64_ksyms.c~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/arch/sparc64/kernel/sparc64_ksyms.c 2005-03-18 13:49:15.000000000 -0800 @@ -87,7 +87,10 @@ extern int svr4_setcontext(svr4_ucontext extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); extern long sparc32_open(const char __user * filename, int flags, int mode); -extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space); +extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, + unsigned long offset, unsigned long size, pgprot_t prot, int space); +extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot); extern void (*prom_palette)(int); extern int __ashrdi3(int, int); @@ -254,6 +257,7 @@ EXPORT_SYMBOL(pci_dma_supported); /* I/O device mmaping on Sparc64. */ EXPORT_SYMBOL(io_remap_page_range); +EXPORT_SYMBOL(io_remap_pfn_range); /* Solaris/SunOS binary compatibility */ EXPORT_SYMBOL(_sigpause_common); diff -puN arch/sparc64/mm/generic.c~io_remap_pfn_range-add-for-all-arch-es arch/sparc64/mm/generic.c --- 25/arch/sparc64/mm/generic.c~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/arch/sparc64/mm/generic.c 2005-03-18 13:49:15.000000000 -0800 @@ -20,10 +20,6 @@ * * They use a pgprot that sets PAGE_IO and does not check the * mem_map table as this is independent of normal memory. - * - * As a special hack if the lowest bit of offset is set the - * side-effect bit will be turned off. This is used as a - * performance improvement on FFB/AFB. -DaveM */ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigned long address, @@ -33,6 +29,8 @@ static inline void io_remap_pte_range(st { unsigned long end; + /* clear hack bit that was used as a write_combine side-effect flag */ + offset &= ~0x1UL; address &= ~PMD_MASK; end = address + size; if (end > PMD_SIZE) @@ -41,22 +39,22 @@ static inline void io_remap_pte_range(st pte_t entry; unsigned long curend = address + PAGE_SIZE; - entry = mk_pte_io((offset & ~(0x1UL)), prot, space); + entry = mk_pte_io(offset, prot, space); if (!(address & 0xffff)) { if (!(address & 0x3fffff) && !(offset & 0x3ffffe) && end >= address + 0x400000) { - entry = mk_pte_io((offset & ~(0x1UL)), + entry = mk_pte_io(offset, __pgprot(pgprot_val (prot) | _PAGE_SZ4MB), space); curend = address + 0x400000; offset += 0x400000; } else if (!(address & 0x7ffff) && !(offset & 0x7fffe) && end >= address + 0x80000) { - entry = mk_pte_io((offset & ~(0x1UL)), + entry = mk_pte_io(offset, __pgprot(pgprot_val (prot) | _PAGE_SZ512K), space); curend = address + 0x80000; offset += 0x80000; } else if (!(offset & 0xfffe) && end >= address + 0x10000) { - entry = mk_pte_io((offset & ~(0x1UL)), + entry = mk_pte_io(offset, __pgprot(pgprot_val (prot) | _PAGE_SZ64K), space); curend = address + 0x10000; @@ -66,8 +64,6 @@ static inline void io_remap_pte_range(st } else offset += PAGE_SIZE; - if (offset & 0x1UL) - pte_val(entry) &= ~(_PAGE_E); do { BUG_ON(!pte_none(*pte)); set_pte_at(mm, address, pte, entry); @@ -150,3 +146,37 @@ int io_remap_page_range(struct vm_area_s return error; } + +int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + int error = 0; + pgd_t * dir; + unsigned long beg = from; + unsigned long end = from + size; + struct mm_struct *mm = vma->vm_mm; + int space = GET_IOSPACE(pfn); + unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; + + prot = __pgprot(pg_iobits); + offset -= from; + dir = pgd_offset(mm, from); + flush_cache_range(vma, beg, end); + + spin_lock(&mm->page_table_lock); + while (from < end) { + pud_t *pud = pud_alloc(current->mm, dir, from); + error = -ENOMEM; + if (!pud) + break; + error = io_remap_pud_range(mm, pud, from, end - from, offset + from, prot, space); + if (error) + break; + from = (from + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } + flush_tlb_range(vma, beg, end); + spin_unlock(&mm->page_table_lock); + + return error; +} diff -puN arch/sparc/kernel/sparc_ksyms.c~io_remap_pfn_range-add-for-all-arch-es arch/sparc/kernel/sparc_ksyms.c --- 25/arch/sparc/kernel/sparc_ksyms.c~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/arch/sparc/kernel/sparc_ksyms.c 2005-03-18 13:49:15.000000000 -0800 @@ -164,6 +164,7 @@ EXPORT_SYMBOL(get_auxio); #endif EXPORT_SYMBOL(request_fast_irq); EXPORT_SYMBOL(io_remap_page_range); +EXPORT_SYMBOL(io_remap_pfn_range); /* P3: iounit_xxx may be needed, sun4d users */ /* EXPORT_SYMBOL(iounit_map_dma_init); */ /* EXPORT_SYMBOL(iounit_map_dma_page); */ diff -puN arch/sparc/mm/generic.c~io_remap_pfn_range-add-for-all-arch-es arch/sparc/mm/generic.c --- 25/arch/sparc/mm/generic.c~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/arch/sparc/mm/generic.c 2005-03-18 13:49:15.000000000 -0800 @@ -118,3 +118,37 @@ int io_remap_page_range(struct vm_area_s flush_tlb_range(vma, beg, end); return error; } + +int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + int error = 0; + pgd_t * dir; + unsigned long beg = from; + unsigned long end = from + size; + struct mm_struct *mm = vma->vm_mm; + int space = GET_IOSPACE(pfn); + unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; + + prot = __pgprot(pg_iobits); + offset -= from; + dir = pgd_offset(mm, from); + flush_cache_range(vma, beg, end); + + spin_lock(&mm->page_table_lock); + while (from < end) { + pmd_t *pmd = pmd_alloc(current->mm, dir, from); + error = -ENOMEM; + if (!pmd) + break; + error = io_remap_pmd_range(mm, pmd, from, end - from, offset + from, prot, space); + if (error) + break; + from = (from + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } + spin_unlock(&mm->page_table_lock); + + flush_tlb_range(vma, beg, end); + return error; +} diff -puN include/asm-alpha/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-alpha/pgtable.h --- 25/include/asm-alpha/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-alpha/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -340,6 +340,13 @@ extern inline pte_t mk_swap_pte(unsigned remap_pfn_range(vma, start, pfn, size, prot); \ }) +#define io_remap_pfn_range(vma, start, pfn, size, prot) \ + remap_pfn_range(vma, start, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #define pte_ERROR(e) \ printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \ diff -puN include/asm-arm26/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-arm26/pgtable.h --- 25/include/asm-arm26/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-arm26/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -293,6 +293,13 @@ static inline pte_t mk_pte_phys(unsigned #define io_remap_page_range(vma,from,phys,size,prot) \ remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma,from,pfn,size,prot) \ + remap_pfn_range(vma, from, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM_PGTABLE_H */ diff -puN include/asm-arm/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-arm/pgtable.h --- 25/include/asm-arm/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-arm/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -419,6 +419,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD #define io_remap_page_range(vma,from,phys,size,prot) \ remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma,from,pfn,size,prot) \ + remap_pfn_range(vma, from, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #define pgtable_cache_init() do { } while (0) #endif /* !__ASSEMBLY__ */ diff -puN include/asm-frv/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-frv/pgtable.h --- 25/include/asm-frv/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-frv/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -503,6 +503,13 @@ static inline int pte_file(pte_t pte) #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY #define __HAVE_ARCH_PTEP_GET_AND_CLEAR diff -puN include/asm-h8300/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-h8300/pgtable.h --- 25/include/asm-h8300/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-h8300/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -55,6 +55,13 @@ extern int is_in_rom(unsigned long); #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* * All 32bit addresses are effectively valid for vmalloc... * Sort of meaningless for non-VM targets. diff -puN include/asm-i386/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-i386/pgtable.h --- 25/include/asm-i386/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-i386/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -405,6 +405,13 @@ extern void noexec_setup(const char *str #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY #define __HAVE_ARCH_PTEP_GET_AND_CLEAR diff -puN include/asm-ia64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-ia64/pgtable.h --- 25/include/asm-ia64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-ia64/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -447,6 +447,13 @@ extern void paging_init (void); #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. diff -puN include/asm-m32r/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-m32r/pgtable.h --- 25/include/asm-m32r/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-m32r/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -381,6 +381,13 @@ static inline void pmd_set(pmd_t * pmdp, #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY #define __HAVE_ARCH_PTEP_GET_AND_CLEAR diff -puN include/asm-m68knommu/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-m68knommu/pgtable.h --- 25/include/asm-m68knommu/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-m68knommu/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -59,6 +59,13 @@ extern int is_in_rom(unsigned long); #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* * All 32bit addresses are effectively valid for vmalloc... * Sort of meaningless for non-VM targets. diff -puN include/asm-m68k/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-m68k/pgtable.h --- 25/include/asm-m68k/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-m68k/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -144,6 +144,13 @@ static inline void update_mmu_cache(stru #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* MMU-specific headers */ #ifdef CONFIG_SUN3 diff -puN include/asm-mips/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-mips/pgtable.h --- 25/include/asm-mips/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-mips/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -367,11 +367,27 @@ static inline int io_remap_page_range(st phys_t phys_addr_high = fixup_bigphys_addr(paddr, size); return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); } + +static inline int io_remap_pfn_range(struct vm_area_struct *vma, + unsigned long vaddr, + unsigned long pfn, + unsigned long size, + pgprot_t prot) +{ + phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); + return remap_pfn_range(vma, vaddr, pfn, size, prot); +} #else #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ - remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) #endif +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #include /* diff -puN include/asm-parisc/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-parisc/pgtable.h --- 25/include/asm-parisc/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-parisc/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -501,6 +501,13 @@ static inline void ptep_set_wrprotect(st #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* We provide our own get_unmapped_area to provide cache coherency */ #define HAVE_ARCH_UNMAPPED_AREA diff -puN include/asm-ppc64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-ppc64/pgtable.h --- 25/include/asm-ppc64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-ppc64/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -527,6 +527,13 @@ extern void update_mmu_cache(struct vm_a #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + void pgtable_cache_init(void); extern void hpte_init_native(void); diff -puN include/asm-ppc/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-ppc/pgtable.h --- 25/include/asm-ppc/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-ppc/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -735,11 +735,27 @@ static inline int io_remap_page_range(st phys_addr_t paddr64 = fixup_bigphys_addr(paddr, size); return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot); } + +static inline int io_remap_pfn_range(struct vm_area_struct *vma, + unsigned long vaddr, + unsigned long pfn, + unsigned long size, + pgprot_t prot) +{ + phys_addr_t paddr64 = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); + return remap_pfn_range(vma, vaddr, pfn, size, prot); +} #else #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) #endif +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* * No page table caches to initialise */ diff -puN include/asm-sh64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-sh64/pgtable.h --- 25/include/asm-sh64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-sh64/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -482,6 +482,14 @@ extern void update_mmu_cache(struct vm_a #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) + +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #endif /* !__ASSEMBLY__ */ /* diff -puN include/asm-sh/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-sh/pgtable.h --- 25/include/asm-sh/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-sh/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -279,6 +279,13 @@ typedef pte_t *pte_addr_t; #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + /* * No page table caches to initialise */ diff -puN include/asm-sparc64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-sparc64/pgtable.h --- 25/include/asm-sparc64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-sparc64/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -431,6 +432,17 @@ extern unsigned long *sparc64_valid_addr extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space); +extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, + unsigned long pfn, + unsigned long size, pgprot_t prot); + +/* + * For sparc32&64, the pfn in io_remap_pfn_range() carries in + * its high 4 bits. These macros/functions put it there or get it from there. + */ +#define MK_IOSPACE_PFN(space, pfn) (pfn | (space << (BITS_PER_LONG - 4))) +#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) +#define GET_PFN(pfn) (pfn & 0x0fffffffffffffffUL) /* Override for {pgd,pmd}_addr_end() to deal with the virtual address * space hole. We simply sign extend bit 43. diff -puN include/asm-sparc/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-sparc/pgtable.h --- 25/include/asm-sparc/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-sparc/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -454,8 +454,20 @@ extern unsigned long *sparc_valid_addr_b #define kern_addr_valid(addr) \ (test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap)) -extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to, +extern int io_remap_page_range(struct vm_area_struct *vma, + unsigned long from, unsigned long to, unsigned long size, pgprot_t prot, int space); +extern int io_remap_pfn_range(struct vm_area_struct *vma, + unsigned long from, unsigned long pfn, + unsigned long size, pgprot_t prot); + +/* + * For sparc32&64, the pfn in io_remap_pfn_range() carries in + * its high 4 bits. These macros/functions put it there or get it from there. + */ +#define MK_IOSPACE_PFN(space, pfn) (pfn | (space << (BITS_PER_LONG - 4))) +#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4)) +#define GET_PFN(pfn) (pfn & 0x0fffffffUL) #include diff -puN include/asm-x86_64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es include/asm-x86_64/pgtable.h --- 25/include/asm-x86_64/pgtable.h~io_remap_pfn_range-add-for-all-arch-es 2005-03-18 13:49:15.000000000 -0800 +++ 25-akpm/include/asm-x86_64/pgtable.h 2005-03-18 13:49:15.000000000 -0800 @@ -407,6 +407,13 @@ extern int kern_addr_valid(unsigned long #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) +#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ + remap_pfn_range(vma, vaddr, pfn, size, prot) + +#define MK_IOSPACE_PFN(space, pfn) (pfn) +#define GET_IOSPACE(pfn) 0 +#define GET_PFN(pfn) (pfn) + #define HAVE_ARCH_UNMAPPED_AREA #define pgtable_cache_init() do { } while (0) _