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_single_mbuf ,
42 .Nm sglist_append_uio ,
43 .Nm sglist_append_user ,
44 .Nm sglist_append_vmpages ,
47 .Nm sglist_consume_uio ,
49 .Nm sglist_count_mbuf_epg ,
50 .Nm sglist_count_vmpages ,
59 .Nd manage a scatter/gather list of physical memory addresses
64 .Fn sglist_alloc "int nsegs" "int mflags"
66 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
68 .Fn sglist_append_bio "struct sglist *sg" "struct bio *bp"
70 .Fn sglist_append_mbuf_epg "struct sglist *sg" "struct mbuf *m" "size_t offset" "size_t len"
72 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
74 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
76 .Fn sglist_append_sglist "struct sglist *sg" "struct sglist *source" "size_t offset" "size_t len"
78 .Fn sglist_append_single_mbuf "struct sglist *sg" "struct mbuf *m"
80 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
82 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
84 .Fn sglist_append_vmpages "struct sglist *sg" "vm_page_t *m" "size_t pgoff" "size_t len"
86 .Fn sglist_build "void *buf" "size_t len" "int mflags"
88 .Fn sglist_clone "struct sglist *sg" "int mflags"
90 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
92 .Fn sglist_count "void *buf" "size_t len"
94 .Fn sglist_count_mbuf_epg "struct mbuf *m" "size_t offset" "size_t len"
96 .Fn sglist_count_vmpages "vm_page_t *m" "size_t pgoff" "size_t len"
98 .Fn sglist_free "struct sglist *sg"
100 .Fn sglist_hold "struct sglist *sg"
102 .Fn sglist_init "struct sglist *sg" "int maxsegs" "struct sglist_seg *segs"
104 .Fn sglist_join "struct sglist *first" "struct sglist *second"
106 .Fn sglist_length "struct sglist *sg"
108 .Fn sglist_reset "struct sglist *sg"
110 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
112 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
116 API manages physical address ranges.
117 Each list contains one or more elements.
118 Each element contains a starting physical address and a length.
119 Scatter/gather lists are read-only while they are shared.
120 If one wishes to alter an existing scatter/gather list and does not hold the
121 sole reference to the list,
122 then one should create a new list instead of modifying the existing list.
124 Each scatter/gather list object contains a reference count.
125 New lists are created with a single reference.
126 New references are obtained by calling
128 and are released by calling
130 .Ss Allocating and Initializing Lists
133 object consists of a header structure and a variable-length array of
134 scatter/gather list elements.
137 function allocates a new list that contains a header and
139 scatter/gather list elements.
142 argument can be set to either
149 function returns the number of scatter/gather list elements needed to describe
150 the physical address ranges mapped by a single kernel virtual address range.
151 The kernel virtual address range starts at
158 .Nm sglist_count_mbuf_epg
159 function returns the number of scatter/gather list elements needed to describe
160 the external multipage mbuf buffer
162 The ranges start at an offset of
164 relative to the start of the buffer and is
169 .Nm sglist_count_vmpages
170 function returns the number of scatter/gather list elements needed to describe
171 the physical address ranges of a buffer backed by an array of virtual memory
174 The buffer starts at an offset of
176 bytes relative to the first page and is
182 function allocates a new scatter/gather list object that describes the physical
183 address ranges mapped by a single kernel virtual address range.
184 The kernel virtual address range starts at
191 argument can be set to either
198 function returns a copy of an existing scatter/gather list object
202 argument can be set to either
206 This can be used to obtain a private copy of a scatter/gather list before
211 function initializes a scatter/gather list header.
212 The header is pointed to by
214 and is initialized to manage an array of
216 scatter/gather list elements pointed to by
218 This can be used to initialize a scatter/gather list header whose storage
221 In that case, the caller should not call
223 to release its own reference and is responsible for ensuring all other
224 references to the list are dropped before it releases the storage for
228 .Ss Constructing Scatter/Gather Lists
231 API provides several routines for building a scatter/gather list to describe
235 family of routines can be used to append the physical address ranges described
236 by an object to the end of a scatter/gather list.
237 All of these routines return 0 on success or an error on failure.
238 If a request to append an address range to a scatter/gather list fails,
239 the scatter/gather list will remain unchanged.
243 function appends the physical address ranges described by a single kernel
244 virtual address range to the scatter/gather list
246 The kernel virtual address range starts at
253 .Nm sglist_append_bio
254 function appends the physical address ranges described by a single bio
256 to the scatter/gather list
260 .Nm sglist_append_mbuf_epg
261 function appends the physical address ranges described by the
266 to the scatter/gather list
268 The physical address ranges start at offset
276 .Nm sglist_append_mbuf ,
277 .Nm sglist_append_mbuf_epg
278 only adds ranges for a single mbuf,
279 not an entire mbuf chain.
282 .Nm sglist_append_mbuf
283 function appends the physical address ranges described by an entire mbuf
286 to the scatter/gather list
290 .Nm sglist_append_mbuf
291 function appends the physical address ranges described by a single mbuf
293 to the scatter/gather list
297 .Nm sglist_append_phys
298 function appends a single physical address range to the scatter/gather list
300 The physical address range starts at
307 .Nm sglist_append_sglist
308 function appends physical address ranges described by the scatter/gather list
310 to the scatter/gather list
312 The physical address ranges start at offset
321 .Nm sglist_append_uio
322 function appends the physical address ranges described by a
324 object to the scatter/gather list
326 Note that it is the caller's responsibility to ensure that the pages backing
327 the I/O request are wired for the lifetime of
329 Note also that this routine does not modify
333 .Nm sglist_append_user
334 function appends the physical address ranges described by a single user
335 virtual address range to the scatter/gather list
337 The user virtual address range is relative to the address space of the thread
344 Note that it is the caller's responsibility to ensure that the pages backing
345 the user buffer are wired for the lifetime of
349 .Nm sglist_append_vmpages
350 function appends the physical address ranges of a buffer backed by an array
351 of virtual memory pages
353 The buffer starts at an offset of
355 bytes relative to the first page and is
360 .Nm sglist_consume_uio
361 function is a variation of
362 .Nm sglist_append_uio .
364 .Nm sglist_append_uio ,
365 it appends the physical address ranges described by
367 to the scatter/gather list
370 .Nm sglist_append_uio ,
372 .Nm sglist_consume_uio
373 modifies the I/O request to indicate that the appended address ranges have
374 been processed similar to calling
376 This routine will only append ranges that describe up to
378 total bytes in length.
379 If the available segments in the scatter/gather list are exhausted before
384 structure will be updated to reflect the actual number of bytes processed,
386 .Nm sglist_consume_io
387 will return zero to indicate success.
388 In effect, this function will perform partial reads or writes.
389 The caller can compare the
393 before and after calling
394 .Nm sglist_consume_uio
395 to determine the actual number of bytes processed.
396 .Ss Manipulating Scatter/Gather Lists
399 function appends physical address ranges from the scatter/gather list
406 It returns zero on success or an error on failure.
410 function splits an existing scatter/gather list into two lists.
413 bytes described by the list
415 are moved to a new list
419 describes a total address range that is smaller than
422 then all of the address ranges will be moved to the new list at
426 will be an empty list.
427 The caller may supply an existing scatter/gather list in
429 If so, the list must be empty.
430 Otherwise, the caller may set
434 in which case a new scatter/gather list will be allocated.
443 list is modified by this call, it must be a private list with no other
447 function returns zero on success or an error on failure.
451 function generates a new scatter/gather list from a sub-range of an existing
454 The sub-range to extract is specified by the
459 The new scatter/gather list is stored in
465 the caller may either provide an empty scatter/gather list,
472 will allocate a new list subject to
479 and does not require it to be a private list.
482 function returns zero on success or an error on failure.
483 .Ss Miscellaneous Routines
486 function clears the scatter/gather list
488 so that it no longer maps any address ranges.
489 This can allow reuse of a single scatter/gather list object for multiple
494 function returns the total length of the physical address ranges described
495 by the scatter/gather list
503 functions return a new scatter/gather list on success or
509 family of functions and the
510 .Nm sglist_consume_uio ,
515 functions return zero on success or an error on failure.
520 functions return a count of scatter/gather list elements.
524 function returns a count of address space described by a scatter/gather list
529 functions return the following errors on failure:
532 The scatter/gather list has zero segments.
534 There are not enough available segments in the scatter/gather list to append
535 the specified physical address ranges.
539 .Nm sglist_consume_uio
540 function returns the following error on failure:
543 The scatter/gather list has zero segments.
548 function returns the following error on failure:
551 There are not enough available segments in the scatter/gather list
553 to append the physical address ranges from
559 function returns the following errors on failure:
564 scatter/gather list does not describe enough address space to cover the
567 The caller-supplied scatter/gather list in
571 An attempt to allocate a new scatter/gather list with
577 There are not enough available segments in the caller-supplied scatter/gather
580 to describe the requested physical address ranges.
585 function returns the following errors on failure:
590 scatter/gather list has more than one reference.
592 The caller-supplied scatter/gather list in
596 An attempt to allocate a new scatter/gather list with
602 There are not enough available segments in the caller-supplied scatter/gather
605 to describe the requested physical address ranges.
613 This API was first introduced in