Specifications

This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
450
|
Chapter 15: Memory Mapping and DMA
The processor, once again, should not access the DMA buffer after this call has been
made.
Single-page streaming mappings
Occasionally, you may want to set up a mapping on a buffer for which you have a
struct page pointer; this can happen, for example, with user-space buffers mapped
with get_user_pages. To set up and tear down streaming mappings using
struct page
pointers, use the following:
dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size,
enum dma_data_direction direction);
void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
size_t size, enum dma_data_direction direction);
The offset and size arguments can be used to map part of a page. It is recom-
mended, however, that partial-page mappings be avoided unless you are really sure
of what you are doing. Mapping part of a page can lead to cache coherency prob-
lems if the allocation covers only part of a cache line; that, in turn, can lead to mem-
ory corruption and extremely difficult-to-debug bugs.
Scatter/gather mappings
Scatter/gather mappings are a special type of streaming DMA mapping. Suppose you
have several buffers, all of which need to be transferred to or from the device. This
situation can come about in several ways, including from a readv or writev system
call, a clustered disk I/O request, or a list of pages in a mapped kernel I/O buffer.
You could simply map each buffer, in turn, and perform the required operation, but
there are advantages to mapping the whole list at once.
Many devices can accept a scatterlist of array pointers and lengths, and transfer them
all in one DMA operation; for example, “zero-copy” networking is easier if packets
can be built in multiple pieces. Another reason to map scatterlists as a whole is to
take advantage of systems that have mapping registers in the bus hardware. On such
systems, physically discontiguous pages can be assembled into a single, contiguous
array from the device’s point of view. This technique works only when the entries in
the scatterlist are equal to the page size in length (except the first and last), but when
it does work, it can turn multiple operations into a single DMA, and speed things up
accordingly.
Finally, if a bounce buffer must be used, it makes sense to coalesce the entire list into
a single buffer (since it is being copied anyway).
So now you’re convinced that mapping of scatterlists is worthwhile in some situa-
tions. The first step in mapping a scatterlist is to create and fill in an array of
struct
scatterlist
describing the buffers to be transferred. This structure is architecture
,ch15.13676 Page 450 Friday, January 21, 2005 11:04 AM