stream.h revision 2c5680450e24a9562142739ba7f7143b9b6acef4
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#ifndef _SYS_STREAM_H
#define _SYS_STREAM_H
#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 11.44 */
/*
* For source compatibility
*/
#include <sys/isa_defs.h>
#ifdef _KERNEL
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Data queue.
*
* NOTE: The *only* public fields are documented in queue(9S).
* Everything else is implementation-private.
*
* The locking rules for the queue_t structure are extremely subtle and vary
* widely depending on the field in question. As such, each field is
* annotated according to the following legend:
*
* Q9S: The field is documented in queue(9S) and may be accessed without
* locks by a STREAMS module when inside an entry point (e.g., put(9E)).
* However, no fields can be directly modified unless q_lock is held
* (which is not possible in a DDI compliant STREAMS module), with the
* following exceptions:
*
* - q_ptr: can be modified as per the rules of the STREAMS module.
* The STREAMS framework ignores q_ptr and thus imposes *no*
* locking rules on it.
* - q_qinfo: can be modified before qprocson().
*
* - q_minpsz, q_maxpsz, q_hiwat, q_lowat: can be modified as per the
* rules of the STREAMS module. The STREAMS framework never
* modifies these fields, and is tolerant of temporarily
* stale field values.
*
* In general, the STREAMS framework employs one of the following
* techniques to ensure STREAMS modules can safely access Q9S fields:
*
* - The field is only modified by the framework when the stream is
* locked with strlock() (q_next).
*
* - The field is modified by the framework, but the modifies are
* atomic, and temporarily stale values are harmless (q_count,
* q_first, q_last).
*
* - The field is modified by the framework, but the field's visible
* values are either constant or directly under the control
* of the STREAMS module itself (q_flag).
*
* QLK: The field must be accessed or modified under q_lock, except when
* the stream has been locked with strlock(). If multiple q_locks must
* be acquired, q_locks at higher addresses must be taken first.
*
* STR: The field can be accessed without a lock, but must be modified under
* strlock().
*
* SQLK: The field must be accessed or modified under SQLOCK().
*
* NOLK: The field can be accessed without a lock, but can only be modified
* when the queue_t is not known to any other threads.
*
* SVLK: The field must be accessed or modified under the service_queue lock.
* Note that service_lock must be taken after any needed q_locks,
* and that no other lock should be taken while service_lock is held.
*
* In addition, it is always acceptable to modify a field that is not yet
* known to any other threads -- and other special case exceptions exist in
* the code. Also, q_lock is used with q_wait to implement a stream head
* monitor for reads and writes.
*/
typedef struct queue {
void *q_ptr; /* Q9S: module-specific data */
unsigned char q_nband; /* QLK: number of bands */
short q_struiot; /* QLK: sync streams Q UIO mode */
/*
* Syncq scheduling
*/
/*
* NOLK: Reference to the queue's module's implementation
* structure. This will be NULL for queues associated with drivers.
*/
struct fmodsw_impl *q_fp;
} queue_t;
/*
* Queue flags; unused flags not documented in queue(9S) can be recycled.
*/
/* UNUSED 0x00000200 was QHLIST */
/* UNUSED 0x00000400 was QUNSAFE */
/* all MT type flags */
/* UNUSED 0x00400000 was QHOT */
/* UNUSED 0x00800000 was QNEXTHOT */
/* UNUSED 0x01000000 was _QNEXTLESS */
/* an sodirect_t with sockfs */
/* queue sqflags (protected by SQLOCK). */
/* This is also noted by the */
/* q_draining field, but this one is */
/* protected by SQLOCK */
/*
* Structure that describes the separate information
* for each priority band in the queue.
*/
typedef struct qband {
} qband_t;
/*
* qband flags
*/
/*
* Maximum number of bands.
*/
#define NBAND 256
/*
* Fields that can be manipulated through strqset() and strqget().
*/
typedef enum qfields {
QHIWAT = 0, /* q_hiwat or qb_hiwat */
QBAD = 9
} qfields_t;
/*
* Module information structure
*/
struct module_info {
char *mi_idname; /* module name */
};
/*
* queue information structure (with Synchronous STREAMS extensions)
*/
struct qinit {
int (*qi_putp)(); /* put procedure */
int (*qi_srvp)(); /* service procedure */
int (*qi_qopen)(); /* called on startup */
int (*qi_qclose)(); /* called on finish */
int (*qi_qadmin)(); /* for future use */
int (*qi_rwp)(); /* r/w procedure */
int (*qi_infop)(); /* information procedure */
int qi_struiot; /* stream uio type for struio() */
};
/*
* Values for qi_struiot and q_struiot:
*/
#define STRUIOT_DONTCARE 0 /* use current uiomove() (default) */
/*
* Streamtab (used in cdevsw and fmodsw to point to module or driver)
*/
struct streamtab {
struct qinit *st_muxrinit;
struct qinit *st_muxwinit;
};
/*
* Structure sent to mux drivers to indicate a link.
*/
struct linkblk {
/* (set to NULL for persistent links) */
int l_index; /* index for lower stream. */
};
/*
* Esballoc data buffer freeing routine
*/
typedef struct free_rtn {
void (*free_func)();
} frtn_t;
/*
* Data block descriptor
*
* NOTE: db_base, db_lim, db_ref and db_type are the *only* public fields,
* as described in datab(9S). Everything else is implementation-private.
*/
#define DBLK_REFMAX 255U
typedef struct datab {
unsigned char *db_base;
unsigned char *db_lim;
unsigned char db_ref;
unsigned char db_type;
unsigned char db_flags;
unsigned char db_struioflag;
void *db_cache; /* kmem cache descriptor */
union {
double enforce_alignment;
unsigned char data[8];
struct {
union {
} cksum_val; /* used to store calculated cksum */
} cksum;
/*
* Union used for future extensions (pointer to data ?).
*/
} db_struioun;
} dblk_t;
/*
*/
/*
* Used by GLDv2 to store the TCI information.
*/
#define MBLK_GETLABEL(mp) \
/*
* Message block descriptor
*/
typedef struct msgb {
unsigned char *b_rptr;
unsigned char *b_wptr;
unsigned char b_band;
unsigned char b_tag;
unsigned short b_flag;
} mblk_t;
/*
* bcache descriptor
*/
typedef struct bcache {
struct kmem_cache *buffer_cache;
struct kmem_cache *dblk_cache;
int alloc;
int destroy;
} bcache_t;
/*
* db_flags values (all implementation private!)
*/
/*
* db_struioflag values:
*/
/*
* Message flags. These are interpreted by the stream head.
*/
/* write side of stream */
/* UNUSED 0x08 was MSGNOGET (can be recycled) */
/*
* Streams message types.
*/
/*
* Data and protocol messages (regular and priority)
*/
/*
* Control messages (regular and priority)
*/
/*
* Control messages (high priority; go to head of queue)
*/
/*
* Queue message class definitions.
*/
/*
* IOCTL structure - this structure is the format of the M_IOCTL message type.
*/
#if defined(_LP64)
struct iocblk {
int ioc_cmd; /* ioctl command type */
int ioc_rval; /* return value */
int ioc_error; /* error code */
};
#else
struct iocblk {
int ioc_cmd; /* ioctl command type */
int ioc_error; /* error code */
int ioc_rval; /* return value */
int ioc_fill1;
};
#endif /* _LP64 */
/* {ioc,cp}_flags values */
#define IOC_NATIVE DATAMODEL_NATIVE
/*
* Is the ioctl data formatted for our native model?
*/
/*
* structure for the M_COPYIN and M_COPYOUT message types.
*/
#if defined(_LP64)
struct copyreq {
int cq_cmd; /* ioctl command (from ioc_cmd) */
};
#else
struct copyreq {
int cq_cmd; /* ioctl command (from ioc_cmd) */
};
#endif /* _LP64 */
/*
* structure for the M_IOCDATA message type.
*/
#if defined(_LP64)
struct copyresp {
int cp_cmd; /* ioctl command (from ioc_cmd) */
/* non-zero -> failure */
};
#else
struct copyresp {
int cp_cmd; /* ioctl command (from ioc_cmd) */
/* non-zero -> failure */
int cp_filler[3];
};
#endif /* _LP64 */
/*
* Since these structures are all intended to travel in the same message
* at different stages of a STREAMS ioctl, this union is used to determine
* the message size in strdoioctl().
*/
union ioctypes {
};
/*
* Options structure for M_SETOPTS message. This is sent upstream
* by a module or driver to set stream head options.
*/
struct stroptions {
short so_readopt; /* read option */
unsigned char so_band; /* band for water marks */
};
/* flags for stream options set message */
#ifdef _KERNEL
/*
* to a struiod_t is passed as a parameter to the rwnext() call.
*
* as there isn't a formal definition of IOV_MAX ???
*/
#define DEF_IOV_MAX 16
typedef struct struiod {
} struiod_t;
/*
* Structure for information procedure calls.
*/
typedef struct infod {
unsigned char d_cmd; /* info info request command */
unsigned char d_res; /* info info command results */
int d_bytes; /* mblk(s) byte count */
int d_count; /* count of mblk(s) */
} infod_t;
/*
* Values for d_cmd & d_res.
*/
/*
* Structure used by _I_CMD mechanism, similar in spirit to iocblk.
*/
typedef struct cmdblk {
int cb_cmd; /* ioctl command type */
int cb_error; /* error code */
} cmdblk_t;
#endif /* _KERNEL */
/*
* Miscellaneous parameters and flags.
*/
/*
* Values for stream flag in open to indicate module open, clone open,
* and the return value for failure.
*/
/*
* Priority definitions for block allocation.
*/
#define BPRI_LO 1
#define BPRI_MED 2
#define BPRI_HI 3
/*
* Value for packet size that denotes infinity
*/
#define INFPSZ -1
/*
* Flags for flushq()
*/
#define FLUSHDATA 0 /* don't flush control messages */
/*
* Flag for transparent ioctls
*/
#define TRANSPARENT (unsigned int)(-1)
/*
*/
#define STRHIGH 5120
#define STRLOW 1024
/*
* Block allocation parameters
*/
/*
* qwriter perimeter types
*/
/*
* Definitions of Streams macros and function interfaces.
*/
/*
* canenable - check if queue can be enabled by putq().
*/
/*
* Test if data block type is one of the data messages (i.e. not a control
* message).
*/
(type) == M_MULTIDATA || \
/*
* Extract queue class of message block.
*/
/*
* Align address on next lower word boundary.
*/
/*
* Find the max size of data block.
*/
#ifdef _KERNEL
/*
* For two-byte M_ERROR messages: indication that a side does not have an error
*/
#define NOERROR ((unsigned char)-1)
/*
* declarations of common routines
*/
extern void bcache_destroy(bcache_t *);
extern void flushq_common(queue_t *, int, int);
extern int canputnext(queue_t *);
extern int bcanputnext(queue_t *, unsigned char);
extern int putnextctl(queue_t *, int);
extern int putnextctl1(queue_t *, int, int);
extern void unbufcall(bufcall_id_t);
extern void unfreezestr(queue_t *);
void (*)(void *), void *);
extern void create_putlocks(queue_t *, int);
extern int mp_cont_len(mblk_t *, int *);
/*
* shared or externally configured data structures
*/
extern int nstrpush; /* maximum number of pushes allowed */
#endif /* _KERNEL */
#ifdef __cplusplus
}
#endif
#endif /* _SYS_STREAM_H */