Home | History | Annotate | Download | only in os
      1     0    stevel /*
      2     0    stevel  * CDDL HEADER START
      3     0    stevel  *
      4     0    stevel  * The contents of this file are subject to the terms of the
      5  1907       edp  * Common Development and Distribution License (the "License").
      6  1907       edp  * You may not use this file except in compliance with the License.
      7     0    stevel  *
      8     0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0    stevel  * or http://www.opensolaris.org/os/licensing.
     10     0    stevel  * See the License for the specific language governing permissions
     11     0    stevel  * and limitations under the License.
     12     0    stevel  *
     13     0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0    stevel  *
     19     0    stevel  * CDDL HEADER END
     20     0    stevel  */
     21     0    stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     22     0    stevel /*	  All Rights Reserved  	*/
     23     0    stevel 
     24     0    stevel 
     25     0    stevel /*
     26  8752     Peter  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     27     0    stevel  * Use is subject to license terms.
     28     0    stevel  */
     29     0    stevel 
     30     0    stevel #include <sys/types.h>
     31     0    stevel #include <sys/sysmacros.h>
     32     0    stevel #include <sys/param.h>
     33     0    stevel #include <sys/errno.h>
     34     0    stevel #include <sys/signal.h>
     35     0    stevel #include <sys/stat.h>
     36     0    stevel #include <sys/proc.h>
     37     0    stevel #include <sys/cred.h>
     38     0    stevel #include <sys/user.h>
     39     0    stevel #include <sys/vnode.h>
     40     0    stevel #include <sys/file.h>
     41     0    stevel #include <sys/stream.h>
     42     0    stevel #include <sys/strsubr.h>
     43     0    stevel #include <sys/stropts.h>
     44     0    stevel #include <sys/tihdr.h>
     45     0    stevel #include <sys/var.h>
     46     0    stevel #include <sys/poll.h>
     47     0    stevel #include <sys/termio.h>
     48     0    stevel #include <sys/ttold.h>
     49     0    stevel #include <sys/systm.h>
     50     0    stevel #include <sys/uio.h>
     51     0    stevel #include <sys/cmn_err.h>
     52     0    stevel #include <sys/sad.h>
     53  3448  dh155122 #include <sys/netstack.h>
     54     0    stevel #include <sys/priocntl.h>
     55     0    stevel #include <sys/jioctl.h>
     56     0    stevel #include <sys/procset.h>
     57     0    stevel #include <sys/session.h>
     58     0    stevel #include <sys/kmem.h>
     59     0    stevel #include <sys/filio.h>
     60     0    stevel #include <sys/vtrace.h>
     61     0    stevel #include <sys/debug.h>
     62     0    stevel #include <sys/strredir.h>
     63     0    stevel #include <sys/fs/fifonode.h>
     64     0    stevel #include <sys/fs/snode.h>
     65     0    stevel #include <sys/strlog.h>
     66     0    stevel #include <sys/strsun.h>
     67     0    stevel #include <sys/project.h>
     68     0    stevel #include <sys/kbio.h>
     69     0    stevel #include <sys/msio.h>
     70     0    stevel #include <sys/tty.h>
     71     0    stevel #include <sys/ptyvar.h>
     72     0    stevel #include <sys/vuid_event.h>
     73     0    stevel #include <sys/modctl.h>
     74     0    stevel #include <sys/sunddi.h>
     75     0    stevel #include <sys/sunldi_impl.h>
     76     0    stevel #include <sys/autoconf.h>
     77     0    stevel #include <sys/policy.h>
     78  5895  yz147064 #include <sys/dld.h>
     79  3448  dh155122 #include <sys/zone.h>
     80  2712   nn35248 
     81  2712   nn35248 /*
     82  2712   nn35248  * This define helps improve the readability of streams code while
     83  2712   nn35248  * still maintaining a very old streams performance enhancement.  The
     84  2712   nn35248  * performance enhancement basically involved having all callers
     85  2712   nn35248  * of straccess() perform the first check that straccess() will do
     86  2712   nn35248  * locally before actually calling straccess().  (There by reducing
     87  2712   nn35248  * the number of unnecessary calls to straccess().)
     88  2712   nn35248  */
     89  2712   nn35248 #define	i_straccess(x, y)	((stp->sd_sidp == NULL) ? 0 : \
     90  2712   nn35248 				    (stp->sd_vnode->v_type == VFIFO) ? 0 : \
     91  2712   nn35248 				    straccess((x), (y)))
     92  2712   nn35248 
     93     0    stevel /*
     94     0    stevel  * what is mblk_pull_len?
     95     0    stevel  *
     96     0    stevel  * If a streams message consists of many short messages,
     97     0    stevel  * a performance degradation occurs from copyout overhead.
     98     0    stevel  * To decrease the per mblk overhead, messages that are
     99     0    stevel  * likely to consist of many small mblks are pulled up into
    100     0    stevel  * one continuous chunk of memory.
    101     0    stevel  *
    102     0    stevel  * To avoid the processing overhead of examining every
    103     0    stevel  * mblk, a quick heuristic is used. If the first mblk in
    104     0    stevel  * the message is shorter than mblk_pull_len, it is likely
    105     0    stevel  * that the rest of the mblk will be short.
    106     0    stevel  *
    107     0    stevel  * This heuristic was decided upon after performance tests
    108     0    stevel  * indicated that anything more complex slowed down the main
    109     0    stevel  * code path.
    110     0    stevel  */
    111     0    stevel #define	MBLK_PULL_LEN 64
    112     0    stevel uint32_t mblk_pull_len = MBLK_PULL_LEN;
    113     0    stevel 
    114     0    stevel /*
    115     0    stevel  * The sgttyb_handling flag controls the handling of the old BSD
    116     0    stevel  * TIOCGETP, TIOCSETP, and TIOCSETN ioctls as follows:
    117     0    stevel  *
    118     0    stevel  * 0 - Emit no warnings at all and retain old, broken behavior.
    119     0    stevel  * 1 - Emit no warnings and silently handle new semantics.
    120     0    stevel  * 2 - Send cmn_err(CE_NOTE) when either TIOCSETP or TIOCSETN is used
    121     0    stevel  *     (once per system invocation).  Handle with new semantics.
    122     0    stevel  * 3 - Send SIGSYS when any TIOCGETP, TIOCSETP, or TIOCSETN call is
    123     0    stevel  *     made (so that offenders drop core and are easy to debug).
    124     0    stevel  *
    125     0    stevel  * The "new semantics" are that TIOCGETP returns B38400 for
    126     0    stevel  * sg_[io]speed if the corresponding value is over B38400, and that
    127     0    stevel  * TIOCSET[PN] accept B38400 in these cases to mean "retain current
    128     0    stevel  * bit rate."
    129     0    stevel  */
    130     0    stevel int sgttyb_handling = 1;
    131     0    stevel static boolean_t sgttyb_complaint;
    132     0    stevel 
    133     0    stevel /* don't push drcompat module by default on Style-2 streams */
    134     0    stevel static int push_drcompat = 0;
    135     0    stevel 
    136     0    stevel /*
    137     0    stevel  * id value used to distinguish between different ioctl messages
    138     0    stevel  */
    139     0    stevel static uint32_t ioc_id;
    140     0    stevel 
    141     0    stevel static void putback(struct stdata *, queue_t *, mblk_t *, int);
    142     0    stevel static void strcleanall(struct vnode *);
    143     0    stevel static int strwsrv(queue_t *);
    144  6583      meem static int strdocmd(struct stdata *, struct strcmd *, cred_t *);
    145     0    stevel 
    146     0    stevel /*
    147     0    stevel  * qinit and module_info structures for stream head read and write queues
    148     0    stevel  */
    149     0    stevel struct module_info strm_info = { 0, "strrhead", 0, INFPSZ, STRHIGH, STRLOW };
    150     0    stevel struct module_info stwm_info = { 0, "strwhead", 0, 0, 0, 0 };
    151     0    stevel struct qinit strdata = { strrput, NULL, NULL, NULL, NULL, &strm_info };
    152     0    stevel struct qinit stwdata = { NULL, strwsrv, NULL, NULL, NULL, &stwm_info };
    153     0    stevel struct module_info fiform_info = { 0, "fifostrrhead", 0, PIPE_BUF, FIFOHIWAT,
    154     0    stevel     FIFOLOWAT };
    155     0    stevel struct module_info fifowm_info = { 0, "fifostrwhead", 0, 0, 0, 0 };
    156     0    stevel struct qinit fifo_strdata = { strrput, NULL, NULL, NULL, NULL, &fiform_info };
    157     0    stevel struct qinit fifo_stwdata = { NULL, strwsrv, NULL, NULL, NULL, &fifowm_info };
    158     0    stevel 
    159     0    stevel extern kmutex_t	strresources;	/* protects global resources */
    160     0    stevel extern kmutex_t muxifier;	/* single-threads multiplexor creation */
    161     0    stevel 
    162     0    stevel static boolean_t msghasdata(mblk_t *bp);
    163     0    stevel #define	msgnodata(bp) (!msghasdata(bp))
    164     0    stevel 
    165     0    stevel /*
    166     0    stevel  * Stream head locking notes:
    167     0    stevel  *	There are four monitors associated with the stream head:
    168     0    stevel  *	1. v_stream monitor: in stropen() and strclose() v_lock
    169     0    stevel  *		is held while the association of vnode and stream
    170     0    stevel  *		head is established or tested for.
    171     0    stevel  *	2. open/close/push/pop monitor: sd_lock is held while each
    172     0    stevel  *		thread bids for exclusive access to this monitor
    173     0    stevel  *		for opening or closing a stream.  In addition, this
    174     0    stevel  *		monitor is entered during pushes and pops.  This
    175     0    stevel  *		guarantees that during plumbing operations there
    176     0    stevel  *		is only one thread trying to change the plumbing.
    177     0    stevel  *		Any other threads present in the stream are only
    178     0    stevel  *		using the plumbing.
    179     0    stevel  *	3. read/write monitor: in the case of read, a thread holds
    180     0    stevel  *		sd_lock while trying to get data from the stream
    181     0    stevel  *		head queue.  if there is none to fulfill a read
    182     0    stevel  *		request, it sets RSLEEP and calls cv_wait_sig() down
    183     0    stevel  *		in strwaitq() to await the arrival of new data.
    184     0    stevel  *		when new data arrives in strrput(), sd_lock is acquired
    185     0    stevel  *		before testing for RSLEEP and calling cv_broadcast().
    186     0    stevel  *		the behavior of strwrite(), strwsrv(), and WSLEEP
    187     0    stevel  *		mirror this.
    188     0    stevel  *	4. ioctl monitor: sd_lock is gotten to ensure that only one
    189     0    stevel  *		thread is doing an ioctl at a time.
    190     0    stevel  */
    191     0    stevel 
    192     0    stevel static int
    193     0    stevel push_mod(queue_t *qp, dev_t *devp, struct stdata *stp, const char *name,
    194  3448  dh155122     int anchor, cred_t *crp, uint_t anchor_zoneid)
    195     0    stevel {
    196     0    stevel 	int error;
    197     0    stevel 	fmodsw_impl_t *fp;
    198     0    stevel 
    199     0    stevel 	if (stp->sd_flag & (STRHUP|STRDERR|STWRERR)) {
    200     0    stevel 		error = (stp->sd_flag & STRHUP) ? ENXIO : EIO;
    201     0    stevel 		return (error);
    202     0    stevel 	}
    203     0    stevel 	if (stp->sd_pushcnt >= nstrpush) {
    204     0    stevel 		return (EINVAL);
    205     0    stevel 	}
    206     0    stevel 
    207     0    stevel 	if ((fp = fmodsw_find(name, FMODSW_HOLD | FMODSW_LOAD)) == NULL) {
    208     0    stevel 		stp->sd_flag |= STREOPENFAIL;
    209     0    stevel 		return (EINVAL);
    210     0    stevel 	}
    211     0    stevel 
    212     0    stevel 	/*
    213     0    stevel 	 * push new module and call its open routine via qattach
    214     0    stevel 	 */
    215     0    stevel 	if ((error = qattach(qp, devp, 0, crp, fp, B_FALSE)) != 0)
    216     0    stevel 		return (error);
    217     0    stevel 
    218     0    stevel 	/*
    219     0    stevel 	 * Check to see if caller wants a STREAMS anchor
    220     0    stevel 	 * put at this place in the stream, and add if so.
    221     0    stevel 	 */
    222     0    stevel 	mutex_enter(&stp->sd_lock);
    223  3448  dh155122 	if (anchor == stp->sd_pushcnt) {
    224     0    stevel 		stp->sd_anchor = stp->sd_pushcnt;
    225  3448  dh155122 		stp->sd_anchorzone = anchor_zoneid;
    226  3448  dh155122 	}
    227     0    stevel 	mutex_exit(&stp->sd_lock);
    228     0    stevel 
    229     0    stevel 	return (0);
    230     0    stevel }
    231     0    stevel 
    232     0    stevel /*
    233     0    stevel  * Open a stream device.
    234     0    stevel  */
    235     0    stevel int
    236     0    stevel stropen(vnode_t *vp, dev_t *devp, int flag, cred_t *crp)
    237     0    stevel {
    238     0    stevel 	struct stdata *stp;
    239     0    stevel 	queue_t *qp;
    240     0    stevel 	int s;
    241  5895  yz147064 	dev_t dummydev, savedev;
    242     0    stevel 	struct autopush *ap;
    243  5895  yz147064 	struct dlautopush dlap;
    244     0    stevel 	int error = 0;
    245     0    stevel 	ssize_t	rmin, rmax;
    246     0    stevel 	int cloneopen;
    247     0    stevel 	queue_t *brq;
    248     0    stevel 	major_t major;
    249  3448  dh155122 	str_stack_t *ss;
    250  3448  dh155122 	zoneid_t zoneid;
    251  3448  dh155122 	uint_t anchor;
    252     0    stevel 
    253     0    stevel 	if (audit_active)
    254     0    stevel 		audit_stropen(vp, devp, flag, crp);
    255     0    stevel 
    256     0    stevel 	/*
    257     0    stevel 	 * If the stream already exists, wait for any open in progress
    258     0    stevel 	 * to complete, then call the open function of each module and
    259     0    stevel 	 * driver in the stream.  Otherwise create the stream.
    260     0    stevel 	 */
    261     0    stevel 	TRACE_1(TR_FAC_STREAMS_FR, TR_STROPEN, "stropen:%p", vp);
    262     0    stevel retry:
    263     0    stevel 	mutex_enter(&vp->v_lock);
    264     0    stevel 	if ((stp = vp->v_stream) != NULL) {
    265     0    stevel 
    266     0    stevel 		/*
    267     0    stevel 		 * Waiting for stream to be created to device
    268     0    stevel 		 * due to another open.
    269     0    stevel 		 */
    270  5753       gww 		mutex_exit(&vp->v_lock);
    271  5753       gww 
    272  5753       gww 		if (STRMATED(stp)) {
    273  5753       gww 			struct stdata *strmatep = stp->sd_mate;
    274  5753       gww 
    275  5753       gww 			STRLOCKMATES(stp);
    276  5753       gww 			if (strmatep->sd_flag & (STWOPEN|STRCLOSE|STRPLUMB)) {
    277  5753       gww 				if (flag & (FNDELAY|FNONBLOCK)) {
    278  5753       gww 					error = EAGAIN;
    279  5753       gww 					mutex_exit(&strmatep->sd_lock);
    280  5753       gww 					goto ckreturn;
    281  5753       gww 				}
    282  5753       gww 				mutex_exit(&stp->sd_lock);
    283  5753       gww 				if (!cv_wait_sig(&strmatep->sd_monitor,
    284  5753       gww 				    &strmatep->sd_lock)) {
    285  5753       gww 					error = EINTR;
    286  5753       gww 					mutex_exit(&strmatep->sd_lock);
    287  5753       gww 					mutex_enter(&stp->sd_lock);
    288  5753       gww 					goto ckreturn;
    289  5753       gww 				}
    290  5753       gww 				mutex_exit(&strmatep->sd_lock);
    291  5753       gww 				goto retry;
    292  5753       gww 			}
    293  5753       gww 			if (stp->sd_flag & (STWOPEN|STRCLOSE|STRPLUMB)) {
    294  5753       gww 				if (flag & (FNDELAY|FNONBLOCK)) {
    295  5753       gww 					error = EAGAIN;
    296  5753       gww 					mutex_exit(&strmatep->sd_lock);
    297  5753       gww 					goto ckreturn;
    298  5753       gww 				}
    299  5753       gww 				mutex_exit(&strmatep->sd_lock);
    300  5753       gww 				if (!cv_wait_sig(&stp->sd_monitor,
    301  5753       gww 				    &stp->sd_lock)) {
    302  5753       gww 					error = EINTR;
    303  5753       gww 					goto ckreturn;
    304  5753       gww 				}
    305  5753       gww 				mutex_exit(&stp->sd_lock);
    306  5753       gww 				goto retry;
    307  5753       gww 			}
    308  5753       gww 
    309  5753       gww 			if (stp->sd_flag & (STRDERR|STWRERR)) {
    310  5753       gww 				error = EIO;
    311     0    stevel 				mutex_exit(&strmatep->sd_lock);
    312     0    stevel 				goto ckreturn;
    313     0    stevel 			}
    314  5753       gww 
    315  5753       gww 			stp->sd_flag |= STWOPEN;
    316  5753       gww 			STRUNLOCKMATES(stp);
    317  5753       gww 		} else {
    318  5753       gww 			mutex_enter(&stp->sd_lock);
    319  5753       gww 			if (stp->sd_flag & (STWOPEN|STRCLOSE|STRPLUMB)) {
    320  5753       gww 				if (flag & (FNDELAY|FNONBLOCK)) {
    321  5753       gww 					error = EAGAIN;
    322  5753       gww 					goto ckreturn;
    323  5753       gww 				}
    324  5753       gww 				if (!cv_wait_sig(&stp->sd_monitor,
    325  5753       gww 				    &stp->sd_lock)) {
    326  5753       gww 					error = EINTR;
    327  5753       gww 					goto ckreturn;
    328  5753       gww 				}
    329  5753       gww 				mutex_exit(&stp->sd_lock);
    330  5753       gww 				goto retry;  /* could be clone! */
    331  5753       gww 			}
    332  5753       gww 
    333  5753       gww 			if (stp->sd_flag & (STRDERR|STWRERR)) {
    334  5753       gww 				error = EIO;
    335     0    stevel 				goto ckreturn;
    336     0    stevel 			}
    337  5753       gww 
    338  5753       gww 			stp->sd_flag |= STWOPEN;
    339  5753       gww 			mutex_exit(&stp->sd_lock);
    340  5753       gww 		}
    341     0    stevel 
    342     0    stevel 		/*
    343     0    stevel 		 * Open all modules and devices down stream to notify
    344     0    stevel 		 * that another user is streaming.  For modules, set the
    345     0    stevel 		 * last argument to MODOPEN and do not pass any open flags.
    346     0    stevel 		 * Ignore dummydev since this is not the first open.
    347     0    stevel 		 */
    348  5753       gww 		claimstr(stp->sd_wrq);
    349  5753       gww 		qp = stp->sd_wrq;
    350  5753       gww 		while (_SAMESTR(qp)) {
    351  5753       gww 			qp = qp->q_next;
    352  5753       gww 			if ((error = qreopen(_RD(qp), devp, flag, crp)) != 0)
    353  5753       gww 				break;
    354  5753       gww 		}
    355  5753       gww 		releasestr(stp->sd_wrq);
    356  5753       gww 		mutex_enter(&stp->sd_lock);
    357  5753       gww 		stp->sd_flag &= ~(STRHUP|STWOPEN|STRDERR|STWRERR);
    358  5753       gww 		stp->sd_rerror = 0;
    359  5753       gww 		stp->sd_werror = 0;
    360     0    stevel ckreturn:
    361  5753       gww 		cv_broadcast(&stp->sd_monitor);
    362  5753       gww 		mutex_exit(&stp->sd_lock);
    363  5753       gww 		return (error);
    364     0    stevel 	}
    365     0    stevel 
    366     0    stevel 	/*
    367     0    stevel 	 * This vnode isn't streaming.  SPECFS already
    368     0    stevel 	 * checked for multiple vnodes pointing to the
    369     0    stevel 	 * same stream, so create a stream to the driver.
    370     0    stevel 	 */
    371     0    stevel 	qp = allocq();
    372     0    stevel 	stp = shalloc(qp);
    373     0    stevel 
    374     0    stevel 	/*
    375     0    stevel 	 * Initialize stream head.  shalloc() has given us
    376     0    stevel 	 * exclusive access, and we have the vnode locked;
    377     0    stevel 	 * we can do whatever we want with stp.
    378     0    stevel 	 */
    379     0    stevel 	stp->sd_flag = STWOPEN;
    380     0    stevel 	stp->sd_siglist = NULL;
    381     0    stevel 	stp->sd_pollist.ph_list = NULL;
    382     0    stevel 	stp->sd_sigflags = 0;
    383     0    stevel 	stp->sd_mark = NULL;
    384     0    stevel 	stp->sd_closetime = STRTIMOUT;
    385     0    stevel 	stp->sd_sidp = NULL;
    386     0    stevel 	stp->sd_pgidp = NULL;
    387     0    stevel 	stp->sd_vnode = vp;
    388     0    stevel 	stp->sd_rerror = 0;
    389     0    stevel 	stp->sd_werror = 0;
    390     0    stevel 	stp->sd_wroff = 0;
    391   898      kais 	stp->sd_tail = 0;
    392     0    stevel 	stp->sd_iocblk = NULL;
    393  6583      meem 	stp->sd_cmdblk = NULL;
    394     0    stevel 	stp->sd_pushcnt = 0;
    395     0    stevel 	stp->sd_qn_minpsz = 0;
    396     0    stevel 	stp->sd_qn_maxpsz = INFPSZ - 1;	/* used to check for initialization */
    397     0    stevel 	stp->sd_maxblk = INFPSZ;
    398     0    stevel 	qp->q_ptr = _WR(qp)->q_ptr = stp;
    399     0    stevel 	STREAM(qp) = STREAM(_WR(qp)) = stp;
    400     0    stevel 	vp->v_stream = stp;
    401     0    stevel 	mutex_exit(&vp->v_lock);
    402     0    stevel 	if (vp->v_type == VFIFO) {
    403     0    stevel 		stp->sd_flag |= OLDNDELAY;
    404     0    stevel 		/*
    405     0    stevel 		 * This means, both for pipes and fifos
    406     0    stevel 		 * strwrite will send SIGPIPE if the other
    407     0    stevel 		 * end is closed. For putmsg it depends
    408     0    stevel 		 * on whether it is a XPG4_2 application
    409     0    stevel 		 * or not
    410     0    stevel 		 */
    411     0    stevel 		stp->sd_wput_opt = SW_SIGPIPE;
    412     0    stevel 
    413     0    stevel 		/* setq might sleep in kmem_alloc - avoid holding locks. */
    414     0    stevel 		setq(qp, &fifo_strdata, &fifo_stwdata, NULL, QMTSAFE,
    415     0    stevel 		    SQ_CI|SQ_CO, B_FALSE);
    416     0    stevel 
    417     0    stevel 		set_qend(qp);
    418   560      meem 		stp->sd_strtab = fifo_getinfo();
    419     0    stevel 		_WR(qp)->q_nfsrv = _WR(qp);
    420     0    stevel 		qp->q_nfsrv = qp;
    421     0    stevel 		/*
    422     0    stevel 		 * Wake up others that are waiting for stream to be created.
    423     0    stevel 		 */
    424     0    stevel 		mutex_enter(&stp->sd_lock);
    425     0    stevel 		/*
    426     0    stevel 		 * nothing is be pushed on stream yet, so
    427     0    stevel 		 * optimized stream head packetsizes are just that
    428     0    stevel 		 * of the read queue
    429     0    stevel 		 */
    430     0    stevel 		stp->sd_qn_minpsz = qp->q_minpsz;
    431     0    stevel 		stp->sd_qn_maxpsz = qp->q_maxpsz;
    432     0    stevel 		stp->sd_flag &= ~STWOPEN;
    433     0    stevel 		goto fifo_opendone;
    434     0    stevel 	}
    435     0    stevel 	/* setq might sleep in kmem_alloc - avoid holding locks. */
    436     0    stevel 	setq(qp, &strdata, &stwdata, NULL, QMTSAFE, SQ_CI|SQ_CO, B_FALSE);
    437     0    stevel 
    438     0    stevel 	set_qend(qp);
    439     0    stevel 
    440     0    stevel 	/*
    441     0    stevel 	 * Open driver and create stream to it (via qattach).
    442     0    stevel 	 */
    443  5895  yz147064 	savedev = *devp;
    444     0    stevel 	cloneopen = (getmajor(*devp) == clone_major);
    445     0    stevel 	if ((error = qattach(qp, devp, flag, crp, NULL, B_FALSE)) != 0) {
    446     0    stevel 		mutex_enter(&vp->v_lock);
    447     0    stevel 		vp->v_stream = NULL;
    448     0    stevel 		mutex_exit(&vp->v_lock);
    449     0    stevel 		mutex_enter(&stp->sd_lock);
    450     0    stevel 		cv_broadcast(&stp->sd_monitor);
    451     0    stevel 		mutex_exit(&stp->sd_lock);
    452     0    stevel 		freeq(_RD(qp));
    453     0    stevel 		shfree(stp);
    454     0    stevel 		return (error);
    455     0    stevel 	}
    456     0    stevel 	/*
    457     0    stevel 	 * Set sd_strtab after open in order to handle clonable drivers
    458     0    stevel 	 */
    459     0    stevel 	stp->sd_strtab = STREAMSTAB(getmajor(*devp));
    460     0    stevel 
    461     0    stevel 	/*
    462     0    stevel 	 * Historical note: dummydev used to be be prior to the initial
    463     0    stevel 	 * open (via qattach above), which made the value seen
    464     0    stevel 	 * inconsistent between an I_PUSH and an autopush of a module.
    465     0    stevel 	 */
    466     0    stevel 	dummydev = *devp;
    467     0    stevel 
    468     0    stevel 	/*
    469     0    stevel 	 * For clone open of old style (Q not associated) network driver,
    470     0    stevel 	 * push DRMODNAME module to handle DL_ATTACH/DL_DETACH
    471     0    stevel 	 */
    472     0    stevel 	brq = _RD(_WR(qp)->q_next);
    473     0    stevel 	major = getmajor(*devp);
    474     0    stevel 	if (push_drcompat && cloneopen && NETWORK_DRV(major) &&
    475     0    stevel 	    ((brq->q_flag & _QASSOCIATED) == 0)) {
    476  3448  dh155122 		if (push_mod(qp, &dummydev, stp, DRMODNAME, 0, crp, 0) != 0)
    477     0    stevel 			cmn_err(CE_WARN, "cannot push " DRMODNAME
    478     0    stevel 			    " streams module");
    479     0    stevel 	}
    480     0    stevel 
    481  5895  yz147064 	if (!NETWORK_DRV(major)) {
    482  5895  yz147064 		savedev = *devp;
    483  5895  yz147064 	} else {
    484  5895  yz147064 		/*
    485  5895  yz147064 		 * For network devices, process differently based on the
    486  5895  yz147064 		 * return value from dld_autopush():
    487  5895  yz147064 		 *
    488  5895  yz147064 		 *   0: the passed-in device points to a GLDv3 datalink with
    489  5895  yz147064 		 *   per-link autopush configuration; use that configuration
    490  5895  yz147064 		 *   and ignore any per-driver autopush configuration.
    491  5895  yz147064 		 *
    492  5895  yz147064 		 *   1: the passed-in device points to a physical GLDv3
    493  5895  yz147064 		 *   datalink without per-link autopush configuration.  The
    494  5895  yz147064 		 *   passed in device was changed to refer to the actual
    495  5895  yz147064 		 *   physical device (if it's not already); we use that new
    496  5895  yz147064 		 *   device to look up any per-driver autopush configuration.
    497  5895  yz147064 		 *
    498  5895  yz147064 		 *   -1: neither of the above cases applied; use the initial
    499  5895  yz147064 		 *   device to look up any per-driver autopush configuration.
    500  5895  yz147064 		 */
    501  5895  yz147064 		switch (dld_autopush(&savedev, &dlap)) {
    502  5895  yz147064 		case 0:
    503  5895  yz147064 			zoneid = crgetzoneid(crp);
    504  5895  yz147064 			for (s = 0; s < dlap.dap_npush; s++) {
    505  5895  yz147064 				error = push_mod(qp, &dummydev, stp,
    506  5895  yz147064 				    dlap.dap_aplist[s], dlap.dap_anchor, crp,
    507  5895  yz147064 				    zoneid);
    508  5895  yz147064 				if (error != 0)
    509  5895  yz147064 					break;
    510  5895  yz147064 			}
    511  5895  yz147064 			goto opendone;
    512  5895  yz147064 		case 1:
    513  5895  yz147064 			break;
    514  5895  yz147064 		case -1:
    515  5895  yz147064 			savedev = *devp;
    516  5895  yz147064 			break;
    517  5895  yz147064 		}
    518  5895  yz147064 	}
    519  5895  yz147064 	/*
    520  5895  yz147064 	 * Find the autopush configuration based on "savedev". Start with the
    521  5895  yz147064 	 * global zone. If not found check in the local zone.
    522  3448  dh155122 	 */
    523  3448  dh155122 	zoneid = GLOBAL_ZONEID;
    524  3448  dh155122 retryap:
    525  3448  dh155122 	ss = netstack_find_by_stackid(zoneid_to_netstackid(zoneid))->
    526  3448  dh155122 	    netstack_str;
    527  5895  yz147064 	if ((ap = sad_ap_find_by_dev(savedev, ss)) == NULL) {
    528  3448  dh155122 		netstack_rele(ss->ss_netstack);
    529  3448  dh155122 		if (zoneid == GLOBAL_ZONEID) {
    530  3448  dh155122 			/*
    531  3448  dh155122 			 * None found. Also look in the zone's autopush table.
    532  3448  dh155122 			 */
    533  3448  dh155122 			zoneid = crgetzoneid(crp);
    534  3448  dh155122 			if (zoneid != GLOBAL_ZONEID)
    535  3448  dh155122 				goto retryap;
    536  3448  dh155122 		}
    537     0    stevel 		goto opendone;
    538  3448  dh155122 	}
    539  3448  dh155122 	anchor = ap->ap_anchor;
    540  3448  dh155122 	zoneid = crgetzoneid(crp);
    541     0    stevel 	for (s = 0; s < ap->ap_npush; s++) {
    542     0    stevel 		error = push_mod(qp, &dummydev, stp, ap->ap_list[s],
    543  3448  dh155122 		    anchor, crp, zoneid);
    544     0    stevel 		if (error != 0)
    545     0    stevel 			break;
    546     0    stevel 	}
    547  3448  dh155122 	sad_ap_rele(ap, ss);
    548  3448  dh155122 	netstack_rele(ss->ss_netstack);
    549     0    stevel 
    550  5895  yz147064 opendone:
    551  5895  yz147064 
    552     0    stevel 	/*
    553     0    stevel 	 * let specfs know that open failed part way through
    554     0    stevel 	 */
    555     0    stevel 	if (error) {
    556     0    stevel 		mutex_enter(&stp->sd_lock);
    557     0    stevel 		stp->sd_flag |= STREOPENFAIL;
    558     0    stevel 		mutex_exit(&stp->sd_lock);
    559     0    stevel 	}
    560     0    stevel 
    561     0    stevel 	/*
    562     0    stevel 	 * Wake up others that are waiting for stream to be created.
    563     0    stevel 	 */
    564     0    stevel 	mutex_enter(&stp->sd_lock);
    565     0    stevel 	stp->sd_flag &= ~STWOPEN;
    566     0    stevel 
    567     0    stevel 	/*
    568     0    stevel 	 * As a performance concern we are caching the values of
    569     0    stevel 	 * q_minpsz and q_maxpsz of the module below the stream
    570     0    stevel 	 * head in the stream head.
    571     0    stevel 	 */
    572     0    stevel 	mutex_enter(QLOCK(stp->sd_wrq->q_next));
    573     0    stevel 	rmin = stp->sd_wrq->q_next->q_minpsz;
    574     0    stevel 	rmax = stp->sd_wrq->q_next->q_maxpsz;
    575     0    stevel 	mutex_exit(QLOCK(stp->sd_wrq->q_next));
    576     0    stevel 
    577     0    stevel 	/* do this processing here as a performance concern */
    578     0    stevel 	if (strmsgsz != 0) {
    579     0    stevel 		if (rmax == INFPSZ)
    580     0    stevel 			rmax = strmsgsz;
    581     0    stevel 		else
    582     0    stevel 			rmax = MIN(strmsgsz, rmax);
    583     0    stevel 	}
    584     0    stevel 
    585     0    stevel 	mutex_enter(QLOCK(stp->sd_wrq));
    586     0    stevel 	stp->sd_qn_minpsz = rmin;
    587     0    stevel 	stp->sd_qn_maxpsz = rmax;
    588     0    stevel 	mutex_exit(QLOCK(stp->sd_wrq));
    589     0    stevel 
    590     0    stevel fifo_opendone:
    591     0    stevel 	cv_broadcast(&stp->sd_monitor);
    592     0    stevel 	mutex_exit(&stp->sd_lock);
    593     0    stevel 	return (error);
    594     0    stevel }
    595     0    stevel 
    596     0    stevel static int strsink(queue_t *, mblk_t *);
    597     0    stevel static struct qinit deadrend = {
    598     0    stevel 	strsink, NULL, NULL, NULL, NULL, &strm_info, NULL
    599     0    stevel };
    600     0    stevel static struct qinit deadwend = {
    601     0    stevel 	NULL, NULL, NULL, NULL, NULL, &stwm_info, NULL
    602     0    stevel };
    603     0    stevel 
    604     0    stevel /*
    605     0    stevel  * Close a stream.
    606     0    stevel  * This is called from closef() on the last close of an open stream.
    607     0    stevel  * Strclean() will already have removed the siglist and pollist
    608     0    stevel  * information, so all that remains is to remove all multiplexor links
    609     0    stevel  * for the stream, pop all the modules (and the driver), and free the
    610     0    stevel  * stream structure.
    611     0    stevel  */
    612     0    stevel 
    613     0    stevel int
    614     0    stevel strclose(struct vnode *vp, int flag, cred_t *crp)
    615     0    stevel {
    616     0    stevel 	struct stdata *stp;
    617     0    stevel 	queue_t *qp;
    618     0    stevel 	int rval;
    619     0    stevel 	int freestp = 1;
    620     0    stevel 	queue_t *rmq;
    621     0    stevel 
    622     0    stevel 	if (audit_active)
    623     0    stevel 		audit_strclose(vp, flag, crp);
    624     0    stevel 
    625     0    stevel 	TRACE_1(TR_FAC_STREAMS_FR,
    626  5753       gww 	    TR_STRCLOSE, "strclose:%p", vp);
    627     0    stevel 	ASSERT(vp->v_stream);
    628     0    stevel 
    629     0    stevel 	stp = vp->v_stream;
    630     0    stevel 	ASSERT(!(stp->sd_flag & STPLEX));
    631     0    stevel 	qp = stp->sd_wrq;
    632     0    stevel 
    633     0    stevel 	/*
    634     0    stevel 	 * Needed so that strpoll will return non-zero for this fd.
    635     0    stevel 	 * Note that with POLLNOERR STRHUP does still cause POLLHUP.
    636     0    stevel 	 */
    637     0    stevel 	mutex_enter(&stp->sd_lock);
    638     0    stevel 	stp->sd_flag |= STRHUP;
    639     0    stevel 	mutex_exit(&stp->sd_lock);
    640     0    stevel 
    641     0    stevel 	/*
    642     0    stevel 	 * If the registered process or process group did not have an
    643     0    stevel 	 * open instance of this stream then strclean would not be
    644     0    stevel 	 * called. Thus at the time of closing all remaining siglist entries
    645     0    stevel 	 * are removed.
    646     0    stevel 	 */
    647     0    stevel 	if (stp->sd_siglist != NULL)
    648     0    stevel 		strcleanall(vp);
    649     0    stevel 
    650     0    stevel 	ASSERT(stp->sd_siglist == NULL);
    651     0    stevel 	ASSERT(stp->sd_sigflags == 0);
    652     0    stevel 
    653     0    stevel 	if (STRMATED(stp)) {
    654     0    stevel 		struct stdata *strmatep = stp->sd_mate;
    655     0    stevel 		int waited = 1;
    656     0    stevel 
    657     0    stevel 		STRLOCKMATES(stp);
    658     0    stevel 		while (waited) {
    659     0    stevel 			waited = 0;
    660     0    stevel 			while (stp->sd_flag & (STWOPEN|STRCLOSE|STRPLUMB)) {
    661     0    stevel 				mutex_exit(&strmatep->sd_lock);
    662     0    stevel 				cv_wait(&stp->sd_monitor, &stp->sd_lock);
    663     0    stevel 				mutex_exit(&stp->sd_lock);
    664     0    stevel 				STRLOCKMATES(stp);
    665     0    stevel 				waited = 1;
    666     0    stevel 			}
    667     0    stevel 			while (strmatep->sd_flag &
    668     0    stevel 			    (STWOPEN|STRCLOSE|STRPLUMB)) {
    669     0    stevel 				mutex_exit(&stp->sd_lock);
    670     0    stevel 				cv_wait(&strmatep->sd_monitor,
    671     0    stevel 				    &strmatep->sd_lock);
    672     0    stevel 				mutex_exit(&strmatep->sd_lock);
    673     0    stevel 				STRLOCKMATES(stp);
    674     0    stevel 				waited = 1;
    675     0    stevel 			}
    676     0    stevel 		}
    677     0    stevel 		stp->sd_flag |= STRCLOSE;
    678     0    stevel 		STRUNLOCKMATES(stp);
    679     0    stevel 	} else {
    680     0    stevel 		mutex_enter(&stp->sd_lock);
    681     0    stevel 		stp->sd_flag |= STRCLOSE;
    682     0    stevel 		mutex_exit(&stp->sd_lock);
    683     0    stevel 	}
    684     0    stevel 
    685     0    stevel 	ASSERT(qp->q_first == NULL);	/* No more delayed write */
    686     0    stevel 
    687     0    stevel 	/* Check if an I_LINK was ever done on this stream */
    688     0    stevel 	if (stp->sd_flag & STRHASLINKS) {
    689  3448  dh155122 		netstack_t *ns;
    690  3448  dh155122 		str_stack_t *ss;
    691  3448  dh155122 
    692  3448  dh155122 		ns = netstack_find_by_cred(crp);
    693  3448  dh155122 		ASSERT(ns != NULL);
    694  3448  dh155122 		ss = ns->netstack_str;
    695  3448  dh155122 		ASSERT(ss != NULL);
    696  3448  dh155122 
    697  3448  dh155122 		(void) munlinkall(stp, LINKCLOSE|LINKNORMAL, crp, &rval, ss);
    698  3448  dh155122 		netstack_rele(ss->ss_netstack);
    699     0    stevel 	}
    700     0    stevel 
    701     0    stevel 	while (_SAMESTR(qp)) {
    702     0    stevel 		/*
    703     0    stevel 		 * Holding sd_lock prevents q_next from changing in
    704     0    stevel 		 * this stream.
    705     0    stevel 		 */
    706     0    stevel 		mutex_enter(&stp->sd_lock);
    707     0    stevel 		if (!(flag & (FNDELAY|FNONBLOCK)) && (stp->sd_closetime > 0)) {
    708     0    stevel 
    709     0    stevel 			/*
    710     0    stevel 			 * sleep until awakened by strwsrv() or timeout
    711     0    stevel 			 */
    712     0    stevel 			for (;;) {
    713     0    stevel 				mutex_enter(QLOCK(qp->q_next));
    714     0    stevel 				if (!(qp->q_next->q_mblkcnt)) {
    715     0    stevel 					mutex_exit(QLOCK(qp->q_next));
    716     0    stevel 					break;
    717     0    stevel 				}
    718     0    stevel 				stp->sd_flag |= WSLEEP;
    719     0    stevel 
    720     0    stevel 				/* ensure strwsrv gets enabled */
    721     0    stevel 				qp->q_next->q_flag |= QWANTW;
    722     0    stevel 				mutex_exit(QLOCK(qp->q_next));
    723     0    stevel 				/* get out if we timed out or recv'd a signal */
    724     0    stevel 				if (str_cv_wait(&qp->q_wait, &stp->sd_lock,
    725     0    stevel 				    stp->sd_closetime, 0) <= 0) {
    726     0    stevel 					break;
    727     0    stevel 				}
    728     0    stevel 			}
    729     0    stevel 			stp->sd_flag &= ~WSLEEP;
    730     0    stevel 		}
    731     0    stevel 		mutex_exit(&stp->sd_lock);
    732     0    stevel 
    733     0    stevel 		rmq = qp->q_next;
    734     0    stevel 		if (rmq->q_flag & QISDRV) {
    735     0    stevel 			ASSERT(!_SAMESTR(rmq));
    736     0    stevel 			wait_sq_svc(_RD(qp)->q_syncq);
    737     0    stevel 		}
    738     0    stevel 
    739     0    stevel 		qdetach(_RD(rmq), 1, flag, crp, B_FALSE);
    740     0    stevel 	}
    741  1907       edp 
    742  1907       edp 	/*
    743  1907       edp 	 * Since we call pollwakeup in close() now, the poll list should
    744  1907       edp 	 * be empty in most cases. The only exception is the layered devices
    745  1907       edp 	 * (e.g. the console drivers with redirection modules pushed on top
    746  1907       edp 	 * of it).  We have to do this after calling qdetach() because
    747  1907       edp 	 * the redirection module won't have torn down the console
    748  1907       edp 	 * redirection until after qdetach() has been invoked.
    749  1907       edp 	 */
    750  1907       edp 	if (stp->sd_pollist.ph_list != NULL) {
    751  1907       edp 		pollwakeup(&stp->sd_pollist, POLLERR);
    752  1907       edp 		pollhead_clean(&stp->sd_pollist);
    753  1907       edp 	}
    754  1907       edp 	ASSERT(stp->sd_pollist.ph_list == NULL);
    755  1907       edp 	ASSERT(stp->sd_sidp == NULL);
    756  1907       edp 	ASSERT(stp->sd_pgidp == NULL);
    757     0    stevel 
    758     0    stevel 	/* Prevent qenable from re-enabling the stream head queue */
    759     0    stevel 	disable_svc(_RD(qp));
    760     0    stevel 
    761     0    stevel 	/*
    762     0    stevel 	 * Wait until service procedure of each queue is
    763     0    stevel 	 * run, if QINSERVICE is set.
    764     0    stevel 	 */
    765     0    stevel 	wait_svc(_RD(qp));
    766     0    stevel 
    767     0    stevel 	/*
    768     0    stevel 	 * Now, flush both queues.
    769     0    stevel 	 */
    770     0    stevel 	flushq(_RD(qp), FLUSHALL);
    771     0    stevel 	flushq(qp, FLUSHALL);
    772     0    stevel 
    773     0    stevel 	/*
    774     0    stevel 	 * If the write queue of the stream head is pointing to a
    775     0    stevel 	 * read queue, we have a twisted stream.  If the read queue
    776     0    stevel 	 * is alive, convert the stream head queues into a dead end.
    777     0    stevel 	 * If the read queue is dead, free the dead pair.
    778     0    stevel 	 */
    779     0    stevel 	if (qp->q_next && !_SAMESTR(qp)) {
    780     0    stevel 		if (qp->q_next->q_qinfo == &deadrend) {	/* half-closed pipe */
    781     0    stevel 			flushq(qp->q_next, FLUSHALL); /* ensure no message */
    782     0    stevel 			shfree(qp->q_next->q_stream);
    783     0    stevel 			freeq(qp->q_next);
    784     0    stevel 			freeq(_RD(qp));
    785     0    stevel 		} else if (qp->q_next == _RD(qp)) {	/* fifo */
    786     0    stevel 			freeq(_RD(qp));
    787     0    stevel 		} else {				/* pipe */
    788     0    stevel 			freestp = 0;
    789     0    stevel 			/*
    790     0    stevel 			 * The q_info pointers are never accessed when
    791     0    stevel 			 * SQLOCK is held.
    792     0    stevel 			 */
    793     0    stevel 			ASSERT(qp->q_syncq == _RD(qp)->q_syncq);
    794     0    stevel 			mutex_enter(SQLOCK(qp->q_syncq));
    795     0    stevel 			qp->q_qinfo = &deadwend;
    796     0    stevel 			_RD(qp)->q_qinfo = &deadrend;
    797     0    stevel 			mutex_exit(SQLOCK(qp->q_syncq));
    798     0    stevel 		}
    799     0    stevel 	} else {
    800     0    stevel 		freeq(_RD(qp)); /* free stream head queue pair */
    801     0    stevel 	}
    802     0    stevel 
    803     0    stevel 	mutex_enter(&vp->v_lock);
    804     0    stevel 	if (stp->sd_iocblk) {
    805     0    stevel 		if (stp->sd_iocblk != (mblk_t *)-1) {
    806     0    stevel 			freemsg(stp->sd_iocblk);
    807     0    stevel 		}
    808     0    stevel 		stp->sd_iocblk = NULL;
    809     0    stevel 	}
    810     0    stevel 	stp->sd_vnode = NULL;
    811     0    stevel 	vp->v_stream = NULL;
    812     0    stevel 	mutex_exit(&vp->v_lock);
    813     0    stevel 	mutex_enter(&stp->sd_lock);
    814  6583      meem 	freemsg(stp->sd_cmdblk);
    815  6583      meem 	stp->sd_cmdblk = NULL;
    816     0    stevel 	stp->sd_flag &= ~STRCLOSE;
    817     0    stevel 	cv_broadcast(&stp->sd_monitor);
    818     0    stevel 	mutex_exit(&stp->sd_lock);
    819     0    stevel 
    820     0    stevel 	if (freestp)
    821     0    stevel 		shfree(stp);
    822     0    stevel 	return (0);
    823     0    stevel }
    824     0    stevel 
    825     0    stevel static int
    826     0    stevel strsink(queue_t *q, mblk_t *bp)
    827     0    stevel {
    828     0    stevel 	struct copyresp *resp;
    829     0    stevel 
    830     0    stevel 	switch (bp->b_datap->db_type) {
    831     0    stevel 	case M_FLUSH:
    832     0    stevel 		if ((*bp->b_rptr & FLUSHW) && !(bp->b_flag & MSGNOLOOP)) {
    833     0    stevel 			*bp->b_rptr &= ~FLUSHR;
    834     0    stevel 			bp->b_flag |= MSGNOLOOP;
    835     0    stevel 			/*
    836     0    stevel 			 * Protect against the driver passing up
    837     0    stevel 			 * messages after it has done a qprocsoff.
    838     0    stevel 			 */
    839     0    stevel 			if (_OTHERQ(q)->q_next == NULL)
    840     0    stevel 				freemsg(bp);
    841     0    stevel 			else
    842     0    stevel 				qreply(q, bp);
    843     0    stevel 		} else {
    844     0    stevel 			freemsg(bp);
    845     0    stevel 		}
    846     0    stevel 		break;
    847     0    stevel 
    848     0    stevel 	case M_COPYIN:
    849     0    stevel 	case M_COPYOUT:
    850     0    stevel 		if (bp->b_cont) {
    851     0    stevel 			freemsg(bp->b_cont);
    852     0    stevel 			bp->b_cont = NULL;
    853     0    stevel 		}
    854     0    stevel 		bp->b_datap->db_type = M_IOCDATA;
    855     0    stevel 		bp->b_wptr = bp->b_rptr + sizeof (struct copyresp);
    856     0    stevel 		resp = (struct copyresp *)bp->b_rptr;
    857     0    stevel 		resp->cp_rval = (caddr_t)1;	/* failure */
    858     0    stevel 		/*
    859     0    stevel 		 * Protect against the driver passing up
    860     0    stevel 		 * messages after it has done a qprocsoff.
    861     0    stevel 		 */
    862     0    stevel 		if (_OTHERQ(q)->q_next == NULL)
    863     0    stevel 			freemsg(bp);
    864     0    stevel 		else
    865     0    stevel 			qreply(q, bp);
    866     0    stevel 		break;
    867     0    stevel 
    868     0    stevel 	case M_IOCTL:
    869     0    stevel 		if (bp->b_cont) {
    870     0    stevel 			freemsg(bp->b_cont);
    871     0    stevel 			bp->b_cont = NULL;
    872     0    stevel 		}
    873     0    stevel 		bp->b_datap->db_type = M_IOCNAK;
    874     0    stevel 		/*
    875     0    stevel 		 * Protect against the driver passing up
    876     0    stevel 		 * messages after it has done a qprocsoff.
    877     0    stevel 		 */
    878     0    stevel 		if (_OTHERQ(q)->q_next == NULL)
    879     0    stevel 			freemsg(bp);
    880     0    stevel 		else
    881     0    stevel 			qreply(q, bp);
    882     0    stevel 		break;
    883     0    stevel 
    884     0    stevel 	default:
    885     0    stevel 		freemsg(bp);
    886     0    stevel 		break;
    887     0    stevel 	}
    888     0    stevel 
    889     0    stevel 	return (0);
    890     0    stevel }
    891     0    stevel 
    892     0    stevel /*
    893     0    stevel  * Clean up after a process when it closes a stream.  This is called
    894     0    stevel  * from closef for all closes, whereas strclose is called only for the
    895     0    stevel  * last close on a stream.  The siglist is scanned for entries for the
    896     0    stevel  * current process, and these are removed.
    897     0    stevel  */
    898     0    stevel void
    899     0    stevel strclean(struct vnode *vp)
    900     0    stevel {
    901     0    stevel 	strsig_t *ssp, *pssp, *tssp;
    902     0    stevel 	stdata_t *stp;
    903     0    stevel 	int update = 0;
    904     0    stevel 
    905     0    stevel 	TRACE_1(TR_FAC_STREAMS_FR,
    906  5753       gww 	    TR_STRCLEAN, "strclean:%p", vp);
    907     0    stevel 	stp = vp->v_stream;
    908     0    stevel 	pssp = NULL;
    909     0    stevel 	mutex_enter(&stp->sd_lock);
    910     0    stevel 	ssp = stp->sd_siglist;
    911     0    stevel 	while (ssp) {
    912     0    stevel 		if (ssp->ss_pidp == curproc->p_pidp) {
    913     0    stevel 			tssp = ssp->ss_next;
    914     0    stevel 			if (pssp)
    915     0    stevel 				pssp->ss_next = tssp;
    916     0    stevel 			else
    917     0    stevel 				stp->sd_siglist = tssp;
    918     0    stevel 			mutex_enter(&pidlock);
    919     0    stevel 			PID_RELE(ssp->ss_pidp);
    920     0    stevel 			mutex_exit(&pidlock);
    921     0    stevel 			kmem_free(ssp, sizeof (strsig_t));
    922     0    stevel 			update = 1;
    923     0    stevel 			ssp = tssp;
    924     0    stevel 		} else {
    925     0    stevel 			pssp = ssp;
    926     0    stevel 			ssp = ssp->ss_next;
    927     0    stevel 		}
    928     0    stevel 	}
    929     0    stevel 	if (update) {
    930     0    stevel 		stp->sd_sigflags = 0;
    931     0    stevel 		for (ssp = stp->sd_siglist; ssp; ssp = ssp->ss_next)
    932     0    stevel 			stp->sd_sigflags |= ssp->ss_events;
    933     0    stevel 	}
    934     0    stevel 	mutex_exit(&stp->sd_lock);
    935     0    stevel }
    936     0    stevel 
    937     0    stevel /*
    938     0    stevel  * Used on the last close to remove any remaining items on the siglist.
    939     0    stevel  * These could be present on the siglist due to I_ESETSIG calls that
    940     0    stevel  * use process groups or processed that do not have an open file descriptor
    941     0    stevel  * for this stream (Such entries would not be removed by strclean).
    942     0    stevel  */
    943     0    stevel static void
    944     0    stevel strcleanall(struct vnode *vp)
    945     0    stevel {
    946     0    stevel 	strsig_t *ssp, *nssp;
    947     0    stevel 	stdata_t *stp;
    948     0    stevel 
    949     0    stevel 	stp = vp->v_stream;
    950     0    stevel 	mutex_enter(&stp->sd_lock);
    951     0    stevel 	ssp = stp->sd_siglist;
    952     0    stevel 	stp->sd_siglist = NULL;
    953     0    stevel 	while (ssp) {
    954     0    stevel 		nssp = ssp->ss_next;
    955     0    stevel 		mutex_enter(&pidlock);
    956     0    stevel 		PID_RELE(ssp->ss_pidp);
    957     0    stevel 		mutex_exit(&pidlock);
    958     0    stevel 		kmem_free(ssp, sizeof (strsig_t));
    959     0    stevel 		ssp = nssp;
    960     0    stevel 	}
    961     0    stevel 	stp->sd_sigflags = 0;
    962     0    stevel 	mutex_exit(&stp->sd_lock);
    963     0    stevel }
    964     0    stevel 
    965     0    stevel /*
    966     0    stevel  * Retrieve the next message from the logical stream head read queue
    967     0    stevel  * using either rwnext (if sync stream) or getq_noenab.
    968     0    stevel  * It is the callers responsibility to call qbackenable after
    969     0    stevel  * it is finished with the message. The caller should not call
    970     0    stevel  * qbackenable until after any putback calls to avoid spurious backenabling.
    971     0    stevel  */
    972     0    stevel mblk_t *
    973     0    stevel strget(struct stdata *stp, queue_t *q, struct uio *uiop, int first,
    974     0    stevel     int *errorp)
    975     0    stevel {
    976     0    stevel 	mblk_t *bp;
    977     0    stevel 	int error;
    978  6769   ja97890 	ssize_t rbytes = 0;
    979  6769   ja97890 
    980  6769   ja97890 	/* Holding sd_lock prevents the read queue from changing  */
    981     0    stevel 	ASSERT(MUTEX_HELD(&stp->sd_lock));
    982     0    stevel 
    983     0    stevel 	if (uiop != NULL && stp->sd_struiordq != NULL &&
    984     0    stevel 	    q->q_first == NULL &&
    985     0    stevel 	    (!first || (stp->sd_wakeq & RSLEEP))) {
    986     0    stevel 		/*
    987     0    stevel 		 * Stream supports rwnext() for the read side.
    988     0    stevel 		 * If this is the first time we're called by e.g. strread
    989     0    stevel 		 * only do the downcall if there is a deferred wakeup
    990     0    stevel 		 * (registered in sd_wakeq).
    991     0    stevel 		 */
    992     0    stevel 		struiod_t uiod;
    993     0    stevel 
    994     0    stevel 		if (first)
    995     0    stevel 			stp->sd_wakeq &= ~RSLEEP;
    996     0    stevel 
    997     0    stevel 		(void) uiodup(uiop, &uiod.d_uio, uiod.d_iov,
    998  5753       gww 		    sizeof (uiod.d_iov) / sizeof (*uiod.d_iov));
    999     0    stevel 		uiod.d_mp = 0;
   1000     0    stevel 		/*
   1001     0    stevel 		 * Mark that a thread is in rwnext on the read side
   1002     0    stevel 		 * to prevent strrput from nacking ioctls immediately.
   1003     0    stevel 		 * When the last concurrent rwnext returns
   1004     0    stevel 		 * the ioctls are nack'ed.
   1005     0    stevel 		 */
   1006     0    stevel 		ASSERT(MUTEX_HELD(&stp->sd_lock));
   1007     0    stevel 		stp->sd_struiodnak++;
   1008     0    stevel 		/*
   1009     0    stevel 		 * Note: rwnext will drop sd_lock.
   1010     0    stevel 		 */
   1011     0    stevel 		error = rwnext(q, &uiod);
   1012     0    stevel 		ASSERT(MUTEX_NOT_HELD(&stp->sd_lock));
   1013     0    stevel 		mutex_enter(&stp->sd_lock);
   1014     0    stevel 		stp->sd_struiodnak--;
   1015     0    stevel 		while (stp->sd_struiodnak == 0 &&
   1016     0    stevel 		    ((bp = stp->sd_struionak) != NULL)) {
   1017     0    stevel 			stp->sd_struionak = bp->b_next;
   1018     0    stevel 			bp->b_next = NULL;
   1019     0    stevel 			bp->b_datap->db_type = M_IOCNAK;
   1020     0    stevel 			/*
   1021     0    stevel 			 * Protect against the driver passing up
   1022     0    stevel 			 * messages after it has done a qprocsoff.
   1023     0    stevel 			 */
   1024     0    stevel 			if (_OTHERQ(q)->q_next == NULL)
   1025     0    stevel 				freemsg(bp);
   1026     0    stevel 			else {
   1027     0    stevel 				mutex_exit(&stp->sd_lock);
   1028     0    stevel 				qreply(q, bp);
   1029     0    stevel 				mutex_enter(&stp->sd_lock);
   1030     0    stevel 			}
   1031     0    stevel 		}
   1032     0    stevel 		ASSERT(MUTEX_HELD(&stp->sd_lock));
   1033     0    stevel 		if (error == 0 || error == EWOULDBLOCK) {
   1034     0    stevel 			if ((bp = uiod.d_mp) != NULL) {
   1035     0    stevel 				*errorp = 0;
   1036     0    stevel 				ASSERT(MUTEX_HELD(&stp->sd_lock));
   1037     0    stevel 				return (bp);
   1038     0    stevel 			}
   1039     0    stevel 			error = 0;
   1040     0    stevel 		} else if (error == EINVAL) {
   1041     0    stevel 			/*
   1042     0    stevel 			 * The stream plumbing must have
   1043     0    stevel 			 * changed while we were away, so
   1044     0    stevel 			 * just turn off rwnext()s.
   1045     0    stevel 			 */
   1046     0    stevel 			error = 0;
   1047     0    stevel 		} else if (error == EBUSY) {
   1048     0    stevel 			/*
   1049     0    stevel 			 * The module might have data in transit using putnext
   1050     0    stevel 			 * Fall back on waiting + getq.
   1051     0    stevel 			 */
   1052     0    stevel 			error = 0;
   1053     0    stevel 		} else {
   1054     0    stevel 			*errorp = error;
   1055     0    stevel 			ASSERT(MUTEX_HELD(&stp->sd_lock));
   1056     0    stevel 			return (NULL);
   1057     0    stevel 		}
   1058     0    stevel 		/*
   1059     0    stevel 		 * Try a getq in case a rwnext() generated mblk
   1060     0    stevel 		 * has bubbled up via strrput().
   1061     0    stevel 		 */
   1062     0    stevel 	}
   1063     0    stevel 	*errorp = 0;
   1064     0    stevel 	ASSERT(MUTEX_HELD(&stp->sd_lock));
   1065  6769   ja97890 
   1066  9491    Anders 	/*
   1067  9491    Anders 	 * If we have a valid uio, try and use this as a guide for how
   1068  9491    Anders 	 * many bytes to retrieve from the queue via getq_noenab().
   1069  9491    Anders 	 * Doing this can avoid unneccesary counting of overlong
   1070  9491    Anders 	 * messages in putback(). We currently only do this for sockets
   1071  9491    Anders 	 * and only if there is no sd_rputdatafunc hook.
   1072  9491    Anders 	 *
   1073  9491    Anders 	 * The sd_rputdatafunc hook transforms the entire message
   1074  9491    Anders 	 * before any bytes in it can be given to a client. So, rbytes
   1075  9491    Anders 	 * must be 0 if there is a hook.
   1076  9491    Anders 	 */
   1077  9491    Anders 	if ((uiop != NULL) && (stp->sd_vnode->v_type == VSOCK) &&
   1078  9491    Anders 	    (stp->sd_rputdatafunc == NULL))
   1079  9491    Anders 		rbytes = uiop->uio_resid;
   1080  9491    Anders 
   1081  9491    Anders 	return (getq_noenab(q, rbytes));
   1082     0    stevel }
   1083     0    stevel 
   1084     0    stevel /*
   1085     0    stevel  * Copy out the message pointed to by `bp' into the uio pointed to by `uiop'.
   1086     0    stevel  * If the message does not fit in the uio the remainder of it is returned;
   1087     0    stevel  * otherwise NULL is returned.  Any embedded zero-length mblk_t's are
   1088     0    stevel  * consumed, even if uio_resid reaches zero.  On error, `*errorp' is set to
   1089     0    stevel  * the error code, the message is consumed, and NULL is returned.
   1090     0    stevel  */
   1091     0    stevel static mblk_t *
   1092     0    stevel struiocopyout(mblk_t *bp, struct uio *uiop, int *errorp)
   1093     0    stevel {
   1094     0    stevel 	int error;
   1095     0    stevel 	ptrdiff_t n;
   1096     0    stevel 	mblk_t *nbp;
   1097     0    stevel 
   1098     0    stevel 	ASSERT(bp->b_wptr >= bp->b_rptr);
   1099     0    stevel 
   1100     0    stevel 	do {
   1101     0    stevel 		if ((n = MIN(uiop->uio_resid, MBLKL(bp))) != 0) {
   1102     0    stevel 			ASSERT(n > 0);
   1103     0    stevel 
   1104     0    stevel 			error = uiomove(bp->b_rptr, n, UIO_READ, uiop);
   1105     0    stevel 			if (error != 0) {
   1106     0    stevel 				freemsg(bp);
   1107     0    stevel 				*errorp = error;
   1108     0    stevel 				return (NULL);
   1109     0    stevel 			}
   1110     0    stevel 		}
   1111     0    stevel 
   1112     0    stevel 		bp->b_rptr += n;
   1113     0    stevel 		while (bp != NULL && (bp->b_rptr >= bp->b_wptr)) {
   1114     0    stevel 			nbp = bp;
   1115     0    stevel 			bp = bp->b_cont;
   1116     0    stevel 			freeb(nbp);
   1117     0    stevel 		}
   1118     0    stevel 	} while (bp != NULL && uiop->uio_resid > 0);
   1119     0    stevel 
   1120     0    stevel 	*errorp = 0;
   1121     0    stevel 	return (bp);
   1122     0    stevel }
   1123     0    stevel 
   1124     0    stevel /*
   1125     0    stevel  * Read a stream according to the mode flags in sd_flag:
   1126     0    stevel  *
   1127     0    stevel  * (default mode)		- Byte stream, msg boundaries are ignored
   1128     0    stevel  * RD_MSGDIS (msg discard)	- Read on msg boundaries and throw away
   1129     0    stevel  *				any data remaining in msg
   1130     0    stevel  * RD_MSGNODIS (msg non-discard) - Read on msg boundaries and put back
   1131     0    stevel  *				any remaining data on head of read queue
   1132     0    stevel  *
   1133     0    stevel  * Consume readable messages on the front of the queue until
   1134     0    stevel  * ttolwp(curthread)->lwp_count
   1135     0    stevel  * is satisfied, the readable messages are exhausted, or a message
   1136     0    stevel  * boundary is reached in a message mode.  If no data was read and
   1137     0    stevel  * the stream was not opened with the NDELAY flag, block until data arrives.
   1138     0    stevel  * Otherwise return the data read and update the count.
   1139     0    stevel  *
   1140     0    stevel  * In default mode a 0 length message signifies end-of-file and terminates
   1141     0    stevel  * a read in progress.  The 0 length message is removed from the queue
   1142     0    stevel  * only if it is the only message read (no data is read).
   1143     0    stevel  *
   1144     0    stevel  * An attempt to read an M_PROTO or M_PCPROTO message results in an
   1145     0    stevel  * EBADMSG error return, unless either RD_PROTDAT or RD_PROTDIS are set.
   1146     0    stevel  * If RD_PROTDAT is set, M_PROTO and M_PCPROTO messages are read as data.
   1147     0    stevel  * If RD_PROTDIS is set, the M_PROTO and M_PCPROTO parts of the message
   1148     0    stevel  * are unlinked from and M_DATA blocks in the message, the protos are
   1149     0    stevel  * thrown away, and the data is read.
   1150     0    stevel  */
   1151     0    stevel /* ARGSUSED */
   1152     0    stevel int
   1153     0    stevel strread(struct vnode *vp, struct uio *uiop, cred_t *crp)
   1154     0    stevel {
   1155     0    stevel 	struct stdata *stp;
   1156     0    stevel 	mblk_t *bp, *nbp;
   1157     0    stevel 	queue_t *q;
   1158     0    stevel 	int error = 0;
   1159     0    stevel 	uint_t old_sd_flag;
   1160     0    stevel 	int first;
   1161     0    stevel 	char rflg;
   1162     0    stevel 	uint_t mark;		/* Contains MSG*MARK and _LASTMARK */
   1163     0    stevel #define	_LASTMARK	0x8000	/* Distinct from MSG*MARK */
   1164     0    stevel 	short delim;
   1165     0    stevel 	unsigned char pri = 0;
   1166     0    stevel 	char waitflag;
   1167     0    stevel 	unsigned char type;
   1168     0    stevel 
   1169     0    stevel 	TRACE_1(TR_FAC_STREAMS_FR,
   1170  5753       gww 	    TR_STRREAD_ENTER, "strread:%p", vp);
   1171     0    stevel 	ASSERT(vp->v_stream);
   1172     0    stevel 	stp = vp->v_stream;
   1173     0    stevel 
   1174  2712   nn35248 	mutex_enter(&stp->sd_lock);
   1175  2712   nn35248 
   1176  2712   nn35248 	if ((error = i_straccess(stp, JCREAD)) != 0) {
   1177  2712   nn35248 		mutex_exit(&stp->sd_lock);
   1178  2712   nn35248 		return (error);
   1179  2712   nn35248 	}
   1180  2712   nn35248 
   1181     0    stevel 	if (stp->sd_flag & (STRDERR|STPLEX)) {
   1182     0    stevel 		error = strgeterr(stp, STRDERR|STPLEX, 0);
   1183     0    stevel 		if (error != 0) {
   1184     0    stevel 			mutex_exit(&stp->sd_lock);
   1185     0    stevel 			return (error);
   1186     0    stevel 		}
   1187     0    stevel 	}
   1188     0    stevel 
   1189     0    stevel 	/*
   1190     0    stevel 	 * Loop terminates when uiop->uio_resid == 0.
   1191     0    stevel 	 */
   1192     0    stevel 	rflg = 0;
   1193     0    stevel 	waitflag = READWAIT;
   1194     0    stevel 	q = _RD(stp->sd_wrq);
   1195     0    stevel 	for (;;) {
   1196     0    stevel 		ASSERT(MUTEX_HELD(&stp->sd_lock));
   1197     0    stevel 		old_sd_flag = stp->sd_flag;
   1198     0    stevel 		mark = 0;
   1199     0    stevel 		delim = 0;
   1200     0    stevel 		first = 1;
   1201     0    stevel 		while ((bp = strget(stp, q, uiop, first, &error)) == NULL) {
   1202     0    stevel 			int done = 0;
   1203     0    stevel 
   1204     0    stevel 			ASSERT(MUTEX_HELD(&stp->sd_lock));
   1205     0    stevel 
   1206     0    stevel 			if (error != 0)
   1207     0    stevel 				goto oops;
   1208     0    stevel 
   1209     0    stevel 			if (stp->sd_flag & (STRHUP|STREOF)) {
   1210     0    stevel 				goto oops;
   1211     0    stevel 			}
   1212     0    stevel 			if (rflg && !(stp->sd_flag & STRDELIM)) {
   1213     0    stevel 				goto oops;
   1214     0    stevel 			}
   1215     0    stevel 			/*
   1216     0    stevel 			 * If a read(fd,buf,0) has been done, there is no
   1217     0    stevel 			 * need to sleep. We always have zero bytes to
   1218     0    stevel 			 * return.
   1219     0    stevel 			 */
   1220     0    stevel 			if (uiop->uio_resid == 0) {
   1221     0    stevel 				goto oops;
   1222     0    stevel 			}
   1223     0    stevel 
   1224     0    stevel 			qbackenable(q, 0);
   1225     0    stevel 
   1226     0    stevel 			TRACE_3(TR_FAC_STREAMS_FR, TR_STRREAD_WAIT,
   1227  5753       gww 			    "strread calls strwaitq:%p, %p, %p",
   1228  5753       gww 			    vp, uiop, crp);
   1229     0    stevel 			if ((error = strwaitq(stp, waitflag, uiop->uio_resid,
   1230     0    stevel 			    uiop->uio_fmode, -1, &done)) != 0 || done) {
   1231     0    stevel 				TRACE_3(TR_FAC_STREAMS_FR, TR_STRREAD_DONE,
   1232  5753       gww 				    "strread error or done:%p, %p, %p",
   1233  5753       gww 				    vp, uiop, crp);
   1234     0    stevel 				if ((uiop->uio_fmode & FNDELAY) &&
   1235     0    stevel 				    (stp->sd_flag & OLDNDELAY) &&
   1236     0    stevel 				    (error == EAGAIN))
   1237     0    stevel 					error = 0;
   1238     0    stevel 				goto oops;
   1239     0    stevel 			}
   1240     0    stevel 			TRACE_3(TR_FAC_STREAMS_FR, TR_STRREAD_AWAKE,
   1241  5753       gww 			    "strread awakes:%p, %p, %p", vp, uiop, crp);
   1242  2712   nn35248 			if ((error = i_straccess(stp, JCREAD)) != 0) {
   1243  2712   nn35248 				goto oops;
   1244     0    stevel 			}
   1245     0    stevel 			first = 0;
   1246     0    stevel 		}
   1247  6707    brutus 
   1248     0    stevel 		ASSERT(MUTEX_HELD(&stp->sd_lock));
   1249     0    stevel 		ASSERT(bp);
   1250     0    stevel 		pri = bp->b_band;
   1251     0    stevel 		/*
   1252     0    stevel 		 * Extract any mark information. If the message is not
   1253     0    stevel 		 * completely consumed this information will be put in the mblk
   1254     0    stevel 		 * that is putback.
   1255     0    stevel 		 * If MSGMARKNEXT is set and the message is completely consumed
   1256     0    stevel 		 * the STRATMARK flag will be set below. Likewise, if
   1257     0    stevel 		 * MSGNOTMARKNEXT is set and the message is
   1258     0    stevel 		 * completely consumed STRNOTATMARK will be set.
   1259     0    stevel 		 *
   1260     0    stevel 		 * For some unknown reason strread only breaks the read at the
   1261     0    stevel 		 * last mark.
   1262     0    stevel 		 */
   1263     0    stevel 		mark = bp->b_flag & (MSGMARK | MSGMARKNEXT | MSGNOTMARKNEXT);
   1264     0    stevel 		ASSERT((mark & (MSGMARKNEXT|MSGNOTMARKNEXT)) !=
   1265  5753       gww 		    (MSGMARKNEXT|MSGNOTMARKNEXT));
   1266     0    stevel 		if (mark != 0 && bp == stp->sd_mark) {
   1267     0    stevel 			if (rflg) {
   1268     0    stevel 				putback(stp, q, bp, pri);
   1269     0    stevel 				goto oops;
   1270     0    stevel 			}
   1271     0    stevel 			mark |= _LASTMARK;
   1272     0    stevel 			stp->sd_mark = NULL;
   1273     0    stevel 		}
   1274     0    stevel 		if ((stp->sd_flag & STRDELIM) && (bp->b_flag & MSGDELIM))
   1275     0    stevel 			delim = 1;
   1276     0    stevel 		mutex_exit(&stp->sd_lock);
   1277     0    stevel 
   1278     0    stevel 		if (STREAM_NEEDSERVICE(stp))
   1279     0    stevel 			stream_runservice(stp);
   1280     0    stevel 
   1281     0    stevel 		type = bp->b_datap->db_type;
   1282     0    stevel 
   1283     0    stevel 		switch (type) {
   1284     0    stevel 
   1285     0    stevel 		case M_DATA:
   1286     0    stevel ismdata:
   1287     0    stevel 			if (msgnodata(bp)) {
   1288     0    stevel 				if (mark || delim) {
   1289     0    stevel 					freemsg(bp);
   1290     0    stevel 				} else if (rflg) {
   1291     0    stevel 
   1292     0    stevel 					/*
   1293     0    stevel 					 * If already read data put zero
   1294     0    stevel 					 * length message back on queue else
   1295     0    stevel 					 * free msg and return 0.
   1296     0    stevel 					 */
   1297     0    stevel 					bp->b_band = pri;
   1298     0    stevel 					mutex_enter(&stp->sd_lock);
   1299     0    stevel 					putback(stp, q, bp, pri);
   1300     0    stevel 					mutex_exit(&stp->sd_lock);
   1301     0    stevel 				} else {
   1302     0    stevel 					freemsg(bp);
   1303     0    stevel 				}
   1304     0    stevel 				error =  0;
   1305     0    stevel 				goto oops1;
   1306     0    stevel 			}
   1307     0    stevel 
   1308     0    stevel 			rflg = 1;
   1309     0    stevel 			waitflag |= NOINTR;
   1310     0    stevel 			bp = struiocopyout(bp, uiop, &error);
   1311     0    stevel 			if (error != 0)
   1312     0    stevel 				goto oops1;
   1313     0    stevel 
   1314     0    stevel 			mutex_enter(&stp->sd_lock);
   1315     0    stevel 			if (bp) {
   1316     0    stevel 				/*
   1317     0    stevel 				 * Have remaining data in message.
   1318     0    stevel 				 * Free msg if in discard mode.
   1319     0    stevel 				 */
   1320     0    stevel 				if (stp->sd_read_opt & RD_MSGDIS) {
   1321     0    stevel 					freemsg(bp);
   1322     0    stevel 				} else {
   1323     0    stevel 					bp->b_band = pri;
   1324     0    stevel 					if ((mark & _LASTMARK) &&
   1325     0    stevel 					    (stp->sd_mark == NULL))
   1326     0    stevel 						stp->sd_mark = bp;
   1327     0    stevel 					bp->b_flag |= mark & ~_LASTMARK;
   1328     0    stevel 					if (delim)
   1329     0    stevel 						bp->b_flag |= MSGDELIM;
   1330     0    stevel 					if (msgnodata(bp))
   1331     0    stevel 						freemsg(bp);
   1332     0    stevel 					else
   1333     0    stevel 						putback(stp, q, bp, pri);
   1334     0    stevel 				}
   1335     0    stevel 			} else {
   1336     0    stevel 				/*
   1337     0    stevel 				 * Consumed the complete message.
   1338     0    stevel 				 * Move the MSG*MARKNEXT information
   1339     0    stevel 				 * to the stream head just in case
   1340     0    stevel 				 * the read queue becomes empty.
   1341     0    stevel 				 *
   1342     0    stevel 				 * If the stream head was at the mark
   1343     0    stevel 				 * (STRATMARK) before we dropped sd_lock above
   1344     0    stevel 				 * and some data was consumed then we have
   1345     0    stevel 				 * moved past the mark thus STRATMARK is
   1346     0    stevel 				 * cleared. However, if a message arrived in
   1347     0    stevel 				 * strrput during the copyout above causing
   1348     0    stevel 				 * STRATMARK to be set we can not clear that
   1349     0    stevel 				 * flag.
   1350     0    stevel 				 */
   1351     0    stevel 				if (mark &
   1352     0    stevel 				    (MSGMARKNEXT|MSGNOTMARKNEXT|MSGMARK)) {
   1353     0    stevel 					if (mark & MSGMARKNEXT) {
   1354     0    stevel 						stp->sd_flag &= ~STRNOTATMARK;
   1355     0    stevel 						stp->sd_flag |= STRATMARK;
   1356     0    stevel 					} else if (mark & MSGNOTMARKNEXT) {
   1357     0    stevel 						stp->sd_flag &= ~STRATMARK;
   1358     0    stevel 						stp->sd_flag |= STRNOTATMARK;
   1359     0    stevel 					} else {
   1360     0    stevel 						stp->sd_flag &=
   1361     0    stevel 						    ~(STRATMARK|STRNOTATMARK);
   1362     0    stevel 					}
   1363     0    stevel 				} else if (rflg && (old_sd_flag & STRATMARK)) {
   1364     0    stevel 					stp->sd_flag &= ~STRATMARK;
   1365     0    stevel 				}
   1366     0    stevel 			}
   1367     0    stevel 
   1368     0    stevel 			/*
   1369     0    stevel 			 * Check for signal messages at the front of the read
   1370     0    stevel 			 * queue and generate the signal(s) if appropriate.
   1371     0    stevel 			 * The only signal that can be on queue is M_SIG at
   1372     0    stevel 			 * this point.
   1373     0    stevel 			 */
   1374     0    stevel 			while ((((bp = q->q_first)) != NULL) &&
   1375  5753       gww 			    (bp->b_datap->db_type == M_SIG)) {
   1376  6769   ja97890 				bp = getq_noenab(q, 0);
   1377     0    stevel 				/*
   1378     0    stevel 				 * sd_lock is held so the content of the
   1379     0    stevel 				 * read queue can not change.
   1380     0    stevel 				 */
   1381  8752     Peter 				ASSERT(bp != NULL && DB_TYPE(bp) == M_SIG);
   1382  8752     Peter 				strsignal_nolock(stp, *bp->b_rptr, bp->b_band);
   1383     0    stevel 				mutex_exit(&stp->sd_lock);
   1384     0    stevel 				freemsg(bp);
   1385     0    stevel 				if (STREAM_NEEDSERVICE(stp))
   1386     0    stevel 					stream_runservice(stp);
   1387     0    stevel 				mutex_enter(&stp->sd_lock);
   1388     0    stevel 			}
   1389     0    stevel 
   1390     0    stevel 			if ((uiop->uio_resid == 0) || (mark & _LASTMARK) ||
   1391     0    stevel 			    delim ||
   1392     0    stevel 			    (stp->sd_read_opt & (RD_MSGDIS|RD_MSGNODIS))) {
   1393     0    stevel 				goto oops;
   1394     0    stevel 			}
   1395     0    stevel 			continue;
   1396     0    stevel 
   1397     0    stevel 		case M_SIG:
   1398     0    stevel 			strsignal(stp, *bp->b_rptr, (int32_t)bp->b_band);
   1399     0    stevel 			freemsg(bp);
   1400     0    stevel 			mutex_enter(&stp->sd_lock);
   1401     0    stevel 			continue;
   1402     0    stevel 
   1403     0    stevel 		case M_PROTO:
   1404     0    stevel 		case M_PCPROTO:
   1405     0    stevel 			/*
   1406     0    stevel 			 * Only data messages are readable.
   1407     0    stevel 			 * Any others generate an error, unless
   1408     0    stevel 			 * RD_PROTDIS or RD_PROTDAT is set.
   1409     0    stevel 			 */
   1410     0    stevel 			if (stp->sd_read_opt & RD_PROTDAT) {
   1411     0    stevel 				for (nbp = bp; nbp; nbp = nbp->b_next) {
   1412  5753       gww 					if ((nbp->b_datap->db_type ==
   1413  5753       gww 					    M_PROTO) ||
   1414  5753       gww 					    (nbp->b_datap->db_type ==
   1415  5753       gww 					    M_PCPROTO)) {
   1416  5753       gww 						nbp->b_datap->db_type = M_DATA;
   1417  5753       gww 					} else {
   1418  5753       gww 						break;
   1419  5753       gww 					}
   1420     0    stevel 				}
   1421     0    stevel 				/*
   1422     0    stevel 				 * clear stream head hi pri flag based on
   1423     0    stevel 				 * first message
   1424     0    stevel 				 */
   1425     0    stevel 				if (type == M_PCPROTO) {
   1426     0    stevel 					mutex_enter(&stp->sd_lock);
   1427     0    stevel 					stp->sd_flag &= ~STRPRI;
   1428     0    stevel 					mutex_exit(&stp->sd_lock);
   1429     0    stevel 				}
   1430     0    stevel 				goto ismdata;
   1431     0    stevel 			} else if (stp->sd_read_opt & RD_PROTDIS) {
   1432     0    stevel 				/*
   1433     0    stevel 				 * discard non-data messages
   1434     0    stevel 				 */
   1435     0    stevel 				while (bp &&
   1436     0    stevel 				    ((bp->b_datap->db_type == M_PROTO) ||
   1437     0    stevel 				    (bp->b_datap->db_type == M_PCPROTO))) {
   1438     0    stevel 					nbp = unlinkb(bp);
   1439     0    stevel 					freeb(bp);
   1440     0    stevel 					bp = nbp;
   1441     0    stevel 				}
   1442     0    stevel 				/*
   1443     0    stevel 				 * clear stream head hi pri flag based on
   1444     0    stevel 				 * first message
   1445     0    stevel 				 */
   1446     0    stevel 				if (type == M_PCPROTO) {
   1447     0    stevel 					mutex_enter(&stp->sd_lock);
   1448     0    stevel 					stp->sd_flag &= ~STRPRI;
   1449     0    stevel 					mutex_exit(&stp->sd_lock);
   1450     0    stevel 				}
   1451     0    stevel 				if (bp) {
   1452     0    stevel 					bp->b_band = pri;
   1453     0    stevel 					goto ismdata;
   1454     0    stevel 				} else {
   1455     0    stevel 					break;
   1456     0    stevel 				}
   1457     0    stevel 			}
   1458     0    stevel 			/* FALLTHRU */
   1459     0    stevel 		case M_PASSFP:
   1460     0    stevel 			if ((bp->b_datap->db_type == M_PASSFP) &&
   1461     0    stevel 			    (stp->sd_read_opt & RD_PROTDIS)) {
   1462     0    stevel 				freemsg(bp);
   1463     0    stevel 				break;
   1464     0    stevel 			}
   1465     0    stevel 			mutex_enter(&stp->sd_lock);
   1466     0    stevel 			putback(stp, q, bp, pri);
   1467     0    stevel 			mutex_exit(&stp->sd_lock);
   1468     0    stevel 			if (rflg == 0)
   1469     0    stevel 				error = EBADMSG;
   1470     0    stevel 			goto oops1;
   1471     0    stevel 
   1472     0    stevel 		default:
   1473     0    stevel 			/*
   1474     0    stevel 			 * Garbage on stream head read queue.
   1475     0    stevel 			 */
   1476     0    stevel 			cmn_err(CE_WARN, "bad %x found at stream head\n",
   1477  5753       gww 			    bp->b_datap->db_type);
   1478     0    stevel 			freemsg(bp);
   1479     0    stevel 			goto oops1;
   1480     0    stevel 		}
   1481     0    stevel 		mutex_enter(&stp->sd_lock);
   1482     0    stevel 	}
   1483     0    stevel oops:
   1484     0    stevel 	mutex_exit(&stp->sd_lock);
   1485     0    stevel oops1:
   1486     0    stevel 	qbackenable(q, pri);
   1487     0    stevel 	return (error);
   1488     0    stevel #undef	_LASTMARK
   1489     0    stevel }
   1490     0    stevel 
   1491     0    stevel /*
   1492     0    stevel  * Default processing of M_PROTO/M_PCPROTO messages.
   1493     0    stevel  * Determine which wakeups and signals are needed.
   1494     0    stevel  * This can be replaced by a user-specified procedure for kernel users
   1495     0    stevel  * of STREAMS.
   1496     0    stevel  */
   1497     0    stevel /* ARGSUSED */
   1498     0    stevel mblk_t *
   1499     0    stevel strrput_proto(vnode_t *vp, mblk_t *mp,
   1500     0    stevel     strwakeup_t *wakeups, strsigset_t *firstmsgsigs,
   1501     0    stevel     strsigset_t *allmsgsigs, strpollset_t *pollwakeups)
   1502     0    stevel {
   1503     0    stevel 	*wakeups = RSLEEP;
   1504     0    stevel 	*allmsgsigs = 0;
   1505     0    stevel 
   1506     0    stevel 	switch (mp->b_datap->db_type) {
   1507     0    stevel 	case M_PROTO:
   1508     0    stevel 		if (mp->b_band == 0) {
   1509     0    stevel 			*firstmsgsigs = S_INPUT | S_RDNORM;
   1510     0    stevel 			*pollwakeups = POLLIN | POLLRDNORM;
   1511     0    stevel 		} else {
   1512     0    stevel 			*firstmsgsigs = S_INPUT | S_RDBAND;
   1513     0    stevel 			*pollwakeups = POLLIN | POLLRDBAND;
   1514     0    stevel 		}
   1515     0    stevel 		break;
   1516     0    stevel 	case M_PCPROTO:
   1517     0    stevel 		*firstmsgsigs = S_HIPRI;
   1518     0    stevel 		*pollwakeups = POLLPRI;
   1519     0    stevel 		break;
   1520     0    stevel 	}
   1521     0    stevel 	return (mp);
   1522     0    stevel }
   1523     0    stevel 
   1524     0    stevel /*
   1525     0    stevel  * Default processing of everything but M_DATA, M_PROTO, M_PCPROTO and
   1526     0    stevel  * M_PASSFP messages.
   1527     0    stevel  * Determine which wakeups and signals are needed.
   1528     0    stevel  * This can be replaced by a user-specified procedure for kernel users
   1529     0    stevel  * of STREAMS.
   1530     0    stevel  */
   1531     0    stevel /* ARGSUSED */
   1532     0    stevel mblk_t *
   1533     0    stevel strrput_misc(vnode_t *vp, mblk_t *mp,
   1534     0    stevel     strwakeup_t *wakeups, strsigset_t *firstmsgsigs,
   1535     0    stevel     strsigset_t *allmsgsigs, strpollset_t *pollwakeups)
   1536     0    stevel {
   1537     0    stevel 	*wakeups = 0;
   1538     0    stevel 	*firstmsgsigs = 0;
   1539     0    stevel 	*allmsgsigs = 0;
   1540     0    stevel 	*pollwakeups = 0;
   1541     0    stevel 	return (mp);
   1542     0    stevel }
   1543     0    stevel 
   1544     0    stevel /*
   1545     0    stevel  * Stream read put procedure.  Called from downstream driver/module
   1546     0    stevel  * with messages for the stream head.  Data, protocol, and in-stream
   1547     0    stevel  * signal messages are placed on the queue, others are handled directly.
   1548     0    stevel  */
   1549     0    stevel int
   1550     0    stevel strrput(queue_t *q, mblk_t *bp)
   1551     0    stevel {
   1552     0    stevel 	struct stdata	*stp;
   1553     0    stevel 	ulong_t		rput_opt;
   1554     0    stevel 	strwakeup_t	wakeups;
   1555     0    stevel 	strsigset_t	firstmsgsigs;	/* Signals if first message on queue */
   1556     0    stevel 	strsigset_t	allmsgsigs;	/* Signals for all messages */
   1557     0    stevel 	strsigset_t	signals;	/* Signals events to generate */
   1558     0    stevel 	strpollset_t	pollwakeups;
   1559     0    stevel 	mblk_t		*nextbp;
   1560     0    stevel 	uchar_t		band = 0;
   1561     0    stevel 	int		hipri_sig;
   1562     0    stevel 
   1563     0    stevel 	stp = (struct stdata *)q->q_ptr;
   1564     0    stevel 	/*
   1565     0    stevel 	 * Use rput_opt for optimized access to the SR_ flags except
   1566     0    stevel 	 * SR_POLLIN. That flag has to be checked under sd_lock since it
   1567     0    stevel 	 * is modified by strpoll().
   1568     0    stevel 	 */
   1569     0    stevel 	rput_opt = stp->sd_rput_opt;
   1570     0    stevel 
   1571     0    stevel 	ASSERT(qclaimed(q));
   1572     0    stevel 	TRACE_2(TR_FAC_STREAMS_FR, TR_STRRPUT_ENTER,
   1573  5753       gww 	    "strrput called with message type:q %p bp %p", q, bp);
   1574     0    stevel 
   1575     0    stevel 	/*
   1576     0    stevel 	 * Perform initial processing and pass to the parameterized functions.
   1577     0    stevel 	 */
   1578     0    stevel 	ASSERT(bp->b_next == NULL);
   1579     0    stevel 
   1580     0    stevel 	switch (bp->b_datap->db_type) {
   1581     0    stevel 	case M_DATA:
   1582     0    stevel 		/*
   1583     0    stevel 		 * sockfs is the only consumer of STREOF and when it is set,
   1584     0    stevel 		 * it implies that the receiver is not interested in receiving
   1585     0    stevel 		 * any more data, hence the mblk is freed to prevent unnecessary
   1586     0    stevel 		 * message queueing at the stream head.
   1587     0    stevel 		 */
   1588     0    stevel 		if (stp->sd_flag == STREOF) {
   1589     0    stevel 			freemsg(bp);
   1590     0    stevel 			return (0);
   1591     0    stevel 		}
   1592     0    stevel 		if ((rput_opt & SR_IGN_ZEROLEN) &&
   1593     0    stevel 		    bp->b_rptr == bp->b_wptr && msgnodata(bp)) {
   1594     0    stevel 			/*
   1595     0    stevel 			 * Ignore zero-length M_DATA messages. These might be
   1596     0    stevel 			 * generated by some transports.
   1597     0    stevel 			 * The zero-length M_DATA messages, even if they
   1598     0    stevel 			 * are ignored, should effect the atmark tracking and
   1599     0    stevel 			 * should wake up a thread sleeping in strwaitmark.
   1600     0    stevel 			 */
   1601     0    stevel 			mutex_enter(&stp->sd_lock);
   1602     0    stevel 			if (bp->b_flag & MSGMARKNEXT) {
   1603     0    stevel 				/*
   1604     0    stevel 				 * Record the position of the mark either
   1605     0    stevel 				 * in q_last or in STRATMARK.
   1606     0    stevel 				 */
   1607     0    stevel 				if (q->q_last != NULL) {
   1608     0    stevel 					q->q_last->b_flag &= ~MSGNOTMARKNEXT;
   1609     0    stevel 					q->q_last->b_flag |= MSGMARKNEXT;
   1610     0    stevel 				} else {
   1611     0    stevel 					stp->sd_flag &= ~STRNOTATMARK;
   1612     0    stevel 					stp->sd_flag |= STRATMARK;
   1613     0    stevel 				}
   1614     0    stevel 			} else if (bp->b_flag & MSGNOTMARKNEXT) {
   1615     0    stevel 				/*
   1616     0    stevel 				 * Record that this is not the position of
   1617     0    stevel 				 * the mark either in q_last or in
   1618     0    stevel 				 * STRNOTATMARK.
   1619     0    stevel 				 */
   1620     0    stevel 				if (q->q_last != NULL) {
   1621     0    stevel 					q->q_last->b_flag &= ~MSGMARKNEXT;
   1622     0    stevel 					q->q_last->b_flag |= MSGNOTMARKNEXT;
   1623     0    stevel 				} else {
   1624     0    stevel 					stp->sd_flag &= ~STRATMARK;
   1625     0    stevel 					stp->sd_flag |= STRNOTATMARK;
   1626     0    stevel 				}
   1627     0    stevel 			}
   1628     0    stevel 			if (stp->sd_flag & RSLEEP) {
   1629     0    stevel 				stp->sd_flag &= ~RSLEEP;
   1630     0    stevel 				cv_broadcast(&q->q_wait);
   1631     0    stevel 			}
   1632     0    stevel 			mutex_exit(&stp->sd_lock);
   1633     0    stevel 			freemsg(bp);
   1634     0    stevel 			return (0);
   1635     0    stevel 		}
   1636     0    stevel 		wakeups = RSLEEP;
   1637     0    stevel 		if (bp->b_band == 0) {
   1638     0    stevel 			firstmsgsigs = S_INPUT | S_RDNORM;
   1639     0    stevel 			pollwakeups = POLLIN | POLLRDNORM;
   1640     0    stevel 		} else {
   1641     0    stevel 			firstmsgsigs = S_INPUT | S_RDBAND;
   1642     0    stevel 			pollwakeups = POLLIN | POLLRDBAND;
   1643     0    stevel 		}
   1644     0    stevel 		if (rput_opt & SR_SIGALLDATA)
   1645     0    stevel 			allmsgsigs = firstmsgsigs;
   1646     0    stevel 		else
   1647     0    stevel 			allmsgsigs = 0;
   1648     0    stevel 
   1649     0    stevel 		mutex_enter(&stp->sd_lock);
   1650     0    stevel 		if ((rput_opt & SR_CONSOL_DATA) &&
   1651  4683   ja97890 		    (q->q_last != NULL) &&
   1652     0    stevel 		    (bp->b_flag & (MSGMARK|MSGDELIM)) == 0) {
   1653     0    stevel 			/*
   1654  4683   ja97890 			 * Consolidate an M_DATA message onto an M_DATA,
   1655     0    stevel 			 * M_PROTO, or M_PCPROTO by merging it with q_last.
   1656     0    stevel 			 * The consolidation does not take place if
   1657     0    stevel 			 * the old message is marked with either of the
   1658     0    stevel 			 * marks or the delim flag or if the new
   1659     0    stevel 			 * message is marked with MSGMARK. The MSGMARK
   1660     0    stevel 			 * check is needed to handle the odd semantics of
   1661     0    stevel 			 * MSGMARK where essentially the whole message
   1662     0    stevel 			 * is to be treated as marked.
   1663     0    stevel 			 * Carry any MSGMARKNEXT  and MSGNOTMARKNEXT from the
   1664     0    stevel 			 * new message to the front of the b_cont chain.
   1665     0    stevel 			 */
   1666  4683   ja97890 			mblk_t *lbp = q->q_last;
   1667  4683   ja97890 			unsigned char db_type = lbp->b_datap->db_type;
   1668  4683   ja97890 
   1669  4683   ja97890 			if ((db_type == M_DATA || db_type == M_PROTO ||
   1670  4683   ja97890 			    db_type == M_PCPROTO) &&
   1671  4683   ja97890 			    !(lbp->b_flag & (MSGDELIM|MSGMARK|MSGMARKNEXT))) {
   1672     0    stevel 				rmvq_noenab(q, lbp);
   1673     0    stevel 				/*
   1674     0    stevel 				 * The first message in the b_cont list
   1675     0    stevel 				 * tracks MSGMARKNEXT and MSGNOTMARKNEXT.
   1676     0    stevel 				 * We need to handle the case where we
   1677  4683   ja97890 				 * are appending:
   1678     0    stevel 				 *
   1679     0    stevel 				 * 1) a MSGMARKNEXT to a MSGNOTMARKNEXT.
   1680     0    stevel 				 * 2) a MSGMARKNEXT to a plain message.
   1681     0    stevel 				 * 3) a MSGNOTMARKNEXT to a plain message
   1682     0    stevel 				 * 4) a MSGNOTMARKNEXT to a MSGNOTMARKNEXT
   1683     0    stevel 				 *    message.
   1684     0    stevel 				 *
   1685     0    stevel 				 * Thus we never append a MSGMARKNEXT or
   1686     0    stevel 				 * MSGNOTMARKNEXT to a MSGMARKNEXT message.
   1687     0    stevel 				 */
   1688     0    stevel 				if (bp->b_flag & MSGMARKNEXT) {
   1689     0    stevel 					lbp->b_flag |= MSGMARKNEXT;
   1690     0    stevel 					lbp->b_flag &= ~MSGNOTMARKNEXT;
   1691     0    stevel 					bp->b_flag &= ~MSGMARKNEXT;
   1692     0    stevel 				} else if (bp->b_flag & MSGNOTMARKNEXT) {
   1693     0    stevel 					lbp->b_flag |= MSGNOTMARKNEXT;
   1694     0    stevel 					bp->b_flag &= ~MSGNOTMARKNEXT;
   1695     0    stevel 				}
   1696     0    stevel 
   1697     0    stevel 				linkb(lbp, bp);
   1698     0    stevel 				bp = lbp;
   1699     0    stevel 				/*
   1700     0    stevel 				 * The new message logically isn't the first
   1701     0    stevel 				 * even though the q_first check below thinks
   1702     0    stevel 				 * it is. Clear the firstmsgsigs to make it
   1703     0    stevel 				 * not appear to be first.
   1704     0    stevel 				 */
   1705     0    stevel 				firstmsgsigs = 0;
   1706     0    stevel 			}
   1707     0    stevel 		}
   1708     0    stevel 		break;
   1709     0    stevel 
   1710     0    stevel 	case M_PASSFP:
   1711     0    stevel 		wakeups = RSLEEP;
   1712     0    stevel 		allmsgsigs = 0;
   1713     0    stevel 		if (bp->b_band == 0) {
   1714     0    stevel 			firstmsgsigs = S_INPUT | S_RDNORM;
   1715     0    stevel 			pollwakeups = POLLIN | POLLRDNORM;
   1716     0    stevel 		} else {
   1717     0    stevel 			firstmsgsigs = S_INPUT | S_RDBAND;
   1718     0    stevel 			pollwakeups = POLLIN | POLLRDBAND;
   1719     0    stevel 		}
   1720     0    stevel 		mutex_enter(&stp->sd_lock);
   1721     0    stevel 		break;
   1722     0    stevel 
   1723     0    stevel 	case M_PROTO:
   1724     0    stevel 	case M_PCPROTO:
   1725     0    stevel 		ASSERT(stp->sd_rprotofunc != NULL);
   1726     0    stevel 		bp = (stp->sd_rprotofunc)(stp->sd_vnode, bp,
   1727  5753       gww 		    &wakeups, &firstmsgsigs, &allmsgsigs, &pollwakeups);
   1728     0    stevel #define	ALLSIG	(S_INPUT|S_HIPRI|S_OUTPUT|S_MSG|S_ERROR|S_HANGUP|S_RDNORM|\
   1729     0    stevel 		S_WRNORM|S_RDBAND|S_WRBAND|S_BANDURG)
   1730     0    stevel #define	ALLPOLL	(POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLWRNORM|POLLRDBAND|\
   1731     0    stevel 		POLLWRBAND)
   1732     0    stevel 
   1733     0    stevel 		ASSERT((wakeups & ~(RSLEEP|WSLEEP)) == 0);
   1734     0    stevel 		ASSERT((firstmsgsigs & ~ALLSIG) == 0);
   1735     0    stevel 		ASSERT((allmsgsigs & ~ALLSIG) == 0);
   1736     0    stevel 		ASSERT((pollwakeups & ~ALLPOLL) == 0);
   1737     0    stevel 
   1738     0    stevel 		mutex_enter(&stp->sd_lock);
   1739     0    stevel 		break;
   1740     0    stevel 
   1741     0    stevel 	default:
   1742     0    stevel 		ASSERT(stp->sd_rmiscfunc != NULL);
   1743     0    stevel 		bp = (stp->sd_rmiscfunc)(stp->sd_vnode, bp,
   1744  5753       gww 		    &wakeups, &firstmsgsigs, &allmsgsigs, &pollwakeups);
   1745     0    stevel 		ASSERT((wakeups & ~(RSLEEP|WSLEEP)) == 0);
   1746     0    stevel 		ASSERT((firstmsgsigs & ~ALLSIG) == 0);
   1747     0    stevel 		ASSERT((allmsgsigs & ~ALLSIG) == 0);
   1748     0    stevel 		ASSERT((pollwakeups & ~ALLPOLL) == 0);
   1749     0    stevel #undef	ALLSIG
   1750     0    stevel #undef	ALLPOLL
   1751     0    stevel 		mutex_enter(&stp->sd_lock);
   1752     0    stevel 		break;
   1753     0    stevel 	}
   1754     0    stevel 	ASSERT(MUTEX_HELD(&stp->sd_lock));
   1755     0    stevel 
   1756     0    stevel 	/* By default generate superset of signals */
   1757     0    stevel 	signals = (firstmsgsigs | allmsgsigs);
   1758     0    stevel 
   1759     0    stevel 	/*
   1760     0    stevel 	 * The  proto and misc functions can return multiple messages
   1761     0    stevel 	 * as a b_next chain. Such messages are processed separately.
   1762     0    stevel 	 */
   1763     0    stevel one_more:
   1764     0    stevel 	hipri_sig = 0;
   1765     0    stevel 	if (bp == NULL) {
   1766     0    stevel 		nextbp = NULL;
   1767     0    stevel 	} else {
   1768     0    stevel 		nextbp = bp->b_next;
   1769     0    stevel 		bp->b_next = NULL;
   1770     0    stevel 
   1771     0    stevel 		switch (bp->b_datap->db_type) {
   1772     0    stevel 		case M_PCPROTO:
   1773     0    stevel 			/*
   1774     0    stevel 			 * Only one priority protocol message is allowed at the
   1775     0    stevel 			 * stream head at a time.
   1776     0    stevel 			 */
   1777     0    stevel 			if (stp->sd_flag & STRPRI) {
   1778     0    stevel 				TRACE_0(TR_FAC_STREAMS_FR, TR_STRRPUT_PROTERR,
   1779     0    stevel 				    "M_PCPROTO already at head");
   1780     0    stevel 				freemsg(bp);
   1781     0    stevel 				mutex_exit(&stp->sd_lock);
   1782     0    stevel 				goto done;
   1783     0    stevel 			}
   1784     0    stevel 			stp->sd_flag |= STRPRI;
   1785     0    stevel 			hipri_sig = 1;
   1786     0    stevel 			/* FALLTHRU */
   1787     0    stevel 		case M_DATA:
   1788     0    stevel 		case M_PROTO:
   1789     0    stevel 		case M_PASSFP:
   1790     0    stevel 			band = bp->b_band;
   1791     0    stevel 			/*
   1792     0    stevel 			 * Marking doesn't work well when messages
   1793     0    stevel 			 * are marked in more than one band.  We only
   1794     0    stevel 			 * remember the last message received, even if
   1795     0    stevel 			 * it is placed on the queue ahead of other
   1796     0    stevel 			 * marked messages.
   1797     0    stevel 			 */
   1798     0    stevel 			if (bp->b_flag & MSGMARK)
   1799     0    stevel 				stp->sd_mark = bp;
   1800     0    stevel 			(void) putq(q, bp);
   1801     0    stevel 
   1802     0    stevel 			/*
   1803     0    stevel 			 * If message is a PCPROTO message, always use
   1804     0    stevel 			 * firstmsgsigs to determine if a signal should be
   1805     0    stevel 			 * sent as strrput is the only place to send
   1806     0    stevel 			 * signals for PCPROTO. Other messages are based on
   1807     0    stevel 			 * the STRGETINPROG flag. The flag determines if
   1808     0    stevel 			 * strrput or (k)strgetmsg will be responsible for
   1809     0    stevel 			 * sending the signals, in the firstmsgsigs case.
   1810     0    stevel 			 */
   1811     0    stevel 			if ((hipri_sig == 1) ||
   1812     0    stevel 			    (((stp->sd_flag & STRGETINPROG) == 0) &&
   1813     0    stevel 			    (q->q_first == bp)))
   1814     0    stevel 				signals = (firstmsgsigs | allmsgsigs);
   1815     0    stevel 			else
   1816     0    stevel 				signals = allmsgsigs;
   1817     0    stevel 			break;
   1818     0    stevel 
   1819     0    stevel 		default:
   1820     0    stevel 			mutex_exit(&stp->sd_lock);
   1821     0    stevel 			(void) strrput_nondata(q, bp);
   1822     0    stevel 			mutex_enter(&stp->sd_lock);
   1823     0    stevel 			break;
   1824     0    stevel 		}
   1825     0    stevel 	}
   1826     0    stevel 	ASSERT(MUTEX_HELD(&stp->sd_lock));
   1827     0    stevel 	/*
   1828     0    stevel 	 * Wake sleeping read/getmsg and cancel deferred wakeup
   1829     0    stevel 	 */
   1830     0    stevel 	if (wakeups & RSLEEP)
   1831     0    stevel 		stp->sd_wakeq &= ~RSLEEP;
   1832     0    stevel 
   1833     0    stevel 	wakeups &= stp->sd_flag;
   1834     0    stevel 	if (wakeups & RSLEEP) {
   1835     0    stevel 		stp->sd_flag &= ~RSLEEP;
   1836     0    stevel 		cv_broadcast(&q->q_wait);
   1837     0    stevel 	}
   1838     0    stevel 	if (wakeups & WSLEEP) {
   1839     0    stevel 		stp->sd_flag &= ~WSLEEP;
   1840     0    stevel 		cv_broadcast(&_WR(q)->q_wait);
   1841     0    stevel 	}
   1842     0    stevel 
   1843     0    stevel 	if (pollwakeups != 0) {
   1844     0    stevel 		if (pollwakeups == (POLLIN | POLLRDNORM)) {
   1845     0    stevel 			/*
   1846     0    stevel 			 * Can't use rput_opt since it was not
   1847     0    stevel 			 * read when sd_lock was held and SR_POLLIN is changed
   1848     0    stevel 			 * by strpoll() under sd_lock.
   1849     0    stevel 			 */
   1850     0    stevel 			if (!(stp->sd_rput_opt & SR_POLLIN))
   1851     0    stevel 				goto no_pollwake;
   1852     0    stevel 			stp->sd_rput_opt &= ~SR_POLLIN;
   1853     0    stevel 		}
   1854     0    stevel 		mutex_exit(&stp->sd_lock);
   1855     0    stevel 		pollwakeup(&stp->sd_pollist, pollwakeups);
   1856     0    stevel 		mutex_enter(&stp->sd_lock);
   1857     0    stevel 	}
   1858     0    stevel no_pollwake:
   1859     0    stevel 
   1860     0    stevel 	/*
   1861     0    stevel 	 * strsendsig can handle multiple signals with a
   1862     0    stevel 	 * single call.
   1863     0    stevel 	 */
   1864     0    stevel 	if (stp->sd_sigflags & signals)
   1865     0    stevel 		strsendsig(stp->sd_siglist, signals, band, 0);
   1866     0    stevel 	mutex_exit(&stp->sd_lock);
   1867     0    stevel 
   1868     0    stevel 
   1869     0    stevel done:
   1870     0    stevel 	if (nextbp == NULL)
   1871     0    stevel 		return (0);
   1872     0    stevel 
   1873     0    stevel 	/*
   1874     0    stevel 	 * Any signals were handled the first time.
   1875     0    stevel 	 * Wakeups and pollwakeups are redone to avoid any race
   1876     0    stevel 	 * conditions - all the messages are not queued until the
   1877     0    stevel 	 * last message has been processed by strrput.
   1878     0    stevel 	 */
   1879     0    stevel 	bp = nextbp;
   1880     0    stevel 	signals = firstmsgsigs = allmsgsigs = 0;
   1881     0    stevel 	mutex_enter(&stp->sd_lock);
   1882     0    stevel 	goto one_more;
   1883     0    stevel }
   1884     0    stevel 
   1885     0    stevel static void
   1886     0    stevel log_dupioc(queue_t *rq, mblk_t *bp)
   1887     0    stevel {
   1888     0    stevel 	queue_t *wq, *qp;
   1889     0    stevel 	char *modnames, *mnp, *dname;
   1890     0    stevel 	size_t maxmodstr;
   1891     0    stevel 	boolean_t islast;
   1892     0    stevel 
   1893     0    stevel 	/*
   1894     0    stevel 	 * Allocate a buffer large enough to hold the names of nstrpush modules
   1895     0    stevel 	 * and one driver, with spaces between and NUL terminator.  If we can't
   1896     0    stevel 	 * get memory, then we'll just log the driver name.
   1897     0    stevel 	 */
   1898     0    stevel 	maxmodstr = nstrpush * (FMNAMESZ + 1);
   1899     0    stevel 	mnp = modnames = kmem_alloc(maxmodstr, KM_NOSLEEP);
   1900     0    stevel 
   1901     0    stevel 	/* march down write side to print log message down to the driver */
   1902     0    stevel 	wq = WR(rq);
   1903     0    stevel 
   1904     0    stevel 	/* make sure q_next doesn't shift around while we're grabbing data */
   1905     0    stevel 	claimstr(wq);
   1906     0    stevel 	qp = wq->q_next;
   1907     0    stevel 	do {
   1908  8752     Peter 		dname = Q2NAME(qp);
   1909     0    stevel 		islast = !SAMESTR(qp) || qp->q_next == NULL;
   1910     0    stevel 		if (modnames == NULL) {
   1911     0    stevel 			/*
   1912     0    stevel 			 * If we don't have memory, then get the driver name in
   1913     0    stevel 			 * the log where we can see it.  Note that memory
   1914     0    stevel 			 * pressure is a possible cause of these sorts of bugs.
   1915     0    stevel 			 */
   1916     0    stevel 			if (islast) {
   1917     0    stevel 				modnames = dname;
   1918     0    stevel 				maxmodstr = 0;
   1919     0    stevel 			}
   1920     0    stevel 		} else {
   1921     0    stevel 			mnp += snprintf(mnp, FMNAMESZ + 1, "%s", dname);
   1922     0    stevel 			if (!islast)
   1923     0    stevel 				*mnp++ = ' ';
   1924     0    stevel 		}
   1925     0    stevel 		qp = qp->q_next;
   1926     0    stevel 	} while (!islast);
   1927     0    stevel 	releasestr(wq);
   1928     0    stevel 	/* Cannot happen unless stream head is corrupt. */
   1929     0    stevel 	ASSERT(modnames != NULL);
   1930     0    stevel 	(void) strlog(rq->q_qinfo->qi_minfo->mi_idnum, 0, 1,
   1931     0    stevel 	    SL_CONSOLE|SL_TRACE|SL_ERROR,
   1932     0    stevel 	    "Warning: stream %p received duplicate %X M_IOC%s; module list: %s",
   1933     0    stevel 	    rq->q_ptr, ((struct iocblk *)bp->b_rptr)->ioc_cmd,
   1934     0    stevel 	    (DB_TYPE(bp) == M_IOCACK ? "ACK" : "NAK"), modnames);
   1935     0    stevel 	if (maxmodstr != 0)
   1936     0    stevel 		kmem_free(modnames, maxmodstr);
   1937     0    stevel }
   1938     0    stevel 
   1939     0    stevel int
   1940     0    stevel strrput_nondata(queue_t *q, mblk_t *bp)
   1941     0    stevel {
   1942     0    stevel 	struct stdata *stp;
   1943     0    stevel 	struct iocblk *iocbp;
   1944     0    stevel 	struct stroptions *sop;
   1945     0    stevel 	struct copyreq *reqp;
   1946     0    stevel 	struct copyresp *resp;
   1947     0    stevel 	unsigned char bpri;
   1948     0    stevel 	unsigned char  flushed_already = 0;
   1949     0    stevel 
   1950     0    stevel 	stp = (struct stdata *)q->q_ptr;
   1951     0    stevel 
   1952     0    stevel 	ASSERT(!(stp->sd_flag & STPLEX));
   1953     0    stevel 	ASSERT(qclaimed(q));
   1954     0    stevel 
   1955     0    stevel 	switch (bp->b_datap->db_type) {
   1956     0    stevel 	case M_ERROR:
   1957     0    stevel 		/*
   1958     0    stevel 		 * An error has occurred downstream, the errno is in the first
   1959     0    stevel 		 * bytes of the message.
   1960     0    stevel 		 */
   1961     0    stevel 		if ((bp->b_wptr - bp->b_rptr) == 2) {	/* New flavor */
   1962     0    stevel 			unsigned char rw = 0;
   1963     0    stevel 
   1964     0    stevel 			mutex_enter(&stp->sd_lock);
   1965     0    stevel 			if (*bp->b_rptr != NOERROR) {	/* read error */
   1966     0    stevel 				if (*bp->b_rptr != 0) {
   1967     0    stevel 					if (stp->sd_flag & STRDERR)
   1968     0    stevel 						flushed_already |= FLUSHR;
   1969     0    stevel 					stp->sd_flag |= STRDERR;
   1970     0    stevel 					rw |= FLUSHR;
   1971     0    stevel 				} else {
   1972     0    stevel 					stp->sd_flag &= ~STRDERR;
   1973     0    stevel 				}
   1974     0    stevel 				stp->sd_rerror = *bp->b_rptr;
   1975     0    stevel 			}
   1976     0    stevel 			bp->b_rptr++;
   1977     0    stevel 			if (*bp->b_rptr != NOERROR) {	/* write error */
   1978     0    stevel 				if (*bp->b_rptr != 0) {
   1979     0    stevel 					if (stp->sd_flag & STWRERR)
   1980     0    stevel 						flushed_already |= FLUSHW;
   1981     0    stevel 					stp->sd_flag |= STWRERR;
   1982     0    stevel 					rw |= FLUSHW;
   1983     0    stevel 				} else {
   1984     0    stevel 					stp->sd_flag &= ~STWRERR;
   1985     0    stevel 				}
   1986     0    stevel 				stp->sd_werror = *bp->b_rptr;
   1987     0    stevel 			}
   1988     0    stevel 			if (rw) {
   1989     0    stevel 				TRACE_2(TR_FAC_STREAMS_FR, TR_STRRPUT_WAKE,
   1990  5753       gww 				    "strrput cv_broadcast:q %p, bp %p",
   1991  5753       gww 				    q, bp);
   1992     0    stevel 				cv_broadcast(&q->q_wait); /* readers */
   1993     0    stevel 				cv_broadcast(&_WR(q)->q_wait); /* writers */
   1994     0    stevel 				cv_broadcast(&stp->sd_monitor); /* ioctllers */
   1995     0    stevel 
   1996     0    stevel 				mutex_exit(&stp->sd_lock);
   1997     0    stevel 				pollwakeup(&stp->sd_pollist, POLLERR);
   1998     0    stevel 				mutex_enter(&stp->sd_lock);
   1999     0    stevel 
   2000     0    stevel 				if (stp->sd_sigflags & S_ERROR)
   2001     0    stevel 					strsendsig(stp->sd_siglist, S_ERROR, 0,
   2002     0    stevel 					    ((rw & FLUSHR) ? stp->sd_rerror :
   2003     0    stevel 					    stp->sd_werror));
   2004     0    stevel 				mutex_exit(&stp->sd_lock);
   2005     0    stevel 				/*
   2006     0    stevel 				 * Send the M_FLUSH only
   2007     0    stevel 				 * for the first M_ERROR
   2008     0    stevel 				 * message on the stream
   2009     0    stevel 				 */
   2010     0    stevel 				if (flushed_already == rw) {
   2011     0    stevel 					freemsg(bp);
   2012     0    stevel 					return (0);
   2013     0    stevel 				}
   2014     0    stevel 
   2015     0    stevel 				bp->b_datap->db_type = M_FLUSH;
   2016     0    stevel 				*bp->b_rptr = rw;
   2017     0    stevel 				bp->b_wptr = bp->b_rptr + 1;
   2018     0    stevel 				/*
   2019     0    stevel 				 * Protect against the driver
   2020     0    stevel 				 * passing up messages after
   2021     0    stevel 				 * it has done a qprocsoff
   2022     0    stevel 				 */
   2023     0    stevel 				if (_OTHERQ(q)->q_next == NULL)
   2024     0    stevel 					freemsg(bp);
   2025     0    stevel 				else
   2026     0    stevel 					qreply(q, bp);
   2027     0    stevel 				return (0);
   2028     0    stevel 			} else
   2029     0    stevel 				mutex_exit(&stp->sd_lock);
   2030     0    stevel 		} else if (*bp->b_rptr != 0) {		/* Old flavor */
   2031     0    stevel 				if (stp->sd_flag & (STRDERR|STWRERR))
   2032     0    stevel 					flushed_already = FLUSHRW;
   2033     0    stevel 				mutex_enter(&stp->sd_lock);
   2034     0    stevel 				stp->sd_flag |= (STRDERR|STWRERR);
   2035     0    stevel 				stp->sd_rerror = *bp->b_rptr;
   2036     0    stevel 				stp->sd_werror = *bp->b_rptr;
   2037     0    stevel 				TRACE_2(TR_FAC_STREAMS_FR,
   2038  5753       gww 				    TR_STRRPUT_WAKE2,
   2039  5753       gww 				    "strrput wakeup #2:q %p, bp %p", q, bp);
   2040     0    stevel 				cv_broadcast(&q->q_wait); /* the readers */
   2041     0    stevel 				cv_broadcast(&_WR(q)->q_wait); /* the writers */
   2042     0    stevel 				cv_broadcast(&stp->sd_monitor); /* ioctllers */
   2043     0    stevel 
   2044     0    stevel 				mutex_exit(&stp->sd_lock);
   2045     0    stevel 				pollwakeup(&stp->sd_pollist, POLLERR);
   2046     0    stevel 				mutex_enter(&stp->sd_lock);
   2047     0    stevel 
   2048     0    stevel 				if (stp->sd_sigflags & S_ERROR)
   2049     0    stevel 					strsendsig(stp->sd_siglist, S_ERROR, 0,
   2050     0    stevel 					    (stp->sd_werror ? stp->sd_werror :
   2051     0    stevel 					    stp->sd_rerror));
   2052     0    stevel 				mutex_exit(&stp->sd_lock);
   2053     0    stevel 
   2054     0    stevel 				/*
   2055     0    stevel 				 * Send the M_FLUSH only
   2056     0    stevel 				 * for the first M_ERROR
   2057     0    stevel 				 * message on the stream
   2058     0    stevel 				 */
   2059     0    stevel 				if (flushed_already != FLUSHRW) {
   2060     0    stevel 					bp->b_datap->db_type = M_FLUSH;
   2061     0    stevel 					*bp->b_rptr = FLUSHRW;
   2062     0    stevel 					/*
   2063     0    stevel 					 * Protect against the driver passing up
   2064     0    stevel 					 * messages after it has done a
   2065     0    stevel 					 * qprocsoff.
   2066     0    stevel 					 */
   2067     0    stevel 				if (_OTHERQ(q)->q_next == NULL)
   2068     0    stevel 					freemsg(bp);
   2069     0    stevel 				else
   2070     0    stevel 					qreply(q, bp);
   2071     0    stevel 				return (0);
   2072     0    stevel 				}
   2073     0    stevel 		}
   2074     0    stevel 		freemsg(bp);
   2075     0    stevel 		return (0);
   2076     0    stevel 
   2077     0    stevel 	case M_HANGUP:
   2078     0    stevel 
   2079     0    stevel 		freemsg(bp);
   2080     0    stevel 		mutex_enter(&stp->sd_lock);
   2081     0    stevel 		stp->sd_werror = ENXIO;
   2082     0    stevel 		stp->sd_flag |= STRHUP;
   2083     0    stevel 		stp->sd_flag &= ~(WSLEEP|RSLEEP);
   2084     0    stevel 
   2085     0    stevel 		/*
   2086     0    stevel 		 * send signal if controlling tty
   2087     0    stevel 		 */
   2088     0    stevel 
   2089     0    stevel 		if (stp->sd_sidp) {
   2090     0    stevel 			prsignal(stp->sd_sidp, SIGHUP);
   2091     0    stevel 			if (stp->sd_sidp != stp->sd_pgidp)
   2092     0    stevel 				pgsignal(stp->sd_pgidp, SIGTSTP);
   2093     0    stevel 		}
   2094     0    stevel 
   2095     0    stevel 		/*
   2096     0    stevel 		 * wake up read, write, and exception pollers and
   2097     0    stevel 		 * reset wakeup mechanism.
   2098     0    stevel 		 */
   2099     0    stevel 		cv_broadcast(&q->q_wait);	/* the readers */
   2100     0    stevel 		cv_broadcast(&_WR(q)->q_wait);	/* the writers */
   2101     0    stevel 		cv_broadcast(&stp->sd_monitor);	/* the ioctllers */
   2102     0    stevel 		strhup(stp);
   2103  2712   nn35248 		mutex_exit(&stp->sd_lock);
   2104     0    stevel 		return (0);
   2105     0    stevel 
   2106     0    stevel 	case M_UNHANGUP:
   2107     0    stevel 		freemsg(bp);
   2108     0    stevel 		mutex_enter(&stp->sd_lock);
   2109     0    stevel 		stp->sd_werror = 0;
   2110     0    stevel 		stp->sd_flag &= ~STRHUP;
   2111     0    stevel 		mutex_exit(&stp->sd_lock);
   2112     0    stevel 		return (0);
   2113     0    stevel 
   2114     0    stevel 	case M_SIG:
   2115     0    stevel 		/*
   2116     0    stevel 		 * Someone downstream wants to post a signal.  The
   2117     0    stevel 		 * signal to post is contained in the first byte of the
   2118     0    stevel 		 * message.  If the message would go on the front of
   2119     0    stevel 		 * the queue, send a signal to the process group
   2120     0    stevel 		 * (if not SIGPOLL) or to the siglist processes
   2121     0    stevel 		 * (SIGPOLL).  If something is already on the queue,
   2122     0    stevel 		 * OR if we are delivering a delayed suspend (*sigh*
   2123     0    stevel 		 * another "tty" hack) and there's no one sleeping already,
   2124     0    stevel 		 * just enqueue the message.
   2125     0    stevel 		 */
   2126     0    stevel 		mutex_enter(&stp->sd_lock);
   2127     0    stevel 		if (q->q_first || (*bp->b_rptr == SIGTSTP &&
   2128     0    stevel 		    !(stp->sd_flag & RSLEEP))) {
   2129     0    stevel 			(void) putq(q, bp);
   2130     0    stevel 			mutex_exit(&stp->sd_lock);
   2131     0    stevel 			return (0);
   2132     0    stevel 		}
   2133     0    stevel 		mutex_exit(&stp->sd_lock);
   2134     0    stevel 		/* FALLTHRU */
   2135     0    stevel 
   2136     0    stevel 	case M_PCSIG:
   2137     0    stevel 		/*
   2138     0    stevel 		 * Don't enqueue, just post the signal.
   2139     0    stevel 		 */
   2140     0    stevel 		strsignal(stp, *bp->b_rptr, 0L);
   2141     0    stevel 		freemsg(bp);
   2142  6583      meem 		return (0);
   2143  6583      meem 
   2144  6583      meem 	case M_CMD:
   2145  6583      meem 		if (MBLKL(bp) != sizeof (cmdblk_t)) {
   2146  6583      meem 			freemsg(bp);
   2147  6583      meem 			return (0);
   2148  6583      meem 		}
   2149  6583      meem 
   2150  6583      meem 		mutex_enter(&stp->sd_lock);
   2151  6583      meem 		if (stp->sd_flag & STRCMDWAIT) {
   2152  6583      meem 			ASSERT(stp->sd_cmdblk == NULL);
   2153  6583      meem 			stp->sd_cmdblk = bp;
   2154  6583      meem 			cv_broadcast(&stp->sd_monitor);
   2155  6583      meem 			mutex_exit(&stp->sd_lock);
   2156  6583      meem 		} else {
   2157  6583      meem 			mutex_exit(&stp->sd_lock);
   2158  6583      meem 			freemsg(bp);
   2159  6583      meem 		}
   2160     0    stevel 		return (0);
   2161     0    stevel 
   2162     0    stevel 	case M_FLUSH:
   2163     0    stevel 		/*
   2164     0    stevel 		 * Flush queues.  The indication of which queues to flush
   2165     0    stevel 		 * is in the first byte of the message.  If the read queue
   2166     0    stevel 		 * is specified, then flush it.  If FLUSHBAND is set, just
   2167     0    stevel 		 * flush the band specified by the second byte of the message.
   2168     0    stevel 		 *
   2169     0    stevel 		 * If a module has issued a M_SETOPT to not flush hi
   2170     0    stevel 		 * priority messages off of the stream head, then pass this
   2171     0    stevel 		 * flag into the flushq code to preserve such messages.
   2172     0    stevel 		 */
   2173     0    stevel 
   2174     0    stevel 		if (*bp->b_rptr & FLUSHR) {
   2175     0    stevel 			mutex_enter(&stp->sd_lock);
   2176     0    stevel 			if (*bp->b_rptr & FLUSHBAND) {
   2177     0    stevel 				ASSERT((bp->b_wptr - bp->b_rptr) >= 2);
   2178     0    stevel 				flushband(q, *(bp->b_rptr + 1), FLUSHALL);
   2179     0    stevel 			} else
   2180     0    stevel 				flushq_common(q, FLUSHALL,
   2181     0    stevel 				    stp->sd_read_opt & RFLUSHPCPROT);
   2182     0    stevel 			if ((q->q_first == NULL) ||
   2183     0    stevel 			    (q->q_first->b_datap->db_type < QPCTL))
   2184     0    stevel 				stp->sd_flag &= ~STRPRI;
   2185     0    stevel 			else {
   2186     0    stevel 				ASSERT(stp->sd_flag & STRPRI);
   2187     0    stevel 			}
   2188     0    stevel 			mutex_exit(&stp->sd_lock);
   2189     0    stevel 		}
   2190     0    stevel 		if ((*bp->b_rptr & FLUSHW) && !(bp->b_flag & MSGNOLOOP)) {
   2191     0    stevel 			*bp->b_rptr &= ~FLUSHR;
   2192     0    stevel 			bp->b_flag |= MSGNOLOOP;
   2193     0    stevel 			/*
   2194     0    stevel 			 * Protect against the driver passing up
   2195     0    stevel 			 * messages after it has done a qprocsoff.
   2196     0    stevel 			 */
   2197     0    stevel 			if (_OTHERQ(q)->q_next == NULL)
   2198     0    stevel 				freemsg(bp);
   2199     0    stevel 			else
   2200     0    stevel 				qreply(q, bp);
   2201     0    stevel 			return (0);
   2202     0    stevel 		}
   2203     0    stevel 		freemsg(bp);
   2204     0    stevel 		return (0);
   2205     0    stevel 
   2206     0    stevel 	case M_IOCACK:
   2207     0    stevel 	case M_IOCNAK:
   2208     0    stevel 		iocbp = (struct iocblk *)bp->b_rptr;
   2209     0    stevel 		/*
   2210     0    stevel 		 * If not waiting for ACK or NAK then just free msg.
   2211     0    stevel 		 * If incorrect id sequence number then just free msg.
   2212     0    stevel 		 * If already have ACK or NAK for user then this is a
   2213     0    stevel 		 *    duplicate, display a warning and free the msg.
   2214     0    stevel 		 */
   2215     0    stevel 		mutex_enter(&stp->sd_lock);
   2216     0    stevel 		if ((stp->sd_flag & IOCWAIT) == 0 || stp->sd_iocblk ||
   2217     0    stevel 		    (stp->sd_iocid != iocbp->ioc_id)) {
   2218     0    stevel 			/*
   2219     0    stevel 			 * If the ACK/NAK is a dup, display a message
   2220     0    stevel 			 * Dup is when sd_iocid == ioc_id, and
   2221     0    stevel 			 * sd_iocblk == <valid ptr> or -1 (the former
   2222     0    stevel 			 * is when an ioctl has been put on the stream
   2223     0    stevel 			 * head, but has not yet been consumed, the
   2224     0    stevel 			 * later is when it has been consumed).
   2225     0    stevel 			 */
   2226     0    stevel 			if ((stp->sd_iocid == iocbp->ioc_id) &&
   2227     0    stevel 			    (stp->sd_iocblk != NULL)) {
   2228     0    stevel 				log_dupioc(q, bp);
   2229     0    stevel 			}
   2230     0    stevel 			freemsg(bp);
   2231     0    stevel 			mutex_exit(&stp->sd_lock);
   2232     0    stevel 			return (0);
   2233     0    stevel 		}
   2234     0    stevel 
   2235     0    stevel 		/*
   2236     0    stevel 		 * Assign ACK or NAK to user and wake up.
   2237     0    stevel 		 */
   2238     0    stevel 		stp->sd_iocblk = bp;
   2239     0    stevel 		cv_broadcast(&stp->sd_monitor);
   2240     0    stevel 		mutex_exit(&stp->sd_lock);
   2241     0    stevel 		return (0);
   2242     0    stevel 
   2243     0    stevel 	case M_COPYIN:
   2244     0    stevel 	case M_COPYOUT:
   2245     0    stevel 		reqp = (struct copyreq *)bp->b_rptr;
   2246     0    stevel 
   2247     0    stevel 		/*
   2248     0    stevel 		 * If not waiting for ACK or NAK then just fail request.
   2249     0    stevel 		 * If already have ACK, NAK, or copy request, then just
   2250     0    stevel 		 * fail request.
   2251     0    stevel 		 * If incorrect id sequence number then just fail request.
   2252     0    stevel 		 */
   2253     0    stevel 		mutex_enter(&stp->sd_lock);
   2254     0    stevel 		if ((stp->sd_flag & IOCWAIT) == 0 || stp->sd_iocblk ||
   2255     0    stevel 		    (stp->sd_iocid != reqp->cq_id)) {
   2256     0    stevel 			if (bp->b_cont) {
   2257     0    stevel 				freemsg(bp->b_cont);
   2258     0    stevel 				bp->b_cont = NULL;
   2259     0    stevel 			}
   2260     0    stevel 			bp->b_datap->db_type = M_IOCDATA;
   2261     0    stevel 			bp->b_wptr = bp->b_rptr + sizeof (struct copyresp);
   2262     0    stevel 			resp = (struct copyresp *)bp->b_rptr;
   2263     0    stevel 			resp->cp_rval = (caddr_t)1;	/* failure */
   2264     0    stevel 			mutex_exit(&stp->sd_lock);
   2265     0    stevel 			putnext(stp->sd_wrq, bp);
   2266     0    stevel 			return (0);
   2267     0    stevel 		}
   2268     0    stevel 
   2269     0    stevel 		/*
   2270     0    stevel 		 * Assign copy request to user and wake up.
   2271     0    stevel 		 */
   2272     0    stevel 		stp->sd_iocblk = bp;
   2273     0    stevel 		cv_broadcast(&stp->sd_monitor);
   2274     0    stevel 		mutex_exit(&stp->sd_lock);
   2275     0    stevel 		return (0);
   2276     0    stevel 
   2277     0    stevel 	case M_SETOPTS:
   2278     0    stevel 		/*
   2279     0    stevel 		 * Set stream head options (read option, write offset,
   2280     0    stevel 		 * min/max packet size, and/or high/low water marks for
   2281     0    stevel 		 * the read side only).
   2282     0    stevel 		 */
   2283     0    stevel 
   2284     0    stevel 		bpri = 0;
   2285     0    stevel 		sop = (struct stroptions *)bp->b_rptr;
   2286     0    stevel 		mutex_enter(&stp->sd_lock);
   2287     0    stevel 		if (sop->so_flags & SO_READOPT) {
   2288     0    stevel 			switch (sop->so_readopt & RMODEMASK) {
   2289     0    stevel 			case RNORM:
   2290     0    stevel 				stp->sd_read_opt &= ~(RD_MSGDIS | RD_MSGNODIS);
   2291     0    stevel 				break;
   2292     0    stevel 
   2293     0    stevel 			case RMSGD:
   2294     0    stevel 				stp->sd_read_opt =
   2295     0    stevel 				    ((stp->sd_read_opt & ~RD_MSGNODIS) |
   2296     0    stevel 				    RD_MSGDIS);
   2297     0    stevel 				break;
   2298     0    stevel 
   2299     0    stevel 			case RMSGN:
   2300     0    stevel 				stp->sd_read_opt =
   2301     0    stevel 				    ((stp->sd_read_opt & ~RD_MSGDIS) |
   2302     0    stevel 				    RD_MSGNODIS);
   2303     0    stevel 				break;
   2304     0    stevel 			}
   2305     0    stevel 			switch (sop->so_readopt & RPROTMASK) {
   2306     0    stevel 			case RPROTNORM:
   2307     0    stevel 				stp->sd_read_opt &= ~(RD_PROTDAT | RD_PROTDIS);
   2308     0    stevel 				break;
   2309     0    stevel 
   2310     0    stevel 			case RPROTDAT:
   2311     0    stevel 				stp->sd_read_opt =
   2312     0    stevel 				    ((stp->sd_read_opt & ~RD_PROTDIS) |
   2313     0    stevel 				    RD_PROTDAT);
   2314     0    stevel 				break;
   2315     0    stevel 
   2316     0    stevel 			case RPROTDIS:
   2317     0    stevel 				stp->sd_read_opt =
   2318     0    stevel 				    ((stp->sd_read_opt & ~RD_PROTDAT) |
   2319     0    stevel 				    RD_PROTDIS);
   2320     0    stevel 				break;
   2321     0    stevel 			}
   2322     0    stevel 			switch (sop->so_readopt & RFLUSHMASK) {
   2323     0    stevel 			case RFLUSHPCPROT:
   2324     0    stevel 				/*
   2325     0    stevel 				 * This sets the stream head to NOT flush
   2326     0    stevel 				 * M_PCPROTO messages.
   2327     0    stevel 				 */
   2328     0    stevel 				stp->sd_read_opt |= RFLUSHPCPROT;
   2329     0    stevel 				break;
   2330     0    stevel 			}
   2331     0    stevel 		}
   2332     0    stevel 		if (sop->so_flags & SO_ERROPT) {
   2333     0    stevel 			switch (sop->so_erropt & RERRMASK) {
   2334     0    stevel 			case RERRNORM:
   2335     0    stevel 				stp->sd_flag &= ~STRDERRNONPERSIST;
   2336     0    stevel 				break;
   2337     0    stevel 			case RERRNONPERSIST:
   2338     0    stevel 				stp->sd_flag |= STRDERRNONPERSIST;
   2339     0    stevel 				break;
   2340     0    stevel 			}
   2341     0    stevel 			switch (sop->so_erropt & WERRMASK) {
   2342     0    stevel 			case WERRNORM:
   2343     0    stevel 				stp->sd_flag &= ~STWRERRNONPERSIST;
   2344     0    stevel 				break;
   2345     0    stevel 			case WERRNONPERSIST:
   2346     0    stevel 				stp->sd_flag |= STWRERRNONPERSIST;
   2347     0    stevel 				break;
   2348     0    stevel 			}
   2349     0    stevel 		}
   2350     0    stevel 		if (sop->so_flags & SO_COPYOPT) {
   2351     0    stevel 			if (sop->so_copyopt & ZCVMSAFE) {
   2352     0    stevel 				stp->sd_copyflag |= STZCVMSAFE;
   2353     0    stevel 				stp->sd_copyflag &= ~STZCVMUNSAFE;
   2354     0    stevel 			} else if (sop->so_copyopt & ZCVMUNSAFE) {
   2355     0    stevel 				stp->sd_copyflag |= STZCVMUNSAFE;
   2356     0    stevel 				stp->sd_copyflag &= ~STZCVMSAFE;
   2357     0    stevel 			}
   2358     0    stevel 
   2359     0    stevel 			if (sop->so_copyopt & COPYCACHED) {
   2360     0    stevel 				stp->sd_copyflag |= STRCOPYCACHED;
   2361     0    stevel 			}
   2362     0    stevel 		}
   2363     0    stevel 		if (sop->so_flags & SO_WROFF)
   2364     0    stevel 			stp->sd_wroff = sop->so_wroff;
   2365   898      kais 		if (sop->so_flags & SO_TAIL)
   2366   898      kais 			stp->sd_tail = sop->so_tail;
   2367     0    stevel 		if (sop->so_flags & SO_MINPSZ)
   2368     0    stevel 			q->q_minpsz = sop->so_minpsz;
   2369     0    stevel 		if (sop->so_flags & SO_MAXPSZ)
   2370     0    stevel 			q->q_maxpsz = sop->so_maxpsz;
   2371     0    stevel 		if (sop->so_flags & SO_MAXBLK)
   2372     0    stevel 			stp->sd_maxblk = sop->so_maxblk;
   2373     0    stevel 		if (sop->so_flags & SO_HIWAT) {
   2374  5753       gww 			if (sop->so_flags & SO_BAND) {
   2375  5753       gww 				if (strqset(q, QHIWAT,
   2376  5753       gww 				    sop->so_band, sop->so_hiwat)) {
   2377  5753       gww 					cmn_err(CE_WARN, "strrput: could not "
   2378  5753       gww 					    "allocate qband\n");
   2379  5753       gww 				} else {
   2380  5753       gww 					bpri = sop->so_band;
   2381  5753       gww 				}
   2382  5753       gww 			} else {
   2383  5753       gww 				q->q_hiwat = sop->so_hiwat;
   2384  5753       gww 			}
   2385     0    stevel 		}
   2386     0    stevel 		if (sop->so_flags & SO_LOWAT) {
   2387  5753       gww 			if (sop->so_flags & SO_BAND) {
   2388  5753       gww 				if (strqset(q, QLOWAT,
   2389  5753       gww 				    sop->so_band, sop->so_lowat)) {
   2390  5753       gww 					cmn_err(CE_WARN, "strrput: could not "
   2391  5753       gww 					    "allocate qband\n");
   2392  5753       gww 				} else {
   2393  5753       gww 					bpri = sop->so_band;
   2394  5753       gww 				}
   2395  5753       gww 			} else {
   2396  5753       gww 				q->q_lowat = sop->so_lowat;
   2397  5753       gww 			}
   2398     0    stevel 		}
   2399     0    stevel 		if (sop->so_flags & SO_MREADON)
   2400     0    stevel 			stp->sd_flag |= SNDMREAD;
   2401     0    stevel 		if (sop->so_flags & SO_MREADOFF)
   2402     0    stevel 			stp->sd_flag &= ~SNDMREAD;
   2403     0    stevel 		if (sop->so_flags & SO_NDELON)
   2404     0    stevel 			stp->sd_flag |= OLDNDELAY;
   2405     0    stevel 		if (sop->so_flags & SO_NDELOFF)
   2406     0    stevel 			stp->sd_flag &= ~OLDNDELAY;
   2407     0    stevel 		if (sop->so_flags & SO_ISTTY)
   2408     0    stevel 			stp->sd_flag |= STRISTTY;
   2409     0    stevel 		if (sop->so_flags & SO_ISNTTY)
   2410     0    stevel 			stp->sd_flag &= ~STRISTTY;
   2411     0    stevel 		if (sop->so_flags & SO_TOSTOP)
   2412     0    stevel 			stp->sd_flag |= STRTOSTOP;
   2413     0    stevel 		if (sop->so_flags & SO_TONSTOP)
   2414     0    stevel 			stp->sd_flag &= ~STRTOSTOP;
   2415     0    stevel 		if (sop->so_flags & SO_DELIM)
   2416     0    stevel 			stp->sd_flag |= STRDELIM;
   2417     0    stevel 		if (sop->so_flags & SO_NODELIM)
   2418     0    stevel 			stp->sd_flag &= ~STRDELIM;
   2419     0    stevel 
   2420     0    stevel 		mutex_exit(&stp->sd_lock);
   2421     0    stevel 		freemsg(bp);
   2422     0    stevel 
   2423     0    stevel 		/* Check backenable in case the water marks changed */
   2424     0    stevel 		qbackenable(q, bpri);
   2425     0    stevel 		return (0);
   2426     0    stevel 
   2427     0    stevel 	/*
   2428     0    stevel 	 * The following set of cases deal with situations where two stream
   2429     0    stevel 	 * heads are connected to each other (twisted streams).  These messages
   2430     0    stevel 	 * have no meaning at the stream head.
   2431     0    stevel 	 */
   2432     0    stevel 	case M_BREAK:
   2433     0    stevel 	case M_CTL:
   2434     0    stevel 	case M_DELAY:
   2435     0    stevel 	case M_START:
   2436     0    stevel 	case M_STOP:
   2437     0    stevel 	case M_IOCDATA:
   2438     0    stevel 	case M_STARTI:
   2439     0    stevel 	case M_STOPI:
   2440     0    stevel 		freemsg(bp);
   2441     0    stevel 		return (0);
   2442     0    stevel 
   2443     0    stevel 	case M_IOCTL:
   2444     0    stevel 		/*
   2445     0    stevel 		 * Always NAK this condition
   2446     0    stevel 		 * (makes no sense)
   2447     0    stevel 		 * If there is one or more threads in the read side
   2448     0    stevel 		 * rwnext we have to defer the nacking until that thread
   2449     0    stevel 		 * returns (in strget).
   2450     0    stevel 		 */
   2451     0    stevel 		mutex_enter(&stp->sd_lock);
   2452     0    stevel 		if (stp->sd_struiodnak != 0) {
   2453     0    stevel 			/*
   2454     0    stevel 			 * Defer NAK to the streamhead. Queue at the end
   2455     0    stevel 			 * the list.
   2456     0    stevel 			 */
   2457     0    stevel 			mblk_t *mp = stp->sd_struionak;
   2458     0    stevel 
   2459     0    stevel 			while (mp && mp->b_next)
   2460     0    stevel 				mp = mp->b_next;
   2461     0    stevel 			if (mp)
   2462     0    stevel 				mp->b_next = bp;
   2463     0    stevel 			else
   2464     0    stevel 				stp->sd_struionak = bp;
   2465     0    stevel 			bp->b_next = NULL;
   2466     0    stevel 			mutex_exit(&stp->sd_lock);
   2467     0    stevel 			return (0);
   2468     0    stevel 		}
   2469     0    stevel 		mutex_exit(&stp->sd_lock);
   2470     0    stevel 
   2471     0    stevel 		bp->b_datap->db_type = M_IOCNAK;
   2472     0    stevel 		/*
   2473     0    stevel 		 * Protect against the driver passing up
   2474     0    stevel 		 * messages after it has done a qprocsoff.
   2475     0    stevel 		 */
   2476     0    stevel 		if (_OTHERQ(q)->q_next == NULL)
   2477     0    stevel 			freemsg(bp);
   2478     0    stevel 		else
   2479     0    stevel 			qreply(q, bp);
   2480     0    stevel 		return (0);
   2481     0    stevel 
   2482     0    stevel 	default:
   2483     0    stevel #ifdef DEBUG
   2484     0    stevel 		cmn_err(CE_WARN,
   2485  5753       gww 		    "bad message type %x received at stream head\n",
   2486  5753       gww 		    bp->b_datap->db_type);
   2487     0    stevel #endif
   2488     0    stevel 		freemsg(bp);
   2489     0    stevel 		return (0);
   2490     0    stevel 	}
   2491     0    stevel 
   2492     0    stevel 	/* NOTREACHED */
   2493     0    stevel }
   2494     0    stevel 
   2495     0    stevel /*
   2496     0    stevel  * Check if the stream pointed to by `stp' can be written to, and return an
   2497     0    stevel  * error code if not.  If `eiohup' is set, then return EIO if STRHUP is set.
   2498     0    stevel  * If `sigpipeok' is set and the SW_SIGPIPE option is enabled on the stream,
   2499     0    stevel  * then always return EPIPE and send a SIGPIPE to the invoking thread.
   2500     0    stevel  */
   2501     0    stevel static int
   2502     0    stevel strwriteable(struct stdata *stp, boolean_t eiohup, boolean_t sigpipeok)
   2503     0    stevel {
   2504     0    stevel 	int error;
   2505     0    stevel 
   2506     0    stevel 	ASSERT(MUTEX_HELD(&stp->sd_lock));
   2507     0    stevel 
   2508     0    stevel 	/*
   2509     0    stevel 	 * For modem support, POSIX states that on writes, EIO should
   2510     0    stevel 	 * be returned if the stream has been hung up.
   2511     0    stevel 	 */
   2512     0    stevel 	if (eiohup && (stp->sd_flag & (STPLEX|STRHUP)) == STRHUP)
   2513     0    stevel 		error = EIO;
   2514     0    stevel 	else
   2515     0    stevel 		error = strgeterr(stp, STRHUP|STPLEX|STWRERR, 0);
   2516     0    stevel 
   2517     0    stevel 	if (error != 0) {
   2518     0    stevel 		if (!(stp->sd_flag & STPLEX) &&
   2519     0    stevel 		    (stp->sd_wput_opt & SW_SIGPIPE) && sigpipeok) {
   2520     0    stevel 			tsignal(curthread, SIGPIPE);
   2521     0    stevel 			error = EPIPE;
   2522     0    stevel 		}
   2523     0    stevel 	}
   2524     0    stevel 
   2525     0    stevel 	return (error);
   2526     0    stevel }
   2527     0    stevel 
   2528     0    stevel /*
   2529     0    stevel  * Copyin and send data down a stream.
   2530     0    stevel  * The caller will allocate and copyin any control part that precedes the
   2531  8778      Erik  * message and pass that in as mctl.
   2532     0    stevel  *
   2533     0    stevel  * Caller should *not* hold sd_lock.
   2534     0    stevel  * When EWOULDBLOCK is returned the caller has to redo the canputnext
   2535     0    stevel  * under sd_lock in order to avoid missing a backenabling wakeup.
   2536     0    stevel  *
   2537     0    stevel  * Use iosize = -1 to not send any M_DATA. iosize = 0 sends zero-length M_DATA.
   2538     0    stevel  *
   2539     0    stevel  * Set MSG_IGNFLOW in flags to ignore flow control for hipri messages.
   2540     0    stevel  * For sync streams we can only ignore flow control by reverting to using
   2541     0    stevel  * putnext.
   2542     0    stevel  *
   2543     0    stevel  * If sd_maxblk is less than *iosize this routine might return without
   2544     0    stevel  * transferring all of *iosize. In all cases, on return *iosize will contain
   2545     0    stevel  * the amount of data that was transferred.
   2546     0    stevel  */
   2547     0    stevel static int
   2548     0    stevel strput(struct stdata *stp, mblk_t *mctl, struct uio *uiop, ssize_t *iosize,
   2549     0    stevel     int b_flag, int pri, int flags)
   2550     0    stevel {
   2551     0    stevel 	struiod_t uiod;
   2552     0    stevel 	mblk_t *mp;
   2553     0    stevel 	queue_t *wqp = stp->sd_wrq;
   2554     0    stevel 	int error = 0;
   2555     0    stevel 	ssize_t count = *iosize;
   2556     0    stevel 
   2557     0    stevel 	ASSERT(MUTEX_NOT_HELD(&stp->sd_lock));
   2558     0    stevel 
   2559     0    stevel 	if (uiop != NULL && count >= 0)
   2560     0    stevel 		flags |= stp->sd_struiowrq ? STRUIO_POSTPONE : 0;
   2561     0    stevel 
   2562     0    stevel 	if (!(flags & STRUIO_POSTPONE)) {
   2563     0    stevel 		/*
   2564     0    stevel 		 * Use regular canputnext, strmakedata, putnext sequence.
   2565     0    stevel 		 */
   2566     0    stevel 		if (pri == 0) {
   2567     0    stevel 			if (!canputnext(wqp) && !(flags & MSG_IGNFLOW)) {
   2568     0    stevel 				freemsg(mctl);
   2569     0    stevel 				return (EWOULDBLOCK);
   2570     0    stevel 			}
   2571     0    stevel 		} else {
   2572     0    stevel 			if (!(flags & MSG_IGNFLOW) && !bcanputnext(wqp, pri)) {
   2573     0    stevel 				freemsg(mctl);
   2574     0    stevel 				return (EWOULDBLOCK);
   2575     0    stevel 			}
   2576     0    stevel 		}
   2577     0    stevel 
   2578     0    stevel 		if ((error = strmakedata(iosize, uiop, stp, flags,
   2579  5753       gww 		    &mp)) != 0) {
   2580     0    stevel 			freemsg(mctl);
   2581     0    stevel 			/*
   2582     0    stevel 			 * need to change return code to ENOMEM
   2583     0    stevel 			 * so that this is not confused with
   2584     0    stevel 			 * flow control, EAGAIN.
   2585     0    stevel 			 */
   2586     0    stevel 
   2587     0    stevel 			if (error == EAGAIN)
   2588     0    stevel 				return (ENOMEM);
   2589     0    stevel 			else
   2590     0    stevel 				return (error);
   2591     0    stevel 		}
   2592     0    stevel 		if (mctl != NULL) {
   2593     0    stevel 			if (mctl->b_cont == NULL)
   2594     0    stevel 				mctl->b_cont = mp;
   2595     0    stevel 			else if (mp != NULL)
   2596     0    stevel 				linkb(mctl, mp);
   2597     0    stevel 			mp = mctl;
   2598     0    stevel 		} else if (mp == NULL)
   2599     0    stevel 			return (0);
   2600     0    stevel 
   2601     0    stevel 		mp->b_flag |= b_flag;
   2602     0    stevel 		mp->b_band = (uchar_t)pri;
   2603     0    stevel 
   2604     0    stevel 		if (flags & MSG_IGNFLOW) {
   2605     0    stevel 			/*
   2606     0    stevel 			 * XXX Hack: Don't get stuck running service
   2607     0    stevel 			 * procedures. This is needed for sockfs when
   2608     0    stevel 			 * sending the unbind message out of the rput
   2609     0    stevel 			 * procedure - we don't want a put procedure
   2610     0    stevel 			 * to run service procedures.
   2611     0    stevel 			 */
   2612     0    stevel 			putnext(wqp, mp);
   2613     0    stevel 		} else {
   2614     0    stevel 			stream_willservice(stp);
   2615     0    stevel 			putnext(wqp, mp);
   2616     0    stevel 			stream_runservice(stp);
   2617     0    stevel 		}
   2618     0    stevel 		return (0);
   2619     0    stevel 	}
   2620     0    stevel 	/*
   2621     0    stevel 	 * Stream supports rwnext() for the write side.
   2622     0    stevel 	 */
   2623     0    stevel 	if ((error = strmakedata(iosize, uiop, stp, flags, &mp)) != 0) {
   2624     0    stevel 		freemsg(mctl);
   2625     0    stevel 		/*
   2626     0    stevel 		 * map EAGAIN to ENOMEM since EAGAIN means "flow controlled".
   2627     0    stevel 		 */
   2628     0    stevel 		return (error == EAGAIN ? ENOMEM : error);
   2629     0    stevel 	}
   2630     0    stevel 	if (mctl != NULL) {
   2631     0    stevel 		if (mctl->b_cont == NULL)
   2632     0    stevel 			mctl->b_cont = mp;
   2633     0    stevel 		else if (mp != NULL)
   2634     0    stevel 			linkb(mctl, mp);
   2635     0    stevel 		mp = mctl;
   2636     0    stevel 	} else if (mp == NULL) {
   2637     0    stevel 		return (0);
   2638     0    stevel 	}
   2639     0    stevel 
   2640     0    stevel 	mp->b_flag |= b_flag;
   2641     0    stevel 	mp->b_band = (uchar_t)pri;
   2642     0    stevel 
   2643     0    stevel 	(void) uiodup(uiop, &uiod.d_uio, uiod.d_iov,
   2644  5753       gww 	    sizeof (uiod.d_iov) / sizeof (*uiod.d_iov));
   2645     0    stevel 	uiod.d_uio.uio_offset = 0;
   2646     0    stevel 	uiod.d_mp = mp;
   2647     0    stevel 	error = rwnext(wqp, &uiod);
   2648     0    stevel 	if (! uiod.d_mp) {
   2649     0    stevel 		uioskip(uiop, *iosize);
   2650     0    stevel 		return (error);
   2651     0    stevel 	}
   2652     0    stevel 	ASSERT(mp == uiod.d_mp);
   2653     0    stevel 	if (error == EINVAL) {
   2654     0    stevel 		/*
   2655     0    stevel 		 * The stream plumbing must have changed while
   2656     0    stevel 		 * we were away, so just turn off rwnext()s.
   2657     0    stevel 		 */
   2658     0    stevel 		error = 0;
   2659     0    stevel 	} else if (error == EBUSY || error == EWOULDBLOCK) {
   2660     0    stevel 		/*
   2661     0    stevel 		 * Couldn't enter a perimeter or took a page fault,
   2662     0    stevel 		 * so fall-back to putnext().
   2663     0    stevel 		 */
   2664     0    stevel 		error = 0;
   2665     0    stevel 	} else {
   2666     0    stevel 		freemsg(mp);
   2667     0    stevel 		return (error);
   2668     0    stevel 	}
   2669     0    stevel 	/* Have to check canput before consuming data from the uio */
   2670     0    stevel 	if (pri == 0) {
   2671     0    stevel 		if (!canputnext(wqp) && !(flags & MSG_IGNFLOW)) {
   2672     0    stevel 			freemsg(mp);
   2673     0    stevel 			return (EWOULDBLOCK);
   2674     0    stevel 		}
   2675     0    stevel 	} else {
   2676     0    stevel 		if (!bcanputnext(wqp, pri) && !(flags & MSG_IGNFLOW)) {
   2677     0    stevel 			freemsg(mp);
   2678     0    stevel 			return (EWOULDBLOCK);
   2679     0    stevel 		}
   2680     0    stevel 	}
   2681     0    stevel 	ASSERT(mp == uiod.d_mp);
   2682     0    stevel 	/* Copyin data from the uio */
   2683     0    stevel 	if ((error = struioget(wqp, mp, &uiod, 0)) != 0) {
   2684     0    stevel 		freemsg(mp);
   2685     0    stevel 		return (error);
   2686     0    stevel 	}
   2687     0    stevel 	uioskip(uiop, *iosize);
   2688     0    stevel 	if (flags & MSG_IGNFLOW) {
   2689     0    stevel 		/*
   2690     0    stevel 		 * XXX Hack: Don't get stuck running service procedures.
   2691     0    stevel 		 * This is needed for sockfs when sending the unbind message
   2692     0    stevel 		 * out of the rput procedure - we don't want a put procedure
   2693     0    stevel 		 * to run service procedures.
   2694     0    stevel 		 */
   2695     0    stevel 		putnext(wqp, mp);
   2696     0    stevel 	} else {
   2697     0    stevel 		stream_willservice(stp);
   2698     0    stevel 		putnext(wqp, mp);
   2699     0    stevel 		stream_runservice(stp);
   2700     0    stevel 	}
   2701     0    stevel 	return (0);
   2702     0    stevel }
   2703     0    stevel 
   2704     0    stevel /*
   2705     0    stevel  * Write attempts to break the write request into messages conforming
   2706     0    stevel  * with the minimum and maximum packet sizes set downstream.
   2707     0    stevel  *
   2708     0    stevel  * Write will not block if downstream queue is full and
   2709     0    stevel  * O_NDELAY is set, otherwise it will block waiting for the queue to get room.
   2710     0    stevel  *
   2711     0    stevel  * A write of zero bytes gets packaged into a zero length message and sent
   2712     0    stevel  * downstream like any other message.
   2713     0    stevel  *
   2714     0    stevel  * If buffers of the requested sizes are not available, the write will
   2715     0    stevel  * sleep until the buffers become available.
   2716     0    stevel  *
   2717     0    stevel  * Write (if specified) will supply a write offset in a message if it
   2718     0    stevel  * makes sense. This can be specified by downstream modules as part of
   2719     0    stevel  * a M_SETOPTS message.  Write will not supply the write offset if it
   2720     0    stevel  * cannot supply any data in a buffer.  In other words, write will never
   2721     0    stevel  * send down an empty packet due to a write offset.
   2722     0    stevel  */
   2723     0    stevel /* ARGSUSED2 */
   2724     0    stevel int
   2725     0    stevel strwrite(struct vnode *vp, struct uio *uiop, cred_t *crp)
   2726     0    stevel {
   2727   741  masputra 	return (strwrite_common(vp, uiop, crp, 0));
   2728   741  masputra }
   2729   741  masputra 
   2730   741  masputra /* ARGSUSED2 */
   2731   741  masputra int
   2732   741  masputra strwrite_common(struct vnode *vp, struct uio *uiop, cred_t *crp, int wflag)
   2733   741  masputra {
   2734     0    stevel 	struct stdata *stp;
   2735     0    stevel 	struct queue *wqp;
   2736     0    stevel 	ssize_t rmin, rmax;
   2737     0    stevel 	ssize_t iosize;
   2738   741  masputra 	int waitflag;
   2739     0    stevel 	int tempmode;
   2740     0    stevel 	int error = 0;
   2741     0    stevel 	int b_flag;
   2742     0    stevel 
   2743     0    stevel 	ASSERT(vp->v_stream);
   2744     0    stevel 	stp = vp->v_stream;
   2745     0    stevel 
   2746  2712   nn35248 	mutex_enter(&stp->sd_lock);
   2747  2712   nn35248 
   2748  2712   nn35248 	if ((error = i_straccess(stp, JCWRITE)) != 0) {
   2749  2712   nn35248 		mutex_exit(&stp->sd_lock);
   2750  2712   nn35248 		return (error);
   2751  2712   nn35248 	}
   2752     0    stevel 
   2753     0    stevel 	if (stp->sd_flag & (STWRERR|STRHUP|STPLEX)) {
   2754     0    stevel 		error = strwriteable(stp, B_TRUE, B_TRUE);
   2755  2712   nn35248 		if (error != 0) {
   2756  2712   nn35248 			mutex_exit(&stp->sd_lock);
   2757  2712   nn35248 			return (error);
   2758  2712   nn35248 		}
   2759  2712   nn35248 	}
   2760  2712   nn35248 
   2761  2712   nn35248 	mutex_exit(&stp->sd_lock);
   2762     0    stevel 
   2763     0    stevel 	wqp = stp->sd_wrq;
   2764     0    stevel 
   2765     0    stevel 	/* get these values from them cached in the stream head */
   2766     0    stevel 	rmin = stp->sd_qn_minpsz;
   2767     0    stevel 	rmax = stp->sd_qn_maxpsz;
   2768     0    stevel 
   2769     0    stevel 	/*
   2770     0    stevel 	 * Check the min/max packet size constraints.  If min packet size
   2771     0    stevel 	 * is non-zero, the write cannot be split into multiple messages
   2772     0    stevel 	 * and still guarantee the size constraints.
   2773     0    stevel 	 */
   2774     0    stevel 	TRACE_1(TR_FAC_STREAMS_FR, TR_STRWRITE_IN, "strwrite in:q %p", wqp);
   2775     0    stevel 
   2776     0    stevel 	ASSERT((rmax >= 0) || (rmax == INFPSZ));
   2777     0    stevel 	if (rmax == 0) {
   2778     0    stevel 		return (0);
   2779     0    stevel 	}
   2780     0    stevel 	if (rmin > 0) {
   2781     0    stevel 		if (uiop->uio_resid < rmin) {
   2782     0    stevel 			TRACE_3(TR_FAC_STREAMS_FR, TR_STRWRITE_OUT,
   2783  5753       gww 			    "strwrite out:q %p out %d error %d",
   2784  5753       gww 			    wqp, 0, ERANGE);
   2785     0    stevel 			return (ERANGE);
   2786     0    stevel 		}
   2787     0    stevel 		if ((rmax != INFPSZ) && (uiop->uio_resid > rmax)) {
   2788     0    stevel 			TRACE_3(TR_FAC_STREAMS_FR, TR_STRWRITE_OUT,
   2789  5753       gww 			    "strwrite out:q %p out %d error %d",
   2790  5753       gww 			    wqp, 1, ERANGE);
   2791     0    stevel 			return (ERANGE);
   2792     0    stevel 		}
   2793     0    stevel 	}
   2794     0    stevel 
   2795     0    stevel 	/*
   2796     0    stevel 	 * Do until count satisfied or error.
   2797     0    stevel 	 */
   2798   741  masputra 	waitflag = WRITEWAIT | wflag;
   2799     0    stevel 	if (stp->sd_flag & OLDNDELAY)
   2800     0    stevel 		tempmode = uiop->uio_fmode & ~FNDELAY;
   2801     0    stevel 	else
   2802     0    stevel 		tempmode = uiop->uio_fmode;
   2803     0    stevel 
   2804     0    stevel 	if (rmax == INFPSZ)
   2805     0    stevel 		rmax = uiop->uio_resid;
   2806     0    stevel 
   2807     0    stevel 	/*
   2808     0    stevel 	 * Note that tempmode does not get used in strput/strmakedata
   2809     0    stevel 	 * but only in strwaitq. The other routines use uio_fmode
   2810     0    stevel 	 * unmodified.
   2811     0    stevel 	 */
   2812     0    stevel 
   2813     0    stevel 	/* LINTED: constant in conditional context */
   2814     0    stevel 	while (1) {	/* breaks when uio_resid reaches zero */
   2815     0    stevel 		/*
   2816     0    stevel 		 * Determine the size of the next message to be
   2817     0    stevel 		 * packaged.  May have to break write into several
   2818     0    stevel 		 * messages based on max packet size.
   2819     0    stevel 		 */
   2820     0    stevel 		iosize = MIN(uiop->uio_resid, rmax);
   2821     0    stevel 
   2822     0    stevel 		/*
   2823     0    stevel 		 * Put block downstream when flow control allows it.
   2824     0    stevel 		 */
   2825     0    stevel 		if ((stp->sd_flag & STRDELIM) && (uiop->uio_resid == iosize))
   2826     0    stevel 			b_flag = MSGDELIM;
   2827     0    stevel 		else
   2828     0    stevel 			b_flag = 0;
   2829     0    stevel 
   2830     0    stevel 		for (;;) {
   2831     0    stevel 			int done = 0;
   2832     0    stevel 
   2833  5753       gww 			error = strput(stp, NULL, uiop, &iosize, b_flag, 0, 0);
   2834     0    stevel 			if (error == 0)
   2835     0    stevel 				break;
   2836     0    stevel 			if (error != EWOULDBLOCK)
   2837     0    stevel 				goto out;
   2838     0    stevel 
   2839     0    stevel 			mutex_enter(&stp->sd_lock);
   2840     0    stevel 			/*
   2841     0    stevel 			 * Check for a missed wakeup.
   2842     0    stevel 			 * Needed since strput did not hold sd_lock across
   2843     0    stevel 			 * the canputnext.
   2844     0    stevel 			 */
   2845     0    stevel 			if (canputnext(wqp)) {
   2846     0    stevel 				/* Try again */
   2847     0    stevel 				mutex_exit(&stp->sd_lock);
   2848     0    stevel 				continue;
   2849     0    stevel 			}
   2850     0    stevel 			TRACE_1(TR_FAC_STREAMS_FR, TR_STRWRITE_WAIT,
   2851  5753       gww 			    "strwrite wait:q %p wait", wqp);
   2852     0    stevel 			if ((error = strwaitq(stp, waitflag, (ssize_t)0,
   2853     0    stevel 			    tempmode, -1, &done)) != 0 || done) {
   2854     0    stevel 				mutex_exit(&stp->sd_lock);
   2855     0    stevel 				if ((vp->v_type == VFIFO) &&
   2856     0    stevel 				    (uiop->uio_fmode & FNDELAY) &&
   2857     0    stevel 				    (error == EAGAIN))
   2858     0    stevel 					error = 0;
   2859     0    stevel 				goto out;
   2860     0    stevel 			}
   2861     0    stevel 			TRACE_1(TR_FAC_STREAMS_FR, TR_STRWRITE_WAKE,
   2862  5753       gww 			    "strwrite wake:q %p awakes", wqp);
   2863  2712   nn35248 			if ((error = i_straccess(stp, JCWRITE)) != 0) {
   2864  2712   nn35248 				mutex_exit(&stp->sd_lock);
   2865  2712   nn35248 				goto out;
   2866  2712   nn35248 			}
   2867  2712   nn35248 			mutex_exit(&stp->sd_lock);
   2868     0    stevel 		}
   2869     0    stevel 		waitflag |= NOINTR;
   2870     0    stevel 		TRACE_2(TR_FAC_STREAMS_FR, TR_STRWRITE_RESID,
   2871  5753       gww 		    "strwrite resid:q %p uiop %p", wqp, uiop);
   2872     0    stevel 		if (uiop->uio_resid) {
   2873     0    stevel 			/* Recheck for errors - needed for sockets */
   2874     0    stevel 			if ((stp->sd_wput_opt & SW_RECHECK_ERR) &&
   2875     0    stevel 			    (stp->sd_flag & (STWRERR|STRHUP|STPLEX))) {
   2876     0    stevel 				mutex_enter(&stp->sd_lock);
   2877     0    stevel 				error = strwriteable(stp, B_FALSE, B_TRUE);
   2878     0    stevel 				mutex_exit(&stp->sd_lock);
   2879     0    stevel 				if (error != 0)
   2880     0    stevel 					return (error);
   2881     0    stevel 			}
   2882     0    stevel 			continue;
   2883     0    stevel 		}
   2884     0    stevel 		break;
   2885     0    stevel 	}
   2886     0    stevel out:
   2887     0    stevel 	/*
   2888     0    stevel 	 * For historical reasons, applications expect EAGAIN when a data
   2889     0    stevel 	 * mblk_t cannot be allocated, so change ENOMEM back to EAGAIN.
   2890     0    stevel 	 */
   2891     0    stevel 	if (error == ENOMEM)
   2892     0    stevel 		error = EAGAIN;
   2893     0    stevel 	TRACE_3(TR_FAC_STREAMS_FR, TR_STRWRITE_OUT,
   2894  5753       gww 	    "strwrite out:q %p out %d error %d", wqp, 2, error);
   2895     0    stevel 	return (error);
   2896     0    stevel }
   2897     0    stevel 
   2898     0    stevel /*
   2899     0    stevel  * Stream head write service routine.
   2900     0    stevel  * Its job is to wake up any sleeping writers when a queue
   2901     0    stevel  * downstream needs data (part of the flow control in putq and getq).
   2902     0    stevel  * It also must wake anyone sleeping on a poll().
   2903     0    stevel  * For stream head right below mux module, it must also invoke put procedure
   2904     0    stevel  * of next downstream module.
   2905     0    stevel  */
   2906     0    stevel int
   2907     0    stevel strwsrv(queue_t *q)
   2908     0    stevel {
   2909     0    stevel 	struct stdata *stp;
   2910     0    stevel 	queue_t *tq;
   2911     0    stevel 	qband_t *qbp;
   2912     0    stevel 	int i;
   2913     0    stevel 	qband_t *myqbp;
   2914     0    stevel 	int isevent;
   2915     0    stevel 	unsigned char	qbf[NBAND];	/* band flushing backenable flags */
   2916     0    stevel 
   2917     0    stevel 	TRACE_1(TR_FAC_STREAMS_FR,
   2918  5753       gww 	    TR_STRWSRV, "strwsrv:q %p", q);
   2919     0    stevel 	stp = (struct stdata *)q->q_ptr;
   2920     0    stevel 	ASSERT(qclaimed(q));
   2921     0    stevel 	mutex_enter(&stp->sd_lock);
   2922     0    stevel 	ASSERT(!(stp->sd_flag & STPLEX));
   2923     0    stevel 
   2924     0    stevel 	if (stp->sd_flag & WSLEEP) {
   2925     0    stevel 		stp->sd_flag &= ~WSLEEP;
   2926     0    stevel 		cv_broadcast(&q->q_wait);
   2927     0    stevel 	}
   2928     0    stevel 	mutex_exit(&stp->sd_lock);
   2929     0    stevel 
   2930     0    stevel 	/* The other end of a stream pipe went away. */
   2931     0    stevel 	if ((tq = q->q_next) == NULL) {
   2932     0    stevel 		return (0);
   2933     0    stevel 	}
   2934     0    stevel 
   2935     0    stevel 	/* Find the next module forward that has a service procedure */
   2936     0    stevel 	claimstr(q);
   2937     0    stevel 	tq = q->q_nfsrv;
   2938     0    stevel 	ASSERT(tq != NULL);
   2939     0    stevel 
   2940     0    stevel 	if ((q->q_flag & QBACK)) {
   2941     0    stevel 		if ((tq->q_flag & QFULL)) {
   2942     0    stevel 			mutex_enter(QLOCK(tq));
   2943     0    stevel 			if (!(tq->q_flag & QFULL)) {
   2944     0    stevel 				mutex_exit(QLOCK(tq));
   2945     0    stevel 				goto wakeup;
   2946     0    stevel 			}
   2947     0    stevel 			/*
   2948     0    stevel 			 * The queue must have become full again. Set QWANTW
   2949     0    stevel 			 * again so strwsrv will be back enabled when
   2950     0    stevel 			 * the queue becomes non-full next time.
   2951     0    stevel 			 */
   2952     0    stevel 			tq->q_flag |= QWANTW;
   2953     0    stevel 			mutex_exit(QLOCK(tq));
   2954     0    stevel 		} else {
   2955     0    stevel 		wakeup:
   2956     0    stevel 			pollwakeup(&stp->sd_pollist, POLLWRNORM);
   2957     0    stevel 			mutex_enter(&stp->sd_lock);
   2958     0    stevel 			if (stp->sd_sigflags & S_WRNORM)
   2959     0    stevel 				strsendsig(stp->sd_siglist, S_WRNORM, 0, 0);
   2960     0    stevel 			mutex_exit(&stp->sd_lock);
   2961     0    stevel 		}
   2962     0    stevel 	}
   2963     0    stevel 
   2964     0    stevel 	isevent = 0;
   2965     0    stevel 	i = 1;
   2966     0    stevel 	bzero((caddr_t)qbf, NBAND);
   2967     0    stevel 	mutex_enter(QLOCK(tq));
   2968     0    stevel 	if ((myqbp = q->q_bandp) != NULL)
   2969     0    stevel 		for (qbp = tq->q_bandp; qbp && myqbp; qbp = qbp->qb_next) {
   2970     0    stevel 			ASSERT(myqbp);
   2971     0    stevel 			if ((myqbp->qb_flag & QB_BACK)) {
   2972     0    stevel 				if (qbp->qb_flag & QB_FULL) {
   2973     0    stevel 					/*
   2974     0    stevel 					 * The band must have become full again.
   2975     0    stevel 					 * Set QB_WANTW again so strwsrv will
   2976     0    stevel 					 * be back enabled when the band becomes
   2977     0    stevel 					 * non-full next time.
   2978     0    stevel 					 */
   2979     0    stevel 					qbp->qb_flag |= QB_WANTW;
   2980     0    stevel 				} else {
   2981     0    stevel 					isevent = 1;
   2982     0    stevel 					qbf[i] = 1;
   2983     0    stevel 				}
   2984     0    stevel 			}
   2985     0    stevel 			myqbp = myqbp->qb_next;
   2986     0    stevel 			i++;
   2987     0    stevel 		}
   2988     0    stevel 	mutex_exit(QLOCK(tq));
   2989     0    stevel 
   2990     0    stevel 	if (isevent) {
   2991  5753       gww 		for (i = tq->q_nband; i; i--) {
   2992  5753       gww 			if (qbf[i]) {
   2993  5753       gww 				pollwakeup(&stp->sd_pollist, POLLWRBAND);
   2994  5753       gww 				mutex_enter(&stp->sd_lock);
   2995  5753       gww 				if (stp->sd_sigflags & S_WRBAND)
   2996  5753       gww 					strsendsig(stp->sd_siglist, S_WRBAND,
   2997  5753       gww 					    (uchar_t)i, 0);
   2998  5753       gww 				mutex_exit(&stp->sd_lock);
   2999  5753       gww 			}
   3000  5753       gww 		}
   3001     0    stevel 	}
   3002     0    stevel 
   3003     0    stevel 	releasestr(q);
   3004     0    stevel 	return (0);
   3005     0    stevel }
   3006     0    stevel 
   3007     0    stevel /*
   3008     0    stevel  * Special case of strcopyin/strcopyout for copying
   3009     0    stevel  * struct strioctl that can deal with both data
   3010     0    stevel  * models.
   3011     0    stevel  */
   3012     0    stevel 
   3013     0    stevel #ifdef	_LP64
   3014     0    stevel 
   3015     0    stevel static int
   3016     0    stevel strcopyin_strioctl(void *from, void *to, int flag, int copyflag)
   3017     0    stevel {
   3018     0    stevel 	struct	strioctl32 strioc32;
   3019     0    stevel 	struct	strioctl *striocp;
   3020     0    stevel 
   3021     0    stevel 	if (copyflag & U_TO_K) {
   3022     0    stevel 		ASSERT((copyflag & K_TO_K) == 0);
   3023     0    stevel 
   3024     0    stevel 		if ((flag & FMODELS) == DATAMODEL_ILP32) {
   3025     0    stevel 			if (copyin(from, &strioc32, sizeof (strioc32)))
   3026     0    stevel 				return (EFAULT);
   3027     0    stevel 
   3028     0    stevel 			striocp = (struct strioctl *)to;
   3029     0    stevel 			striocp->ic_cmd	= strioc32.ic_cmd;
   3030     0    stevel 			striocp->ic_timout = strioc32.ic_timout;
   3031     0    stevel 			striocp->ic_len	= strioc32.ic_len;
   3032     0    stevel 			striocp->ic_dp	= (char *)(uintptr_t)strioc32.ic_dp;
   3033     0    stevel 
   3034     0    stevel 		} else { /* NATIVE data model */
   3035     0    stevel 			if (copyin(from, to, sizeof (struct strioctl))) {
   3036     0    stevel 				return (EFAULT);
   3037     0    stevel 			} else {
   3038     0    stevel 				return (0);
   3039     0    stevel 			}
   3040     0    stevel 		}
   3041     0    stevel 	} else {
   3042     0    stevel 		ASSERT(copyflag & K_TO_K);
   3043     0    stevel 		bcopy(from, to, sizeof (struct strioctl));
   3044     0    stevel 	}
   3045     0    stevel 	return (0);
   3046     0    stevel }
   3047     0    stevel 
   3048     0    stevel static int
   3049     0    stevel strcopyout_strioctl(void *from, void *to, int flag, int copyflag)
   3050     0    stevel {
   3051     0    stevel 	struct	strioctl32 strioc32;
   3052     0    stevel 	struct	strioctl *striocp;
   3053     0    stevel 
   3054     0    stevel 	if (copyflag & U_TO_K) {
   3055     0    stevel 		ASSERT((copyflag & K_TO_K) == 0);
   3056     0    stevel 
   3057     0    stevel 		if ((flag & FMODELS) == DATAMODEL_ILP32) {
   3058     0    stevel 			striocp = (struct strioctl *)from;
   3059     0    stevel 			strioc32.ic_cmd	= striocp->ic_cmd;
   3060     0    stevel 			strioc32.ic_timout = striocp->ic_timout;
   3061     0    stevel 			strioc32.ic_len	= striocp->ic_len;
   3062     0    stevel 			strioc32.ic_dp	= (caddr32_t)(uintptr_t)striocp->ic_dp;
   3063     0    stevel 			ASSERT((char *)(uintptr_t)strioc32.ic_dp ==
   3064     0    stevel 			    striocp->ic_dp);
   3065     0    stevel 
   3066     0    stevel 			if (copyout(&strioc32, to, sizeof (strioc32)))
   3067     0    stevel 				return (EFAULT);
   3068     0    stevel 
   3069     0    stevel 		} else { /* NATIVE data model */
   3070     0    stevel 			if (copyout(from, to, sizeof (struct strioctl))) {
   3071     0    stevel 				return (EFAULT);
   3072     0    stevel 			} else {
   3073     0    stevel 				return (0);
   3074     0    stevel 			}
   3075     0    stevel 		}
   3076     0    stevel 	} else {
   3077     0    stevel 		ASSERT(copyflag & K_TO_K);
   3078     0    stevel 		bcopy(from, to, sizeof (struct strioctl));
   3079     0    stevel 	}
   3080     0    stevel 	return (0);
   3081     0    stevel }
   3082     0    stevel 
   3083     0    stevel #else	/* ! _LP64 */
   3084     0    stevel 
   3085     0    stevel /* ARGSUSED2 */
   3086     0    stevel static int
   3087     0    stevel strcopyin_strioctl(void *from, void *to, int flag, int copyflag)
   3088     0    stevel {
   3089     0    stevel 	return (strcopyin(from, to, sizeof (struct strioctl), copyflag));
   3090     0    stevel }
   3091     0    stevel 
   3092     0    stevel /* ARGSUSED2 */
   3093     0    stevel static int
   3094     0    stevel <