diff options
Diffstat (limited to 'arch/ia64/pci')
-rw-r--r-- | arch/ia64/pci/pci.c | 22 |
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 | |||
591 | pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, | 591 | pci_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)) |