Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
Direct Memory Access
|
451
dependent, and is described in <asm/scatterlist.h>. However, it always contains three
fields:
struct page *page;
The struct page pointer corresponding to the buffer to be used in the scatter/gather
operation.
unsigned int length;
unsigned int offset;
The length of that buffer and its offset within the page
To map a scatter/gather DMA operation, your driver should set the
page, offset, and
length fields in a struct scatterlist entry for each buffer to be transferred. Then
call:
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction direction)
where nents is the number of scatterlist entries passed in. The return value is the
number of DMA buffers to transfer; it may be less than
nents.
For each buffer in the input scatterlist, dma_map_sg determines the proper bus
address to give to the device. As part of that task, it also coalesces buffers that are
adjacent to each other in memory. If the system your driver is running on has an I/O
memory management unit, dma_map_sg also programs that unit’s mapping regis-
ters, with the possible result that, from your device’s point of view, you are able to
transfer a single, contiguous buffer. You will never know what the resulting transfer
will look like, however, until after the call.
Your driver should transfer each buffer returned by pci_map_sg. The bus address and
length of each buffer are stored in the
struct scatterlist entries, but their location
in the structure varies from one architecture to the next. Two macros have been
defined to make it possible to write portable code:
dma_addr_t sg_dma_address(struct scatterlist *sg);
Returns the bus (DMA) address from this scatterlist entry.
unsigned int sg_dma_len(struct scatterlist *sg);
Returns the length of this buffer.
Again, remember that the address and length of the buffers to transfer may be differ-
ent from what was passed in to dma_map_sg.
Once the transfer is complete, a scatter/gather mapping is unmapped with a call to
dma_unmap_sg:
void dma_unmap_sg(struct device *dev, struct scatterlist *list,
int nents, enum dma_data_direction direction);
Note that nents must be the number of entries that you originally passed to dma_map_sg
and not the number of DMA buffers the function returned to you.
,ch15.13676 Page 451 Friday, January 21, 2005 11:04 AM