#include <sys/ddi.h> #include <sys/sunddi.h> int ddi_dma_mem_alloc(ddi_dma_handle_t handle, size_t length, ddi_device_acc_attr_t *accattrp, uint_t flags, int (*waitfp) (caddr_t), caddr_t arg, caddr_t *kaddrp, size_t *real_length, ddi_acc_handle_t *handlep);
Solaris DDI specific (Solaris DDI).
Possible values of the data transfer are:
The callback function must take whatever steps are necessary to protect its critical resources, data structures, queues, and so on.
The ddi_dma_mem_alloc() function allocates memory for DMA transfers to or from a device. The allocation will obey the alignment, padding constraints and device granularity as specified by the DMA attributes (see ddi_dma_attr(9S)) passed to ddi_dma_alloc_handle(9F) and the more restrictive attributes imposed by the system.
The flags parameter should be set to DDI_DMA_STREAMING if the device is doing sequential, unidirectional, block-sized, and block-aligned transfers to or from memory. The alignment and padding constraints specified by the minxfer and burstsizes fields in the DMA attribute structure, ddi_dma_attr(9S) (see ddi_dma_alloc_handle(9F)) will be used to allocate the most effective hardware support for large transfers. For example, if an I/O transfer can be sped up by using an I/O cache, which has a minimum transfer of one cache line, ddi_dma_mem_alloc() will align the memory at a cache line boundary and it will round up real_length to a multiple of the cache line size.
The flags parameter should be set to DDI_DMA_CONSISTENT if the device accesses memory randomly, or if synchronization steps using ddi_dma_sync(9F) need to be as efficient as possible. I/O parameter blocks used for communication between a device and a driver should be allocated using DDI_DMA_CONSISTENT.
The device access attributes are specified in the location pointed by the accattrp argument (see ddi_device_acc_attr(9S)).
The data access handle is returned in handlep. handlep is opaque - drivers may not attempt to interpret its value. To access the data content, the driver must invoke ddi_get8(9F) or ddi_put8(9F) (depending on the data transfer direction) with the data access handle.
DMA resources must be established before performing a DMA transfer by passing kaddrp and real_length as returned from ddi_dma_mem_alloc() and the flag DDI_DMA_STREAMING or DDI_DMA_CONSISTENT to ddi_dma_addr_bind_handle(9F). In addition, to ensure the consistency of a memory object shared between the CPU and the device after a DMA transfer, explicit synchronization steps using ddi_dma_sync(9F) or ddi_dma_unbind_handle(9F) are required.
The ddi_dma_mem_alloc() function returns:
The ddi_dma_mem_alloc() function can be called from user, interrupt, or kernel context except when waitfp is set to DDI_DMA_SLEEP, in which case it cannot be called from interrupt context.
ddi_dma_addr_bind_handle(9F), ddi_dma_alloc_handle(9F), ddi_dma_mem_free(9F), ddi_dma_sync(9F), ddi_dma_unbind_handle(9F), ddi_get8(9F), ddi_put8(9F), ddi_device_acc_attr(9S), ddi_dma_attr(9S)
If DDI_NEVERSWAP_ACC is specified, memory can be used for any purpose; but if either endian mode is specified, you must use ddi_get/put* and never anything else.