Another example of programmed I/O might be a driver writing data one byte at a time directly to the device's memory. Each byte is retrieved from the uio(9S) structure using uwritec(9F), then sent to the device. read(9E) can use ureadc(9F) to transfer a byte from the device to the area described by the uio(9S) structure.
static int
xxwrite(dev_t dev, struct uio *uiop, cred_t *credp)
{
int value;
struct xxstate *xsp;
xsp = ddi_get_soft_state(statep, getminor(dev));
if (xsp == NULL)
return (ENXIO);
if the device implements a power manageable component, do this:
pm_busy_component(xsp->dip, 0);
if (xsp->pm_suspended)
ddi_dev_is_needed(xsp->dip, normal power);
while (uiop->uio_resid > 0) {
/*
* do the programmed I/O access
*/
value = uwritec(uiop);
if (value == -1)
return (EFAULT);
ddi_put8(xsp->data_access_handle, &xsp->regp->data,
(uint8_t)value);
ddi_put8(xsp->data_access_handle, &xsp->regp->csr,
START_TRANSFER);
/*
* this device requires a ten microsecond delay
* between writes
*/
drv_usecwait(10);
}
pm_idle_component(xsp->dip, 0);
return (0);
}