diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2005-09-09 16:10:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 17:03:42 -0400 |
commit | ddb99f3d35b178f0715aab2f9d9ab25f61814347 (patch) | |
tree | 45b9f3dab3204555465216dd18269f170c1e6429 /Documentation | |
parent | 754c79768eed257dabd922b85cb9271822e50794 (diff) |
[PATCH] ISA DMA API documentation
Documentation for how the ISA DMA controller is handled in the kernel.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/DMA-ISA-LPC.txt | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/Documentation/DMA-ISA-LPC.txt b/Documentation/DMA-ISA-LPC.txt new file mode 100644 index 000000000000..705f6be92bdb --- /dev/null +++ b/Documentation/DMA-ISA-LPC.txt | |||
@@ -0,0 +1,151 @@ | |||
1 | DMA with ISA and LPC devices | ||
2 | ============================ | ||
3 | |||
4 | Pierre Ossman <drzeus@drzeus.cx> | ||
5 | |||
6 | This document describes how to do DMA transfers using the old ISA DMA | ||
7 | controller. Even though ISA is more or less dead today the LPC bus | ||
8 | uses the same DMA system so it will be around for quite some time. | ||
9 | |||
10 | Part I - Headers and dependencies | ||
11 | --------------------------------- | ||
12 | |||
13 | To do ISA style DMA you need to include two headers: | ||
14 | |||
15 | #include <linux/dma-mapping.h> | ||
16 | #include <asm/dma.h> | ||
17 | |||
18 | The first is the generic DMA API used to convert virtual addresses to | ||
19 | physical addresses (see Documentation/DMA-API.txt for details). | ||
20 | |||
21 | The second contains the routines specific to ISA DMA transfers. Since | ||
22 | this is not present on all platforms make sure you construct your | ||
23 | Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries | ||
24 | to build your driver on unsupported platforms. | ||
25 | |||
26 | Part II - Buffer allocation | ||
27 | --------------------------- | ||
28 | |||
29 | The ISA DMA controller has some very strict requirements on which | ||
30 | memory it can access so extra care must be taken when allocating | ||
31 | buffers. | ||
32 | |||
33 | (You usually need a special buffer for DMA transfers instead of | ||
34 | transferring directly to and from your normal data structures.) | ||
35 | |||
36 | The DMA-able address space is the lowest 16 MB of _physical_ memory. | ||
37 | Also the transfer block may not cross page boundaries (which are 64 | ||
38 | or 128 KiB depending on which channel you use). | ||
39 | |||
40 | In order to allocate a piece of memory that satisfies all these | ||
41 | requirements you pass the flag GFP_DMA to kmalloc. | ||
42 | |||
43 | Unfortunately the memory available for ISA DMA is scarce so unless you | ||
44 | allocate the memory during boot-up it's a good idea to also pass | ||
45 | __GFP_REPEAT and __GFP_NOWARN to make the allocater try a bit harder. | ||
46 | |||
47 | (This scarcity also means that you should allocate the buffer as | ||
48 | early as possible and not release it until the driver is unloaded.) | ||
49 | |||
50 | Part III - Address translation | ||
51 | ------------------------------ | ||
52 | |||
53 | To translate the virtual address to a physical use the normal DMA | ||
54 | API. Do _not_ use isa_virt_to_phys() even though it does the same | ||
55 | thing. The reason for this is that the function isa_virt_to_phys() | ||
56 | will require a Kconfig dependency to ISA, not just ISA_DMA_API which | ||
57 | is really all you need. Remember that even though the DMA controller | ||
58 | has its origins in ISA it is used elsewhere. | ||
59 | |||
60 | Note: x86_64 had a broken DMA API when it came to ISA but has since | ||
61 | been fixed. If your arch has problems then fix the DMA API instead of | ||
62 | reverting to the ISA functions. | ||
63 | |||
64 | Part IV - Channels | ||
65 | ------------------ | ||
66 | |||
67 | A normal ISA DMA controller has 8 channels. The lower four are for | ||
68 | 8-bit transfers and the upper four are for 16-bit transfers. | ||
69 | |||
70 | (Actually the DMA controller is really two separate controllers where | ||
71 | channel 4 is used to give DMA access for the second controller (0-3). | ||
72 | This means that of the four 16-bits channels only three are usable.) | ||
73 | |||
74 | You allocate these in a similar fashion as all basic resources: | ||
75 | |||
76 | extern int request_dma(unsigned int dmanr, const char * device_id); | ||
77 | extern void free_dma(unsigned int dmanr); | ||
78 | |||
79 | The ability to use 16-bit or 8-bit transfers is _not_ up to you as a | ||
80 | driver author but depends on what the hardware supports. Check your | ||
81 | specs or test different channels. | ||
82 | |||
83 | Part V - Transfer data | ||
84 | ---------------------- | ||
85 | |||
86 | Now for the good stuff, the actual DMA transfer. :) | ||
87 | |||
88 | Before you use any ISA DMA routines you need to claim the DMA lock | ||
89 | using claim_dma_lock(). The reason is that some DMA operations are | ||
90 | not atomic so only one driver may fiddle with the registers at a | ||
91 | time. | ||
92 | |||
93 | The first time you use the DMA controller you should call | ||
94 | clear_dma_ff(). This clears an internal register in the DMA | ||
95 | controller that is used for the non-atomic operations. As long as you | ||
96 | (and everyone else) uses the locking functions then you only need to | ||
97 | reset this once. | ||
98 | |||
99 | Next, you tell the controller in which direction you intend to do the | ||
100 | transfer using set_dma_mode(). Currently you have the options | ||
101 | DMA_MODE_READ and DMA_MODE_WRITE. | ||
102 | |||
103 | Set the address from where the transfer should start (this needs to | ||
104 | be 16-bit aligned for 16-bit transfers) and how many bytes to | ||
105 | transfer. Note that it's _bytes_. The DMA routines will do all the | ||
106 | required translation to values that the DMA controller understands. | ||
107 | |||
108 | The final step is enabling the DMA channel and releasing the DMA | ||
109 | lock. | ||
110 | |||
111 | Once the DMA transfer is finished (or timed out) you should disable | ||
112 | the channel again. You should also check get_dma_residue() to make | ||
113 | sure that all data has been transfered. | ||
114 | |||
115 | Example: | ||
116 | |||
117 | int flags, residue; | ||
118 | |||
119 | flags = claim_dma_lock(); | ||
120 | |||
121 | clear_dma_ff(); | ||
122 | |||
123 | set_dma_mode(channel, DMA_MODE_WRITE); | ||
124 | set_dma_addr(channel, phys_addr); | ||
125 | set_dma_count(channel, num_bytes); | ||
126 | |||
127 | dma_enable(channel); | ||
128 | |||
129 | release_dma_lock(flags); | ||
130 | |||
131 | while (!device_done()); | ||
132 | |||
133 | flags = claim_dma_lock(); | ||
134 | |||
135 | dma_disable(channel); | ||
136 | |||
137 | residue = dma_get_residue(channel); | ||
138 | if (residue != 0) | ||
139 | printk(KERN_ERR "driver: Incomplete DMA transfer!" | ||
140 | " %d bytes left!\n", residue); | ||
141 | |||
142 | release_dma_lock(flags); | ||
143 | |||
144 | Part VI - Suspend/resume | ||
145 | ------------------------ | ||
146 | |||
147 | It is the driver's responsibility to make sure that the machine isn't | ||
148 | suspended while a DMA transfer is in progress. Also, all DMA settings | ||
149 | are lost when the system suspends so if your driver relies on the DMA | ||
150 | controller being in a certain state then you have to restore these | ||
151 | registers upon resume. | ||