Provided by: freebsd-manpages_11.1-3_all bug

NAME

     sglist, sglist_alloc, sglist_append, sglist_append_bio, sglist_append_mbuf,
     sglist_append_phys, sglist_append_uio, sglist_append_user, sglist_append_vmpages,
     sglist_build, sglist_clone, sglist_consume_uio, sglist_count, sglist_count_vmpages,
     sglist_free, sglist_hold, sglist_init, sglist_join, sglist_length, sglist_reset,
     sglist_slice, sglist_split — manage a scatter/gather list of physical memory addresses

SYNOPSIS

     #include <sys/types.h>
     #include <sys/sglist.h>

     struct sglist *
     sglist_alloc(int nsegs, int mflags);

     int
     sglist_append(struct sglist *sg, void *buf, size_t len);

     int
     sglist_append_bio(struct sglist *sg, struct bio *bp);

     int
     sglist_append_mbuf(struct sglist *sg, struct mbuf *m);

     int
     sglist_append_phys(struct sglist *sg, vm_paddr_t paddr, size_t len);

     int
     sglist_append_uio(struct sglist *sg, struct uio *uio);

     int
     sglist_append_user(struct sglist *sg, void *buf, size_t len, struct thread *td);

     int
     sglist_append_vmpages(struct sglist *sg, vm_page_t *m, size_t pgoff, size_t len);

     struct sglist *
     sglist_build(void *buf, size_t len, int mflags);

     struct sglist *
     sglist_clone(struct sglist *sg, int mflags);

     int
     sglist_consume_uio(struct sglist *sg, struct uio *uio, size_t resid);

     int
     sglist_count(void *buf, size_t len);

     int
     sglist_count_vmpages(vm_page_t *m, size_t pgoff, size_t len);

     void
     sglist_free(struct sglist *sg);

     struct sglist *
     sglist_hold(struct sglist *sg);

     void
     sglist_init(struct sglist *sg, int maxsegs, struct sglist_seg *segs);

     int
     sglist_join(struct sglist *first, struct sglist *second);

     size_t
     sglist_length(struct sglist *sg);

     void
     sglist_reset(struct sglist *sg);

     int
     sglist_slice(struct sglist *original, struct sglist **slice, size_t offset, size_t length,
         int mflags);

     int
     sglist_split(struct sglist *original, struct sglist **head, size_t length, int mflags);

DESCRIPTION

     The sglist API manages physical address ranges.  Each list contains one or more elements.
     Each element contains a starting physical address and a length.  Scatter/gather lists are
     read-only while they are shared.  If one wishes to alter an existing scatter/gather list and
     does not hold the sole reference to the list, then one should create a new list instead of
     modifying the existing list.

     Each scatter/gather list object contains a reference count.  New lists are created with a
     single reference.  New references are obtained by calling sglist_hold and are released by
     calling sglist_free.

   Allocating and Initializing Lists
     Each sglist object consists of a header structure and a variable-length array of
     scatter/gather list elements.  The sglist_alloc function allocates a new list that contains
     a header and nsegs scatter/gather list elements.  The mflags argument can be set to either
     M_NOWAIT or M_WAITOK.

     The sglist_count function returns the number of scatter/gather list elements needed to
     describe the physical address ranges mapped by a single kernel virtual address range.  The
     kernel virtual address range starts at buf and is len bytes long.

     The sglist_count_vmpages function returns the number of scatter/gather list elements needed
     to describe the physical address ranges of a buffer backed by an array of virtual memory
     pages m.  The buffer starts at an offset of pgoff bytes relative to the first page and is
     len bytes long.

     The sglist_build function allocates a new scatter/gather list object that describes the
     physical address ranges mapped by a single kernel virtual address range.  The kernel virtual
     address range starts at buf and is len bytes long.  The mflags argument can be set to either
     M_NOWAIT or M_WAITOK.

     The sglist_clone function returns a copy of an existing scatter/gather list object sg.  The
     mflags argument can be set to either M_NOWAIT or M_WAITOK.  This can be used to obtain a
     private copy of a scatter/gather list before modifying it.

     The sglist_init function initializes a scatter/gather list header.  The header is pointed to
     by sg and is initialized to manage an array of maxsegs scatter/gather list elements pointed
     to by segs.  This can be used to initialize a scatter/gather list header whose storage is
     not provided by sglist_alloc.  In that case, the caller should not call sglist_free to
     release its own reference and is responsible for ensuring all other references to the list
     are dropped before it releases the storage for sg and segs.

   Constructing Scatter/Gather Lists
     The sglist API provides several routines for building a scatter/gather list to describe one
     or more objects.  Specifically, the sglist_append family of routines can be used to append
     the physical address ranges described by an object to the end of a scatter/gather list.  All
     of these routines return 0 on success or an error on failure.  If a request to append an
     address range to a scatter/gather list fails, the scatter/gather list will remain unchanged.

     The sglist_append function appends the physical address ranges described by a single kernel
     virtual address range to the scatter/gather list sg.  The kernel virtual address range
     starts at buf and is len bytes long.

     The sglist_append_bio function appends the physical address ranges described by a single bio
     bp to the scatter/gather list sg.

     The sglist_append_mbuf function appends the physical address ranges described by an entire
     mbuf chain m to the scatter/gather list sg.

     The sglist_append_phys function appends a single physical address range to the
     scatter/gather list sg.  The physical address range starts at paddr and is len bytes long.

     The sglist_append_uio function appends the physical address ranges described by a uio(9)
     object to the scatter/gather list sg.  Note that it is the caller's responsibility to ensure
     that the pages backing the I/O request are wired for the lifetime of sg.  Note also that
     this routine does not modify uio.

     The sglist_append_user function appends the physical address ranges described by a single
     user virtual address range to the scatter/gather list sg.  The user virtual address range is
     relative to the address space of the thread td.  It starts at buf and is len bytes long.
     Note that it is the caller's responsibility to ensure that the pages backing the user buffer
     are wired for the lifetime of sg.

     The sglist_append_vmpages function appends the physical address ranges of a buffer backed by
     an array of virtual memory pages m.  The buffer starts at an offset of pgoff bytes relative
     to the first page and is len bytes long.

     The sglist_consume_uio function is a variation of sglist_append_uio.  As with
     sglist_append_uio, it appends the physical address ranges described by uio to the
     scatter/gather list sg.  Unlike sglist_append_uio, however, sglist_consume_uio modifies the
     I/O request to indicate that the appended address ranges have been processed similar to
     calling uiomove(9).  This routine will only append ranges that describe up to resid total
     bytes in length.  If the available segments in the scatter/gather list are exhausted before
     resid bytes are processed, then the uio structure will be updated to reflect the actual
     number of bytes processed, and sglist_consume_io will return zero to indicate success.  In
     effect, this function will perform partial reads or writes.  The caller can compare the
     uio_resid member of uio before and after calling sglist_consume_uio to determine the actual
     number of bytes processed.

   Manipulating Scatter/Gather Lists
     The sglist_join function appends physical address ranges from the scatter/gather list second
     onto first and then resets second to an empty list.  It returns zero on success or an error
     on failure.

     The sglist_split function splits an existing scatter/gather list into two lists.  The first
     length bytes described by the list original are moved to a new list *head.  If original
     describes a total address range that is smaller than length bytes, then all of the address
     ranges will be moved to the new list at *head and original will be an empty list.  The
     caller may supply an existing scatter/gather list in *head.  If so, the list must be empty.
     Otherwise, the caller may set *head to NULL in which case a new scatter/gather list will be
     allocated.  In that case, mflags may be set to either M_NOWAIT or M_WAITOK.  Note that since
     the original list is modified by this call, it must be a private list with no other
     references.  The sglist_split function returns zero on success or an error on failure.

     The sglist_slice function generates a new scatter/gather list from a sub-range of an
     existing scatter/gather list original.  The sub-range to extract is specified by the offset
     and length parameters.  The new scatter/gather list is stored in *slice.  As with head for
     sglist_join, the caller may either provide an empty scatter/gather list, or it may set
     *slice to NULL in which case sglist_slice will allocate a new list subject to mflags.
     Unlike sglist_split, sglist_slice does not modify original and does not require it to be a
     private list.  The sglist_split function returns zero on success or an error on failure.

   Miscellaneous Routines
     The sglist_reset function clears the scatter/gather list sg so that it no longer maps any
     address ranges.  This can allow reuse of a single scatter/gather list object for multiple
     requests.

     The sglist_length function returns the total length of the physical address ranges described
     by the scatter/gather list sg.

RETURN VALUES

     The sglist_alloc, sglist_build, and sglist_clone functions return a new scatter/gather list
     on success or NULL on failure.

     The sglist_append family of functions and the sglist_consume_uio, sglist_join, sglist_slice,
     and sglist_split functions return zero on success or an error on failure.

     The sglist_count and sglist_count_vmpages functions return a count of scatter/gather list
     elements.

     The sglist_length function returns a count of address space described by a scatter/gather
     list in bytes.

ERRORS

     The sglist_append functions return the following errors on failure:

     [EINVAL]           The scatter/gather list has zero segments.

     [EFBIG]            There are not enough available segments in the scatter/gather list to
                        append the specified physical address ranges.

     The sglist_consume_uio function returns the following error on failure:

     [EINVAL]           The scatter/gather list has zero segments.

     The sglist_join function returns the following error on failure:

     [EFBIG]            There are not enough available segments in the scatter/gather list first
                        to append the physical address ranges from second.

     The sglist_slice function returns the following errors on failure:

     [EINVAL]           The original scatter/gather list does not describe enough address space
                        to cover the requested sub-range.

     [EINVAL]           The caller-supplied scatter/gather list in *slice is not empty.

     [ENOMEM]           An attempt to allocate a new scatter/gather list with M_NOWAIT set in
                        mflags failed.

     [EFBIG]            There are not enough available segments in the caller-supplied
                        scatter/gather list in *slice to describe the requested physical address
                        ranges.

     The sglist_split function returns the following errors on failure:

     [EDOOFUS]          The original scatter/gather list has more than one reference.

     [EINVAL]           The caller-supplied scatter/gather list in *head is not empty.

     [ENOMEM]           An attempt to allocate a new scatter/gather list with M_NOWAIT set in
                        mflags failed.

     [EFBIG]            There are not enough available segments in the caller-supplied
                        scatter/gather list in *head to describe the requested physical address
                        ranges.

SEE ALSO

     g_bio(9), malloc(9), mbuf(9), uio(9)

HISTORY

     This API was first introduced in FreeBSD 8.0.