xtalk_dma(D3)xtalk_dma(D3)NAME
xtalk_dmatrans_addr - construct DMA address
xtalk_dmatrans_list - construct DMA addresses
xtalk_dmamap_alloc - allocate an XIO DMA channel
xtalk_dmamap_addr - set DMA channel target
xtalk_dmamap_list - set DMA channel targets
xtalk_dmamap_done - mark DMA channel unused
xtalk_dmamap_free - release XIO DMA channel resources
xtalk_dmamap_drain - drain a DMA MAP based DMA path
xtalk_dmaaddr_drain - drain a DMA path to a specific block
xtalk_dmalist_drain - drain a DMA path for an alenlist
SYNOPSIS
#include <sys/xtalk/xtalk.h>
iopaddr_t
xtalk_dmatrans_addr(
vertex_hdl_t vhdl,
device_desc_t desc,
iopaddr_t addr,
size_t size,
unsigned flags)
alenlist_t
xtalk_dmatrans_list(
vertex_hdl_t vhdl,
device_desc_t desc,
alenlist_t list,
unsigned flags)
xtalk_dmamap_t
xtalk_dmamap_alloc(
vertex_hdl_t vhdl,
device_desc_t desc,
xtalk_space_t space,
size_t max,
unsigned flags)
iopaddr_t
xtalk_dmamap_addr(
xtalk_dmamap_t map,
iopaddr_t addr,
size_t size);
alenlist_t
xtalk_dmamap_list(
xtalk_dmamap_t map,
alenlist_t list,
unsigned flags);
void
xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
Page 1
xtalk_dma(D3)xtalk_dma(D3)
void
xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
void
xtalk_dmamap_drain(
xtalk_dmamap_t *xtalk_dmamap)
void
xtalk_dmaaddr_drain(
vertex_hdl_t vhdl,
paddr_t addr,
size_t bytes)
void
xtalk_dmalist_drain(
vertex_hdl_t vhdl,
alenlist_t *list)
Arguments
vhdl is the appropriate XIO connection point.
desc is a device descriptor, usually zero.
addr is the offset within the space.
size is the size of the mapped region.
list is an ordered list of address/length pairs.
max is the maximum size mapped at any one time.
flags is used to specify attributes of the mapping.
DESCRIPTION
When a device driver wishes to use Direct Memory Access (DMA) to
communicate with a device, the system needs to have a chance to set up
any appropriate mapping registers.
There are two different models for how to do this. The simple model
provides permanent mappings through fixed mapping resources.
o xtalk_dmatrans_addr() is the one-stop shopping place for using system
fixed shareable mapping resources to construct an XIO DMA address
that will land the DMA requests at the targeted memory location.
This is not always possible, and when it is not, the function will
return NULL.
o xtalk_dmatrans_list() is similar, but operates on a list of blocks of
memory returning a list of blocks of XIO space.
Page 2
xtalk_dma(D3)xtalk_dma(D3)
It is not always possible to establish such mappings using common shared
system resources, so the concept of a DMA channel that preallocates
scarce mapping resources is provided.
Such channels are allocated using xtalk_dmamap_alloc(), which is given
the maximum size to be mapped.
o xtalk_dmamap_addr() or xtalk_dmamap_list() is then used to actually
establish the proper mappings for a DMA target; given the base
address and block size of the region for DMA (or a list of these), it
will hand back the base XIO address to be used for accessing that
region (or a list of these).
o If the same DMA channel is to be used at different times to map
different target areas, xtalk_dmamap_done() should be called to idle
any mapping hardware (and possibly flush out any pipes or buffers
along the path that might do unexpected things when mapping registers
are modified). Then xtalk_dmamap_addr() or xtalk_dmamap_list() can
again be called, specifying the new target area.
When a driver is completely finished with a DMA channel -- either because
the channel is used only for initialization of the device, or because the
device or the driver is being shut down -- the DMA channel resources
should be released back to the system using xtalk_dmamap_free().
xtalk_dmamap_drain(), xtalk_dmaaddr_drain() and xtalk_dmalist_drain() are
used after a device reports it has completed DMA, to be sure that all
data along the DMA path has in fact reached its destination.
DMA Attribute Flags
All functions that have flag words can be asked to set up or disable
certain DMA acceleration features of whatever machine is in use.
XTALK_INPLACE
When list operations are performed, this flag requests that the
list be modified in place. If this flag is not specified, the
infrastructure will attempt to allocate a new list for the result
data, which will take longer and may fail but which will avoid
modifying the input list.
XTALK_NOSLEEP
If this flag is specified, any resources that are needed from the
system are allocated without sleeping. If any resource allocation
would have required the infrastructure to sleep, the service call
will return a failure code.
Translation Results
If the target of the DMA is not in fact memory, the result of a
translation may be a packed XIO address, which contains not only the
Page 3
xtalk_dma(D3)xtalk_dma(D3)
usual 48-bit offset in the target port, but the actual 4-bit target XIO
port number. While this is likely to be a rare condition, triggered only
when code explicitly schedules DMA to a destination that is memory-mapped
from another device, it is advisable for all drivers calling xtalk_dma*()
services to check for and handle these packed addresses. For more
information, see XIO_PACK(D3).
EXAMPLES
Here is one way that a driver might make use of dmamap and dmatrans
calls.
xiofoo_attach(vertex_hdl_t vhdl)
{
xtalk_dmamap_t command_map;
iopaddr_t command_dma;
struct xiofoo_regs *reg_pio;
struct xiofoo_ring *command_ring;
...
/*
* This driver has decided to use a dmamap
* to get to its command rings, which contain
* things like DMA addresses and counts.
*/
/* allocate the channel
*/
command_map = xtalk_dmamap_alloc
(vhdl, 0, RINGBYTES, 0);
command_dma = xtalk_dmamap_addr(
command_map,
kvtophys(command_ring),
RINGBYTES);
/* tell the device where it can find
* it's command rings.
*/
reg_pio->command_dma = command_dma;
...
}
{
caddr_t data_buffer;
size_t data_size;
...
data_dma = xtalk_dmatrans_addr(vhdl, 0,
Page 4
xtalk_dma(D3)xtalk_dma(D3)kvtophys(data_buffer), data_size, 0);
command_ring->data_dma_addr = data_dma;
command_ring->data_dma_size = data_size;
command_ring->ready = 1;
}
SEE ALSOXIO_PACK(D3), xtalk(D3), xtalk_error(D3), xtalk_get(D3), xtalk_intr(D3),
xtalk_pio(D3).
DIAGNOSTICSxtalk_dmatrans_addr() will return XIO_NOWHERE if shared (fixed) resources
can not be used to construct a valid XIO address that maps to the desired
range of physical addresses.
xtalk_dmatrans_list() will return a null pointer if any of the requested
physical address blocks can not be reached using shared fixed resources,
or if unable to allocate a return list.
xtalk_dmamap_alloc() will return a null pointer if resources can not be
allocated to establish DMA mappings of the requested size, or if the
parameters are inconsistent.
xtalk_dmamap_addr() will return a null pointer if the specified target
address can not be mapped using the specified DMA channel; this would
usually be due to specifying a target block that is outside the
previously specified target area or is larger than the previously
specified maximum mapping size. It may also return a null pointer if the
DMA channel is currently in use and has not been marked idle by a
xtalk_dmamap_done() call.
xtalk_dmamap_addr() can return a null pointer for all the reasons
mentioned above, or if it is unable to allocate the return list.
Page 5