Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
Direct Memory Access
|
445
The mask should show the bits that your device can address; if it is limited to 24 bits,
for example, you would pass
mask as 0x0FFFFFF. The return value is nonzero if DMA
is possible with the given
mask;ifdma_set_mask returns 0, you are not able to use
DMA operations with this device. Thus, the initialization code in a driver for a device
limited to 24-bit DMA operations might look like:
if (dma_set_mask (dev, 0xffffff))
card->use_dma = 1;
else {
card->use_dma = 0; /* We'll have to live without DMA */
printk (KERN_WARN, "mydev: DMA not supported\n");
}
Again, if your device supports normal, 32-bit DMA operations, there is no need to
call dma_set_mask.
DMA mappings
A DMA mapping is a combination of allocating a DMA buffer and generating an
address for that buffer that is accessible by the device. It is tempting to get that
address with a simple call to virt_to_bus, but there are strong reasons for avoiding
that approach. The first of those is that reasonable hardware comes with an IOMMU
that provides a set of mapping registers for the bus. The IOMMU can arrange for any
physical memory to appear within the address range accessible by the device, and it
can cause physically scattered buffers to look contiguous to the device. Making use
of the IOMMU requires using the generic DMA layer; virt_to_bus is not up to the
task.
Note that not all architectures have an IOMMU; in particular, the popular x86 plat-
form has no IOMMU support. A properly written driver need not be aware of the I/O
support hardware it is running over, however.
Setting up a useful address for the device may also, in some cases, require the estab-
lishment of a bounce buffer. Bounce buffers are created when a driver attempts to
perform DMA on an address that is not reachable by the peripheral device—a high-
memory address, for example. Data is then copied to and from the bounce buffer as
needed. Needless to say, use of bounce buffers can slow things down, but some-
times there is no alternative.
DMA mappings must also address the issue of cache coherency. Remember that mod-
ern processors keep copies of recently accessed memory areas in a fast, local cache;
without this cache, reasonable performance is not possible. If your device changes an
area of main memory, it is imperative that any processor caches covering that area be
invalidated; otherwise the processor may work with an incorrect image of main mem-
ory, and data corruption results. Similarly, when your device uses DMA to read data
from main memory, any changes to that memory residing in processor caches must be
flushed out first. These cache coherency issues can create no end of obscure and diffi-
cult-to-find bugs if the programmer is not careful. Some architectures manage cache
,ch15.13676 Page 445 Friday, January 21, 2005 11:04 AM