aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/pci')
-rw-r--r--arch/ia64/pci/pci.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 73696b4a2eed..07d0e92742c8 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -591,6 +591,9 @@ int
591pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, 591pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
592 enum pci_mmap_state mmap_state, int write_combine) 592 enum pci_mmap_state mmap_state, int write_combine)
593{ 593{
594 unsigned long size = vma->vm_end - vma->vm_start;
595 pgprot_t prot;
596
594 /* 597 /*
595 * I/O space cannot be accessed via normal processor loads and 598 * I/O space cannot be accessed via normal processor loads and
596 * stores on this platform. 599 * stores on this platform.
@@ -604,15 +607,24 @@ pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
604 */ 607 */
605 return -EINVAL; 608 return -EINVAL;
606 609
610 if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
611 return -EINVAL;
612
613 prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size,
614 vma->vm_page_prot);
615
607 /* 616 /*
608 * Leave vm_pgoff as-is, the PCI space address is the physical 617 * If the user requested WC, the kernel uses UC or WC for this region,
609 * address on this platform. 618 * and the chipset supports WC, we can use WC. Otherwise, we have to
619 * use the same attribute the kernel uses.
610 */ 620 */
611 if (write_combine && efi_range_is_wc(vma->vm_start, 621 if (write_combine &&
612 vma->vm_end - vma->vm_start)) 622 ((pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_UC ||
623 (pgprot_val(prot) & _PAGE_MA_MASK) == _PAGE_MA_WC) &&
624 efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
613 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 625 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
614 else 626 else
615 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 627 vma->vm_page_prot = prot;
616 628
617 if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, 629 if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
618 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 630 vma->vm_end - vma->vm_start, vma->vm_page_prot))