DDI_DMAE(9F)            Kernel Functions for Drivers            DDI_DMAE(9F)
NAME
       ddi_dmae, ddi_dmae_alloc, ddi_dmae_release, ddi_dmae_prog,
       ddi_dmae_disable, ddi_dmae_enable, ddi_dmae_stop, ddi_dmae_getcnt,
       ddi_dmae_1stparty, ddi_dmae_getattr - system DMA engine functions
SYNOPSIS
       int ddi_dmae_alloc(
dev_info_t *dip, 
int chnl, 
int (*callback) (caddr_t),            
caddr_t arg);       
int ddi_dmae_release(
dev_info_t *dip, 
int chnl);       
int ddi_dmae_prog(
dev_info_t *dip, 
struct ddi_dmae_req *dmaereqp,            
ddi_dma_cookie_t *cookiep, 
int chnl);       
int ddi_dmae_disable(
dev_info_t *dip, 
int chnl);       
int ddi_dmae_enable(
dev_info_t *dip, 
int chnl);       
int ddi_dmae_stop(
dev_info_t *dip, 
int chnl);       
int ddi_dmae_getcnt(
dev_info_t *dip, 
int chnl, 
int *countp);       
int ddi_dmae_1stparty(
dev_info_t *dip, 
int chnl);       
int ddi_dmae_getattr(
dev_info_t *dip, 
ddi_dma_attr_t *attrp);
INTERFACE LEVEL
       illumos DDI specific (illumos DDI).
PARAMETERS
       dip                   A 
dev_info pointer that identifies the device.       
chnl                   A 
DMA channel number. On 
ISA buses this number must be 
0,                   
1, 
2, 
3, 
5, 
6, or 
7.       
callback                   The address of a function to call back later if resources
                   are not currently available. The following special
                   function addresses may also be used:                   
DDI_DMA_SLEEP                                       Wait until resources are available.                   
DDI_DMA_DONTWAIT                                       Do not wait until resources are
                                       available and do not schedule a
                                       callback.       
arg                   Argument to be passed to the callback function, if
                   specified.       
dmaereqp                   A pointer to a 
DMA engine request structure. See                   
ddi_dmae_req(9S).       
cookiep                   A pointer to a 
ddi_dma_cookie(9S) object, which contains
                   the address and count.       
countp                   A pointer to an integer that will receive the count of
                   the number of bytes not yet transferred upon completion
                   of a 
DMA operation.       
attrp                   A pointer to a 
DMA  attribute structure. See                   
ddi_dma_attr(9S).
DESCRIPTION
       There are three possible ways that a device can perform 
DMA engine
       functions:       
Bus master DMA                          If the device is capable of acting as a true bus
                          master, then the driver should program the
                          device's 
DMA registers directly and not make use
                          of the 
DMA engine functions described here. The
                          driver should obtain the 
DMA address and count
                          from 
ddi_dma_cookie(9S).       
Third-party DMA                          This method uses the system 
DMA engine that is
                          resident on the main system board. In this model,
                          the device cooperates with the system's 
DMA engine
                          to effect the data transfers between the device
                          and memory. The driver uses the functions
                          documented here, except 
ddi_dmae_1stparty(), to
                          initialize and program the 
DMA engine. For each                          
DMA data transfer, the driver programs the 
DMA                          engine and then gives the device  a command to
                          initiate the transfer in cooperation with that
                          engine.       
First-party DMA                          Using this method, the device uses its own 
DMA bus
                          cycles, but requires a channel from the system's                          
DMA engine. After allocating the 
DMA channel, the                          
ddi_dmae_1stparty() function may be used to
                          perform whatever configuration is necessary to
                          enable this mode.   
ddi_dmae_alloc()       The 
ddi_dmae_alloc() function is used to acquire a 
DMA channel of the
       system 
DMA engine. 
ddi_dmae_alloc() allows only one device at a time
       to have a particular 
DMA channel allocated. It must be called prior
       to any other system  
DMA engine function on a channel. If the device
       allows the channel to be shared with other devices, it must be freed
       using 
ddi_dmae_release() after completion of the 
DMA operation. In
       any case, the channel must be released before the driver successfully
       detaches. See 
detach(9E). No other driver may acquire the 
DMA channel
       until it is released.
       If the requested channel is not immediately available, the value of       
callback determines what action will be taken. If the value of       
callback is 
DDI_DMA_DONTWAIT, 
ddi_dmae_alloc() will return
       immediately. The value 
DDI_DMA_SLEEP will cause the thread to sleep
       and not return until the channel has been acquired. Any other value
       is assumed to be a callback function address. In that case,       
ddi_dmae_alloc() returns immediately, and when resources might have
       become available, the callback function is called (with the argument       
arg) from interrupt context. When the callback function is called, it
       should attempt to allocate the 
DMA channel again. If it succeeds or
       no longer needs the channel, it must return the value       
DDI_DMA_CALLBACK_DONE. If it tries to allocate the channel but fails
       to do so, it must return the value 
DDI_DMA_CALLBACK_RUNOUT. In this
       case, the callback function is put back on a list to be called again
       later.   
ddi_dmae_prog()       The 
ddi_dmae_prog() function programs the 
DMA channel for a 
DMA       transfer. The 
ddi_dmae_req structure contains all the information
       necessary to set up the channel, except for the memory address and
       count. Once the channel has been programmed, subsequent calls to       
ddi_dmae_prog() may specify a value of 
NULL for 
dmaereqp if no
       changes to the programming are required other than the address and
       count values. It disables the channel prior to setup, and enables the
       channel before returning. The 
DMA address and count are specified by
       passing 
ddi_dmae_prog() a 
DMA cookie.  Other 
DMA engine parameters
       are specified by the 
DMA engine request structure passed in through       
dmaereqp. The fields of that structure are documented in       
ddi_dmae_req(9S).
       Before using 
ddi_dmae_prog(), you must allocate system 
DMA resources
       using 
DMA setup functions such as 
ddi_dma_mem_alloc(9F).       
ddi_dma_addr_bind_handle(9F) can then be used to retrieve a cookie
       which contains the address and count. Then this cookie is passed to       
ddi_dmae_prog().   
ddi_dmae_disable()       The 
ddi_dmae_disable() function disables the 
DMA channel so that it
       no longer responds to a device's  
DMA service requests.   
ddi_dmae_enable()       The 
ddi_dmae_enable() function enables the 
DMA channel for operation.
       This may be used to re-enable the channel after a call to       
ddi_dmae_disable(). The channel is automatically enabled after
       successful programming by 
ddi_dmae_prog().   
ddi_dmae_stop()       The 
ddi_dmae_stop() function disables the channel and terminates any
       active operation.   
ddi_dmae_getcnt()       The 
ddi_dmae_getcnt() function examines the count register of the 
DMA       channel and sets 
*countp to the number of bytes remaining to be
       transferred.  The channel is assumed to be stopped.   
ddi_dmae_1stparty()       In the case of 
ISA buses, 
ddi_dmae_1stparty() configures a channel in
       the system's 
DMA engine to operate in a ``slave'' (``cascade'') mode.
       When operating in 
ddi_dmae_1stparty() mode, the  
DMA channel must
       first be allocated using 
ddi_dmae_alloc() and then configured using       
ddi_dmae_1stparty(). The driver then programs the device to perform
       the I/O, including the necessary 
DMA address and count values
       obtained from the 
ddi_dma_cookie(9S).   
ddi_dmae_getattr()       The 
ddi_dmae_getattr() function fills in the 
DMA attribute structure,
       pointed to by 
attrp, with the 
DMA attributes of the system 
DMA       engine. Drivers for devices that perform their own bus mastering or
       use first-party 
DMA must create and initialize their own 
DMA       attribute structures; they should not use 
ddi_dmae_getattr().  The       
DMA attribute structure must be passed to the 
DMA resource allocation
       functions to provide the information necessary to break the 
DMA       request into 
DMA windows and 
DMA cookies. See 
ddi_dma_cookie_iter(9F)       and 
ddi_dma_getwin(9F).
RETURN VALUES
       DDI_SUCCESS                              Upon success, for all of these routines.       
DDI_FAILURE                              May be returned due to invalid arguments.       
DDI_DMA_NORESOURCES                              May be returned by 
ddi_dmae_alloc() if the
                              requested resources are not available and the
                              value of 
dmae_waitfp is not 
DDI_DMA_SLEEP.
CONTEXT
       If 
ddi_dmae_alloc() is called from interrupt context, then its       
dmae_waitfp argument and the callback function must not have the
       value 
DDI_DMA_SLEEP. Otherwise, all these routines can be called from
       user, interrupt, or kernel context.
ATTRIBUTES
       See 
attributes(7) for descriptions of the following attributes:
       +---------------+-----------------+
       |ATTRIBUTE TYPE | ATTRIBUTE VALUE |
       +---------------+-----------------+
       |Architecture   | x86             |
       +---------------+-----------------+
SEE ALSO
       isa(5), 
attributes(7), 
ddi_dma_addr_bind_handle(9F),       
ddi_dma_buf_setup(9F), 
ddi_dma_cookie_iter(9F), 
ddi_dma_getwin(9F),       
ddi_dma_mem_alloc(9F), 
ddi_dma_attr(9S), 
ddi_dma_cookie(9S),       
ddi_dmae_req(9S)                              January 18, 2020                  DDI_DMAE(9F)