1 // SPDX-License-Identifier: GPL-2.0
3 * Generic PCI resource mmap helper
5 * Copyright © 2017 Amazon.com, Inc. or its affiliates.
7 * Author: David Woodhouse <dwmw2@infradead.org>
10 #include <linux/kernel.h>
12 #include <linux/pci.h>
16 #ifdef ARCH_GENERIC_PCI_MMAP_RESOURCE
18 static const struct vm_operations_struct pci_phys_vm_ops
= {
19 #ifdef CONFIG_HAVE_IOREMAP_PROT
20 .access
= generic_access_phys
,
24 int pci_mmap_resource_range(struct pci_dev
*pdev
, int bar
,
25 struct vm_area_struct
*vma
,
26 enum pci_mmap_state mmap_state
, int write_combine
)
31 size
= ((pci_resource_len(pdev
, bar
) - 1) >> PAGE_SHIFT
) + 1;
32 if (vma
->vm_pgoff
+ vma_pages(vma
) > size
)
36 vma
->vm_page_prot
= pgprot_writecombine(vma
->vm_page_prot
);
38 vma
->vm_page_prot
= pgprot_device(vma
->vm_page_prot
);
40 if (mmap_state
== pci_mmap_io
) {
41 ret
= pci_iobar_pfn(pdev
, bar
, vma
);
45 vma
->vm_pgoff
+= (pci_resource_start(pdev
, bar
) >> PAGE_SHIFT
);
47 vma
->vm_ops
= &pci_phys_vm_ops
;
49 return io_remap_pfn_range(vma
, vma
->vm_start
, vma
->vm_pgoff
,
50 vma
->vm_end
- vma
->vm_start
,
56 #if (defined(CONFIG_SYSFS) || defined(CONFIG_PROC_FS)) && \
57 (defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE))
59 int pci_mmap_fits(struct pci_dev
*pdev
, int resno
, struct vm_area_struct
*vma
,
60 enum pci_mmap_api mmap_api
)
62 resource_size_t pci_start
= 0, pci_end
;
63 unsigned long nr
, start
, size
;
65 if (pci_resource_len(pdev
, resno
) == 0)
68 start
= vma
->vm_pgoff
;
69 size
= ((pci_resource_len(pdev
, resno
) - 1) >> PAGE_SHIFT
) + 1;
70 if (mmap_api
== PCI_MMAP_PROCFS
) {
71 pci_resource_to_user(pdev
, resno
, &pdev
->resource
[resno
],
72 &pci_start
, &pci_end
);
73 pci_start
>>= PAGE_SHIFT
;
75 if (start
>= pci_start
&& start
< pci_start
+ size
&&
76 start
+ nr
<= pci_start
+ size
)