Port I/O is pretty simple compared to all the hoopla we saw with MMIO. This is because the processor provides machine instructions to directly perform the work. Of course, just like MMIO, you are expected to politely ask the kernel for permission to access a PIO region (we covered this in the Asking the kernel's permission section). The APIs for doing this are request_region() and release_region() (their parameters are identical to their MMIO counterpart APIs).
So, how can you access and perform I/O (reads and writes) upon the I/O port(s)? Again, the kernel provides API wrappers over the underlying assembly/machine instructions to do so for both reading and writing. Using them, you can perform I/O reads and writes in three possible bit-widths; that is, 8-bit, 16-bit, and 32-bit:
- PMIO reads: inb(), inw(), and inl()
- PMIO writes: outb(), outw(), and outl()
Quite intuitively, b implies byte-wide (8 bits), w implies word-wide ...