17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 2261961e0fSrobinson 237c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 247c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 27e8031f0aSraf * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 287c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*09b0d01cSGary Mills * Copyright 2014 Gary Mills 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include "mt.h" 337c478bd9Sstevel@tonic-gate #include <errno.h> 347c478bd9Sstevel@tonic-gate #include <unistd.h> 357c478bd9Sstevel@tonic-gate #include <sys/stream.h> 367c478bd9Sstevel@tonic-gate #include <stropts.h> 377c478bd9Sstevel@tonic-gate #define _SUN_TPI_VERSION 2 387c478bd9Sstevel@tonic-gate #include <sys/tihdr.h> 397c478bd9Sstevel@tonic-gate #include <sys/timod.h> 407c478bd9Sstevel@tonic-gate #include <xti.h> 417c478bd9Sstevel@tonic-gate #include <assert.h> 427c478bd9Sstevel@tonic-gate #include "tx.h" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate int 457c478bd9Sstevel@tonic-gate _tx_look(int fd, int api_semantics) 467c478bd9Sstevel@tonic-gate { 477c478bd9Sstevel@tonic-gate int state; 487c478bd9Sstevel@tonic-gate int sv_errno; 497c478bd9Sstevel@tonic-gate int do_expinline_peek; /* unusual XTI specific processing */ 507c478bd9Sstevel@tonic-gate struct _ti_user *tiptr; 517c478bd9Sstevel@tonic-gate 5261961e0fSrobinson if ((tiptr = _t_checkfd(fd, 0, api_semantics)) == NULL) 537c478bd9Sstevel@tonic-gate return (-1); 547c478bd9Sstevel@tonic-gate sig_mutex_lock(&tiptr->ti_lock); 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate if (_T_IS_XTI(api_semantics)) 577c478bd9Sstevel@tonic-gate do_expinline_peek = 1; 587c478bd9Sstevel@tonic-gate else 597c478bd9Sstevel@tonic-gate do_expinline_peek = 0; 607c478bd9Sstevel@tonic-gate state = _t_look_locked(fd, tiptr, do_expinline_peek, api_semantics); 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate sv_errno = errno; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate sig_mutex_unlock(&tiptr->ti_lock); 657c478bd9Sstevel@tonic-gate errno = sv_errno; 667c478bd9Sstevel@tonic-gate return (state); 677c478bd9Sstevel@tonic-gate } 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate /* 707c478bd9Sstevel@tonic-gate * _t_look_locked() assumes tiptr->ti_lock lock is already held and signals 717c478bd9Sstevel@tonic-gate * already blocked in MT case. 727c478bd9Sstevel@tonic-gate * Intended for use by other TLI routines only. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate int 757c478bd9Sstevel@tonic-gate _t_look_locked( 767c478bd9Sstevel@tonic-gate int fd, 777c478bd9Sstevel@tonic-gate struct _ti_user *tiptr, 787c478bd9Sstevel@tonic-gate int do_expinline_peek, 797c478bd9Sstevel@tonic-gate int api_semantics 807c478bd9Sstevel@tonic-gate ) 817c478bd9Sstevel@tonic-gate { 827c478bd9Sstevel@tonic-gate struct strpeek strpeek; 8361961e0fSrobinson int retval; 847c478bd9Sstevel@tonic-gate union T_primitives *pptr; 857c478bd9Sstevel@tonic-gate t_scalar_t type; 867c478bd9Sstevel@tonic-gate t_scalar_t ctltype; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate assert(MUTEX_HELD(&tiptr->ti_lock)); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate #ifdef notyet 917c478bd9Sstevel@tonic-gate if (_T_IS_XTI(api_semantics)) { 927c478bd9Sstevel@tonic-gate /* 937c478bd9Sstevel@tonic-gate * XTI requires the strange T_GODATA and T_GOEXDATA 947c478bd9Sstevel@tonic-gate * events which are almost brain-damaged but thankfully 957c478bd9Sstevel@tonic-gate * not tested. Anyone feeling the need for those should 967c478bd9Sstevel@tonic-gate * consider the need for using non-blocking endpoint. 977c478bd9Sstevel@tonic-gate * Probably introduced at the behest of some weird-os 987c478bd9Sstevel@tonic-gate * vendor which did not understand the non-blocking endpoint 997c478bd9Sstevel@tonic-gate * option. 1007c478bd9Sstevel@tonic-gate * We choose not to implment these mis-features. 1017c478bd9Sstevel@tonic-gate * Here is the plan-of-action (POA)if we are ever forced 1027c478bd9Sstevel@tonic-gate * to implement these. 1037c478bd9Sstevel@tonic-gate * - When returning TFLOW set state to indicate if it was 1047c478bd9Sstevel@tonic-gate * a normal or expedited data send attempt. 1057c478bd9Sstevel@tonic-gate * - In routines that set TFLOW, clear the above set state 1067c478bd9Sstevel@tonic-gate * on each entry/reentry 1077c478bd9Sstevel@tonic-gate * - In this routine, if that state flag is set, 1087c478bd9Sstevel@tonic-gate * do a I_CANPUT on appropriate band to to see if it 1097c478bd9Sstevel@tonic-gate * is writeable. If that indicates that the band is 1107c478bd9Sstevel@tonic-gate * writeable, return T_GODATA or T_GOEXDATA event. 1117c478bd9Sstevel@tonic-gate * 1127c478bd9Sstevel@tonic-gate * Actions are also influenced by whether T_EXDATA_REQ stays 1137c478bd9Sstevel@tonic-gate * band 1 or goes to band 0 if EXPINLINE is set 1147c478bd9Sstevel@tonic-gate * 1157c478bd9Sstevel@tonic-gate * We will also need to sort out if "write side" events 1167c478bd9Sstevel@tonic-gate * (such as T_GODATA/T_GOEXDATA) take precedence over 1177c478bd9Sstevel@tonic-gate * all other events (all read side) or not. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate } 1207c478bd9Sstevel@tonic-gate #endif /* notyet */ 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate strpeek.ctlbuf.maxlen = (int)sizeof (ctltype); 1237c478bd9Sstevel@tonic-gate strpeek.ctlbuf.len = 0; 1247c478bd9Sstevel@tonic-gate strpeek.ctlbuf.buf = (char *)&ctltype; 1257c478bd9Sstevel@tonic-gate strpeek.databuf.maxlen = 0; 1267c478bd9Sstevel@tonic-gate strpeek.databuf.len = 0; 1277c478bd9Sstevel@tonic-gate strpeek.databuf.buf = NULL; 1287c478bd9Sstevel@tonic-gate strpeek.flags = 0; 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate do { 131e8031f0aSraf retval = ioctl(fd, I_PEEK, &strpeek); 1327c478bd9Sstevel@tonic-gate } while (retval < 0 && errno == EINTR); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate if (retval < 0) { 1357c478bd9Sstevel@tonic-gate /* 136*09b0d01cSGary Mills * XTI semantics (also identical to documented 137*09b0d01cSGary Mills * TLI semantics). 1387c478bd9Sstevel@tonic-gate */ 1397c478bd9Sstevel@tonic-gate t_errno = TSYSERR; 1407c478bd9Sstevel@tonic-gate return (-1); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate /* 1447c478bd9Sstevel@tonic-gate * if something there and cntl part also there 1457c478bd9Sstevel@tonic-gate */ 1467c478bd9Sstevel@tonic-gate if ((tiptr->ti_lookcnt > 0) || 147*09b0d01cSGary Mills ((retval > 0) && (strpeek.ctlbuf.len >= 148*09b0d01cSGary Mills (int)sizeof (t_scalar_t)))) { 14961961e0fSrobinson /* LINTED pointer cast */ 1507c478bd9Sstevel@tonic-gate pptr = (union T_primitives *)strpeek.ctlbuf.buf; 1517c478bd9Sstevel@tonic-gate if (tiptr->ti_lookcnt > 0) { 15261961e0fSrobinson /* LINTED pointer cast */ 1537c478bd9Sstevel@tonic-gate type = *((t_scalar_t *)tiptr->ti_lookbufs.tl_lookcbuf); 1547c478bd9Sstevel@tonic-gate /* 1557c478bd9Sstevel@tonic-gate * If message on stream head is a T_DISCON_IND, that 1567c478bd9Sstevel@tonic-gate * has priority over a T_ORDREL_IND in the look 1577c478bd9Sstevel@tonic-gate * buffer. 1587c478bd9Sstevel@tonic-gate * (This assumes that T_ORDREL_IND can only be in the 1597c478bd9Sstevel@tonic-gate * first look buffer in the list) 1607c478bd9Sstevel@tonic-gate */ 1617c478bd9Sstevel@tonic-gate if ((type == T_ORDREL_IND) && retval && 1627c478bd9Sstevel@tonic-gate (pptr->type == T_DISCON_IND)) { 1637c478bd9Sstevel@tonic-gate type = pptr->type; 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate * Blow away T_ORDREL_IND 1667c478bd9Sstevel@tonic-gate */ 1677c478bd9Sstevel@tonic-gate _t_free_looklist_head(tiptr); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate } else 1707c478bd9Sstevel@tonic-gate type = pptr->type; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate switch (type) { 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate case T_CONN_IND: 1757c478bd9Sstevel@tonic-gate return (T_LISTEN); 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate case T_CONN_CON: 1787c478bd9Sstevel@tonic-gate return (T_CONNECT); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate case T_DISCON_IND: 1817c478bd9Sstevel@tonic-gate return (T_DISCONNECT); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate case T_DATA_IND: { 1847c478bd9Sstevel@tonic-gate int event = T_DATA; 1857c478bd9Sstevel@tonic-gate int retval, exp_on_q; 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate if (do_expinline_peek && 1887c478bd9Sstevel@tonic-gate (tiptr->ti_prov_flag & EXPINLINE)) { 1897c478bd9Sstevel@tonic-gate assert(_T_IS_XTI(api_semantics)); 1907c478bd9Sstevel@tonic-gate retval = _t_expinline_queued(fd, &exp_on_q); 1917c478bd9Sstevel@tonic-gate if (retval < 0) { 1927c478bd9Sstevel@tonic-gate t_errno = TSYSERR; 1937c478bd9Sstevel@tonic-gate return (-1); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate if (exp_on_q) 1967c478bd9Sstevel@tonic-gate event = T_EXDATA; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate return (event); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate case T_UNITDATA_IND: 2027c478bd9Sstevel@tonic-gate return (T_DATA); 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate case T_EXDATA_IND: 2057c478bd9Sstevel@tonic-gate return (T_EXDATA); 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate case T_UDERROR_IND: 2087c478bd9Sstevel@tonic-gate return (T_UDERR); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate case T_ORDREL_IND: 2117c478bd9Sstevel@tonic-gate return (T_ORDREL); 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate default: 2147c478bd9Sstevel@tonic-gate t_errno = TSYSERR; 2157c478bd9Sstevel@tonic-gate errno = EPROTO; 2167c478bd9Sstevel@tonic-gate return (-1); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate } 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate /* 2217c478bd9Sstevel@tonic-gate * if something there put no control part 2227c478bd9Sstevel@tonic-gate * it must be data on the stream head. 2237c478bd9Sstevel@tonic-gate */ 2247c478bd9Sstevel@tonic-gate if ((retval > 0) && (strpeek.ctlbuf.len <= 0)) { 2257c478bd9Sstevel@tonic-gate int event = T_DATA; 2267c478bd9Sstevel@tonic-gate int retval, exp_on_q; 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate if (do_expinline_peek && 2297c478bd9Sstevel@tonic-gate (tiptr->ti_prov_flag & EXPINLINE)) { 2307c478bd9Sstevel@tonic-gate assert(_T_IS_XTI(api_semantics)); 2317c478bd9Sstevel@tonic-gate retval = _t_expinline_queued(fd, &exp_on_q); 23261961e0fSrobinson if (retval < 0) 2337c478bd9Sstevel@tonic-gate return (-1); 2347c478bd9Sstevel@tonic-gate if (exp_on_q) 2357c478bd9Sstevel@tonic-gate event = T_EXDATA; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate return (event); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * if msg there and control 2427c478bd9Sstevel@tonic-gate * part not large enough to determine type? 2437c478bd9Sstevel@tonic-gate * it must be illegal TLI message 2447c478bd9Sstevel@tonic-gate */ 2457c478bd9Sstevel@tonic-gate if ((retval > 0) && (strpeek.ctlbuf.len > 0)) { 2467c478bd9Sstevel@tonic-gate t_errno = TSYSERR; 2477c478bd9Sstevel@tonic-gate errno = EPROTO; 2487c478bd9Sstevel@tonic-gate return (-1); 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate return (0); 2517c478bd9Sstevel@tonic-gate } 252