Next | Prev | Up | Top | Contents | Index

Mapping DMA Addresses

A DMA map is a system object that represents a mapping between a buffer in kernel virtual space and a range of VME bus addresses. After creating a DMA map, a driver uses the map to specify the target address and length to be programmed into a VME bus master before a DMA transfer.

The functions that operate on DMA maps are summarized in Table 14-2.

Functions That Operate on DMA Maps
FunctionHeader FilesCan SleepPurpose
dma_map(D3) dmamap.h & types.h & sema.hNLoad DMA mapping registers for an imminent transfer.
dma_mapbp(D3) dmamap.h & types.h & sema.hNLoad DMA mapping registers for an imminent transfer.
dma_mapaddr(D3) dmamap.h & types.h & sema.hNReturn the "bus virtual" address for a given map and address.
dma_mapalloc(D3) dmamap.h & types.h & sema.hYAllocate a DMA map.
dma_mapfree(D3) dmamap.h & types.h & sema.hNFree a DMA map.
vme_adapter(D3) vmereg.h & types.hNDetermine VME adapter that corresponds to a given memory address.

A device driver allocates a DMA map using dma_mapalloc(). This is typically done in the pfxedtinit() entry point, provided that the maximum I/O size is known at that time (see "Entry Point edtinit()"). The important argument to dma_mapalloc() is the maximum number of pages (I/O pages, the unit is IO_NBPP declared in sys/immu.h) to be mapped at one time.

Note: In the Challenge and Onyx systems, a limit of 64 MB of mapped DMA space per VME adapater is imposed by the hardware. Some few megabytes of this are taken early by system drivers. Owing to a bug in IRIX 5.3 and 6.1, a request for 64 MB or more is not rejected, but waits forever. However, in any release, a call to dma_mapalloc() that requests a single map close to the 64 MB limit is likely to wait indefinitely for enough map space to become available. DMA maps created by a loadable driver should be released in the pfxunload() entry point (see "Entry Point unload()" and "Unloading").


Using a DMA Map

A DMA map is used prior to a DMA transfer into or out of a buffer in kernel virtual space. The function dma_map() takes a DMA map, a buffer address, and a length. It assigns a span of contiguous VME addresses of the specified length, and sets up a mapping between that range of VME addresses and the physical addresses that represent the specified buffer.

When the buffer spans two or more physical pages (IO_NBPP units), dma_map() sets up a scatter/gather operation, so that the VME bus controller will place the data in the appropriate page frames.

It is possible that dma_map() cannot map the entire size of the buffer. This can occur only when the buffer spans two or more pages, and is caused by a shortage of mapping registers in the bus adapter. The function maps as much of the buffer as it can, and returns the length of the mapped data.

You must always anticipate that dma_map() might map less than the requested number of bytes, so that the DMA transfer has to be done in two or more operations.

Following the call to dma_map(), you call dma_mapaddr() to get the bus virtual address that represents the first byte of the buffer. This is the address you program into the bus master device (using a PIO store), in order to set its starting transfer address. Then you initiate the DMA transfer (again by storing a command into a device register using PIO).


Next | Prev | Up | Top | Contents | Index