@@ -48,7 +48,8 @@ extern int pci_proc_domain(struct pci_bus *bus);
struct vm_area_struct;
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
-#define HAVE_PCI_MMAP 1
+#define HAVE_PCI_MMAP 1
+#define HAVE_PCI_MMAP_IO 1
extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
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 */
#define HAVE_PCI_MMAP 1
+#define HAVE_PCI_MMAP_IO 1
#define arch_can_pci_mmap_wc() 1
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. */
#define HAVE_PCI_MMAP
+#define HAVE_PCI_MMAP_IO
#define HAVE_ARCH_PCI_GET_UNMAPPED_AREA
#define get_pci_unmapped_area get_fb_unmapped_area
@@ -48,6 +48,7 @@ struct pci_dev;
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
#define HAVE_PCI_MMAP 1
+#define HAVE_PCI_MMAP_IO 1
/* This was wrapped in #if 0 since the first merge of xtensa support...
#define arch_can_pci_mmap_wc() 1
@@ -1174,11 +1174,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
} else {
pdev->res_attr[num] = res_attr;
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;
- res_attr->write = pci_write_resource_io;
+ if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
+ res_attr->read = pci_read_resource_io;
+ res_attr->write = pci_write_resource_io;
+#ifdef HAVE_PCI_MMAP_IO
+ res_attr->mmap = pci_mmap_resource_uc;
+#endif
+ } else {
+ res_attr->mmap = pci_mmap_resource_uc;
+ }
}
res_attr->attr.name = res_attr_name;
res_attr->attr.mode = S_IRUSR | S_IWUSR;
@@ -200,11 +200,12 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
ret = pci_domain_nr(dev->bus);
break;
-#ifdef HAVE_PCI_MMAP
+#ifdef HAVE_PCI_MMAP_IO
case PCIIOC_MMAP_IS_IO:
fpriv->mmap_state = pci_mmap_io;
break;
-
+#endif
+#ifdef HAVE_PCI_MMAP
case PCIIOC_MMAP_IS_MEM:
fpriv->mmap_state = pci_mmap_mem;
break;
@@ -239,6 +240,11 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
+#ifndef HAVE_PCI_MMAP_IO
+ if (fpriv->mmap_state == pci_mmap_io)
+ return -EINVAL;
+#endif
+
if (fpriv->mmap_state == pci_mmap_io)
res_bit = IORESOURCE_IO;
else