1ddi_dmae(9F) Kernel Functions for Drivers ddi_dmae(9F)
2
3
4
6 ddi_dmae, ddi_dmae_alloc, ddi_dmae_release, ddi_dmae_prog,
7 ddi_dmae_disable, ddi_dmae_enable, ddi_dmae_stop, ddi_dmae_getcnt,
8 ddi_dmae_1stparty, ddi_dmae_getlim, ddi_dmae_getattr - system DMA
9 engine functions
10
12 int ddi_dmae_alloc(dev_info_t *dip, int chnl, int (*callback) (caddr_t),
13 caddr_t arg);
14
15
16 int ddi_dmae_release(dev_info_t *dip, int chnl);
17
18
19 int ddi_dmae_prog(dev_info_t *dip, struct ddi_dmae_req *dmaereqp,
20 ddi_dma_cookie_t *cookiep, int chnl);
21
22
23 int ddi_dmae_disable(dev_info_t *dip, int chnl);
24
25
26 int ddi_dmae_enable(dev_info_t *dip, int chnl);
27
28
29 int ddi_dmae_stop(dev_info_t *dip, int chnl);
30
31
32 int ddi_dmae_getcnt(dev_info_t *dip, int chnl, int *countp);
33
34
35 int ddi_dmae_1stparty(dev_info_t *dip, int chnl);
36
37
38 int ddi_dmae_getlim(dev_info_t *dip, ddi_dma_lim_t *limitsp);
39
40
41 int ddi_dmae_getattr(dev_info_t *dip, ddi_dma_attr_t *attrp);
42
43
45 Solaris DDI specific (Solaris DDI). The ddi_dmae_getlim() interface,
46 described below, is obsolete. Use ddi_dmae_getattr(), also described
47 below, to replace it.
48
50 dip A dev_info pointer that identifies the device.
51
52
53 chnl A DMA channel number. On ISA buses this number must be 0,
54 1, 2, 3, 5, 6, or 7.
55
56
57 callback The address of a function to call back later if resources
58 are not currently available. The following special function
59 addresses may also be used:
60
61 DDI_DMA_SLEEP Wait until resources are available.
62
63
64 DDI_DMA_DONTWAIT Do not wait until resources are avail‐
65 able and do not schedule a callback.
66
67
68
69 arg Argument to be passed to the callback function, if speci‐
70 fied.
71
72
73 dmaereqp A pointer to a DMA engine request structure. See
74 ddi_dmae_req(9S).
75
76
77 cookiep A pointer to a ddi_dma_cookie(9S) object, obtained from
78 ddi_dma_segtocookie(9F), which contains the address and
79 count.
80
81
82 countp A pointer to an integer that will receive the count of the
83 number of bytes not yet transferred upon completion of a
84 DMA operation.
85
86
87 limitsp A pointer to a DMA limit structure. See
88 ddi_dma_lim_x86(9S).
89
90
91 attrp A pointer to a DMA attribute structure. See
92 ddi_dma_attr(9S).
93
94
96 There are three possible ways that a device can perform DMA engine
97 functions:
98
99 Bus master DMA If the device is capable of acting as a true bus
100 master, then the driver should program the device's
101 DMA registers directly and not make use of the DMA
102 engine functions described here. The driver should
103 obtain the DMA address and count from ddi_dma_segto‐
104 cookie(9F). See ddi_dma_cookie(9S) for a description
105 of a DMA cookie.
106
107
108 Third-party DMA This method uses the system DMA engine that is resi‐
109 dent on the main system board. In this model, the
110 device cooperates with the system's DMA engine to
111 effect the data transfers between the device and
112 memory. The driver uses the functions documented
113 here, except ddi_dmae_1stparty(), to initialize and
114 program the DMA engine. For each DMA data transfer,
115 the driver programs the DMA engine and then gives
116 the device a command to initiate the transfer in
117 cooperation with that engine.
118
119
120 First-party DMA Using this method, the device uses its own DMA bus
121 cycles, but requires a channel from the system's DMA
122 engine. After allocating the DMA channel, the
123 ddi_dmae_1stparty() function may be used to perform
124 whatever configuration is necessary to enable this
125 mode.
126
127
128 ddi_dmae_alloc()
129 The ddi_dmae_alloc() function is used to acquire a DMA channel of the
130 system DMA engine. ddi_dmae_alloc() allows only one device at a time to
131 have a particular DMA channel allocated. It must be called prior to any
132 other system DMA engine function on a channel. If the device allows
133 the channel to be shared with other devices, it must be freed using
134 ddi_dmae_release() after completion of the DMA operation. In any case,
135 the channel must be released before the driver successfully detaches.
136 See detach(9E). No other driver may acquire the DMA channel until it is
137 released.
138
139
140 If the requested channel is not immediately available, the value of
141 callback determines what action will be taken. If the value of callback
142 is DDI_DMA_DONTWAIT, ddi_dmae_alloc() will return immediately. The
143 value DDI_DMA_SLEEP will cause the thread to sleep and not return until
144 the channel has been acquired. Any other value is assumed to be a call‐
145 back function address. In that case, ddi_dmae_alloc() returns immedi‐
146 ately, and when resources might have become available, the callback
147 function is called (with the argument arg) from interrupt context. When
148 the callback function is called, it should attempt to allocate the DMA
149 channel again. If it succeeds or no longer needs the channel, it must
150 return the value DDI_DMA_CALLBACK_DONE. If it tries to allocate the
151 channel but fails to do so, it must return the value DDI_DMA_CALL‐
152 BACK_RUNOUT. In this case, the callback function is put back on a list
153 to be called again later.
154
155 ddi_dmae_prog()
156 The ddi_dmae_prog() function programs the DMA channel for a DMA trans‐
157 fer. The ddi_dmae_req structure contains all the information necessary
158 to set up the channel, except for the memory address and count. Once
159 the channel has been programmed, subsequent calls to ddi_dmae_prog()
160 may specify a value of NULL for dmaereqp if no changes to the program‐
161 ming are required other than the address and count values. It disables
162 the channel prior to setup, and enables the channel before returning.
163 The DMA address and count are specified by passing ddi_dmae_prog() a
164 cookie obtained from ddi_dma_segtocookie(9F). Other DMA engine parame‐
165 ters are specified by the DMA engine request structure passed in
166 through dmaereqp. The fields of that structure are documented in
167 ddi_dmae_req(9S).
168
169
170 Before using ddi_dmae_prog(), you must allocate system DMA resources
171 using DMA setup functions such as ddi_dma_buf_setup(9F). ddi_dma_segto‐
172 cookie(9F) can then be used to retrieve a cookie which contains the
173 address and count. Then this cookie is passed to ddi_dmae_prog().
174
175 ddi_dmae_disable()
176 The ddi_dmae_disable() function disables the DMA channel so that it no
177 longer responds to a device's DMA service requests.
178
179 ddi_dmae_enable()
180 The ddi_dmae_enable() function enables the DMA channel for operation.
181 This may be used to re-enable the channel after a call to ddi_dmae_dis‐
182 able(). The channel is automatically enabled after successful program‐
183 ming by ddi_dmae_prog().
184
185 ddi_dmae_stop()
186 The ddi_dmae_stop() function disables the channel and terminates any
187 active operation.
188
189 ddi_dmae_getcnt()
190 The ddi_dmae_getcnt() function examines the count register of the DMA
191 channel and sets *countp to the number of bytes remaining to be trans‐
192 ferred. The channel is assumed to be stopped.
193
194 ddi_dmae_1stparty()
195 In the case of ISA buses, ddi_dmae_1stparty() configures a channel in
196 the system's DMA engine to operate in a ``slave'' (``cascade'') mode.
197
198
199 When operating in ddi_dmae_1stparty() mode, the DMA channel must first
200 be allocated using ddi_dmae_alloc() and then configured using
201 ddi_dmae_1stparty(). The driver then programs the device to perform the
202 I/O, including the necessary DMA address and count values obtained from
203 ddi_dma_segtocookie(9F).
204
205 ddi_dmae_getlim()
206 This function is obsolete. Use ddi_dmae_getattr(), described below,
207 instead.
208
209
210 The ddi_dmae_getlim() function fills in the DMA limit structure,
211 pointed to by limitsp, with the DMA limits of the system DMA engine.
212 Drivers for devices that perform their own bus mastering or use first-
213 party DMA must create and initialize their own DMA limit structures;
214 they should not use ddi_dmae_getlim(). The DMA limit structure must be
215 passed to the DMA setup routines so that they will know how to break
216 the DMA request into windows and segments (see ddi_dma_nextseg(9F) and
217 ddi_dma_nextwin(9F)). If the device has any particular restrictions on
218 transfer size or granularity (such as the size of disk sector), the
219 driver should further restrict the values in the structure members
220 before passing them to the DMA setup routines. The driver must not
221 relax any of the restrictions embodied in the structure after it is
222 filled in by ddi_dmae_getlim(). After calling ddi_dmae_getlim(), a
223 driver must examine, and possibly set, the size of the DMA engine's
224 scatter/gather list to determine whether DMA chaining will be used. See
225 ddi_dma_lim_x86(9S) and ddi_dmae_req(9S) for additional information on
226 scatter/gather DMA.
227
228 ddi_dmae_getattr()
229 The ddi_dmae_getattr() function fills in the DMA attribute structure,
230 pointed to by attrp, with the DMA attributes of the system DMA engine.
231 Drivers for devices that perform their own bus mastering or use first-
232 party DMA must create and initialize their own DMA attribute struc‐
233 tures; they should not use ddi_dmae_getattr(). The DMA attribute struc‐
234 ture must be passed to the DMA resource allocation functions to provide
235 the information necessary to break the DMA request into DMA windows and
236 DMA cookies. See ddi_dma_nextcookie(9F) and ddi_dma_getwin(9F).
237
239 DDI_SUCCESS Upon success, for all of these routines.
240
241
242 DDI_FAILURE May be returned due to invalid arguments.
243
244
245 DDI_DMA_NORESOURCES May be returned by ddi_dmae_alloc() if the
246 requested resources are not available and the
247 value of dmae_waitfp is not DDI_DMA_SLEEP.
248
249
251 If ddi_dmae_alloc() is called from interrupt context, then its
252 dmae_waitfp argument and the callback function must not have the value
253 DDI_DMA_SLEEP. Otherwise, all these routines can be called from user,
254 interrupt, or kernel context.
255
257 See attributes(5) for descriptions of the following attributes:
258
259
260
261
262 ┌─────────────────────────────┬─────────────────────────────┐
263 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
264 ├─────────────────────────────┼─────────────────────────────┤
265 │Architecture │x86 │
266 └─────────────────────────────┴─────────────────────────────┘
267
269 isa(4), attributes(5), ddi_dma_buf_setup(9F), ddi_dma_getwin(9F),
270 ddi_dma_nextcookie(9F), ddi_dma_nextseg(9F), ddi_dma_nextwin(9F),
271 ddi_dma_segtocookie(9F), ddi_dma_setup(9F), ddi_dma_attr(9S),
272 ddi_dma_cookie(9S), ddi_dma_lim_x86(9S), ddi_dma_req(9S),
273 ddi_dmae_req(9S)
274
275
276
277SunOS 5.11 04 Apr 2006 ddi_dmae(9F)