Specifications

This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
444
|
Chapter 15: Memory Mapping and DMA
At the lowest level (again, we’ll look at a higher-level solution shortly), the Linux ker-
nel provides a portable solution by exporting the following functions, defined in
<asm/io.h>. The use of these functions is strongly discouraged, because they work
properly only on systems with a very simple I/O architecture; nonetheless, you may
encounter them when working with kernel code.
unsigned long virt_to_bus(volatile void *address);
void *bus_to_virt(unsigned long address);
These functions perform a simple conversion between kernel logical addresses and
bus addresses. They do not work in any situation where an I/O memory manage-
ment unit must be programmed or where bounce buffers must be used. The right
way of performing this conversion is with the generic DMA layer, so we now move
on to that topic.
The Generic DMA Layer
DMA operations, in the end, come down to allocating a buffer and passing bus
addresses to your device. However, the task of writing portable drivers that perform
DMA safely and correctly on all architectures is harder than one might think. Differ-
ent systems have different ideas of how cache coherency should work; if you do not
handle this issue correctly, your driver may corrupt memory. Some systems have
complicated bus hardware that can make the DMA task easier—or harder. And not
all systems can perform DMA out of all parts of memory. Fortunately, the kernel
provides a bus- and architecture-independent DMA layer that hides most of these
issues from the driver author. We strongly encourage you to use this layer for DMA
operations in any driver you write.
Many of the functions below require a pointer to a
struct device. This structure is
the low-level representation of a device within the Linux device model. It is not
something that drivers often have to work with directly, but you do need it when
using the generic DMA layer. Usually, you can find this structure buried inside the
bus specific that describes your device. For example, it can be found as the
dev field
in
struct pci_device or struct usb_device. The device structure is covered in detail
in Chapter 14.
Drivers that use the following functions should include <linux/dma-mapping.h>.
Dealing with difficult hardware
The first question that must be answered before attempting DMA is whether the
given device is capable of such an operation on the current host. Many devices are
limited in the range of memory they can address, for a number of reasons. By default,
the kernel assumes that your device can perform DMA to any 32-bit address. If this is
not the case, you should inform the kernel of that fact with a call to:
int dma_set_mask(struct device *dev, u64 mask);
,ch15.13676 Page 444 Friday, January 21, 2005 11:04 AM