[PATCH] ppc32: PCI mmap update

From: Benjamin Herrenschmidt
Date: Tue Mar 30 2004 - 00:48:52 EST


This patch updates the ppc32 PCI mmap facility to allow mmap'ing of
space outside of the actual devices, using the host bridge resources
instead. This allow userland to map things like legacy IO space by
either using the bridge device itself, or simply any PCI device on
the same bus domain

diff -urN linux-2.5/arch/ppc/kernel/pci.c linuxppc-2.5-benh/arch/ppc/kernel/pci.c
--- linux-2.5/arch/ppc/kernel/pci.c 2004-03-01 18:11:11.000000000 +1100
+++ linuxppc-2.5-benh/arch/ppc/kernel/pci.c 2004-03-29 13:56:09.000000000 +1000
@@ -159,7 +159,6 @@
ppc_md.pcibios_fixup_resources(dev);
}

-
void
pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
struct resource *res)
@@ -1522,51 +1521,43 @@
{
struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long io_offset = 0;
- int i, res_bit;
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long base;
+ struct resource *res;
+ int i;
+ int ret = -EINVAL;

if (hose == 0)
return -EINVAL; /* should never happen */
+ if (offset + size <= offset)
+ return -EINVAL;

- /* If memory, add on the PCI bridge address offset */
if (mmap_state == pci_mmap_mem) {
+ /* PCI memory space */
+ base = hose->pci_mem_offset;
+ for (i = 0; i < 3; ++i) {
+ res = &hose->mem_resources[i];
+ if (res->flags == 0)
+ continue;
+ if (offset >= res->start - base
+ && offset + size - 1 <= res->end - base) {
+ ret = 0;
+ break;
+ }
+ }
offset += hose->pci_mem_offset;
- res_bit = IORESOURCE_MEM;
} else {
- io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
- offset += io_offset;
- res_bit = IORESOURCE_IO;
+ /* PCI I/O space */
+ base = (unsigned long)hose->io_base_virt - isa_io_base;
+ res = &hose->io_resource;
+ if (offset >= res->start - base
+ && offset + size - 1 <= res->end - base)
+ ret = 0;
+ offset += hose->io_base_phys;
}

- /*
- * 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 = &dev->resource[i];
- int flags = rp->flags;
-
- /* 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;
-
- /* found it! construct the final physical address */
- if (mmap_state == pci_mmap_io)
- offset += hose->io_base_phys - io_offset;
-
- vma->vm_pgoff = offset >> PAGE_SHIFT;
- return 0;
- }
-
- return -EINVAL;
+ vma->vm_pgoff = offset >> PAGE_SHIFT;
+ return ret;
}

/*


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/