Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
448
|
Chapter 15: Memory Mapping and DMA
returned. As with dma_alloc_coherent, the address of the resulting DMA buffer is
returned as a kernel virtual address and stored in
handle as a bus address.
Unneeded buffers should be returned to the pool with:
void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t addr);
Setting up streaming DMA mappings
Streaming mappings have a more complicated interface than the coherent variety, for
a number of reasons. These mappings expect to work with a buffer that has already
been allocated by the driver and, therefore, have to deal with addresses that they did
not choose. On some architectures, streaming mappings can also have multiple, dis-
contiguous pages and multipart “scatter/gather” buffers. For all of these reasons,
streaming mappings have their own set of mapping functions.
When setting up a streaming mapping, you must tell the kernel in which direction
the data is moving. Some symbols (of type
enum dma_data_direction) have been
defined for this purpose:
DMA_TO_DEVICE
DMA_FROM_DEVICE
These two symbols should be reasonably self-explanatory. If data is being sent to
the device (in response, perhaps, to a write system call),
DMA_TO_DEVICE should be
used; data going to the CPU, instead, is marked with
DMA_FROM_DEVICE.
DMA_BIDIRECTIONAL
If data can move in either direction, use DMA_BIDIRECTIONAL.
DMA_NONE
This symbol is provided only as a debugging aid. Attempts to use buffers with
this “direction” cause a kernel panic.
It may be tempting to just pick
DMA_BIDIRECTIONAL at all times, but driver authors
should resist that temptation. On some architectures, there is a performance penalty
to pay for that choice.
When you have a single buffer to transfer, map it with dma_map_single:
dma_addr_t dma_map_single(struct device *dev, void *buffer, size_t size,
enum dma_data_direction direction);
The return value is the bus address that you can pass to the device or NULL if some-
thing goes wrong.
Once the transfer is complete, the mapping should be deleted with dma_unmap_single:
void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction);
Here, the size and direction arguments must match those used to map the buffer.
,ch15.13676 Page 448 Friday, January 21, 2005 11:04 AM