DMA_START(K) UNIX System V DMA_START(K)
Name
dma_start - queues DMA request
Syntax
#include "sys/dma.h"
int
dma_start(arg)
struct dmareq *arg;
Description
The dma_start routine queues a DMA request for later
execution when the requested channel is available.
dma_start can be used in initialization or interrupt
routines. The format of the dmareq structure is as follows:
struct dmareq {
struct dmareq *d_nxt; /* reserved */
unsigned short d_chan; /* specifies channel */
unsigned short d_mode; /* direction of transfer */
paddr_t d_addr; /* physical src or dst */
long d_cnt; /* number of bytes or words */
int (*d_proc)();/* address of rtn to call */
char *d_params; /* ptr to params for d_proc */
};
The dmareq structure contains enough information to specify
the transfer, the address of a routine to call when the
channel is available, and an address of further data that
may be needed by the xxd_proc routine (the d_proc field of
the structure).
Possible values for d_chan are:
8-Bit Channels: DMA_CH0, DMA_CH1, DMA_CH2, DMA_CH3
16-Bit Channels: DMA_CH5, DMA_CH6, DMA_CH7
Channel 4 is not available. Other channels may be
permanently allocated by system drivers. Consult the
/usr/adm/messages file for which channels are in use. Use
printcfg in your driver initialization routine to display
the DMA channel that you select.
dma_start sets up the kernel to allocate the DMA channel for
the driver. By filling in the d_chan field with the channel
you want, the d_mode with the mode you want, and the
xxd_proc with a pointer to the routine to be called once the
DMA channel is allocated, the driver can request that the
kernel allocate a channel.
When the channel is allocated, the routine pointed to by
xxd_proc is called with a pointer to the dmareq structure.
At this point, the DMA channel has been allocated as if the
driver had done so with dma_alloc.
If the routine was not able to allocate the channel
immediately, but had to queue your request, this routine
will return a 0.
Example
For example, to allocate DMA channel 1 for reading and with
foo_proc as the xxd_proc routine, use:
/* set up dma structure */
extern int foo_proc();
struct dmareq foo_req = { /* DMA request structure: */
(struct dmareq *)0, /* d_nxt */
DMA_CH1, /* d_chan */
DMA_Rdmode, /* d_mode */
(paddr_t)0, /* d_addr */
(long)0, /* d_cnt */
foo_proc, /* d_proc */
(char *)0, /* d_params */
};
...
dma_start( &foo_req );
/* we don't care if we are queued or not */
return;
Parameters
The arg argument is a pointer to the dmareq structure that
specifies the transfer that is required.
Return Value
If the channel is available, it is marked as ``busy,'' and
arg->d_proc is called at spl6(K) with a pointer to arg as a
parameter. The dma_start routine then returns a non-zero
value.
If the channel is not available, the structure *arg is
linked to the end of a list of pending requests, and
dma_alloc(K) simply returns 0.
Note
The kernel routines contained in the xxd_proc routine are
executed at spl6(K) and should observe all the normal rules
of an interrupt routine. Specifically, this means that no
assumptions about the currently running process may be made.
In addition, the interrupt priority level should not be
lowered, and sleep(K), delay(K), or other routines that call
sleep cannot be used.
See Also
dma_enable(K), dma_resid(K), dma_param(K), dma_alloc(K),
dma_relse(K)
(printed 7/6/89)