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