To improve performance, the CPU uses internal store buffers to temporarily store data.
Using internal buffers can affect the synchronization of device I/O operations. Therefore, the
driver needs to take explicit steps to make sure that writes to registers
are completed at the proper time.
For example, consider the case where access to device space, such as registers
or a frame buffer, is synchronized by a lock. The driver needs
to check that the store to the device space has actually completed before
releasing the lock. The release of the lock does not guarantee the flushing
of I/O buffers.
To give another example, when acknowledging an interrupt, the driver usually sets or
clears a bit in a device control register. The driver must ensure that
the write to the control register has reached the device before the interrupt
handler returns. Similarly, a device might require a delay, that is, driver busy-waits,
after writing a command to the control register. In such a case, the
driver must ensure that the write has reached the device before delaying.
Where device registers can be read without undesirable side effects, verification of a
write can simply consist of reading the register immediately after the write. If
that particular register cannot be read without undesirable side effects, another device register
in the same register set can be used.