1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*0Sstevel@tonic-gate /* All Rights Reserved */
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" /* from S5R4 1.4 */
32*0Sstevel@tonic-gate
33*0Sstevel@tonic-gate /*
34*0Sstevel@tonic-gate * Transport Interface Library read/write module - issue 1
35*0Sstevel@tonic-gate */
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate #include <sys/types.h>
38*0Sstevel@tonic-gate #include <sys/param.h>
39*0Sstevel@tonic-gate #include <sys/stream.h>
40*0Sstevel@tonic-gate #include <sys/stropts.h>
41*0Sstevel@tonic-gate #include <sys/tihdr.h>
42*0Sstevel@tonic-gate #include <sys/debug.h>
43*0Sstevel@tonic-gate #include <sys/errno.h>
44*0Sstevel@tonic-gate #include <sys/kmem.h>
45*0Sstevel@tonic-gate #include <sys/tirdwr.h>
46*0Sstevel@tonic-gate #include <sys/conf.h>
47*0Sstevel@tonic-gate #include <sys/modctl.h>
48*0Sstevel@tonic-gate #include <sys/ddi.h>
49*0Sstevel@tonic-gate #include <sys/sunddi.h>
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gate #define ORDREL 002
52*0Sstevel@tonic-gate #define DISCON 004
53*0Sstevel@tonic-gate #define FATAL 010
54*0Sstevel@tonic-gate #define WAITACK 020
55*0Sstevel@tonic-gate #define TIRDWR_ID 4
56*0Sstevel@tonic-gate
57*0Sstevel@tonic-gate /*
58*0Sstevel@tonic-gate * Per-Stream private data structure.
59*0Sstevel@tonic-gate */
60*0Sstevel@tonic-gate struct trw_trw {
61*0Sstevel@tonic-gate queue_t *trw_rdq;
62*0Sstevel@tonic-gate uint_t trw_flags;
63*0Sstevel@tonic-gate };
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gate /*
66*0Sstevel@tonic-gate * stream data structure definitions
67*0Sstevel@tonic-gate */
68*0Sstevel@tonic-gate static int tirdwropen(queue_t *q, dev_t *dev,
69*0Sstevel@tonic-gate int flag, int sflag, cred_t *cr);
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gate static int tirdwrclose(queue_t *q, int flag, cred_t *cr);
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gate static int check_strhead(queue_t *q);
74*0Sstevel@tonic-gate
75*0Sstevel@tonic-gate /*
76*0Sstevel@tonic-gate * To save instructions, since STREAMS ignores the return value
77*0Sstevel@tonic-gate * from these functions, they are defined as void here. Kind of icky, but...
78*0Sstevel@tonic-gate */
79*0Sstevel@tonic-gate static void tirdwrrput(queue_t *q, mblk_t *mp);
80*0Sstevel@tonic-gate static void tirdwrwput(queue_t *q, mblk_t *mp);
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gate static struct module_info tirdwr_info = {
83*0Sstevel@tonic-gate TIRDWR_ID,
84*0Sstevel@tonic-gate "tirdwr",
85*0Sstevel@tonic-gate 0,
86*0Sstevel@tonic-gate INFPSZ,
87*0Sstevel@tonic-gate 4096,
88*0Sstevel@tonic-gate 1024
89*0Sstevel@tonic-gate };
90*0Sstevel@tonic-gate
91*0Sstevel@tonic-gate static struct qinit tirdwrrinit = {
92*0Sstevel@tonic-gate (int (*)())tirdwrrput,
93*0Sstevel@tonic-gate (int (*)())NULL,
94*0Sstevel@tonic-gate tirdwropen,
95*0Sstevel@tonic-gate tirdwrclose,
96*0Sstevel@tonic-gate nulldev,
97*0Sstevel@tonic-gate &tirdwr_info,
98*0Sstevel@tonic-gate NULL
99*0Sstevel@tonic-gate };
100*0Sstevel@tonic-gate
101*0Sstevel@tonic-gate static struct qinit tirdwrwinit = {
102*0Sstevel@tonic-gate (int (*)())tirdwrwput,
103*0Sstevel@tonic-gate (int (*)())NULL,
104*0Sstevel@tonic-gate tirdwropen,
105*0Sstevel@tonic-gate tirdwrclose,
106*0Sstevel@tonic-gate nulldev,
107*0Sstevel@tonic-gate &tirdwr_info,
108*0Sstevel@tonic-gate NULL
109*0Sstevel@tonic-gate };
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate static struct streamtab trwinfo = {
112*0Sstevel@tonic-gate &tirdwrrinit,
113*0Sstevel@tonic-gate &tirdwrwinit,
114*0Sstevel@tonic-gate NULL,
115*0Sstevel@tonic-gate NULL
116*0Sstevel@tonic-gate };
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gate static struct fmodsw fsw = {
119*0Sstevel@tonic-gate "tirdwr",
120*0Sstevel@tonic-gate &trwinfo,
121*0Sstevel@tonic-gate D_NEW|D_MTQPAIR|D_MP
122*0Sstevel@tonic-gate };
123*0Sstevel@tonic-gate
124*0Sstevel@tonic-gate static struct modlstrmod modlstrmod = {
125*0Sstevel@tonic-gate &mod_strmodops, "xport interface rd/wr str mod", &fsw
126*0Sstevel@tonic-gate };
127*0Sstevel@tonic-gate
128*0Sstevel@tonic-gate static struct modlinkage modlinkage = {
129*0Sstevel@tonic-gate MODREV_1, &modlstrmod, NULL
130*0Sstevel@tonic-gate };
131*0Sstevel@tonic-gate
132*0Sstevel@tonic-gate int
_init(void)133*0Sstevel@tonic-gate _init(void)
134*0Sstevel@tonic-gate {
135*0Sstevel@tonic-gate return (mod_install(&modlinkage));
136*0Sstevel@tonic-gate }
137*0Sstevel@tonic-gate
138*0Sstevel@tonic-gate int
_fini(void)139*0Sstevel@tonic-gate _fini(void)
140*0Sstevel@tonic-gate {
141*0Sstevel@tonic-gate return (mod_remove(&modlinkage));
142*0Sstevel@tonic-gate }
143*0Sstevel@tonic-gate
144*0Sstevel@tonic-gate int
_info(struct modinfo * modinfop)145*0Sstevel@tonic-gate _info(struct modinfo *modinfop)
146*0Sstevel@tonic-gate {
147*0Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop));
148*0Sstevel@tonic-gate }
149*0Sstevel@tonic-gate
150*0Sstevel@tonic-gate static void send_fatal(queue_t *q, mblk_t *mp);
151*0Sstevel@tonic-gate static void strip_strhead(queue_t *q);
152*0Sstevel@tonic-gate
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate /*
155*0Sstevel@tonic-gate * tirdwropen - open routine gets called when the
156*0Sstevel@tonic-gate * module gets pushed onto the stream.
157*0Sstevel@tonic-gate */
158*0Sstevel@tonic-gate /*ARGSUSED*/
159*0Sstevel@tonic-gate static int
tirdwropen(queue_t * q,dev_t * dev,int flag,int sflag,cred_t * cr)160*0Sstevel@tonic-gate tirdwropen(
161*0Sstevel@tonic-gate queue_t *q,
162*0Sstevel@tonic-gate dev_t *dev,
163*0Sstevel@tonic-gate int flag,
164*0Sstevel@tonic-gate int sflag,
165*0Sstevel@tonic-gate cred_t *cr)
166*0Sstevel@tonic-gate {
167*0Sstevel@tonic-gate struct trw_trw *trwptr;
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gate /* check if already open */
170*0Sstevel@tonic-gate if (q->q_ptr) {
171*0Sstevel@tonic-gate return (0);
172*0Sstevel@tonic-gate }
173*0Sstevel@tonic-gate
174*0Sstevel@tonic-gate /*
175*0Sstevel@tonic-gate * Allocate a new trw_trw struct.
176*0Sstevel@tonic-gate */
177*0Sstevel@tonic-gate trwptr = kmem_alloc(sizeof (struct trw_trw), KM_SLEEP);
178*0Sstevel@tonic-gate
179*0Sstevel@tonic-gate /* initialize data structure */
180*0Sstevel@tonic-gate trwptr->trw_flags = 0;
181*0Sstevel@tonic-gate trwptr->trw_rdq = q;
182*0Sstevel@tonic-gate q->q_ptr = (caddr_t)trwptr;
183*0Sstevel@tonic-gate WR(q)->q_ptr = (caddr_t)trwptr;
184*0Sstevel@tonic-gate qprocson(q);
185*0Sstevel@tonic-gate
186*0Sstevel@tonic-gate freezestr(q);
187*0Sstevel@tonic-gate
188*0Sstevel@tonic-gate (void) strqset(WR(q), QMAXPSZ, 0, (uintptr_t)WR(q)->q_next->q_maxpsz);
189*0Sstevel@tonic-gate (void) strqset(q, QMAXPSZ, 0, (uintptr_t)q->q_next->q_maxpsz);
190*0Sstevel@tonic-gate
191*0Sstevel@tonic-gate if (!check_strhead(q)) {
192*0Sstevel@tonic-gate unfreezestr(q);
193*0Sstevel@tonic-gate qprocsoff(q);
194*0Sstevel@tonic-gate kmem_free(trwptr, sizeof (struct trw_trw));
195*0Sstevel@tonic-gate return (EPROTO);
196*0Sstevel@tonic-gate }
197*0Sstevel@tonic-gate strip_strhead(q);
198*0Sstevel@tonic-gate unfreezestr(q);
199*0Sstevel@tonic-gate
200*0Sstevel@tonic-gate return (0);
201*0Sstevel@tonic-gate }
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gate /*
204*0Sstevel@tonic-gate * tirdwrclose - This routine gets called when the module
205*0Sstevel@tonic-gate * gets popped off of the stream.
206*0Sstevel@tonic-gate */
207*0Sstevel@tonic-gate
208*0Sstevel@tonic-gate /*ARGSUSED1*/
209*0Sstevel@tonic-gate static int
tirdwrclose(queue_t * q,int flag,cred_t * cr)210*0Sstevel@tonic-gate tirdwrclose(queue_t *q, int flag, cred_t *cr)
211*0Sstevel@tonic-gate {
212*0Sstevel@tonic-gate struct trw_trw *trwptr;
213*0Sstevel@tonic-gate mblk_t *mp;
214*0Sstevel@tonic-gate union T_primitives *pptr;
215*0Sstevel@tonic-gate
216*0Sstevel@tonic-gate qprocsoff(q);
217*0Sstevel@tonic-gate trwptr = (struct trw_trw *)q->q_ptr;
218*0Sstevel@tonic-gate
219*0Sstevel@tonic-gate ASSERT(trwptr != NULL);
220*0Sstevel@tonic-gate
221*0Sstevel@tonic-gate /*
222*0Sstevel@tonic-gate * Send up a T_DISCON_IND if necessary.
223*0Sstevel@tonic-gate */
224*0Sstevel@tonic-gate if ((trwptr->trw_flags & ORDREL) && !(trwptr->trw_flags & FATAL))
225*0Sstevel@tonic-gate if (mp = allocb(sizeof (struct T_discon_req), BPRI_LO)) {
226*0Sstevel@tonic-gate pptr = (union T_primitives *)mp->b_rptr;
227*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr + sizeof (struct T_ordrel_req);
228*0Sstevel@tonic-gate pptr->type = T_ORDREL_REQ;
229*0Sstevel@tonic-gate mp->b_datap->db_type = M_PROTO;
230*0Sstevel@tonic-gate putnext(WR(q), mp);
231*0Sstevel@tonic-gate }
232*0Sstevel@tonic-gate
233*0Sstevel@tonic-gate kmem_free(trwptr, sizeof (struct trw_trw));
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate return (0);
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate
238*0Sstevel@tonic-gate /*
239*0Sstevel@tonic-gate * tirdwrrput - Module read queue put procedure.
240*0Sstevel@tonic-gate * This is called from the module or
241*0Sstevel@tonic-gate * driver downstream.
242*0Sstevel@tonic-gate */
243*0Sstevel@tonic-gate
244*0Sstevel@tonic-gate static void
tirdwrrput(queue_t * q,mblk_t * mp)245*0Sstevel@tonic-gate tirdwrrput(queue_t *q, mblk_t *mp)
246*0Sstevel@tonic-gate {
247*0Sstevel@tonic-gate union T_primitives *pptr;
248*0Sstevel@tonic-gate struct trw_trw *trwptr;
249*0Sstevel@tonic-gate mblk_t *tmp;
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate trwptr = (struct trw_trw *)q->q_ptr;
252*0Sstevel@tonic-gate
253*0Sstevel@tonic-gate ASSERT(trwptr != NULL);
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate if ((trwptr->trw_flags & FATAL) && !(trwptr->trw_flags & WAITACK)) {
256*0Sstevel@tonic-gate freemsg(mp);
257*0Sstevel@tonic-gate return;
258*0Sstevel@tonic-gate }
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gate switch (mp->b_datap->db_type) {
261*0Sstevel@tonic-gate
262*0Sstevel@tonic-gate default:
263*0Sstevel@tonic-gate putnext(q, mp);
264*0Sstevel@tonic-gate break;
265*0Sstevel@tonic-gate
266*0Sstevel@tonic-gate case M_DATA:
267*0Sstevel@tonic-gate putnext(q, mp);
268*0Sstevel@tonic-gate break;
269*0Sstevel@tonic-gate
270*0Sstevel@tonic-gate case M_PCPROTO:
271*0Sstevel@tonic-gate case M_PROTO:
272*0Sstevel@tonic-gate /* is there enough data to check type */
273*0Sstevel@tonic-gate if ((mp->b_wptr - mp->b_rptr) < sizeof (t_scalar_t)) {
274*0Sstevel@tonic-gate /* malformed message */
275*0Sstevel@tonic-gate freemsg(mp);
276*0Sstevel@tonic-gate break;
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate pptr = (union T_primitives *)mp->b_rptr;
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gate switch (pptr->type) {
281*0Sstevel@tonic-gate
282*0Sstevel@tonic-gate case T_EXDATA_IND:
283*0Sstevel@tonic-gate send_fatal(q, mp);
284*0Sstevel@tonic-gate break;
285*0Sstevel@tonic-gate case T_DATA_IND:
286*0Sstevel@tonic-gate if (msgdsize(mp) == 0) {
287*0Sstevel@tonic-gate freemsg(mp);
288*0Sstevel@tonic-gate break;
289*0Sstevel@tonic-gate }
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gate tmp = (mblk_t *)unlinkb(mp);
292*0Sstevel@tonic-gate freemsg(mp);
293*0Sstevel@tonic-gate putnext(q, tmp);
294*0Sstevel@tonic-gate break;
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate case T_ORDREL_IND:
297*0Sstevel@tonic-gate trwptr->trw_flags |= ORDREL;
298*0Sstevel@tonic-gate mp->b_datap->db_type = M_DATA;
299*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr;
300*0Sstevel@tonic-gate putnext(q, mp);
301*0Sstevel@tonic-gate break;
302*0Sstevel@tonic-gate
303*0Sstevel@tonic-gate case T_DISCON_IND:
304*0Sstevel@tonic-gate trwptr->trw_flags |= DISCON;
305*0Sstevel@tonic-gate trwptr->trw_flags &= ~ORDREL;
306*0Sstevel@tonic-gate if (msgdsize(mp) != 0) {
307*0Sstevel@tonic-gate tmp = (mblk_t *)unlinkb(mp);
308*0Sstevel@tonic-gate putnext(q, tmp);
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate mp->b_datap->db_type = M_HANGUP;
311*0Sstevel@tonic-gate mp->b_wptr = mp->b_rptr;
312*0Sstevel@tonic-gate putnext(q, mp);
313*0Sstevel@tonic-gate break;
314*0Sstevel@tonic-gate
315*0Sstevel@tonic-gate default:
316*0Sstevel@tonic-gate send_fatal(q, mp);
317*0Sstevel@tonic-gate break;
318*0Sstevel@tonic-gate }
319*0Sstevel@tonic-gate }
320*0Sstevel@tonic-gate }
321*0Sstevel@tonic-gate
322*0Sstevel@tonic-gate
323*0Sstevel@tonic-gate /*
324*0Sstevel@tonic-gate * tirdwrwput - Module write queue put procedure.
325*0Sstevel@tonic-gate * This is called from the module or
326*0Sstevel@tonic-gate * stream head upstream.
327*0Sstevel@tonic-gate */
328*0Sstevel@tonic-gate static void
tirdwrwput(queue_t * q,mblk_t * mp)329*0Sstevel@tonic-gate tirdwrwput(queue_t *q, mblk_t *mp)
330*0Sstevel@tonic-gate {
331*0Sstevel@tonic-gate struct trw_trw *trwptr;
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gate trwptr = (struct trw_trw *)q->q_ptr;
334*0Sstevel@tonic-gate
335*0Sstevel@tonic-gate ASSERT(trwptr != NULL);
336*0Sstevel@tonic-gate
337*0Sstevel@tonic-gate if (trwptr->trw_flags & FATAL) {
338*0Sstevel@tonic-gate freemsg(mp);
339*0Sstevel@tonic-gate return;
340*0Sstevel@tonic-gate }
341*0Sstevel@tonic-gate
342*0Sstevel@tonic-gate switch (mp->b_datap->db_type) {
343*0Sstevel@tonic-gate default:
344*0Sstevel@tonic-gate putnext(q, mp);
345*0Sstevel@tonic-gate break;
346*0Sstevel@tonic-gate
347*0Sstevel@tonic-gate case M_DATA:
348*0Sstevel@tonic-gate putnext(q, mp);
349*0Sstevel@tonic-gate break;
350*0Sstevel@tonic-gate
351*0Sstevel@tonic-gate case M_PROTO:
352*0Sstevel@tonic-gate case M_PCPROTO:
353*0Sstevel@tonic-gate send_fatal(q, mp);
354*0Sstevel@tonic-gate break;
355*0Sstevel@tonic-gate }
356*0Sstevel@tonic-gate }
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gate
359*0Sstevel@tonic-gate static void
send_fatal(queue_t * q,mblk_t * mp)360*0Sstevel@tonic-gate send_fatal(queue_t *q, mblk_t *mp)
361*0Sstevel@tonic-gate {
362*0Sstevel@tonic-gate struct trw_trw *trwptr;
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gate trwptr = (struct trw_trw *)q->q_ptr;
365*0Sstevel@tonic-gate
366*0Sstevel@tonic-gate trwptr->trw_flags |= FATAL;
367*0Sstevel@tonic-gate mp->b_datap->db_type = M_ERROR;
368*0Sstevel@tonic-gate *mp->b_datap->db_base = EPROTO;
369*0Sstevel@tonic-gate mp->b_rptr = mp->b_datap->db_base;
370*0Sstevel@tonic-gate mp->b_wptr = mp->b_datap->db_base + sizeof (char);
371*0Sstevel@tonic-gate freemsg(unlinkb(mp));
372*0Sstevel@tonic-gate if (q->q_flag&QREADR)
373*0Sstevel@tonic-gate putnext(q, mp);
374*0Sstevel@tonic-gate else
375*0Sstevel@tonic-gate qreply(q, mp);
376*0Sstevel@tonic-gate }
377*0Sstevel@tonic-gate
378*0Sstevel@tonic-gate static int
check_strhead(queue_t * q)379*0Sstevel@tonic-gate check_strhead(queue_t *q)
380*0Sstevel@tonic-gate {
381*0Sstevel@tonic-gate mblk_t *mp;
382*0Sstevel@tonic-gate union T_primitives *pptr;
383*0Sstevel@tonic-gate
384*0Sstevel@tonic-gate for (mp = q->q_next->q_first; mp != NULL; mp = mp->b_next) {
385*0Sstevel@tonic-gate
386*0Sstevel@tonic-gate switch (mp->b_datap->db_type) {
387*0Sstevel@tonic-gate case M_PROTO:
388*0Sstevel@tonic-gate pptr = (union T_primitives *)mp->b_rptr;
389*0Sstevel@tonic-gate if ((mp->b_wptr - mp->b_rptr) < sizeof (t_scalar_t))
390*0Sstevel@tonic-gate return (0);
391*0Sstevel@tonic-gate switch (pptr->type) {
392*0Sstevel@tonic-gate
393*0Sstevel@tonic-gate case T_EXDATA_IND:
394*0Sstevel@tonic-gate return (0);
395*0Sstevel@tonic-gate case T_DATA_IND:
396*0Sstevel@tonic-gate if (mp->b_cont &&
397*0Sstevel@tonic-gate (mp->b_cont->b_datap->db_type != M_DATA))
398*0Sstevel@tonic-gate return (0);
399*0Sstevel@tonic-gate break;
400*0Sstevel@tonic-gate default:
401*0Sstevel@tonic-gate return (0);
402*0Sstevel@tonic-gate }
403*0Sstevel@tonic-gate break;
404*0Sstevel@tonic-gate
405*0Sstevel@tonic-gate case M_PCPROTO:
406*0Sstevel@tonic-gate return (0);
407*0Sstevel@tonic-gate
408*0Sstevel@tonic-gate case M_DATA:
409*0Sstevel@tonic-gate case M_SIG:
410*0Sstevel@tonic-gate break;
411*0Sstevel@tonic-gate default:
412*0Sstevel@tonic-gate return (0);
413*0Sstevel@tonic-gate }
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate return (1);
416*0Sstevel@tonic-gate }
417*0Sstevel@tonic-gate
418*0Sstevel@tonic-gate static void
strip_strhead(queue_t * q)419*0Sstevel@tonic-gate strip_strhead(queue_t *q)
420*0Sstevel@tonic-gate {
421*0Sstevel@tonic-gate mblk_t *mp;
422*0Sstevel@tonic-gate mblk_t *emp;
423*0Sstevel@tonic-gate mblk_t *tmp;
424*0Sstevel@tonic-gate union T_primitives *pptr;
425*0Sstevel@tonic-gate
426*0Sstevel@tonic-gate q = q->q_next;
427*0Sstevel@tonic-gate /*CSTYLED*/
428*0Sstevel@tonic-gate for (mp = q->q_first; mp != NULL; ) {
429*0Sstevel@tonic-gate
430*0Sstevel@tonic-gate switch (mp->b_datap->db_type) {
431*0Sstevel@tonic-gate case M_PROTO:
432*0Sstevel@tonic-gate pptr = (union T_primitives *)mp->b_rptr;
433*0Sstevel@tonic-gate switch (pptr->type) {
434*0Sstevel@tonic-gate
435*0Sstevel@tonic-gate case T_DATA_IND:
436*0Sstevel@tonic-gate if (msgdsize(mp) == 0) {
437*0Sstevel@tonic-gate strip0:
438*0Sstevel@tonic-gate tmp = mp->b_next;
439*0Sstevel@tonic-gate rmvq(q, mp);
440*0Sstevel@tonic-gate freemsg(mp);
441*0Sstevel@tonic-gate mp = tmp;
442*0Sstevel@tonic-gate break;
443*0Sstevel@tonic-gate }
444*0Sstevel@tonic-gate emp = mp->b_next;
445*0Sstevel@tonic-gate rmvq(q, mp);
446*0Sstevel@tonic-gate tmp = (mblk_t *)unlinkb(mp);
447*0Sstevel@tonic-gate freeb(mp);
448*0Sstevel@tonic-gate (void) insq(q, emp, tmp);
449*0Sstevel@tonic-gate mp = emp;
450*0Sstevel@tonic-gate break;
451*0Sstevel@tonic-gate }
452*0Sstevel@tonic-gate break;
453*0Sstevel@tonic-gate
454*0Sstevel@tonic-gate case M_DATA:
455*0Sstevel@tonic-gate if (msgdsize(mp) == 0)
456*0Sstevel@tonic-gate goto strip0;
457*0Sstevel@tonic-gate mp = mp->b_next;
458*0Sstevel@tonic-gate break;
459*0Sstevel@tonic-gate
460*0Sstevel@tonic-gate case M_SIG:
461*0Sstevel@tonic-gate mp = mp->b_next;
462*0Sstevel@tonic-gate break;
463*0Sstevel@tonic-gate }
464*0Sstevel@tonic-gate }
465*0Sstevel@tonic-gate }
466