Mercurial > illumos > git > illumos-gate
comparison usr/src/man/man9f/ddi_dma_cookie_iter.9f @ 19431:5599be23ae32
12183 Want new IPD 13 DMA Cookie APIs
Reviewed by: Alex Wilson <alex@uq.edu.au>
Reviewed by: Paul Winder <paul@winders.demon.co.uk>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Garrett D'Amore <garrett@damore.org>
author | Robert Mustacchi <rm@fingolfin.org> |
---|---|
date | Wed, 18 Dec 2019 06:18:35 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
19430:6e69910f8ded | 19431:5599be23ae32 |
---|---|
1 .\" | |
2 .\" This file and its contents are supplied under the terms of the | |
3 .\" Common Development and Distribution License ("CDDL"), version 1.0. | |
4 .\" You may only use this file in accordance with the terms of version | |
5 .\" 1.0 of the CDDL. | |
6 .\" | |
7 .\" A full copy of the text of the CDDL should have accompanied this | |
8 .\" source. A copy of the CDDL is also available via the Internet at | |
9 .\" http://www.illumos.org/license/CDDL. | |
10 .\" | |
11 .\" | |
12 .\" Copyright 2019 Robert Mustacchi | |
13 .\" | |
14 .Dd December 9, 2019 | |
15 .Dt DDI_DMA_COOKIE_ITER 9F | |
16 .Os | |
17 .Sh NAME | |
18 .Nm ddi_dma_cookie_get , | |
19 .Nm ddi_dma_cookie_iter , | |
20 .Nm ddi_dma_cookie_one , | |
21 .Nm ddi_dma_ncookies , | |
22 .Nm ddi_dma_nextcookie | |
23 .Nd retrieve DMA cookies | |
24 .Sh SYNOPSIS | |
25 .In sys/ddi.h | |
26 .In sys/sunddi.h | |
27 .Ft "const ddi_dma_cookie_t *" | |
28 .Fo ddi_dma_cookie_iter | |
29 .Fa "ddi_dma_handle_t handle" | |
30 .Fa "const ddi_dma_cookie_t *cookiep" | |
31 .Fc | |
32 .Ft "const ddi_dma_cookie_t *" | |
33 .Fo ddi_dma_cookie_get | |
34 .Fa "ddi_dma_handle_t handle" | |
35 .Fa "uint_t index" | |
36 .Fc | |
37 .Ft "const ddi_dma_cookie_t *" | |
38 .Fo ddi_dma_cookie_one | |
39 .Fa "ddi_dma_handle_t handle" | |
40 .Fc | |
41 .Ft "uint_t" | |
42 .Fo ddi_dma_ncookies | |
43 .Fa "ddi_dma_handle_t handle" | |
44 .Fc | |
45 .Ft void | |
46 .Fo ddi_dma_nextcookie | |
47 .Fa "ddi_dma_handle_t handle" | |
48 .Fa "ddi_dma_cookie_t *cookiep" | |
49 .Fc | |
50 .Sh PARAMETERS | |
51 .Bl -tag -width Fa | |
52 .It Fa handle | |
53 The DMA handle obtained by a call to | |
54 .Xr ddi_dma_alloc_handle 9F . | |
55 .It Fa cookie | |
56 A pointer to a | |
57 .Xr ddi_dma_cookie 9S | |
58 structure. | |
59 .It Fa index | |
60 An unsigned integer that represents the index of a cookie to obtain. | |
61 The first entry is at index zero. | |
62 .El | |
63 .Sh DESCRIPTION | |
64 The | |
65 .Fn ddi_dma_cookie_iter , | |
66 .Fn ddi_dma_cookie_get , | |
67 and | |
68 .Fn ddi_dma_cookie_one | |
69 functions obtain information about DMA cookies. | |
70 When a DMA request, represented by the DMA handle | |
71 .Fa handle , | |
72 has been bound to a series of addresses with the | |
73 .Xr ddi_dma_addr_bind_handle 9F | |
74 or | |
75 .Xr ddi_dma_buf_bind_handle 9F | |
76 functions, the resulting addresses are stored in one or more | |
77 .Xr ddi_dma_cookie 9S | |
78 structures. | |
79 the three different functions provide different ways to obtain cookies | |
80 and are safe alternatives to the unsafe | |
81 .Fn ddi_dma_nextcookie | |
82 function. | |
83 To see how to use these functions, please see the | |
84 .Sx EXAMPLES | |
85 section. | |
86 .Pp | |
87 The | |
88 .Fn ddi_dma_cookie_iter | |
89 function provides a way to iterate over all the cookies that are | |
90 associated with the DMA handle | |
91 .Fa handle . | |
92 To get the first handle, pass | |
93 .Dv NULL | |
94 in | |
95 .Fa cookiep . | |
96 Do not use the DMA cookie returned from either of the | |
97 .Xr ddi_dma_addr_bind_handle 9F | |
98 or | |
99 .Xr ddi_dma_buf_bind_handle 9F | |
100 functions. | |
101 To get subsequent cookies, pass the returned cookie as the argument | |
102 .Fa cookiep . | |
103 When the function returns | |
104 .Dv NULL | |
105 then that indicates that the last handle has been iterated over. | |
106 .Pp | |
107 The | |
108 .Fn ddi_dma_cookie_get | |
109 function returns a specific cookie. | |
110 The | |
111 .Fa index | |
112 indicates which of the cookies should be returned. | |
113 The first cookie is at index | |
114 .Sy 0 . | |
115 If an invalid index is specified, the function returns | |
116 .Dv NULL . | |
117 .Pp | |
118 The | |
119 .Ft ddi_dma_cookie_one | |
120 function is a convenience function for DMA requests that have a single | |
121 cookie. | |
122 This function always returns the single cookie assosciated with the DMA | |
123 handle | |
124 .Fa handle . | |
125 If this function is used when there is a DMA request with multiple | |
126 cookies, then it will panic the system. | |
127 It can never return | |
128 .Dv NULL . | |
129 .Pp | |
130 The | |
131 .Fn ddi_dma_ncookies | |
132 function returns the number of DMA cookies that are associated with the | |
133 DMA handle | |
134 .Fa handle . | |
135 If there are no DMA resources bound to the handle, then this will return | |
136 .Sy 0 . | |
137 .Pp | |
138 The | |
139 .Fn ddi_dma_nextcookie | |
140 function was the historical function that was associated with obtaining | |
141 DMA cookies. | |
142 It should not be used due to several flaws. | |
143 The | |
144 .Fn ddi_dma_nextcookie | |
145 function mutates the underlying DMA handle meaning that a driver cannot | |
146 obtain a cookie a second time and thus a device driver using this | |
147 interface must either manually keep storage of the cookie around wasting | |
148 space or rebind the handle, wasting time. | |
149 In addition, there is no way for the function to indicate that a driver | |
150 has consumed all of its cookies. | |
151 If for some reason a device driver calls the | |
152 .Fn ddi_dma_nextcookie | |
153 function more times than there are cookies, the results are undefined. | |
154 In short, this function should not be used for any purpose. | |
155 Use the | |
156 .Fn ddi_dma_cookie_iter , | |
157 .Fn ddi_dma_cookie_get , | |
158 or | |
159 .Fn ddi_dma_cookie_one | |
160 functions instead. | |
161 .Sh CONTEXT | |
162 The | |
163 .Fn ddi_dma_cookie_iter , | |
164 .Fn ddi_dma_cookie_get , | |
165 .Fn ddi_dma_cookie_one , | |
166 .Fn ddi_dma_ncookies , | |
167 and | |
168 .Fn ddi_dma_nextcookie | |
169 functions may be called from | |
170 .Sy user , | |
171 .Sy kernel , | |
172 or | |
173 .Sy interrupt | |
174 context. | |
175 .Sh RETURN VALUES | |
176 Upon successful completion, the | |
177 .Fn ddi_dma_cookie_iter , | |
178 .Fn ddi_dma_cookie_get , | |
179 .Fn ddi_dma_cookie_one | |
180 functions will return the requested DMA cookie. | |
181 If there are no more cookies, or | |
182 .Fa coookiep | |
183 is invalid, the | |
184 .Fn ddi_dma_cookie_iter | |
185 function will return | |
186 .Dv NULL . | |
187 If | |
188 .Fa index | |
189 does not correspond to a valid cookie, the | |
190 .Fn ddi_dma_cookie_get | |
191 function will return | |
192 .Dv NULL . | |
193 If there is not exactly one DMA cookie, or another issue occurs, then the | |
194 .Fn ddi_dma_cookie_one | |
195 function will panic the system. | |
196 .Pp | |
197 Upon successful completion, the | |
198 .Fn ddi_dma_ncookies | |
199 function returns the number of cookies associated with | |
200 .Fa handle . | |
201 If there are none, then | |
202 .Sy 0 | |
203 is returned. | |
204 .Pp | |
205 The | |
206 .Fn ddi_dma_nextcookie | |
207 function always updates | |
208 .Fa cookiep | |
209 regardless of whether it is valid or not. | |
210 .Sh EXAMPLES | |
211 .Sy Example 1 | |
212 Using the | |
213 .Fn ddi_dma_cookie_iter | |
214 function to obtain all DMA cookies. | |
215 .Bd -literal | |
216 /* | |
217 * This example assumes that either ddi_dma_addr_bind_handle() or | |
218 * ddi_dma_buf_bind_handle() has already been successfully called. | |
219 */ | |
220 void | |
221 program_dma(ddi_dma_handle_t handle) | |
222 { | |
223 const ddi_dma_cookie_t *c; | |
224 | |
225 for (cookie = ddi_dma_cookie_iter(handle, NULL); c != NULL; | |
226 c = ddi_dma_cookie_iter(handle, c)) { | |
227 /* | |
228 * Use the dmac_laddress and dmac_size members to | |
229 * properly program the device or descriptor rings. | |
230 */ | |
231 } | |
232 } | |
233 .Ed | |
234 .Pp | |
235 .Sy Example 2 | |
236 Using the | |
237 .Fn ddi_dma_cookie_get | |
238 function. | |
239 .Bd -literal | |
240 /* | |
241 * This example assumes that either ddi_dma_mem_alloc() has already | |
242 * been successfully called. | |
243 */ | |
244 int | |
245 bind_dma(ddi_dma_handle_t handle, void *addr, size_t len) | |
246 { | |
247 int ret; | |
248 uint_t i, ncookies; | |
249 ddi_dma_cookie_t first; | |
250 | |
251 ret = ddi_dma_addr_bind_handle(handle, NULL, addr, len, | |
252 DDI_DMA_RDWR | DDI_DMA_CONSISTENT, NULL, NULL, &first, | |
253 &ncookies); | |
254 if (ret != DDI_DMA_MAPPED) { | |
255 return (ret); | |
256 } | |
257 | |
258 /* | |
259 * A driver doesn't need to store ncookies. It can get it again | |
260 * by simply calling ddi_dma_ncookies() and using the result in | |
261 * place of ncookies from ddi_dma_addr_bind_handle(). | |
262 */ | |
263 for (i = 0; i < ncookies; i++) { | |
264 const ddi_dma_cookie_t *cookie; | |
265 | |
266 cookie = ddi_dma_coookie_get(handle, i); | |
267 /* | |
268 * Use the dmac_laddress and dmac_size members to | |
269 * properly program the device or descriptor rings. | |
270 */ | |
271 } | |
272 } | |
273 .Ed | |
274 .Sh SEE ALSO | |
275 .Xr ddi_dma_addr_bind_handle 9F , | |
276 .Xr ddi_dma_alloc_handle 9F , | |
277 .Xr ddi_dma_buf_bind_handle 9F , | |
278 .Xr ddi_dma_unbind_handle 9F , | |
279 .Xr ddi_dma_cookie 9S | |
280 .Rs | |
281 .%T Writing Device Drivers | |
282 .Re |