And also flags to specify which address space the I/O ports reside in, and
which how to adjust the host-PCI bridge to bring the appropriate bit of the
PCI address space into view through the CPU address space window. Don't laugh
- it happens.
> I really don't like hacing virtual access functions that makes memory
> mapped I/O look the same as I/O operations.
Why not? It makes drivers a simpler and more flexible if they can treat
different types of resource in the same way. serial.c is a really good example
of this:
| static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
| {
| switch (info->io_type) {
| #ifdef CONFIG_HUB6
| case SERIAL_IO_HUB6:
| outb(info->hub6 - 1 + offset, info->port);
| return inb(info->port+1);
| #endif
| case SERIAL_IO_MEM:
| return readb((unsigned long) info->iomem_base +
| (offset<<info->iomem_reg_shift));
| #ifdef CONFIG_SERIAL_GSC
| case SERIAL_IO_GSC:
| return gsc_readb(info->iomem_base + offset);
| #endif
| default:
| return inb(info->port + offset);
| }
| }
The switch has to be performed at runtime - so you get at least one
conditional branch in your code, probably more. My proposal would replace the
conditional branch with a subroutine (which lacks the pipline stall).
Also a number of drivers (eg: ne2k-pci) have to be bound to compile time to
either I/O space or memory space. This would allow you to do it at runtime
without incurring conditional branching.
> For memory mapped I/O you want to be able to smart optimizations to reduce
> the access on the PCI bus (or similar).
I wouldn't have thought you'd want to reduce the number of accesses to the PCI
bus. If, for example, you did to writes to a memory-mapped I/O register, you
don't want the first to be optimised away.
David
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/