Commit e854d8b2 authored by David Woodhouse's avatar David Woodhouse Committed by Bjorn Helgaas

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: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 11df1954
...@@ -119,7 +119,8 @@ useful return codes should be provided. ...@@ -119,7 +119,8 @@ useful return codes should be provided.
Platforms which support write-combining maps of PCI resources must define Platforms which support write-combining maps of PCI resources must define
arch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when arch_can_pci_mmap_wc() which shall evaluate to non-zero at runtime when
write-combining is permitted. write-combining is permitted. Platforms which support maps of I/O resources
define arch_can_pci_mmap_io() similarly.
Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms
wishing to support legacy functionality should define it and provide wishing to support legacy functionality should define it and provide
......
...@@ -48,7 +48,8 @@ extern int pci_proc_domain(struct pci_bus *bus); ...@@ -48,7 +48,8 @@ extern int pci_proc_domain(struct pci_bus *bus);
struct vm_area_struct; struct vm_area_struct;
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
#define HAVE_PCI_MMAP 1 #define HAVE_PCI_MMAP 1
#define arch_can_pci_mmap_io() 1
extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
size_t count); size_t count);
......
...@@ -80,6 +80,7 @@ struct vm_area_struct; ...@@ -80,6 +80,7 @@ struct vm_area_struct;
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() and it does WC */ /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() and it does WC */
#define HAVE_PCI_MMAP 1 #define HAVE_PCI_MMAP 1
#define arch_can_pci_mmap_io() 1
#define arch_can_pci_mmap_wc() 1 #define arch_can_pci_mmap_wc() 1
extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
......
...@@ -42,6 +42,7 @@ static inline int pci_proc_domain(struct pci_bus *bus) ...@@ -42,6 +42,7 @@ static inline int pci_proc_domain(struct pci_bus *bus)
/* Platform support for /proc/bus/pci/X/Y mmap()s. */ /* Platform support for /proc/bus/pci/X/Y mmap()s. */
#define HAVE_PCI_MMAP #define HAVE_PCI_MMAP
#define arch_can_pci_mmap_io() 1
#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA #define HAVE_ARCH_PCI_GET_UNMAPPED_AREA
#define get_pci_unmapped_area get_fb_unmapped_area #define get_pci_unmapped_area get_fb_unmapped_area
......
...@@ -47,7 +47,8 @@ struct pci_dev; ...@@ -47,7 +47,8 @@ struct pci_dev;
#define PCI_DMA_BUS_IS_PHYS (1) #define PCI_DMA_BUS_IS_PHYS (1)
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
#define HAVE_PCI_MMAP 1 #define HAVE_PCI_MMAP 1
#define arch_can_pci_mmap_io() 1
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
......
...@@ -1174,11 +1174,14 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) ...@@ -1174,11 +1174,14 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
} else { } else {
pdev->res_attr[num] = res_attr; pdev->res_attr[num] = res_attr;
sprintf(res_attr_name, "resource%d", num); sprintf(res_attr_name, "resource%d", num);
res_attr->mmap = pci_mmap_resource_uc; if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
} res_attr->read = pci_read_resource_io;
if (pci_resource_flags(pdev, num) & IORESOURCE_IO) { res_attr->write = pci_write_resource_io;
res_attr->read = pci_read_resource_io; if (arch_can_pci_mmap_io())
res_attr->write = pci_write_resource_io; res_attr->mmap = pci_mmap_resource_uc;
} else {
res_attr->mmap = pci_mmap_resource_uc;
}
} }
res_attr->attr.name = res_attr_name; res_attr->attr.name = res_attr_name;
res_attr->attr.mode = S_IRUSR | S_IWUSR; res_attr->attr.mode = S_IRUSR | S_IWUSR;
......
...@@ -202,6 +202,8 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, ...@@ -202,6 +202,8 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
#ifdef HAVE_PCI_MMAP #ifdef HAVE_PCI_MMAP
case PCIIOC_MMAP_IS_IO: case PCIIOC_MMAP_IS_IO:
if (!arch_can_pci_mmap_io())
return -EINVAL;
fpriv->mmap_state = pci_mmap_io; fpriv->mmap_state = pci_mmap_io;
break; break;
...@@ -232,15 +234,16 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -232,15 +234,16 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
{ {
struct pci_dev *dev = PDE_DATA(file_inode(file)); struct pci_dev *dev = PDE_DATA(file_inode(file));
struct pci_filp_private *fpriv = file->private_data; struct pci_filp_private *fpriv = file->private_data;
int i, ret, write_combine = 0, res_bit; int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
if (fpriv->mmap_state == pci_mmap_io) if (fpriv->mmap_state == pci_mmap_io) {
if (!arch_can_pci_mmap_io())
return -EINVAL;
res_bit = IORESOURCE_IO; res_bit = IORESOURCE_IO;
else }
res_bit = IORESOURCE_MEM;
/* Make sure the caller is mapping a real resource for this device */ /* Make sure the caller is mapping a real resource for this device */
for (i = 0; i < PCI_ROM_RESOURCE; i++) { for (i = 0; i < PCI_ROM_RESOURCE; i++) {
......
...@@ -1636,6 +1636,9 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, ...@@ -1636,6 +1636,9 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
#ifndef arch_can_pci_mmap_wc #ifndef arch_can_pci_mmap_wc
#define arch_can_pci_mmap_wc() 0 #define arch_can_pci_mmap_wc() 0
#endif #endif
#ifndef arch_can_pci_mmap_io
#define arch_can_pci_mmap_io() 0
#endif
#ifndef pci_root_bus_fwnode #ifndef pci_root_bus_fwnode
#define pci_root_bus_fwnode(bus) NULL #define pci_root_bus_fwnode(bus) NULL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment