Specifications

This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
452
|
Chapter 15: Memory Mapping and DMA
Scatter/gather mappings are streaming DMA mappings, and the same access rules
apply to them as to the single variety. If you must access a mapped scatter/gather list,
you must synchronize it first:
void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction);
void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction direction);
PCI double-address cycle mappings
Normally, the DMA support layer works with 32-bit bus addresses, possibly
restricted by a specific device’s DMA mask. The PCI bus, however, also supports a
64-bit addressing mode, the double-address cycle (DAC). The generic DMA layer
does not support this mode for a couple of reasons, the first of which being that it is
a PCI-specific feature. Also, many implementations of DAC are buggy at best, and,
because DAC is slower than a regular, 32-bit DMA, there can be a performance cost.
Even so, there are applications where using DAC can be the right thing to do; if you
have a device that is likely to be working with very large buffers placed in high mem-
ory, you may want to consider implementing DAC support. This support is avail-
able only for the PCI bus, so PCI-specific routines must be used.
To use DAC, your driver must include <linux/pci.h>. You must set a separate DMA
mask:
int pci_dac_set_dma_mask(struct pci_dev *pdev, u64 mask);
You can use DAC addressing only if this call returns 0.
A special type (
dma64_addr_t) is used for DAC mappings. To establish one of these
mappings, call pci_dac_page_to_dma:
dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page,
unsigned long offset, int direction);
DAC mappings, you will notice, can be made only from struct page pointers (they
should live in high memory, after all, or there is no point in using them); they
must be created a single page at a time. The
direction argument is the PCI equiv-
alent of the
enum dma_data_direction used in the generic DMA layer; it should be
PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE, or PCI_DMA_BIDIRECTIONAL.
DAC mappings require no external resources, so there is no need to explicitly release
them after use. It is necessary, however, to treat DAC mappings like other streaming
mappings, and observe the rules regarding buffer ownership. There is a set of func-
tions for synchronizing DMA buffers that is analogous to the generic variety:
void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev,
dma64_addr_t dma_addr,
size_t len,
int direction);
,ch15.13676 Page 452 Friday, January 21, 2005 11:04 AM