Writing Device Drivers

DMA Callback Example

In Example 7-1, xxstart() is used as the callback function and the per-device state structure is given as its argument. xxstart() attempts to start the command. If the command cannot be started because resources are not available, xxstart() is scheduled to be called sometime later, when resources might be available.

Because xxstart() is used as a DMA callback, it must follow these rules imposed on DMA callbacks:


Example 7-1 Allocating DMA Resources

static int
xxstart(caddr_t arg)
{
	struct xxstate *xsp = (struct xxstate *)arg;
	struct device_reg *regp;
	int flags;
	mutex_enter(&xsp->mu);
	if (xsp->busy) {
	    	/* transfer in progress */
	    	mutex_exit(&xsp->mu);
	    	return (0);
	}
	xsp->busy = 1;
	mutex_exit(&xsp->mu);
	regp = xsp->regp;
	if (transfer is a read) {
	    	flags = DDI_DMA_READ;
	} else {
	    	flags = DDI_DMA_WRITE;
	}
	if (ddi_dma_buf_bind_handle(xsp->handle,xsp->bp,flags,
xxstart,
	    	(caddr_t)xsp, &cookie, &ccount) != DDI_DMA_MAPPED) {
	    	/* really should check all return values in a switch */
	    	return (DDI_DMA_CALLBACK_RUNOUT);
	}
	...
	program the DMA engine
	...
	return (DDI_DMA_CALLBACK_DONE);
}