Merge branch 'vendor/OPENSSL'
[dragonfly.git] / share / man / man9 / sglist.9
1 .\"
2 .\" Copyright (c) 2009 Advanced Computing Technologies LLC
3 .\" Written by: John H. Baldwin <jhb@FreeBSD.org>
4 .\" All rights reserved.
5 .\"
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
8 .\" are met:
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\" 2. Redistributions in binary form must reproduce the above copyright
12 .\"    notice, this list of conditions and the following disclaimer in the
13 .\"    documentation and/or other materials provided with the distribution.
14 .\"
15 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 .\" SUCH DAMAGE.
26 .\"
27 .\" $FreeBSD: src/share/man/man9/sglist.9,v 1.4 2010/07/31 10:01:15 joel Exp $
28 .\"
29 .Dd December 8, 2012
30 .Dt SGLIST 9
31 .Os
32 .Sh NAME
33 .Nm sglist ,
34 .Nm sglist_alloc ,
35 .Nm sglist_append ,
36 .Nm sglist_append_mbuf ,
37 .Nm sglist_append_phys ,
38 .Nm sglist_append_uio ,
39 .Nm sglist_append_user ,
40 .Nm sglist_build ,
41 .Nm sglist_clone ,
42 .Nm sglist_consume_uio ,
43 .Nm sglist_count ,
44 .Nm sglist_free ,
45 .Nm sglist_hold ,
46 .Nm sglist_init ,
47 .Nm sglist_join ,
48 .Nm sglist_length ,
49 .Nm sglist_reset ,
50 .Nm sglist_slice ,
51 .Nm sglist_split
52 .Nd manage a scatter/gather list of physical memory addresses
53 .Sh SYNOPSIS
54 .In sys/types.h
55 .In sys/thread.h
56 .In sys/sglist.h
57 .Ft struct sglist *
58 .Fn sglist_alloc "int nsegs" "int mflags"
59 .Ft int
60 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
61 .Ft int
62 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
63 .Ft int
64 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
65 .Ft int
66 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
67 .Ft int
68 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
69 .Ft struct sglist *
70 .Fn sglist_build "void *buf" "size_t len" "int mflags"
71 .Ft struct sglist *
72 .Fn sglist_clone "struct sglist *sg" "int mflags"
73 .Ft int
74 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
75 .Ft int
76 .Fn sglist_count "void *buf" "size_t len"
77 .Ft void
78 .Fn sglist_free "struct sglist *sg"
79 .Ft struct sglist *
80 .Fn sglist_hold "struct sglist *sg"
81 .Ft void
82 .Fn sglist_init "struct sglist *sg" "u_short maxsegs" "struct sglist_seg *segs"
83 .Ft int
84 .Fn sglist_join "struct sglist *first" "struct sglist *second"
85 .Ft size_t
86 .Fn sglist_length "struct sglist *sg"
87 .Ft void
88 .Fn sglist_reset "struct sglist *sg"
89 .Ft int
90 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
91 .Ft int
92 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
93 .Sh DESCRIPTION
94 The
95 .Nm
96 API manages physical address ranges.
97 Each list contains one or more elements.
98 Each element contains a starting physical address and a length.
99 Scatter/gather lists are read-only while they are shared.
100 If one wishes to alter an existing scatter/gather list and does not hold the
101 sole reference to the list,
102 then one should create a new list instead of modifying the existing list.
103 .Pp
104 Each scatter/gather list object contains a reference count.
105 New lists are created with a single reference.
106 New references are obtained by calling
107 .Nm sglist_hold
108 and are released by calling
109 .Nm sglist_free .
110 .Ss Allocating and Initializing Lists
111 Each
112 .Nm
113 object consists of a header structure and a variable-length array of
114 scatter/gather list elements.
115 The
116 .Nm sglist_alloc
117 function allocates a new list that contains a header and
118 .Fa nsegs
119 scatter/gather list elements.
120 The
121 .Fa mflags
122 argument can be set to either
123 .Dv M_NOWAIT
124 or
125 .Dv M_WAITOK .
126 .Pp
127 The
128 .Nm sglist_count
129 function returns the number of scatter/gather list elements needed to describe
130 the physical address ranges mapped by a single kernel virtual address range.
131 The kernel virtual address range starts at
132 .Fa buf
133 and is
134 .Fa len
135 bytes long.
136 .Pp
137 The
138 .Nm sglist_build
139 function allocates a new scatter/gather list object that describes the physical
140 address ranges mapped by a single kernel virtual address range.
141 The kernel virtual address range starts at
142 .Fa buf
143 and is
144 .Fa len
145 bytes long.
146 The
147 .Fa mflags
148 argument can be set to either
149 .Dv M_NOWAIT
150 or
151 .Dv M_WAITOK .
152 .Pp
153 The
154 .Nm sglist_clone
155 function returns a copy of an existing scatter/gather list object
156 .Fa sg .
157 The
158 .Fa mflags
159 argument can be set to either
160 .Dv M_NOWAIT
161 or
162 .Dv M_WAITOK .
163 This can be used to obtain a private copy of a scatter/gather list before
164 modifying it.
165 .Pp
166 The
167 .Nm sglist_init
168 function initializes a scatter/gather list header.
169 The header is pointed to by
170 .Fa sg
171 and is initialized to manage an array of
172 .Fa maxsegs
173 scatter/gather list elements pointed to by
174 .Fa segs .
175 This can be used to initialize a scatter/gather list header whose storage
176 is not provided by
177 .Nm sglist_alloc .
178 In that case, the caller should not call
179 .Nm sglist_free
180 to release its own reference and is responsible for ensuring all other
181 references to the list are dropped before it releases the storage for
182 .Fa sg
183 and
184 .Fa segs .
185 .Ss Constructing Scatter/Gather Lists
186 The
187 .Nm
188 API provides several routines for building a scatter/gather list to describe
189 one or more objects.
190 Specifically, the
191 .Nm sglist_append
192 family of routines can be used to append the physical address ranges described
193 by an object to the end of a scatter/gather list.
194 All of these routines return 0 on success or an error on failure.
195 If a request to append an address range to a scatter/gather list fails,
196 the scatter/gather list will remain unchanged.
197 .Pp
198 The
199 .Nm sglist_append
200 function appends the physical address ranges described by a single kernel
201 virtual address range to the scatter/gather list
202 .Fa sg .
203 The kernel virtual address range starts at
204 .Fa buf
205 and is
206 .Fa len
207 bytes long.
208 .Pp
209 The
210 .Nm sglist_append_mbuf
211 function appends the physical address ranges described by an entire mbuf
212 chain
213 .Fa m
214 to the scatter/gather list
215 .Fa sg .
216 .Pp
217 The
218 .Nm sglist_append_phys
219 function appends a single physical address range to the scatter/gather list
220 .Fa sg .
221 The physical address range starts at
222 .Fa paddr
223 and is
224 .Fa len
225 bytes long.
226 .Pp
227 The
228 .Nm sglist_append_uio
229 function appends the physical address ranges described by a
230 .Xr uio 9
231 object to the scatter/gather list
232 .Fa sg .
233 Note that it is the caller's responsibility to ensure that the pages backing
234 the I/O request are wired for the lifetime of
235 .Fa sg .
236 Note also that this routine does not modify
237 .Fa uio .
238 .Pp
239 The
240 .Nm sglist_append_user
241 function appends the physical address ranges described by a single user
242 virtual address range to the scatter/gather list
243 .Fa sg .
244 The user virtual address range is relative to the address space of the thread
245 .Fa td .
246 It starts at
247 .Fa buf
248 and is
249 .Fa len
250 bytes long.
251 Note that it is the caller's responsibility to ensure that the pages backing
252 the user buffer are wired for the lifetime of
253 .Fa sg .
254 .Pp
255 The
256 .Nm sglist_consume_uio
257 function is a variation of
258 .Nm sglist_append_uio .
259 As with
260 .Nm sglist_append_uio ,
261 it appends the physical address ranges described by
262 .Fa uio
263 to the scatter/gather list
264 .Fa sg .
265 Unlike
266 .Nm sglist_append_uio ,
267 however,
268 .Nm sglist_consume_uio
269 modifies the I/O request to indicate that the appended address ranges have
270 been processed similar to calling
271 .Xr uiomove 9 .
272 This routine will only append ranges that describe up to
273 .Fa resid
274 total bytes in length.
275 If the available segments in the scatter/gather list are exhausted before
276 .Fa resid
277 bytes are processed,
278 then the
279 .Fa uio
280 structure will be updated to reflect the actual number of bytes processed,
281 and
282 .Nm sglist_consume_io
283 will return zero to indicate success.
284 In effect, this function will perform partial reads or writes.
285 The caller can compare the
286 .Fa uio_resid
287 member of
288 .Fa uio
289 before and after calling
290 .Nm sglist_consume_uio
291 to determine the actual number of bytes processed.
292 .Ss Manipulating Scatter/Gather Lists
293 The
294 .Nm sglist_join
295 function appends physical address ranges from the scatter/gather list
296 .Fa second
297 onto
298 .Fa first
299 and then resets
300 .Fa second
301 to an empty list.
302 It returns zero on success or an error on failure.
303 .Pp
304 The
305 .Nm sglist_split
306 function splits an existing scatter/gather list into two lists.
307 The first
308 .Fa length
309 bytes described by the list
310 .Fa original
311 are moved to a new list
312 .Fa *head .
313 If
314 .Fa original
315 describes a total address range that is smaller than
316 .Fa length
317 bytes,
318 then all of the address ranges will be moved to the new list at
319 .Fa *head
320 and
321 .Fa original
322 will be an empty list.
323 The caller may supply an existing scatter/gather list in
324 .Fa *head .
325 If so, the list must be empty.
326 Otherwise, the caller may set
327 .Fa *head
328 to
329 .Dv NULL
330 in which case a new scatter/gather list will be allocated.
331 In that case,
332 .Fa mflags
333 may be set to either
334 .Dv M_NOWAIT
335 or
336 .Dv M_WAITOK .
337 Note that since the
338 .Fa original
339 list is modified by this call, it must be a private list with no other
340 references.
341 The
342 .Nm sglist_split
343 function returns zero on success or an error on failure.
344 .Pp
345 The
346 .Nm sglist_slice
347 function generates a new scatter/gather list from a sub-range of an existing
348 scatter/gather list
349 .Fa original .
350 The sub-range to extract is specified by the
351 .Fa offset
352 and
353 .Fa length
354 parameters.
355 The new scatter/gather list is stored in
356 .Fa *slice .
357 As with
358 .Fa head
359 for
360 .Nm sglist_join ,
361 the caller may either provide an empty scatter/gather list,
362 or it may set
363 .Fa *slice
364 to
365 .Dv NULL
366 in which case
367 .Nm sglist_slice
368 will allocate a new list subject to
369 .Fa mflags .
370 Unlike
371 .Nm sglist_split ,
372 .Nm sglist_slice
373 does not modify
374 .Fa original
375 and does not require it to be a private list.
376 The
377 .Nm sglist_split
378 function returns zero on success or an error on failure.
379 .Ss Miscellaneous Routines
380 The
381 .Nm sglist_reset
382 function clears the scatter/gather list
383 .Fa sg
384 so that it no longer maps any address ranges.
385 This can allow reuse of a single scatter/gather list object for multiple
386 requests.
387 .Pp
388 The
389 .Nm sglist_length
390 function returns the total length of the physical address ranges described
391 by the scatter/gather list
392 .Fa sg .
393 .Sh RETURN VALUES
394 The
395 .Nm sglist_alloc ,
396 .Nm sglist_build ,
397 and
398 .Nm sglist_clone
399 functions return a new scatter/gather list on success or
400 .Dv NULL
401 on failure.
402 .Pp
403 The
404 .Nm sglist_append
405 family of functions and the
406 .Nm sglist_consume_uio ,
407 .Nm sglist_join ,
408 .Nm sglist_slice ,
409 and
410 .Nm sglist_split
411 functions return zero on success or an error on failure.
412 .Pp
413 The
414 .Nm sglist_count
415 function returns a count of scatter/gather list elements.
416 .Pp
417 The
418 .Nm sglist_length
419 function returns a count of address space described by a scatter/gather list
420 in bytes.
421 .Sh ERRORS
422 The
423 .Nm sglist_append
424 functions return the following errors on failure:
425 .Bl -tag -width Er
426 .It Bq Er EINVAL
427 The scatter/gather list has zero segments.
428 .It Bq Er EFBIG
429 There are not enough available segments in the scatter/gather list to append
430 the specified physical address ranges.
431 .El
432 .Pp
433 The
434 .Nm sglist_consume_uio
435 function returns the following error on failure:
436 .Bl -tag -width Er
437 .It Bq Er EINVAL
438 The scatter/gather list has zero segments.
439 .El
440 .Pp
441 The
442 .Nm sglist_join
443 function returns the following error on failure:
444 .Bl -tag -width Er
445 .It Bq Er EFBIG
446 There are not enough available segments in the scatter/gather list
447 .Fa first
448 to append the physical address ranges from
449 .Fa second .
450 .El
451 .Pp
452 The
453 .Nm sglist_slice
454 function returns the following errors on failure:
455 .Bl -tag -width Er
456 .It Bq Er EINVAL
457 The
458 .Fa original
459 scatter/gather list does not describe enough address space to cover the
460 requested sub-range.
461 .It Bq Er EINVAL
462 The caller-supplied scatter/gather list in
463 .Fa *slice
464 is not empty.
465 .It Bq Er ENOMEM
466 An attempt to allocate a new scatter/gather list with
467 .Dv M_NOWAIT
468 set in
469 .Fa mflags
470 failed.
471 .It Bq Er EFBIG
472 There are not enough available segments in the caller-supplied scatter/gather
473 list in
474 .Fa *slice
475 to describe the requested physical address ranges.
476 .El
477 .Pp
478 The
479 .Nm sglist_split
480 function returns the following errors on failure:
481 .Bl -tag -width Er
482 .It Bq Er EDOOFUS
483 The
484 .Fa original
485 scatter/gather list has more than one reference.
486 .It Bq Er EINVAL
487 The caller-supplied scatter/gather list in
488 .Fa *head
489 is not empty.
490 .It Bq Er ENOMEM
491 An attempt to allocate a new scatter/gather list with
492 .Dv M_NOWAIT
493 set in
494 .Fa mflags
495 failed.
496 .It Bq Er EFBIG
497 There are not enough available segments in the caller-supplied scatter/gather
498 list in
499 .Fa *head
500 to describe the requested physical address ranges.
501 .El
502 .Sh SEE ALSO
503 .Xr kmalloc 9 ,
504 .Xr mbuf 9 ,
505 .Xr uio 9
506 .Sh HISTORY
507 This API was first introduced in
508 .Fx 8.0 .