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_phys ,
39 .Nm sglist_append_sglist ,
40 .Nm sglist_append_uio ,
41 .Nm sglist_append_user ,
42 .Nm sglist_append_vmpages ,
45 .Nm sglist_consume_uio ,
47 .Nm sglist_count_vmpages ,
56 .Nd manage a scatter/gather list of physical memory addresses
61 .Fn sglist_alloc "int nsegs" "int mflags"
63 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
65 .Fn sglist_append_bio "struct sglist *sg" "struct bio *bp"
67 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
69 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
71 .Fn sglist_append_sglist "struct sglist *sg" "struct sglist *source" "size_t offset" "size_t len"
73 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
75 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
77 .Fn sglist_append_vmpages "struct sglist *sg" "vm_page_t *m" "size_t pgoff" "size_t len"
79 .Fn sglist_build "void *buf" "size_t len" "int mflags"
81 .Fn sglist_clone "struct sglist *sg" "int mflags"
83 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
85 .Fn sglist_count "void *buf" "size_t len"
87 .Fn sglist_count_vmpages "vm_page_t *m" "size_t pgoff" "size_t len"
89 .Fn sglist_free "struct sglist *sg"
91 .Fn sglist_hold "struct sglist *sg"
93 .Fn sglist_init "struct sglist *sg" "int maxsegs" "struct sglist_seg *segs"
95 .Fn sglist_join "struct sglist *first" "struct sglist *second"
97 .Fn sglist_length "struct sglist *sg"
99 .Fn sglist_reset "struct sglist *sg"
101 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
103 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
107 API manages physical address ranges.
108 Each list contains one or more elements.
109 Each element contains a starting physical address and a length.
110 Scatter/gather lists are read-only while they are shared.
111 If one wishes to alter an existing scatter/gather list and does not hold the
112 sole reference to the list,
113 then one should create a new list instead of modifying the existing list.
115 Each scatter/gather list object contains a reference count.
116 New lists are created with a single reference.
117 New references are obtained by calling
119 and are released by calling
121 .Ss Allocating and Initializing Lists
124 object consists of a header structure and a variable-length array of
125 scatter/gather list elements.
128 function allocates a new list that contains a header and
130 scatter/gather list elements.
133 argument can be set to either
140 function returns the number of scatter/gather list elements needed to describe
141 the physical address ranges mapped by a single kernel virtual address range.
142 The kernel virtual address range starts at
149 .Nm sglist_count_vmpages
150 function returns the number of scatter/gather list elements needed to describe
151 the physical address ranges of a buffer backed by an array of virtual memory
154 The buffer starts at an offset of
156 bytes relative to the first page and is
162 function allocates a new scatter/gather list object that describes the physical
163 address ranges mapped by a single kernel virtual address range.
164 The kernel virtual address range starts at
171 argument can be set to either
178 function returns a copy of an existing scatter/gather list object
182 argument can be set to either
186 This can be used to obtain a private copy of a scatter/gather list before
191 function initializes a scatter/gather list header.
192 The header is pointed to by
194 and is initialized to manage an array of
196 scatter/gather list elements pointed to by
198 This can be used to initialize a scatter/gather list header whose storage
201 In that case, the caller should not call
203 to release its own reference and is responsible for ensuring all other
204 references to the list are dropped before it releases the storage for
208 .Ss Constructing Scatter/Gather Lists
211 API provides several routines for building a scatter/gather list to describe
215 family of routines can be used to append the physical address ranges described
216 by an object to the end of a scatter/gather list.
217 All of these routines return 0 on success or an error on failure.
218 If a request to append an address range to a scatter/gather list fails,
219 the scatter/gather list will remain unchanged.
223 function appends the physical address ranges described by a single kernel
224 virtual address range to the scatter/gather list
226 The kernel virtual address range starts at
233 .Nm sglist_append_bio
234 function appends the physical address ranges described by a single bio
236 to the scatter/gather list
240 .Nm sglist_append_mbuf
241 function appends the physical address ranges described by an entire mbuf
244 to the scatter/gather list
248 .Nm sglist_append_phys
249 function appends a single physical address range to the scatter/gather list
251 The physical address range starts at
258 .Nm sglist_append_sglist
259 function appends physical address ranges described by the scatter/gather list
261 to the scatter/gather list
263 The physical address ranges start at offset
272 .Nm sglist_append_uio
273 function appends the physical address ranges described by a
275 object to the scatter/gather list
277 Note that it is the caller's responsibility to ensure that the pages backing
278 the I/O request are wired for the lifetime of
280 Note also that this routine does not modify
284 .Nm sglist_append_user
285 function appends the physical address ranges described by a single user
286 virtual address range to the scatter/gather list
288 The user virtual address range is relative to the address space of the thread
295 Note that it is the caller's responsibility to ensure that the pages backing
296 the user buffer are wired for the lifetime of
300 .Nm sglist_append_vmpages
301 function appends the physical address ranges of a buffer backed by an array
302 of virtual memory pages
304 The buffer starts at an offset of
306 bytes relative to the first page and is
311 .Nm sglist_consume_uio
312 function is a variation of
313 .Nm sglist_append_uio .
315 .Nm sglist_append_uio ,
316 it appends the physical address ranges described by
318 to the scatter/gather list
321 .Nm sglist_append_uio ,
323 .Nm sglist_consume_uio
324 modifies the I/O request to indicate that the appended address ranges have
325 been processed similar to calling
327 This routine will only append ranges that describe up to
329 total bytes in length.
330 If the available segments in the scatter/gather list are exhausted before
335 structure will be updated to reflect the actual number of bytes processed,
337 .Nm sglist_consume_io
338 will return zero to indicate success.
339 In effect, this function will perform partial reads or writes.
340 The caller can compare the
344 before and after calling
345 .Nm sglist_consume_uio
346 to determine the actual number of bytes processed.
347 .Ss Manipulating Scatter/Gather Lists
350 function appends physical address ranges from the scatter/gather list
357 It returns zero on success or an error on failure.
361 function splits an existing scatter/gather list into two lists.
364 bytes described by the list
366 are moved to a new list
370 describes a total address range that is smaller than
373 then all of the address ranges will be moved to the new list at
377 will be an empty list.
378 The caller may supply an existing scatter/gather list in
380 If so, the list must be empty.
381 Otherwise, the caller may set
385 in which case a new scatter/gather list will be allocated.
394 list is modified by this call, it must be a private list with no other
398 function returns zero on success or an error on failure.
402 function generates a new scatter/gather list from a sub-range of an existing
405 The sub-range to extract is specified by the
410 The new scatter/gather list is stored in
416 the caller may either provide an empty scatter/gather list,
423 will allocate a new list subject to
430 and does not require it to be a private list.
433 function returns zero on success or an error on failure.
434 .Ss Miscellaneous Routines
437 function clears the scatter/gather list
439 so that it no longer maps any address ranges.
440 This can allow reuse of a single scatter/gather list object for multiple
445 function returns the total length of the physical address ranges described
446 by the scatter/gather list
454 functions return a new scatter/gather list on success or
460 family of functions and the
461 .Nm sglist_consume_uio ,
466 functions return zero on success or an error on failure.
471 .Nm sglist_count_vmpages
472 functions return a count of scatter/gather list elements.
476 function returns a count of address space described by a scatter/gather list
481 functions return the following errors on failure:
484 The scatter/gather list has zero segments.
486 There are not enough available segments in the scatter/gather list to append
487 the specified physical address ranges.
491 .Nm sglist_consume_uio
492 function returns the following error on failure:
495 The scatter/gather list has zero segments.
500 function returns the following error on failure:
503 There are not enough available segments in the scatter/gather list
505 to append the physical address ranges from
511 function returns the following errors on failure:
516 scatter/gather list does not describe enough address space to cover the
519 The caller-supplied scatter/gather list in
523 An attempt to allocate a new scatter/gather list with
529 There are not enough available segments in the caller-supplied scatter/gather
532 to describe the requested physical address ranges.
537 function returns the following errors on failure:
542 scatter/gather list has more than one reference.
544 The caller-supplied scatter/gather list in
548 An attempt to allocate a new scatter/gather list with
554 There are not enough available segments in the caller-supplied scatter/gather
557 to describe the requested physical address ranges.
565 This API was first introduced in