mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 09:20:13 -04:00
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>
This commit is contained in:
committed by
Bjorn Helgaas
parent
11df19546f
commit
e854d8b2a8
@@ -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);
|
|||||||
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;
|
|||||||
|
|
||||||
/* 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)
|
|||||||
/* 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;
|
|||||||
#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)
|
|||||||
} 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,
|
|||||||
|
|
||||||
#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)
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
#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
|
||||||
|
|||||||
Reference in New Issue
Block a user