/** * pci_mmap_legacy_page_range - map legacy memory space to userland * @bus: bus whose legacy space we're mapping * @vma: vma passed in by mmap * * Map legacy memory space for this device back to userspace using a machine * vector to get the base address. */ int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma) { unsigned long size = vma->vm_end - vma->vm_start; pgprot_t prot; char *addr; /* * Avoid attribute aliasing. See Documentation/ia64/aliasing.txt * for more details. */ if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) return -EINVAL; prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, vma->vm_page_prot); addr = pci_get_legacy_mem(bus); if (IS_ERR(addr)) return PTR_ERR(addr); vma->vm_pgoff += (unsigned long)addr >> PAGE_SHIFT; vma->vm_page_prot = prot; if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, size, vma->vm_page_prot)) return -EAGAIN; return 0; }
static int dk_mmap ( struct file *file, struct vm_area_struct *vma ) { #if defined(__HAVE_PHYS_MEM_ACCESS_PROT) unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; vma->vm_page_prot = phys_mem_access_prot(file, offset, vma->vm_end - vma->vm_start, vma->vm_page_prot); #elif defined(pgprot_noncached) unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; int uncached; uncached = uncached_access(file, offset); if (uncached) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #endif /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end-vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; }
int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { unsigned long size = vma->vm_end - vma->vm_start; pgprot_t prot; /* * I/O space cannot be accessed via normal processor loads and * stores on this platform. */ if (mmap_state == pci_mmap_io) /* * XXX we could relax this for I/O spaces for which ACPI * indicates that the space is 1-to-1 mapped. But at the * moment, we don't support multiple PCI address spaces and * the legacy I/O space is not 1-to-1 mapped, so this is moot. */ return -EINVAL; if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size)) return -EINVAL; prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, vma->vm_page_prot); /* * If the user requested WC, the kernel uses UC or WC for this region, * and the chipset supports WC, we can use WC. Otherwise, we have to * use the same attribute the kernel uses. */ if (write_combine && ((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC || (pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) && efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); else vma->vm_page_prot = prot; if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; }
static int mmap_mem(struct file * file, struct vm_area_struct * vma) { unsigned long prot; #if defined(__HAVE_PHYS_MEM_ACCESS_PROT) unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; vma->vm_page_prot = phys_mem_access_prot(file, offset, vma->vm_end - vma->vm_start, vma->vm_page_prot); #elif defined(pgprot_noncached) unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; int uncached; uncached = uncached_access(file, offset); if (uncached) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #endif prot = pgprot_val(vma->vm_page_prot); prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED; if (prot & _PAGE_WRITE) prot = prot | _PAGE_FILE | _PAGE_VALID | _PAGE_DIRTY; else prot = prot | _PAGE_FILE | _PAGE_VALID; prot &= ~_PAGE_PRESENT; vma->vm_page_prot = __pgprot(prot); /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end-vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; }