Re: [PATCH] powerpc: Use generic pci_mmap_resource_range()
On Mon, Feb 19, 2018 at 12:59:51PM +, David Woodhouse wrote: > Commit f719582435 ("PCI: Add pci_mmap_resource_range() and use it for > ARM64") added this generic function with the intent of using it > everywhere and ultimately killing the old arch-specific implementations. > > Let's get on with that eradication... > > Signed-off-by: David WoodhouseApplied to pci/resource-mmap for v4.17, thanks! Powerpc folks, let me know if you have applied this or would like to, and I'll drop it. > --- > arch/powerpc/include/asm/pci.h | 9 ++-- > arch/powerpc/kernel/pci-common.c | 106 > --- > 2 files changed, 15 insertions(+), 100 deletions(-) > > diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h > index d82802f..401c62a 100644 > --- a/arch/powerpc/include/asm/pci.h > +++ b/arch/powerpc/include/asm/pci.h > @@ -76,10 +76,11 @@ 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() and it does WC > */ > -#define HAVE_PCI_MMAP1 > -#define arch_can_pci_mmap_io() 1 > -#define arch_can_pci_mmap_wc() 1 > +/* Tell PCI code what kind of PCI resource mappings we support */ > +#define HAVE_PCI_MMAP1 > +#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1 > +#define arch_can_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, > size_t count); > diff --git a/arch/powerpc/kernel/pci-common.c > b/arch/powerpc/kernel/pci-common.c > index 446c796..fe9733f 100644 > --- a/arch/powerpc/kernel/pci-common.c > +++ b/arch/powerpc/kernel/pci-common.c > @@ -410,72 +410,22 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) > } > > /* > - * Platform support for /proc/bus/pci/X/Y mmap()s, > - * modelled on the sparc64 implementation by Dave Miller. > + * Platform support for /proc/bus/pci/X/Y mmap()s. > * -- paulus. > */ > - > -/* > - * Adjust vm_pgoff of VMA such that it is the physical page offset > - * corresponding to the 32-bit pci bus offset for DEV requested by the user. > - * > - * Basically, the user finds the base address for his device which he wishes > - * to mmap. They read the 32-bit value from the config space base register, > - * add whatever PAGE_SIZE multiple offset they wish, and feed this into the > - * offset parameter of mmap on /proc/bus/pci/XXX for that device. > - * > - * Returns negative error code on failure, zero on success. > - */ > -static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, > -resource_size_t *offset, > -enum pci_mmap_state mmap_state) > +int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma) > { > - struct pci_controller *hose = pci_bus_to_host(dev->bus); > - unsigned long io_offset = 0; > - int i, res_bit; > - > - if (hose == NULL) > - return NULL;/* should never happen */ > - > - /* If memory, add on the PCI bridge address offset */ > - if (mmap_state == pci_mmap_mem) { > -#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ > - *offset += hose->pci_mem_offset; > -#endif > - res_bit = IORESOURCE_MEM; > - } else { > - io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; > - *offset += io_offset; > - res_bit = IORESOURCE_IO; > - } > - > - /* > - * Check that the offset requested corresponds to one of the > - * resources of the device. > - */ > - for (i = 0; i <= PCI_ROM_RESOURCE; i++) { > - struct resource *rp = >resource[i]; > - int flags = rp->flags; > + struct pci_controller *hose = pci_bus_to_host(pdev->bus); > + resource_size_t ioaddr = pci_resource_start(pdev, bar); > > - /* treat ROM as memory (should be already) */ > - if (i == PCI_ROM_RESOURCE) > - flags |= IORESOURCE_MEM; > - > - /* Active and same type? */ > - if ((flags & res_bit) == 0) > - continue; > - > - /* In the range of this resource? */ > - if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) > - continue; > + if (!hose) > + return -EINVAL; > > - /* found it! construct the final physical address */ > - if (mmap_state == pci_mmap_io) > - *offset += hose->io_base_phys - io_offset; > - return rp; > - } > + /* Convert to an offset within this PCI controller */ > + ioaddr -= (unsigned long)hose->io_base_virt - _IO_BASE; > > - return NULL; > + vma->vm_pgoff += (ioaddr + hose->io_base_phys) >> PAGE_SHIFT; > +
[PATCH] powerpc: Use generic pci_mmap_resource_range()
Commit f719582435 ("PCI: Add pci_mmap_resource_range() and use it for ARM64") added this generic function with the intent of using it everywhere and ultimately killing the old arch-specific implementations. Let's get on with that eradication... Signed-off-by: David Woodhouse--- arch/powerpc/include/asm/pci.h | 9 ++-- arch/powerpc/kernel/pci-common.c | 106 --- 2 files changed, 15 insertions(+), 100 deletions(-) diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index d82802f..401c62a 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h @@ -76,10 +76,11 @@ 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() and it does WC */ -#define HAVE_PCI_MMAP 1 -#define arch_can_pci_mmap_io() 1 -#define arch_can_pci_mmap_wc() 1 +/* Tell PCI code what kind of PCI resource mappings we support */ +#define HAVE_PCI_MMAP 1 +#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1 +#define arch_can_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, size_t count); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 446c796..fe9733f 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -410,72 +410,22 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) } /* - * Platform support for /proc/bus/pci/X/Y mmap()s, - * modelled on the sparc64 implementation by Dave Miller. + * Platform support for /proc/bus/pci/X/Y mmap()s. * -- paulus. */ - -/* - * Adjust vm_pgoff of VMA such that it is the physical page offset - * corresponding to the 32-bit pci bus offset for DEV requested by the user. - * - * Basically, the user finds the base address for his device which he wishes - * to mmap. They read the 32-bit value from the config space base register, - * add whatever PAGE_SIZE multiple offset they wish, and feed this into the - * offset parameter of mmap on /proc/bus/pci/XXX for that device. - * - * Returns negative error code on failure, zero on success. - */ -static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - resource_size_t *offset, - enum pci_mmap_state mmap_state) +int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma) { - struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long io_offset = 0; - int i, res_bit; - - if (hose == NULL) - return NULL;/* should never happen */ - - /* If memory, add on the PCI bridge address offset */ - if (mmap_state == pci_mmap_mem) { -#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ - *offset += hose->pci_mem_offset; -#endif - res_bit = IORESOURCE_MEM; - } else { - io_offset = (unsigned long)hose->io_base_virt - _IO_BASE; - *offset += io_offset; - res_bit = IORESOURCE_IO; - } - - /* -* Check that the offset requested corresponds to one of the -* resources of the device. -*/ - for (i = 0; i <= PCI_ROM_RESOURCE; i++) { - struct resource *rp = >resource[i]; - int flags = rp->flags; + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + resource_size_t ioaddr = pci_resource_start(pdev, bar); - /* treat ROM as memory (should be already) */ - if (i == PCI_ROM_RESOURCE) - flags |= IORESOURCE_MEM; - - /* Active and same type? */ - if ((flags & res_bit) == 0) - continue; - - /* In the range of this resource? */ - if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end) - continue; + if (!hose) + return -EINVAL; - /* found it! construct the final physical address */ - if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; - return rp; - } + /* Convert to an offset within this PCI controller */ + ioaddr -= (unsigned long)hose->io_base_virt - _IO_BASE; - return NULL; + vma->vm_pgoff += (ioaddr + hose->io_base_phys) >> PAGE_SHIFT; + return 0; } /* @@ -527,42 +477,6 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, return prot; } - -/* - * Perform the actual remap of the pages for a PCI device mapping, as - * appropriate for this architecture. The region in the process to map - * is described by vm_start and vm_end members of VMA, the base physical - * address is found in vm_pgoff. - * The pci