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_uio ,
40 .Nm sglist_append_user ,
41 .Nm sglist_append_vmpages ,
44 .Nm sglist_consume_uio ,
46 .Nm sglist_count_vmpages ,
55 .Nd manage a scatter/gather list of physical memory addresses
60 .Fn sglist_alloc "int nsegs" "int mflags"
62 .Fn sglist_append "struct sglist *sg" "void *buf" "size_t len"
64 .Fn sglist_append_bio "struct sglist *sg" "struct bio *bp"
66 .Fn sglist_append_mbuf "struct sglist *sg" "struct mbuf *m"
68 .Fn sglist_append_phys "struct sglist *sg" "vm_paddr_t paddr" "size_t len"
70 .Fn sglist_append_uio "struct sglist *sg" "struct uio *uio"
72 .Fn sglist_append_user "struct sglist *sg" "void *buf" "size_t len" "struct thread *td"
74 .Fn sglist_append_vmpages "struct sglist *sg" "vm_page_t *m" "size_t pgoff" "size_t len"
76 .Fn sglist_build "void *buf" "size_t len" "int mflags"
78 .Fn sglist_clone "struct sglist *sg" "int mflags"
80 .Fn sglist_consume_uio "struct sglist *sg" "struct uio *uio" "size_t resid"
82 .Fn sglist_count "void *buf" "size_t len"
84 .Fn sglist_count_vmpages "vm_page_t *m" "size_t pgoff" "size_t len"
86 .Fn sglist_free "struct sglist *sg"
88 .Fn sglist_hold "struct sglist *sg"
90 .Fn sglist_init "struct sglist *sg" "int maxsegs" "struct sglist_seg *segs"
92 .Fn sglist_join "struct sglist *first" "struct sglist *second"
94 .Fn sglist_length "struct sglist *sg"
96 .Fn sglist_reset "struct sglist *sg"
98 .Fn sglist_slice "struct sglist *original" "struct sglist **slice" "size_t offset" "size_t length" "int mflags"
100 .Fn sglist_split "struct sglist *original" "struct sglist **head" "size_t length" "int mflags"
104 API manages physical address ranges.
105 Each list contains one or more elements.
106 Each element contains a starting physical address and a length.
107 Scatter/gather lists are read-only while they are shared.
108 If one wishes to alter an existing scatter/gather list and does not hold the
109 sole reference to the list,
110 then one should create a new list instead of modifying the existing list.
112 Each scatter/gather list object contains a reference count.
113 New lists are created with a single reference.
114 New references are obtained by calling
116 and are released by calling
118 .Ss Allocating and Initializing Lists
121 object consists of a header structure and a variable-length array of
122 scatter/gather list elements.
125 function allocates a new list that contains a header and
127 scatter/gather list elements.
130 argument can be set to either
137 function returns the number of scatter/gather list elements needed to describe
138 the physical address ranges mapped by a single kernel virtual address range.
139 The kernel virtual address range starts at
146 .Nm sglist_count_vmpages
147 function returns the number of scatter/gather list elements needed to describe
148 the physical address ranges of a buffer backed by an array of virtual memory
151 The buffer starts at an offset of
153 bytes relative to the first page and is
159 function allocates a new scatter/gather list object that describes the physical
160 address ranges mapped by a single kernel virtual address range.
161 The kernel virtual address range starts at
168 argument can be set to either
175 function returns a copy of an existing scatter/gather list object
179 argument can be set to either
183 This can be used to obtain a private copy of a scatter/gather list before
188 function initializes a scatter/gather list header.
189 The header is pointed to by
191 and is initialized to manage an array of
193 scatter/gather list elements pointed to by
195 This can be used to initialize a scatter/gather list header whose storage
198 In that case, the caller should not call
200 to release its own reference and is responsible for ensuring all other
201 references to the list are dropped before it releases the storage for
205 .Ss Constructing Scatter/Gather Lists
208 API provides several routines for building a scatter/gather list to describe
212 family of routines can be used to append the physical address ranges described
213 by an object to the end of a scatter/gather list.
214 All of these routines return 0 on success or an error on failure.
215 If a request to append an address range to a scatter/gather list fails,
216 the scatter/gather list will remain unchanged.
220 function appends the physical address ranges described by a single kernel
221 virtual address range to the scatter/gather list
223 The kernel virtual address range starts at
230 .Nm sglist_append_bio
231 function appends the physical address ranges described by a single bio
233 to the scatter/gather list
237 .Nm sglist_append_mbuf
238 function appends the physical address ranges described by an entire mbuf
241 to the scatter/gather list
245 .Nm sglist_append_phys
246 function appends a single physical address range to the scatter/gather list
248 The physical address range starts at
255 .Nm sglist_append_uio
256 function appends the physical address ranges described by a
258 object to the scatter/gather list
260 Note that it is the caller's responsibility to ensure that the pages backing
261 the I/O request are wired for the lifetime of
263 Note also that this routine does not modify
267 .Nm sglist_append_user
268 function appends the physical address ranges described by a single user
269 virtual address range to the scatter/gather list
271 The user virtual address range is relative to the address space of the thread
278 Note that it is the caller's responsibility to ensure that the pages backing
279 the user buffer are wired for the lifetime of
283 .Nm sglist_append_vmpages
284 function appends the physical address ranges of a buffer backed by an array
285 of virtual memory pages
287 The buffer starts at an offset of
289 bytes relative to the first page and is
294 .Nm sglist_consume_uio
295 function is a variation of
296 .Nm sglist_append_uio .
298 .Nm sglist_append_uio ,
299 it appends the physical address ranges described by
301 to the scatter/gather list
304 .Nm sglist_append_uio ,
306 .Nm sglist_consume_uio
307 modifies the I/O request to indicate that the appended address ranges have
308 been processed similar to calling
310 This routine will only append ranges that describe up to
312 total bytes in length.
313 If the available segments in the scatter/gather list are exhausted before
318 structure will be updated to reflect the actual number of bytes processed,
320 .Nm sglist_consume_io
321 will return zero to indicate success.
322 In effect, this function will perform partial reads or writes.
323 The caller can compare the
327 before and after calling
328 .Nm sglist_consume_uio
329 to determine the actual number of bytes processed.
330 .Ss Manipulating Scatter/Gather Lists
333 function appends physical address ranges from the scatter/gather list
340 It returns zero on success or an error on failure.
344 function splits an existing scatter/gather list into two lists.
347 bytes described by the list
349 are moved to a new list
353 describes a total address range that is smaller than
356 then all of the address ranges will be moved to the new list at
360 will be an empty list.
361 The caller may supply an existing scatter/gather list in
363 If so, the list must be empty.
364 Otherwise, the caller may set
368 in which case a new scatter/gather list will be allocated.
377 list is modified by this call, it must be a private list with no other
381 function returns zero on success or an error on failure.
385 function generates a new scatter/gather list from a sub-range of an existing
388 The sub-range to extract is specified by the
393 The new scatter/gather list is stored in
399 the caller may either provide an empty scatter/gather list,
406 will allocate a new list subject to
413 and does not require it to be a private list.
416 function returns zero on success or an error on failure.
417 .Ss Miscellaneous Routines
420 function clears the scatter/gather list
422 so that it no longer maps any address ranges.
423 This can allow reuse of a single scatter/gather list object for multiple
428 function returns the total length of the physical address ranges described
429 by the scatter/gather list
437 functions return a new scatter/gather list on success or
443 family of functions and the
444 .Nm sglist_consume_uio ,
449 functions return zero on success or an error on failure.
454 .Nm sglist_count_vmpages
455 functions return a count of scatter/gather list elements.
459 function returns a count of address space described by a scatter/gather list
464 functions return the following errors on failure:
467 The scatter/gather list has zero segments.
469 There are not enough available segments in the scatter/gather list to append
470 the specified physical address ranges.
474 .Nm sglist_consume_uio
475 function returns the following error on failure:
478 The scatter/gather list has zero segments.
483 function returns the following error on failure:
486 There are not enough available segments in the scatter/gather list
488 to append the physical address ranges from
494 function returns the following errors on failure:
499 scatter/gather list does not describe enough address space to cover the
502 The caller-supplied scatter/gather list in
506 An attempt to allocate a new scatter/gather list with
512 There are not enough available segments in the caller-supplied scatter/gather
515 to describe the requested physical address ranges.
520 function returns the following errors on failure:
525 scatter/gather list has more than one reference.
527 The caller-supplied scatter/gather list in
531 An attempt to allocate a new scatter/gather list with
537 There are not enough available segments in the caller-supplied scatter/gather
540 to describe the requested physical address ranges.
548 This API was first introduced in