DDI_DMA_MEM_ALLOC(9F)   Kernel Functions for Drivers   DDI_DMA_MEM_ALLOC(9F)
NAME
       ddi_dma_mem_alloc - allocate memory for DMA transfer
SYNOPSIS
       #include <sys/ddi.h>
       #include <sys/sunddi.h>       
int ddi_dma_mem_alloc(
ddi_dma_handle_t handle, 
size_t length,            
const 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);
INTERFACE LEVEL
       illumos DDI specific (illumos DDI).
PARAMETERS
       handle                      The 
DMA handle previously allocated by a call to                      
ddi_dma_alloc_handle(9F).       
length                      The length in bytes of the desired allocation.       
accattrp                      Pointer to a 
ddi_device_acc_attr() structure of the
                      device. See 
ddi_device_acc_attr(9S). The value in                      
devacc_attr_dataorder is ignored in the current
                      release. The value in 
devacc_attr_endian_flags is
                      meaningful on the SPARC architecture only.       
flags                      Used to determine the data transfer mode and/or the
                      cache attribute.
                      Possible values of the data transfer are:                      
DDI_DMA_STREAMING                                            Sequential, unidirectional,
                                            block-sized, and block-aligned
                                            transfers.                      
DDI_DMA_CONSISTENT                                            Nonsequential transfers of small
                                            objects.
                      Possible values of the cache attribute are:                      
IOMEM_DATA_CACHED                                                  The CPU can cache the data
                                                  it fetches and push it to
                                                  memory at a later time.
                                                  This is the default
                                                  attribute that is used if
                                                  no cache attributes are
                                                  specified.                      
IOMEM_DATA_UC_WR_COMBINE                                                  The CPU never caches the
                                                  data, but writes can occur
                                                  out of order or can be
                                                  combined. Reordering is
                                                  implied.
                                                  If                                                  
IOMEM_DATA_UC_WR_COMBINE                                                  is specified but not
                                                  supported,                                                  
IOMEM_DATA_UNCACHED is
                                                  used instead.                      
IOMEM_DATA_UNCACHED                                                  The CPU never caches data,
                                                  but has uncacheable access
                                                  to memory. Strict ordering
                                                  is implied.
                      The cache attributes are mutually exclusive. Any
                      combination of the values leads to a failure. On the
                      SPARC architecture, only 
IOMEM_DATA_CACHED is
                      meaningful. Others lead to a failure.       
waitfp                      The address of a function to call back later if
                      resources are not available now. The callback function
                      indicates how a caller wants to handle the possibility
                      of resources not being available. If callback is set
                      to 
DDI_DMA_DONTWAIT, the caller does not care if the
                      allocation fails, and can handle an allocation failure
                      appropriately. If callback is set to 
DDI_DMA_SLEEP,
                      the caller wishes to have the allocation routines wait
                      for resources to become available. If any other value
                      is set and a DMA resource allocation fails, this value
                      is assumed to be the address of a function to be
                      called when resources become available. When the
                      specified function is called, 
arg is passed to it as
                      an argument. The specified callback function must
                      return either 
DDI_DMA_CALLBACK_RUNOUT or                      
DDI_DMA_CALLBACK_DONE.  
DDI_DMA_CALLBACK_RUNOUT                      indicates that the callback function attempted to
                      allocate DMA resources but failed. In this case, the
                      callback function is put back on a list to be called
                      again  later. 
DDI_DMA_CALLBACK_DONE indicates that
                      either the allocation of DMA resources was successful
                      or the driver no longer wishes to retry. The callback
                      function is called in interrupt context.  Therefore,
                      only system functions accessible from interrupt
                      context are available.
                      The callback function must take whatever steps are
                      necessary to protect its critical resources, data
                      structures, queues, and so on.       
arg                      Argument to be passed to the callback function, if
                      such a function is specified.       
kaddrp                      On successful return, 
kaddrp points to the allocated
                      memory.       
real_length                      The amount of memory, in bytes, allocated. Alignment
                      and padding requirements may require                      
ddi_dma_mem_alloc() to allocate more memory than
                      requested in 
length.       
handlep                      Pointer to a data access handle.
DESCRIPTION
       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.
RETURN VALUES
       The 
ddi_dma_mem_alloc() function returns:       
DDI_SUCCESS                      Memory successfully allocated.       
DDI_FAILURE                      Memory allocation failed.
CONTEXT
       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.
SEE ALSO
       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)       Writing Device DriversWARNINGS
       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.
                                July 13, 2024          DDI_DMA_MEM_ALLOC(9F)