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 94The 95.Nm 96API manages physical address ranges. 97Each list contains one or more elements. 98Each element contains a starting physical address and a length. 99Scatter/gather lists are read-only while they are shared. 100If one wishes to alter an existing scatter/gather list and does not hold the 101sole reference to the list, 102then one should create a new list instead of modifying the existing list. 103.Pp 104Each scatter/gather list object contains a reference count. 105New lists are created with a single reference. 106New references are obtained by calling 107.Nm sglist_hold 108and are released by calling 109.Nm sglist_free . 110.Ss Allocating and Initializing Lists 111Each 112.Nm 113object consists of a header structure and a variable-length array of 114scatter/gather list elements. 115The 116.Nm sglist_alloc 117function allocates a new list that contains a header and 118.Fa nsegs 119scatter/gather list elements. 120The 121.Fa mflags 122argument can be set to either 123.Dv M_NOWAIT 124or 125.Dv M_WAITOK . 126.Pp 127The 128.Nm sglist_count 129function returns the number of scatter/gather list elements needed to describe 130the physical address ranges mapped by a single kernel virtual address range. 131The kernel virtual address range starts at 132.Fa buf 133and is 134.Fa len 135bytes long. 136.Pp 137The 138.Nm sglist_build 139function allocates a new scatter/gather list object that describes the physical 140address ranges mapped by a single kernel virtual address range. 141The kernel virtual address range starts at 142.Fa buf 143and is 144.Fa len 145bytes long. 146The 147.Fa mflags 148argument can be set to either 149.Dv M_NOWAIT 150or 151.Dv M_WAITOK . 152.Pp 153The 154.Nm sglist_clone 155function returns a copy of an existing scatter/gather list object 156.Fa sg . 157The 158.Fa mflags 159argument can be set to either 160.Dv M_NOWAIT 161or 162.Dv M_WAITOK . 163This can be used to obtain a private copy of a scatter/gather list before 164modifying it. 165.Pp 166The 167.Nm sglist_init 168function initializes a scatter/gather list header. 169The header is pointed to by 170.Fa sg 171and is initialized to manage an array of 172.Fa maxsegs 173scatter/gather list elements pointed to by 174.Fa segs . 175This can be used to initialize a scatter/gather list header whose storage 176is not provided by 177.Nm sglist_alloc . 178In that case, the caller should not call 179.Nm sglist_free 180to release its own reference and is responsible for ensuring all other 181references to the list are dropped before it releases the storage for 182.Fa sg 183and 184.Fa segs . 185.Ss Constructing Scatter/Gather Lists 186The 187.Nm 188API provides several routines for building a scatter/gather list to describe 189one or more objects. 190Specifically, the 191.Nm sglist_append 192family of routines can be used to append the physical address ranges described 193by an object to the end of a scatter/gather list. 194All of these routines return 0 on success or an error on failure. 195If a request to append an address range to a scatter/gather list fails, 196the scatter/gather list will remain unchanged. 197.Pp 198The 199.Nm sglist_append 200function appends the physical address ranges described by a single kernel 201virtual address range to the scatter/gather list 202.Fa sg . 203The kernel virtual address range starts at 204.Fa buf 205and is 206.Fa len 207bytes long. 208.Pp 209The 210.Nm sglist_append_mbuf 211function appends the physical address ranges described by an entire mbuf 212chain 213.Fa m 214to the scatter/gather list 215.Fa sg . 216.Pp 217The 218.Nm sglist_append_phys 219function appends a single physical address range to the scatter/gather list 220.Fa sg . 221The physical address range starts at 222.Fa paddr 223and is 224.Fa len 225bytes long. 226.Pp 227The 228.Nm sglist_append_uio 229function appends the physical address ranges described by a 230.Xr uio 9 231object to the scatter/gather list 232.Fa sg . 233Note that it is the caller's responsibility to ensure that the pages backing 234the I/O request are wired for the lifetime of 235.Fa sg . 236Note also that this routine does not modify 237.Fa uio . 238.Pp 239The 240.Nm sglist_append_user 241function appends the physical address ranges described by a single user 242virtual address range to the scatter/gather list 243.Fa sg . 244The user virtual address range is relative to the address space of the thread 245.Fa td . 246It starts at 247.Fa buf 248and is 249.Fa len 250bytes long. 251Note that it is the caller's responsibility to ensure that the pages backing 252the user buffer are wired for the lifetime of 253.Fa sg . 254.Pp 255The 256.Nm sglist_consume_uio 257function is a variation of 258.Nm sglist_append_uio . 259As with 260.Nm sglist_append_uio , 261it appends the physical address ranges described by 262.Fa uio 263to the scatter/gather list 264.Fa sg . 265Unlike 266.Nm sglist_append_uio , 267however, 268.Nm sglist_consume_uio 269modifies the I/O request to indicate that the appended address ranges have 270been processed similar to calling 271.Xr uiomove 9 . 272This routine will only append ranges that describe up to 273.Fa resid 274total bytes in length. 275If the available segments in the scatter/gather list are exhausted before 276.Fa resid 277bytes are processed, 278then the 279.Fa uio 280structure will be updated to reflect the actual number of bytes processed, 281and 282.Nm sglist_consume_io 283will return zero to indicate success. 284In effect, this function will perform partial reads or writes. 285The caller can compare the 286.Fa uio_resid 287member of 288.Fa uio 289before and after calling 290.Nm sglist_consume_uio 291to determine the actual number of bytes processed. 292.Ss Manipulating Scatter/Gather Lists 293The 294.Nm sglist_join 295function appends physical address ranges from the scatter/gather list 296.Fa second 297onto 298.Fa first 299and then resets 300.Fa second 301to an empty list. 302It returns zero on success or an error on failure. 303.Pp 304The 305.Nm sglist_split 306function splits an existing scatter/gather list into two lists. 307The first 308.Fa length 309bytes described by the list 310.Fa original 311are moved to a new list 312.Fa *head . 313If 314.Fa original 315describes a total address range that is smaller than 316.Fa length 317bytes, 318then all of the address ranges will be moved to the new list at 319.Fa *head 320and 321.Fa original 322will be an empty list. 323The caller may supply an existing scatter/gather list in 324.Fa *head . 325If so, the list must be empty. 326Otherwise, the caller may set 327.Fa *head 328to 329.Dv NULL 330in which case a new scatter/gather list will be allocated. 331In that case, 332.Fa mflags 333may be set to either 334.Dv M_NOWAIT 335or 336.Dv M_WAITOK . 337Note that since the 338.Fa original 339list is modified by this call, it must be a private list with no other 340references. 341The 342.Nm sglist_split 343function returns zero on success or an error on failure. 344.Pp 345The 346.Nm sglist_slice 347function generates a new scatter/gather list from a sub-range of an existing 348scatter/gather list 349.Fa original . 350The sub-range to extract is specified by the 351.Fa offset 352and 353.Fa length 354parameters. 355The new scatter/gather list is stored in 356.Fa *slice . 357As with 358.Fa head 359for 360.Nm sglist_join , 361the caller may either provide an empty scatter/gather list, 362or it may set 363.Fa *slice 364to 365.Dv NULL 366in which case 367.Nm sglist_slice 368will allocate a new list subject to 369.Fa mflags . 370Unlike 371.Nm sglist_split , 372.Nm sglist_slice 373does not modify 374.Fa original 375and does not require it to be a private list. 376The 377.Nm sglist_split 378function returns zero on success or an error on failure. 379.Ss Miscellaneous Routines 380The 381.Nm sglist_reset 382function clears the scatter/gather list 383.Fa sg 384so that it no longer maps any address ranges. 385This can allow reuse of a single scatter/gather list object for multiple 386requests. 387.Pp 388The 389.Nm sglist_length 390function returns the total length of the physical address ranges described 391by the scatter/gather list 392.Fa sg . 393.Sh RETURN VALUES 394The 395.Nm sglist_alloc , 396.Nm sglist_build , 397and 398.Nm sglist_clone 399functions return a new scatter/gather list on success or 400.Dv NULL 401on failure. 402.Pp 403The 404.Nm sglist_append 405family of functions and the 406.Nm sglist_consume_uio , 407.Nm sglist_join , 408.Nm sglist_slice , 409and 410.Nm sglist_split 411functions return zero on success or an error on failure. 412.Pp 413The 414.Nm sglist_count 415function returns a count of scatter/gather list elements. 416.Pp 417The 418.Nm sglist_length 419function returns a count of address space described by a scatter/gather list 420in bytes. 421.Sh ERRORS 422The 423.Nm sglist_append 424functions return the following errors on failure: 425.Bl -tag -width Er 426.It Bq Er EINVAL 427The scatter/gather list has zero segments. 428.It Bq Er EFBIG 429There are not enough available segments in the scatter/gather list to append 430the specified physical address ranges. 431.El 432.Pp 433The 434.Nm sglist_consume_uio 435function returns the following error on failure: 436.Bl -tag -width Er 437.It Bq Er EINVAL 438The scatter/gather list has zero segments. 439.El 440.Pp 441The 442.Nm sglist_join 443function returns the following error on failure: 444.Bl -tag -width Er 445.It Bq Er EFBIG 446There are not enough available segments in the scatter/gather list 447.Fa first 448to append the physical address ranges from 449.Fa second . 450.El 451.Pp 452The 453.Nm sglist_slice 454function returns the following errors on failure: 455.Bl -tag -width Er 456.It Bq Er EINVAL 457The 458.Fa original 459scatter/gather list does not describe enough address space to cover the 460requested sub-range. 461.It Bq Er EINVAL 462The caller-supplied scatter/gather list in 463.Fa *slice 464is not empty. 465.It Bq Er ENOMEM 466An attempt to allocate a new scatter/gather list with 467.Dv M_NOWAIT 468set in 469.Fa mflags 470failed. 471.It Bq Er EFBIG 472There are not enough available segments in the caller-supplied scatter/gather 473list in 474.Fa *slice 475to describe the requested physical address ranges. 476.El 477.Pp 478The 479.Nm sglist_split 480function returns the following errors on failure: 481.Bl -tag -width Er 482.It Bq Er EDOOFUS 483The 484.Fa original 485scatter/gather list has more than one reference. 486.It Bq Er EINVAL 487The caller-supplied scatter/gather list in 488.Fa *head 489is not empty. 490.It Bq Er ENOMEM 491An attempt to allocate a new scatter/gather list with 492.Dv M_NOWAIT 493set in 494.Fa mflags 495failed. 496.It Bq Er EFBIG 497There are not enough available segments in the caller-supplied scatter/gather 498list in 499.Fa *head 500to 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 507This API was first introduced in 508.Fx 8.0 . 509