The part of the interface most used by drivers is reading and writing memory-mapped registers on the device. Linux provides interfaces to read and write 8-bit, 16-bit, 32-bit and 64-bit quantities. Due to a historical accident, these are named byte, word, long and quad accesses. Both read and write accesses are supported; there is no prefetch support at this time.
The functions are named readb
,
readw
, readl
,
readq
, writeb
,
writew
, writel
and
writeq
.
Some devices (such as framebuffers) would like to use larger
transfers than 8 bytes at a time. For these devices, the
memcpy_toio
, memcpy_fromio
and memset_io
functions are provided.
Do not use memset or memcpy on IO addresses; they
are not guaranteed to copy data in order.
The read and write functions are defined to be ordered. That is the
compiler is not permitted to reorder the I/O sequence. When the
ordering can be compiler optimised, you can use __readb
and friends to indicate the relaxed ordering. Use
this with care. The rmb
provides a read memory
barrier. The wmb
provides a write memory barrier.
While the basic functions are defined to be synchronous with respect to each other and ordered with respect to each other the busses the devices sit on may themselves have asynchronocity. In paticular many authors are burned by the fact that PCI bus writes are posted asynchronously. A driver author must issue a read from the same device to ensure that writes have occurred in the specific cases the author cares. This kind of property cannot be hidden from driver writers in the API.