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)