ESBALLOC(9F)            Kernel Functions for Drivers            ESBALLOC(9F)
NAME
       esballoc, desballoc, esballoca, desballoca - allocate a message block
       using a caller-supplied buffer
SYNOPSIS
       #include <sys/stream.h>       
mblk_t *esballoc(
uchar_t *base, 
size_t size, 
uint_t pri,            
frtn_t *fr_rtnp);       
mblk_t *desballoc(
uchar_t *base, 
size_t size, 
uint_t pri,            
frtn_t *fr_rtnp);
       #include <sys/strsubr.h>       
mblk_t *esballoca(
uchar_t *base, 
size_t size, 
uint_t pri,            
frtn_t *fr_rtnp);       
mblk_t *desballoca(
uchar_t *base, 
size_t size, 
uint_t pri,            
frtn_t *fr_rtnp);       
mblk_t *esballoc_wait(
uchar_t *base, 
size_t size, 
uint_t pri,            
frtn_t *fr_rtnp);       
mblk_t *esballoca_wait(
uchar_t *base, 
size_t size, 
uint_t pri,            
frtn_t *fr_rtnp);
INTERFACE LEVEL
       esballoc(): Architecture independent level 1 (DDI/DKI)       
esballoca(): illumos DDI specific (illumos DDI)       
desballoc(): illumos DDI specific (illumos DDI)       
desballoca(): illumos DDI specific (illumos DDI)       
esballoc_wait(): Volatile (private DDI function)       
esballoca_wait(): Volatile (private DDI function)
PARAMETERS
       base                  Address of caller-supplied data buffer.       
size                  Number of bytes in data buffer.       
pri                  Priority of the request (no longer used).       
fr_rtnp                  Free routine data structure.
DESCRIPTION
       The 
esballoc(), 
esballoca(), 
desballoc() and 
desballoca() functions
       operate identically to 
allocb(9F), except that the data buffer to
       associate with the message is specified by the caller. The allocated
       message will have both the 
b_wptr and 
b_rptr set to the supplied data
       buffer starting at 
base. Only the buffer itself can be specified by
       the caller. The message block and data block header are allocated as
       if by 
allocb(9F).
       When 
freeb(9F) is called to free the message, the driver's message-
       freeing routine, referenced through the 
free_rtn(9S) structure, is
       called with appropriate arguments to free the data buffer.
       The 
free_rtn(9S) structure includes the following members:
         void (*free_func)();     /* caller's freeing routine */
         caddr_t free_arg;        /* argument to free_func() */
       Instead of requiring a specific number of arguments, the 
free_arg       field is defined of type 
caddr_t. This way, the driver can pass a
       pointer to a structure if more than one argument is needed.  Note
       that the address of the 
free_rtn(9S) structure passed to 
esballoc()       is used when the returned mblk/dblk pair is freed, and must remain
       valid until then.
       If 
esballoc() or 
esballoca() was used, then 
free_func will be called
       asynchronously at some point after the message is no longer
       referenced. If 
desballoc() or 
desballoca() was used, then 
free_func       will be called synchronously by the thread releasing the final
       reference. See 
freeb(9F).
       The 
free_func routine must not sleep, and must not access any
       dynamically allocated data structures that could be freed before or
       during its execution.  In addition, because messages allocated with       
desballoc() or 
desballoca() are freed in the context of the caller,       
free_func must not call another module's 
put procedure, or attempt to
       acquire a private module lock which might be held by another thread
       across a call to a STREAMS utility routine that could free a message
       block. Finally, 
free_func routines specified using 
desballoc() or       
desballoca() may run in interrupt context and thus  must only use
       synchronization primitives that include an interrupt priority
       returned from 
ddi_intr_get_pri(9F) or 
ddi_intr_get_softint_pri(9F).
       If any of these restrictions are not followed, the possibility of
       lock recursion or deadlock exists.
       The variants ending with 'a' (
esballoca() or 
desballoca() add an
       "extra" ref to the dblk returned, also setting an internal flag so
       that 
freeb(9F) handles the extra ref.  The point of this extra ref is
       so that any streams code handling this data block knows that the data
       should not be modified without taking a copy.  This is used by
       callers sending external buffers that must not be modified.
       The variants ending with "_wait" do a sleeping allocation, where the
       ordinary 
esballoc() functions can return NULL when the system is low
       on free memory.
RETURN VALUES
       On success, a pointer to the newly allocated message block is
       returned.  On failure, 
esballoc(), 
esballoca(), 
desballoc() and       
desballoca() return 
NULL.  The functions 
esballoc_wait() and       
esballoca_wait() do not return errors, and instead sleep until memory
       is available.
CONTEXT
       The 
esballoc(), 
esballoca(), 
desballoc() and 
desballoca() functions
       can be called from user, interrupt, or kernel context.  The functions       
esballoc_wait() and 
esballoca_wait() can block and should not be
       called from interrupt context.
ATTRIBUTES
       See 
attributes(7) for descriptions of the following attributes:
       +--------------------+-----------------+
       |  ATTRIBUTE TYPE    | ATTRIBUTE VALUE |
       +--------------------+-----------------+
       |Interface Stability | Committed       |
       +--------------------+-----------------+
       |Interface Stability | Volatile        |
       +--------------------+-----------------+
SEE ALSO
       allocb(9F), 
ddi_intr_get_pri(9F), 
ddi_intr_get_softint_pri(9F),       
freeb(9F), 
datab(9S), 
free_rtn(9S)       Writing Device Drivers       STREAMS Programming Guide                               August 22, 2023                  ESBALLOC(9F)