2 .\" Copyright (c) 2009 Hudson River Trading LLC
3 .\" Written by: John H. Baldwin <jhb@FreeBSD.org>
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
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.
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
36 .Nm sglist_append_bio ,
37 .Nm sglist_append_mbuf ,
38 .Nm sglist_append_mbuf_epg,
39 .Nm sglist_append_phys ,
40 .Nm sglist_append_sglist ,
41 .Nm sglist_append_uio ,
42 .Nm sglist_append_user ,
43 .Nm sglist_append_vmpages ,
46 .Nm sglist_consume_uio ,
48 .Nm sglist_count_mbuf_epg ,
49 .Nm sglist_count_vmpages ,
58 .Nd manage a scatter/gather list of physical memory addresses
63 .Fn sglist_alloc "int nsegs" "int mflags"
65 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
67 .Fn sglist_append_bio "struct sglist *sg" "struct bio *bp"
69 .Fn sglist_append_mbuf_epg "struct sglist *sg" "struct mbuf *m" "size_t offset" "size_t len"
71 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
73 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
75 .Fn sglist_append_sglist "struct sglist *sg" "struct sglist *source" "size_t offset" "size_t len"
77 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
79 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
81 .Fn sglist_append_vmpages "struct sglist *sg" "vm_page_t *m" "size_t pgoff" "size_t len"
83 .Fn sglist_build "void *buf" "size_t len" "int mflags"
85 .Fn sglist_clone "struct sglist *sg" "int mflags"
87 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
89 .Fn sglist_count "void *buf" "size_t len"
91 .Fn sglist_count_mbuf_epg "struct mbuf *m" "size_t offset" "size_t len"
93 .Fn sglist_count_vmpages "vm_page_t *m" "size_t pgoff" "size_t len"
95 .Fn sglist_free "struct sglist *sg"
97 .Fn sglist_hold "struct sglist *sg"
99 .Fn sglist_init "struct sglist *sg" "int maxsegs" "struct sglist_seg *segs"
101 .Fn sglist_join "struct sglist *first" "struct sglist *second"
103 .Fn sglist_length "struct sglist *sg"
105 .Fn sglist_reset "struct sglist *sg"
107 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
109 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
113 API manages physical address ranges.
114 Each list contains one or more elements.
115 Each element contains a starting physical address and a length.
116 Scatter/gather lists are read-only while they are shared.
117 If one wishes to alter an existing scatter/gather list and does not hold the
118 sole reference to the list,
119 then one should create a new list instead of modifying the existing list.
121 Each scatter/gather list object contains a reference count.
122 New lists are created with a single reference.
123 New references are obtained by calling
125 and are released by calling
127 .Ss Allocating and Initializing Lists
130 object consists of a header structure and a variable-length array of
131 scatter/gather list elements.
134 function allocates a new list that contains a header and
136 scatter/gather list elements.
139 argument can be set to either
146 function returns the number of scatter/gather list elements needed to describe
147 the physical address ranges mapped by a single kernel virtual address range.
148 The kernel virtual address range starts at
155 .Nm sglist_count_mbuf_epg
156 function returns the number of scatter/gather list elements needed to describe
157 the external multipage mbuf buffer
159 The ranges start at an offset of
161 relative to the start of the buffer and is
166 .Nm sglist_count_vmpages
167 function returns the number of scatter/gather list elements needed to describe
168 the physical address ranges of a buffer backed by an array of virtual memory
171 The buffer starts at an offset of
173 bytes relative to the first page and is
179 function allocates a new scatter/gather list object that describes the physical
180 address ranges mapped by a single kernel virtual address range.
181 The kernel virtual address range starts at
188 argument can be set to either
195 function returns a copy of an existing scatter/gather list object
199 argument can be set to either
203 This can be used to obtain a private copy of a scatter/gather list before
208 function initializes a scatter/gather list header.
209 The header is pointed to by
211 and is initialized to manage an array of
213 scatter/gather list elements pointed to by
215 This can be used to initialize a scatter/gather list header whose storage
218 In that case, the caller should not call
220 to release its own reference and is responsible for ensuring all other
221 references to the list are dropped before it releases the storage for
225 .Ss Constructing Scatter/Gather Lists
228 API provides several routines for building a scatter/gather list to describe
232 family of routines can be used to append the physical address ranges described
233 by an object to the end of a scatter/gather list.
234 All of these routines return 0 on success or an error on failure.
235 If a request to append an address range to a scatter/gather list fails,
236 the scatter/gather list will remain unchanged.
240 function appends the physical address ranges described by a single kernel
241 virtual address range to the scatter/gather list
243 The kernel virtual address range starts at
250 .Nm sglist_append_bio
251 function appends the physical address ranges described by a single bio
253 to the scatter/gather list
257 .Nm sglist_append_mbuf_epg
258 function appends the physical address ranges described by the
263 to the scatter/gather list
265 The physical address ranges start at offset
273 .Nm sglist_append_mbuf ,
274 .Nm sglist_append_mbuf_epg
275 only adds ranges for a single mbuf,
276 not an entire mbuf chain.
279 .Nm sglist_append_mbuf
280 function appends the physical address ranges described by an entire mbuf
283 to the scatter/gather list
287 .Nm sglist_append_phys
288 function appends a single physical address range to the scatter/gather list
290 The physical address range starts at
297 .Nm sglist_append_sglist
298 function appends physical address ranges described by the scatter/gather list
300 to the scatter/gather list
302 The physical address ranges start at offset
311 .Nm sglist_append_uio
312 function appends the physical address ranges described by a
314 object to the scatter/gather list
316 Note that it is the caller's responsibility to ensure that the pages backing
317 the I/O request are wired for the lifetime of
319 Note also that this routine does not modify
323 .Nm sglist_append_user
324 function appends the physical address ranges described by a single user
325 virtual address range to the scatter/gather list
327 The user virtual address range is relative to the address space of the thread
334 Note that it is the caller's responsibility to ensure that the pages backing
335 the user buffer are wired for the lifetime of
339 .Nm sglist_append_vmpages
340 function appends the physical address ranges of a buffer backed by an array
341 of virtual memory pages
343 The buffer starts at an offset of
345 bytes relative to the first page and is
350 .Nm sglist_consume_uio
351 function is a variation of
352 .Nm sglist_append_uio .
354 .Nm sglist_append_uio ,
355 it appends the physical address ranges described by
357 to the scatter/gather list
360 .Nm sglist_append_uio ,
362 .Nm sglist_consume_uio
363 modifies the I/O request to indicate that the appended address ranges have
364 been processed similar to calling
366 This routine will only append ranges that describe up to
368 total bytes in length.
369 If the available segments in the scatter/gather list are exhausted before
374 structure will be updated to reflect the actual number of bytes processed,
376 .Nm sglist_consume_io
377 will return zero to indicate success.
378 In effect, this function will perform partial reads or writes.
379 The caller can compare the
383 before and after calling
384 .Nm sglist_consume_uio
385 to determine the actual number of bytes processed.
386 .Ss Manipulating Scatter/Gather Lists
389 function appends physical address ranges from the scatter/gather list
396 It returns zero on success or an error on failure.
400 function splits an existing scatter/gather list into two lists.
403 bytes described by the list
405 are moved to a new list
409 describes a total address range that is smaller than
412 then all of the address ranges will be moved to the new list at
416 will be an empty list.
417 The caller may supply an existing scatter/gather list in
419 If so, the list must be empty.
420 Otherwise, the caller may set
424 in which case a new scatter/gather list will be allocated.
433 list is modified by this call, it must be a private list with no other
437 function returns zero on success or an error on failure.
441 function generates a new scatter/gather list from a sub-range of an existing
444 The sub-range to extract is specified by the
449 The new scatter/gather list is stored in
455 the caller may either provide an empty scatter/gather list,
462 will allocate a new list subject to
469 and does not require it to be a private list.
472 function returns zero on success or an error on failure.
473 .Ss Miscellaneous Routines
476 function clears the scatter/gather list
478 so that it no longer maps any address ranges.
479 This can allow reuse of a single scatter/gather list object for multiple
484 function returns the total length of the physical address ranges described
485 by the scatter/gather list
493 functions return a new scatter/gather list on success or
499 family of functions and the
500 .Nm sglist_consume_uio ,
505 functions return zero on success or an error on failure.
510 functions return a count of scatter/gather list elements.
514 function returns a count of address space described by a scatter/gather list
519 functions return the following errors on failure:
522 The scatter/gather list has zero segments.
524 There are not enough available segments in the scatter/gather list to append
525 the specified physical address ranges.
529 .Nm sglist_consume_uio
530 function returns the following error on failure:
533 The scatter/gather list has zero segments.
538 function returns the following error on failure:
541 There are not enough available segments in the scatter/gather list
543 to append the physical address ranges from
549 function returns the following errors on failure:
554 scatter/gather list does not describe enough address space to cover the
557 The caller-supplied scatter/gather list in
561 An attempt to allocate a new scatter/gather list with
567 There are not enough available segments in the caller-supplied scatter/gather
570 to describe the requested physical address ranges.
575 function returns the following errors on failure:
580 scatter/gather list has more than one reference.
582 The caller-supplied scatter/gather list in
586 An attempt to allocate a new scatter/gather list with
592 There are not enough available segments in the caller-supplied scatter/gather
595 to describe the requested physical address ranges.
603 This API was first introduced in