La parte de la interface más usada por los controladores es la lectura y escritura de los registros mapeados en memoria del dispositivo. Linux suministra interfaces para leer y escribir cantidades de 8-bits, 16-bits, 32-bits y 64-bits. Debido a un accidente histórico estos son llamados accesos byte, word, long y quad. Ambos accesos de lectura y escritura son soportados; no hay soporte pre-producido en este momento.
Las funciones tienen los nombres readb, readw, readl, readq, writeb, writew, writel y writeq.
A algunos dispositivos (como los framebuffers) les gustaría usar transferencias más grandes de los 8 bytes cada vez. Para estos dispositivos, son suministradas las funciones memcpy_toio, memcpy_fromio y memset_io. No utilices memset o memcpy en direcciones de E/S; no está garantizado que copien los datos en orden.
Las funciones de lectura y escritura están definidas para ser ordenadas. Esto es, al compilador no le está permitido reordenar la secuencia de E/S. Cuando el órden puede ser compilado de forma optimizada, puedes usar __readb y amigos para indicar un órden relajado. Usa esto con cuidado. La rmb suministra una barrera de lectura de memoria. La wmb suministra una barrera de escritura de memoria.
Mientras las funciones básicas son definidas para ser síncronas y ordenadas con respecto a las otras, los dispositivos que están en los buses quizás sean asíncronos. En particular, algunos autores han sido quemados por el hecho de que las escrituras en el bus PCI son realizadas de forma asíncrona. El autor de un controlador debe de emitir una lectura para el mismo dispositivo para asegurarse de que la escritura ha tenido lugar en los casos específicos que quiere el autor. Este tipo de propiedad no puede ser escondida por los escritores de los controladores en la API.