Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
446
|
Chapter 15: Memory Mapping and DMA
coherency in the hardware, but others require software support. The generic DMA
layer goes to great lengths to ensure that things work correctly on all architectures,
but, as we will see, proper behavior requires adherence to a small set of rules.
The DMA mapping sets up a new type,
dma_addr_t, to represent bus addresses. Vari-
ables of type
dma_addr_t should be treated as opaque by the driver; the only allow-
able operations are to pass them to the DMA support routines and to the device
itself. As a bus address,
dma_addr_t may lead to unexpected problems if used directly
by the CPU.
The PCI code distinguishes between two types of DMA mappings, depending on
how long the DMA buffer is expected to stay around:
Coherent DMA mappings
These mappings usually exist for the life of the driver. A coherent buffer must be
simultaneously available to both the CPU and the peripheral (other types of
mappings, as we will see later, can be available only to one or the other at any
given time). As a result, coherent mappings must live in cache-coherent mem-
ory. Coherent mappings can be expensive to set up and use.
Streaming DMA mappings
Streaming mappings are usually set up for a single operation. Some architec-
tures allow for significant optimizations when streaming mappings are used, as
we see, but these mappings also are subject to a stricter set of rules in how they
may be accessed. The kernel developers recommend the use of streaming map-
pings over coherent mappings whenever possible. There are two reasons for this
recommendation. The first is that, on systems that support mapping registers,
each DMA mapping uses one or more of them on the bus. Coherent mappings,
which have a long lifetime, can monopolize these registers for a long time, even
when they are not being used. The other reason is that, on some hardware,
streaming mappings can be optimized in ways that are not available to coherent
mappings.
The two mapping types must be manipulated in different ways; it’s time to look at
the details.
Setting up coherent DMA mappings
A driver can set up a coherent mapping with a call to dma_alloc_coherent:
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, int flag);
This function handles both the allocation and the mapping of the buffer. The first two
arguments are the device structure and the size of the buffer needed. The function
returns the result of the DMA mapping in two places. The return value from the func-
tion is a kernel virtual address for the buffer, which may be used by the driver; the
associated bus address, meanwhile, is returned in
dma_handle. Allocation is handled in
,ch15.13676 Page 446 Friday, January 21, 2005 11:04 AM