Specifications

This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
Direct Memory Access
|
455
The channels are numbered from 0–7: channel 4 is not available to ISA peripherals,
because it is used internally to cascade the slave controller onto the master. The
available channels are, thus, 0–3 on the slave (the 8-bit channels) and 5–7 on the
master (the 16-bit channels). The size of any DMA transfer, as stored in the control-
ler, is a 16-bit number representing the number of bus cycles. The maximum trans-
fer size is, therefore, 64 KB for the slave controller (because it transfers eight bits in
one cycle) and 128 KB for the master (which does 16-bit transfers).
Because the DMA controller is a system-wide resource, the kernel helps deal with it.
It uses a DMA registry to provide a request-and-free mechanism for the DMA chan-
nels and a set of functions to configure channel information in the DMA controller.
Registering DMA usage
You should be used to kernel registries—we’ve already seen them for I/O ports and
interrupt lines. The DMA channel registry is similar to the others. After <asm/dma.h>
has been included, the following functions can be used to obtain and release owner-
ship of a DMA channel:
int request_dma(unsigned int channel, const char *name);
void free_dma(unsigned int channel);
The channel argument is a number between 0 and 7 or, more precisely, a positive
number less than
MAX_DMA_CHANNELS. On the PC, MAX_DMA_CHANNELS is defined as 8 to
match the hardware. The
name argument is a string identifying the device. The speci-
fied name appears in the file /proc/dma, which can be read by user programs.
The return value from request_dma is
0 for success and -EINVAL or -EBUSY if there was
an error. The former means that the requested channel is out of range, and the latter
means that another device is holding the channel.
We recommend that you take the same care with DMA channels as with I/O ports
and interrupt lines; requesting the channel at open time is much better than request-
ing it from the module initialization function. Delaying the request allows some shar-
ing between drivers; for example, your sound card and your analog I/O interface can
share the DMA channel as long as they are not used at the same time.
We also suggest that you request the DMA channel after you’ve requested the inter-
rupt line and that you release it before the interrupt. This is the conventional order
for requesting the two resources; following the convention avoids possible dead-
locks. Note that every device using DMA needs an IRQ line as well; otherwise, it
couldn’t signal the completion of data transfer.
In a typical case, the code for open looks like the following, which refers to our hypo-
thetical dad module. The dad device as shown uses a fast interrupt handler without
support for shared IRQ lines.
int dad_open (struct inode *inode, struct file *filp)
{
struct dad_device *my_device;
,ch15.13676 Page 455 Friday, January 21, 2005 11:04 AM