Writing Device Drivers

Freeing the DMA Resources

After a DMA transfer is completed (usually in the interrupt routine), the driver can release DMA resources by calling ddi_dma_unbind_handle(9F).

As described in "Synchronizing Memory Objects", ddi_dma_unbind_handle(9F) calls ddi_dma_sync(9F), eliminating the need for any explicit synchronization. After calling ddi_dma_unbind_handle(9F), the DMA resources become invalid, and further references to them have undefined results. Example 7-2shows how to use ddi_dma_unbind_handle(9F).


Example 7-2 Freeing DMA Resources

static u_int
xxintr(caddr_t arg)
{
 	struct xxstate *xsp = (struct xxstate *)arg;
 	uint8_t		status, temp;
 	mutex_enter(&xsp->mu);
 	/* read status */
 	status = ddi_get8(xsp->access_hdl, &xsp->regp->csr);
 	if (!(status & INTERRUPTING)) {
	    	mutex_exit(&xsp->mu);
	    	return (DDI_INTR_UNCLAIMED);
 	}
 	ddi_put8(xsp->access_hdl, &xsp->regp->csr, CLEAR_INTERRUPT);
  	/* for store buffers */
 	temp = ddi_get8(xsp->access_hdl, &xsp->regp->csr);
 	ddi_dma_unbind_handle(xsp->handle);
 	...
	 check for errors
 	...
 	xsp->busy = 0;
 	mutex_exit(&xsp->mu);
 	if (pending transfers) {
	    	(void) xxstart((caddr_t)xsp);
 	}
 	return (DDI_INTR_CLAIMED);
}

The DMA resources should be released and reallocated if a different object will be used in the next transfer. However, if the same object is always used, the resources may be allocated once and continually reused as long as there are intervening calls to ddi_dma_sync(9F).