ddi_dmae_prog(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_getlim,
ddi_dmae_getattr - system DMA engine functions
SYNOPSIS
int ddi_dmae_alloc(dev_info_t *dip, int chnl, int (*call-
back) (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_getlim(dev_info_t *dip, ddi_dma_lim_t *lim-
itsp);
int ddi_dmae_getattr(dev_info_t *dip, ddi_dma_attr_t
*attrp);
INTERFACE LEVEL
Solaris DDI specific (Solaris DDI). The ddi_dmae_getlim()
interface, described below, is obsolete. Use
ddi_dmae_getattr(), also described below, to replace it.
PARAMETERS
dip A dev_info pointer that identifies the device.
chnl A DMA channel number. On ISA or EISA 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, obtained
from ddi_dma_segtocookie(9F), 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 comple-
tion of a DMA operation.
limitsp
A pointer to a DMA limit structure. See
ddi_dma_lim_x86(9S).
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 mas-
ter, 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_segtocookie(9F).
See ddi_dma_cookie(9S) for a description of a DMA
cookie.
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 dev-
ice 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 chan-
nel of the system DMA engine. ddi_dmae_alloc() allows only
one device at a time to have a particular DMA channel allo-
cated. It must be called prior to any other system DMA
engine function on a channel. If the device allows the chan-
nel 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 pro-
grammed, 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 cookie obtained from
ddi_dma_segtocookie(9F). Other DMA engine parameters are
specified by the DMA engine request structure passed in
through dmaereqp. The fields of that structure are docu-
mented in ddi_dmae_req(9S).
Before using ddi_dmae_prog(), you must allocate system DMA
resources using DMA setup functions such as
ddi_dma_buf_setup(9F). ddi_dma_segtocookie(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 ter-
minates 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 and EISA buses, ddi_dmae_1stparty() con-
figures 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 con-
figured 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
ddi_dma_segtocookie(9F).
ddi_dmae_getlim()
Note that this function is obsolete. Use ddi_dmae_getattr(),
described below, instead.
The ddi_dmae_getlim() function fills in the DMA limit struc-
ture, pointed to by limitsp, with the DMA limits of the sys-
tem DMA engine. Drivers for devices that perform their own
bus mastering or use first-party DMA must create and ini-
tialize their own DMA limit structures; they should not use
ddi_dmae_getlim(). The DMA limit structure must be passed to
the DMA setup routines so that they will know how to break
the DMA request into windows and segments (see
ddi_dma_nextseg(9F) and ddi_dma_nextwin(9F)). If the device
has any particular restrictions on transfer size or granu-
larity (such as the size of disk sector), the driver should
further restrict the values in the structure members before
passing them to the DMA setup routines. The driver must not
relax any of the restrictions embodied in the structure
after it is filled in by ddi_dmae_getlim(). After calling
ddi_dmae_getlim(), a driver must examine, and possibly set,
the size of the DMA engine's scatter/gather list to deter-
mine whether DMA chaining will be used. See
ddi_dma_lim_x86(9S) and ddi_dmae_req(9S) for additional
information on scatter/gather DMA.
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 struc-
ture 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_nextcookie(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
may be called from user or interrupt context.
ATTRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
____________________________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
|_____________________________|_____________________________|
| Architecture | x86 |
|_____________________________|_____________________________|
SEE ALSO
eisa(4), isa(4), attributes(5), ddi_dma_buf_setup(9F),
ddi_dma_getwin(9F), ddi_dma_nextcookie(9F),
ddi_dma_nextseg(9F), ddi_dma_nextwin(9F),
ddi_dma_segtocookie(9F), ddi_dma_setup(9F),
ddi_dma_attr(9S), ddi_dma_cookie(9S), ddi_dma_lim_x86(9S),
ddi_dma_req(9S), ddi_dmae_req(9S)
Man(1) output converted with
man2html