Specifications

This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
Direct Memory Access
|
457
particular, we don’t deal with the issue of 8-bit versus 16-bit data transfers. If you are
writing device drivers for ISA device boards, you should find the relevant informa-
tion in the hardware manuals for the devices.
The DMA controller is a shared resource, and confusion could arise if more than one
processor attempts to program it simultaneously. For that reason, the controller is
protected by a spinlock, called
dma_spin_lock. Drivers should not manipulate the
lock directly; however, two functions have been provided to do that for you:
unsigned long claim_dma_lock( );
Acquires the DMA spinlock. This function also blocks interrupts on the local
processor; therefore, the return value is a set of flags describing the previous
interrupt state; it must be passed to the following function to restore the inter-
rupt state when you are done with the lock.
void release_dma_lock(unsigned long flags);
Returns the DMA spinlock and restores the previous interrupt status.
The spinlock should be held when using the functions described next. It should not
be held during the actual I/O, however. A driver should never sleep when holding a
spinlock.
The information that must be loaded into the controller consists of three items: the
RAM address, the number of atomic items that must be transferred (in bytes or
words), and the direction of the transfer. To this end, the following functions are
exported by <asm/dma.h>:
void set_dma_mode(unsigned int channel, char mode);
Indicates whether the channel must read from the device (DMA_MODE_READ)or
write to it (
DMA_MODE_WRITE). A third mode exists, DMA_MODE_CASCADE, which is
used to release control of the bus. Cascading is the way the first controller is con-
nected to the top of the second, but it can also be used by true ISA bus-master
devices. We won’t discuss bus mastering here.
void set_dma_addr(unsigned int channel, unsigned int addr);
Assigns the address of the DMA buffer. The function stores the 24 least signifi-
cant bits of
addr in the controller. The addr argument must be a bus address (see
the section “Bus Addresses” earlier in this chapter).
void set_dma_count(unsigned int channel, unsigned int count);
Assigns the number of bytes to transfer. The count argument represents bytes for
16-bit channels as well; in this case, the number must be even.
,ch15.13676 Page 457 Friday, January 21, 2005 11:04 AM