Commit 585d744b authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] ppc32: PCI mmap update

This 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
parent f2c371c7
......@@ -159,7 +159,6 @@ pcibios_fixup_resources(struct pci_dev *dev)
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 @@ __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
{
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;
}
/*
* 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;
/* 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;
}
return -EINVAL;
vma->vm_pgoff = offset >> PAGE_SHIFT;
return ret;
}
/*
......
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