Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: Add arch_can_pci_mmap_io() on architectures which can mmap() I/O space

This is relatively esoteric, and knowing that we don't have it makes life
easier in some cases rather than just an eventual -EINVAL from
pci_mmap_page_range().

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

authored by

David Woodhouse and committed by
Bjorn Helgaas
e854d8b2 11df1954

+26 -12
+2 -1
Documentation/filesystems/sysfs-pci.txt
··· 119 119 120 120 Platforms which support write-combining maps of PCI resources must define 121 121 arch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when 122 - write-combining is permitted. 122 + write-combining is permitted. Platforms which support maps of I/O resources 123 + define arch_can_pci_mmap_io() similarly. 123 124 124 125 Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms 125 126 wishing to support legacy functionality should define it and provide
+2 -1
arch/microblaze/include/asm/pci.h
··· 48 48 struct vm_area_struct; 49 49 50 50 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ 51 - #define HAVE_PCI_MMAP 1 51 + #define HAVE_PCI_MMAP 1 52 + #define arch_can_pci_mmap_io() 1 52 53 53 54 extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, 54 55 size_t count);
+1
arch/powerpc/include/asm/pci.h
··· 80 80 81 81 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() and it does WC */ 82 82 #define HAVE_PCI_MMAP 1 83 + #define arch_can_pci_mmap_io() 1 83 84 #define arch_can_pci_mmap_wc() 1 84 85 85 86 extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+1
arch/sparc/include/asm/pci_64.h
··· 42 42 /* Platform support for /proc/bus/pci/X/Y mmap()s. */ 43 43 44 44 #define HAVE_PCI_MMAP 45 + #define arch_can_pci_mmap_io() 1 45 46 #define HAVE_ARCH_PCI_GET_UNMAPPED_AREA 46 47 #define get_pci_unmapped_area get_fb_unmapped_area 47 48
+2 -1
arch/xtensa/include/asm/pci.h
··· 47 47 #define PCI_DMA_BUS_IS_PHYS (1) 48 48 49 49 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ 50 - #define HAVE_PCI_MMAP 1 50 + #define HAVE_PCI_MMAP 1 51 + #define arch_can_pci_mmap_io() 1 51 52 52 53 #endif /* __KERNEL__ */ 53 54
+8 -5
drivers/pci/pci-sysfs.c
··· 1174 1174 } else { 1175 1175 pdev->res_attr[num] = res_attr; 1176 1176 sprintf(res_attr_name, "resource%d", num); 1177 - res_attr->mmap = pci_mmap_resource_uc; 1178 - } 1179 - if (pci_resource_flags(pdev, num) & IORESOURCE_IO) { 1180 - res_attr->read = pci_read_resource_io; 1181 - res_attr->write = pci_write_resource_io; 1177 + if (pci_resource_flags(pdev, num) & IORESOURCE_IO) { 1178 + res_attr->read = pci_read_resource_io; 1179 + res_attr->write = pci_write_resource_io; 1180 + if (arch_can_pci_mmap_io()) 1181 + res_attr->mmap = pci_mmap_resource_uc; 1182 + } else { 1183 + res_attr->mmap = pci_mmap_resource_uc; 1184 + } 1182 1185 } 1183 1186 res_attr->attr.name = res_attr_name; 1184 1187 res_attr->attr.mode = S_IRUSR | S_IWUSR;
+7 -4
drivers/pci/proc.c
··· 202 202 203 203 #ifdef HAVE_PCI_MMAP 204 204 case PCIIOC_MMAP_IS_IO: 205 + if (!arch_can_pci_mmap_io()) 206 + return -EINVAL; 205 207 fpriv->mmap_state = pci_mmap_io; 206 208 break; 207 209 ··· 234 232 { 235 233 struct pci_dev *dev = PDE_DATA(file_inode(file)); 236 234 struct pci_filp_private *fpriv = file->private_data; 237 - int i, ret, write_combine = 0, res_bit; 235 + int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM; 238 236 239 237 if (!capable(CAP_SYS_RAWIO)) 240 238 return -EPERM; 241 239 242 - if (fpriv->mmap_state == pci_mmap_io) 240 + if (fpriv->mmap_state == pci_mmap_io) { 241 + if (!arch_can_pci_mmap_io()) 242 + return -EINVAL; 243 243 res_bit = IORESOURCE_IO; 244 - else 245 - res_bit = IORESOURCE_MEM; 244 + } 246 245 247 246 /* Make sure the caller is mapping a real resource for this device */ 248 247 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+3
include/linux/pci.h
··· 1636 1636 #ifndef arch_can_pci_mmap_wc 1637 1637 #define arch_can_pci_mmap_wc() 0 1638 1638 #endif 1639 + #ifndef arch_can_pci_mmap_io 1640 + #define arch_can_pci_mmap_io() 0 1641 + #endif 1639 1642 1640 1643 #ifndef pci_root_bus_fwnode 1641 1644 #define pci_root_bus_fwnode(bus) NULL