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_rcvrel.c and t_rcvreldata.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.
39 #include <sys/stream.h>
40 #define _SUN_TPI_VERSION 2
41 #include <sys/tihdr.h>
42 #include <sys/timod.h>
51 _tx_rcvreldata(int fd
, struct t_discon
*discon
, int api_semantics
)
54 struct strbuf databuf
;
56 union T_primitives
*pptr
;
57 struct _ti_user
*tiptr
;
59 int didalloc
, didralloc
;
64 assert(api_semantics
== TX_XTI_XNS5_API
);
65 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == 0)
67 sig_mutex_lock(&tiptr
->ti_lock
);
69 if (tiptr
->ti_servtype
!= T_COTS_ORD
) {
70 t_errno
= TNOTSUPPORT
;
71 sig_mutex_unlock(&tiptr
->ti_lock
);
75 if (!(tiptr
->ti_state
== T_DATAXFER
||
76 tiptr
->ti_state
== T_OUTREL
)) {
78 sig_mutex_unlock(&tiptr
->ti_lock
);
82 if ((retval
= _t_look_locked(fd
, tiptr
, 0, api_semantics
)) < 0) {
84 sig_mutex_unlock(&tiptr
->ti_lock
);
89 if (retval
== T_DISCONNECT
) {
91 * This ensures preference to T_DISCON_IND which is
92 * the design model for TPI
95 sig_mutex_unlock(&tiptr
->ti_lock
);
100 * Someday there could be transport providers that support T_ORDRELDATA
101 * Until then this function behaves the same as t_rcvrel()
102 * Note: Currently only mOSI ("minimal OSI") provider is specified
103 * to use T_ORDRELDATA so probability of needing it is minimal.
106 if ((tiptr
->ti_lookcnt
> 0) &&
107 /* LINTED pointer cast */
108 (*((t_scalar_t
*)tiptr
->ti_lookbufs
.tl_lookcbuf
) == T_ORDREL_IND
)) {
110 * Current look buffer event is T_ORDREL_IND.
111 * Remove it from look buffer event list.
113 _t_free_looklist_head(tiptr
);
114 _T_TX_NEXTSTATE(T_RCVREL
, tiptr
,
115 "t_rcvreldata: invalid state event T_RCVREL");
116 sig_mutex_unlock(&tiptr
->ti_lock
);
119 if (retval
!= T_ORDREL
) {
121 sig_mutex_unlock(&tiptr
->ti_lock
);
127 * get ordrel off read queue.
128 * use ctl and rcv buffers
130 * Acquire ctlbuf for use in sending/receiving control part
133 if (_t_acquire_ctlbuf(tiptr
, &ctlbuf
, &didalloc
) < 0) {
135 sig_mutex_unlock(&tiptr
->ti_lock
);
141 * Acquire databuf for use in sending/receiving data part
143 if (_t_acquire_databuf(tiptr
, &databuf
, &didralloc
) < 0) {
148 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
149 sig_mutex_unlock(&tiptr
->ti_lock
);
155 * Since we have verified above that an orderly release event
156 * is pending on this endpoint, we assume that this getmsg()
157 * cannot block forever.
160 retval
= getmsg(fd
, &ctlbuf
, &databuf
, &flg
);
161 } while (retval
< 0 && errno
== EINTR
);
169 * did I get entire message?
176 /* LINTED pointer cast */
177 pptr
= (union T_primitives
*)ctlbuf
.buf
;
179 if (ctlbuf
.len
< (int)sizeof (struct T_ordrel_ind
)) {
184 if (pptr
->type
!= T_ORDREL_IND
) {
185 if (pptr
->type
== T_DISCON_IND
) {
187 * T_DISCON_IND gets priority following
188 * TPI design philosphy.
190 * Add it to the events in the "look buffer"
191 * list of events. This routine may defer signals.
193 if (_t_register_lookevent(tiptr
, databuf
.buf
,
194 databuf
.len
, ctlbuf
.buf
,
209 _T_TX_NEXTSTATE(T_RCVREL
, tiptr
,
210 "t_rcvreldata: invalid state event T_RCVREL");
215 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
219 tiptr
->ti_rcvbuf
= databuf
.buf
;
220 sig_mutex_unlock(&tiptr
->ti_lock
);
229 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
233 tiptr
->ti_rcvbuf
= databuf
.buf
;
234 sig_mutex_unlock(&tiptr
->ti_lock
);