4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #pragma ident "%Z%%M% %I% %E% SMI"
31 * t_rcvudata.c and t_rcvvudata.c are very similar and contain common code.
32 * Any changes to either of them should be reviewed to see whether they
33 * are applicable to the other file.
40 #include <sys/stream.h>
41 #define _SUN_TPI_VERSION 2
42 #include <sys/tihdr.h>
43 #include <sys/timod.h>
53 struct t_unitdata
*unitdata
,
55 unsigned int tiovcount
,
61 struct strbuf databuf
;
64 union T_primitives
*pptr
;
65 struct _ti_user
*tiptr
;
71 assert(api_semantics
== TX_XTI_XNS5_API
);
73 if (tiovcount
== 0 || tiovcount
> T_IOV_MAX
) {
78 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == NULL
)
80 sig_mutex_lock(&tiptr
->ti_lock
);
82 if (tiptr
->ti_servtype
!= T_CLTS
) {
83 t_errno
= TNOTSUPPORT
;
84 sig_mutex_unlock(&tiptr
->ti_lock
);
88 if (tiptr
->ti_state
!= T_IDLE
) {
90 sig_mutex_unlock(&tiptr
->ti_lock
);
95 * check if there is something in look buffer
97 if (tiptr
->ti_lookcnt
> 0) {
98 sig_mutex_unlock(&tiptr
->ti_lock
);
104 * Acquire ctlbuf for use in sending/receiving control part
107 if (_t_acquire_ctlbuf(tiptr
, &ctlbuf
, &didalloc
) < 0) {
109 sig_mutex_unlock(&tiptr
->ti_lock
);
116 nbytes
= _t_bytecount_upto_intmax(tiov
, tiovcount
);
118 if (nbytes
!= 0 && ((dataptr
= malloc(nbytes
)) == NULL
)) {
123 databuf
.maxlen
= nbytes
;
125 databuf
.buf
= dataptr
;
128 * This is a call that may block indefinitely so we drop the
129 * lock and allow signals in MT case here and reacquire it.
130 * Error case should roll back state changes done above
131 * (happens to be no state change here)
133 sig_mutex_unlock(&tiptr
->ti_lock
);
134 if ((retval
= getmsg(fd
, &ctlbuf
, &databuf
, &flg
)) < 0) {
140 sig_mutex_lock(&tiptr
->ti_lock
);
144 sig_mutex_lock(&tiptr
->ti_lock
);
147 * is there control piece with data?
149 if (ctlbuf
.len
> 0) {
150 if (ctlbuf
.len
< (int)sizeof (t_scalar_t
)) {
156 /* LINTED pointer cast */
157 pptr
= (union T_primitives
*)ctlbuf
.buf
;
159 switch (pptr
->type
) {
163 (int)sizeof (struct T_unitdata_ind
)) ||
164 (pptr
->unitdata_ind
.OPT_length
&&
165 (ctlbuf
.len
< (int)(pptr
->unitdata_ind
.OPT_length
166 + pptr
->unitdata_ind
.OPT_offset
)))) {
172 if (unitdata
->addr
.maxlen
> 0) {
173 if (TLEN_GT_NLEN(pptr
->unitdata_ind
.SRC_length
,
174 unitdata
->addr
.maxlen
)) {
178 (void) memcpy(unitdata
->addr
.buf
,
179 ctlbuf
.buf
+ pptr
->unitdata_ind
.SRC_offset
,
180 (size_t)pptr
->unitdata_ind
.SRC_length
);
182 pptr
->unitdata_ind
.SRC_length
;
184 if (unitdata
->opt
.maxlen
> 0) {
185 if (TLEN_GT_NLEN(pptr
->unitdata_ind
.OPT_length
,
186 unitdata
->opt
.maxlen
)) {
190 (void) memcpy(unitdata
->opt
.buf
, ctlbuf
.buf
+
191 pptr
->unitdata_ind
.OPT_offset
,
192 (size_t)pptr
->unitdata_ind
.OPT_length
);
194 pptr
->unitdata_ind
.OPT_length
;
196 if (retval
& MOREDATA
)
199 * No state changes happens on T_RCVUDATA
200 * event (NOOP). We do it only to log errors.
202 _T_TX_NEXTSTATE(T_RCVUDATA
, tiptr
,
203 "t_rcvvudata: invalid state event T_RCVUDATA");
208 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
209 _t_scatter(&databuf
, tiov
, tiovcount
);
212 sig_mutex_unlock(&tiptr
->ti_lock
);
213 return (databuf
.len
);
216 if (_t_register_lookevent(tiptr
, 0, 0, ctlbuf
.buf
,
233 } else { /* else part of "if (ctlbuf.len > 0)" */
234 unitdata
->addr
.len
= 0;
235 unitdata
->opt
.len
= 0;
237 * only data in message no control piece
239 if (retval
& MOREDATA
)
242 * No state transition occurs on
243 * event T_RCVUDATA. We do it only to
246 _T_TX_NEXTSTATE(T_RCVUDATA
, tiptr
,
247 "t_rcvvudata: invalid state event T_RCVUDATA");
251 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
252 _t_scatter(&databuf
, tiov
, tiovcount
);
255 sig_mutex_unlock(&tiptr
->ti_lock
);
256 return (databuf
.len
);
264 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
267 sig_mutex_unlock(&tiptr
->ti_lock
);