1 /* 2 * CDDL HEADER START 3 * 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 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1993-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 /* 31 * t_sndrel.c and t_sndreldata.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. 34 */ 35 #include "mt.h" 36 #include <rpc/trace.h> 37 #include <rpc/trace.h> 38 #include <errno.h> 39 #include <stropts.h> 40 #include <sys/stream.h> 41 #define _SUN_TPI_VERSION 2 42 #include <sys/tihdr.h> 43 #include <sys/timod.h> 44 #include <xti.h> 45 #include <assert.h> 46 #include "tx.h" 47 48 int 49 _tx_sndreldata(int fd, struct t_discon *discon, int api_semantics) 50 { 51 struct T_ordrel_req orreq; 52 struct strbuf ctlbuf; 53 struct _ti_user *tiptr; 54 int sv_errno; 55 56 trace2(TR_t_sndreldata, 0, fd); 57 assert(api_semantics == TX_XTI_XNS5_API); 58 if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL) { 59 sv_errno = errno; 60 trace2(TR_t_sndreldata, 1, fd); 61 errno = sv_errno; 62 return (-1); 63 } 64 sig_mutex_lock(&tiptr->ti_lock); 65 66 if (tiptr->ti_servtype != T_COTS_ORD) { 67 t_errno = TNOTSUPPORT; 68 sig_mutex_unlock(&tiptr->ti_lock); 69 trace2(TR_t_sndreldata, 1, fd); 70 return (-1); 71 } 72 73 if (! (tiptr->ti_state == T_DATAXFER || 74 tiptr->ti_state == T_INREL)) { 75 t_errno = TOUTSTATE; 76 sig_mutex_unlock(&tiptr->ti_lock); 77 trace2(TR_t_sndreldata, 1, fd); 78 return (-1); 79 } 80 81 if (_t_look_locked(fd, tiptr, 0, 82 api_semantics) == T_DISCONNECT) { 83 t_errno = TLOOK; 84 sig_mutex_unlock(&tiptr->ti_lock); 85 trace2(TR_t_sndreldata, 1, fd); 86 return (-1); 87 } 88 89 /* 90 * Someday there could be transport providers that support T_ORDRELDATA 91 * Until that happens, this function returns TBADDATA if user data 92 * was specified. If no user data is specified, this function 93 * behaves as t_sndrel() 94 * Note: Currently only mOSI ("minimal OSI") provider is specified 95 * to use T_ORDRELDATA so probability of needing it is minimal. 96 */ 97 98 if (discon && discon->udata.len) { 99 t_errno = TBADDATA; 100 sig_mutex_unlock(&tiptr->ti_lock); 101 return (-1); 102 } 103 104 orreq.PRIM_type = T_ORDREL_REQ; 105 ctlbuf.maxlen = (int)sizeof (struct T_ordrel_req); 106 ctlbuf.len = (int)sizeof (struct T_ordrel_req); 107 ctlbuf.buf = (caddr_t)&orreq; 108 109 /* 110 * Calls to send data (write or putmsg) can potentially 111 * block, for MT case, we drop the lock and enable signals here 112 * and acquire it back 113 */ 114 sig_mutex_unlock(&tiptr->ti_lock); 115 if (putmsg(fd, &ctlbuf, NULL, 0) < 0) { 116 sv_errno = errno; 117 118 if (errno == EAGAIN) 119 t_errno = TFLOW; 120 else 121 t_errno = TSYSERR; 122 trace2(TR_t_sndreldata, 1, fd); 123 errno = sv_errno; 124 return (-1); 125 } 126 sig_mutex_lock(&tiptr->ti_lock); 127 _T_TX_NEXTSTATE(T_SNDREL, tiptr, 128 "t_sndreldata: invalid state on event T_SNDREL"); 129 sig_mutex_unlock(&tiptr->ti_lock); 130 trace2(TR_t_sndreldata, 1, fd); 131 return (0); 132 } 133