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 (c) 2001 by Sun Microsystems, Inc.
  24  * All rights reserved.
  25  */
  26 
  27 #ifndef _TTYMUX_IMPL_H
  28 #define _TTYMUX_IMPL_H
  29 
  30 #pragma ident   "%Z%%M% %I%     %E% SMI"
  31 
  32 #ifdef  __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 #include <sys/types32.h>
  37 #include <sys/param.h>
  38 
  39 /*
  40  * Local definitions.
  41  */
  42 #define SM_TRBIT(code)          (1 << (code)-'@')
  43 
  44 extern uint_t  sm_max_units;
  45 
  46 #define MAX_LQS (sm_max_units)
  47 #define NLUNITS (MAX_LQS + 2)
  48 
  49 /*
  50  * Re-use minor device encoding used by the se(7D) driver.
  51  */
  52 #define ASYNC_DEVICE    (0)
  53 #define OUTLINE         (1 << (NBITSMINOR32 - 1))
  54 #define NULL_PROTOCOL   0
  55 #define ASYN_PROTOCOL   1
  56 #define OUTD_PROTOCOL   2
  57 
  58 #define DEV_TO_UNIT(dev)        (getminor(dev) & ~OUTLINE)
  59 #define DEV_TO_PROTOBITS(dev)   (getminor(dev) & OUTLINE)
  60 
  61 /*
  62  * Driver id
  63  */
  64 #define SM_MOD_ID       0x534d
  65 
  66 /*
  67  * Access modes of the two halves to each others flags
  68  * Q    uq->flags lq->flags
  69  * uq   rw              r
  70  * lq   -                rw
  71  */
  72 /*
  73  * A lower queue is associated with an upper queue
  74  * (used for synchronising dissasociate reqests with the lower half)
  75  * A lower q will not forward messages if SM_UQVALID is set in uqflags.
  76  */
  77 #define SM_UQVALID      (0x1)   /* written by an upper q read by a lower q */
  78 #define SM_OBPCNDEV     (0x2)   /* set when this device is an OBP console */
  79 
  80 /*
  81  * unused flags
  82  */
  83 #define FLUSHR_PEND     (0x1)   /* M_FLUSH is expected on all the lr q's */
  84 
  85 /*
  86  * An open has completed on this stream.
  87  */
  88 #define FULLY_OPEN      (0x2)
  89 #define EXCL_OPEN       (0x4)
  90 
  91 #define SM_CARON        (0x8)
  92 /*
  93  * Flags to disable queues controlled from below.
  94  */
  95 #define HANGUP_MODE     (0x10) /* not used (sets WERROR_MODE instead) */
  96 #define RERROR_MODE     (0x20) /* read error on stream (unset by closing) */
  97 #define WERROR_MODE     (0x40) /* write side error on the stream (set by */
  98                                 /* M_HANGUP/M_ERROR */
  99                                 /* unset by M_UNHANGUP/M_ERROR) */
 100 #define ERROR_MODE      (0x60)  /* read error on stream (unset by M_ERROR) */
 101 
 102 /*
 103  * Flags to disable queues controlled from above.
 104  * Also used by set on queues which are OBP consoles
 105  */
 106 #define SM_STOPPED      (0x080) /* M_STOP has been seen */
 107 #define SM_ISTOPPED     (0x100) /* M_STOPI has been seen */
 108 
 109 /*
 110  * A stream wants something.
 111  */
 112 #define WANT_SC         (0x200) /* carrier status of a stream required */
 113 #define WANT_CL         (0x400) /* CLOCAL status of a stream required */
 114 #define WANT_CD         (0x800) /* CD modem status of a line required */
 115 #define WANT_CDSTAT     (0xe00)
 116 #define WANT_TCSET      (0x20000) /* send down initial termios settings */
 117 
 118 #define WANT_RENB       (0x40000) /* read q is flowcontrolled */
 119 
 120 #define SM_IOCPENDING   (0x80000)
 121 #define SM_CLOSE        (0x100000)
 122 #define SM_INTERNALIOC  (0x200000)
 123 
 124 #define SM_LOGINREQ     (0x400000)
 125 
 126 #define LOCK_UNIT(u)    (mutex_enter(u->sm_umutex)) /* Lock per-stream data */
 127 #define UNLOCK_UNIT(u)  (mutex_exit(u->sm_umutex)) /* Unlock per-stream data */
 128 
 129 /*
 130  * Checks whether an open could potentially block.
 131  */
 132 #define BLOCKING(unitp, proto, flag)    \
 133         (!(flag & (FNDELAY|FNONBLOCK)) &&   \
 134         !(proto == OUTLINE) &&                  \
 135         unitp->sm_lqs &&                             \
 136         (unitp->sm_flags & SM_CARON) == 0)
 137 
 138 /*
 139  * Update termios style control flag with a termio style flag.
 140  */
 141 #define SM_SETCFLAG(qi, tc)     \
 142         qi->sm_ttycommon->t_cflag = \
 143         (qi->sm_ttycommon->t_cflag & 0xffff0000 | (tc)->c_cflag)
 144 #define SM_SETLFLAG(qi, tc)     \
 145         qi->sm_ttycommon->t_iflag = \
 146         (qi->sm_ttycommon->t_iflag & 0xffff0000 | (tc)->c_iflag)
 147 
 148 #define SM_WQ(qi)       (qi->sm_ttycommon->t_writeq)
 149 #define SM_RQ(qi)       (qi->sm_ttycommon->t_readq)
 150 
 151 /*
 152  *
 153  */
 154 struct sm_iocinfo {
 155         int     sm_id;
 156         int     sm_cmd;
 157         void    *sm_data;
 158 };
 159 
 160 /*
 161  * Perform a per instance search for a specified per stream structure.
 162  */
 163 #define get_lqi(ssp, unit)      \
 164         ((unit < MAX_LQS) ? &ssp->sm_lqs[unit] : 0)
 165 
 166 #define get_uqi(ssp, unit)      \
 167         ((unit < NLUNITS) ? &ssp->sm_uqs[unit] : NULL)
 168 
 169 #define CNTRL(c)        ((c)&037)
 170 
 171 #define sm_allocb(size, pri)    allocb(size, pri)
 172 #define sm_copymsg(mp)  ((DB_TYPE(mp) == M_DATA) ? dupmsg(mp) : copymsg(mp))
 173 #define sm_freemsg(mp)  freemsg(mp)
 174 
 175 /*
 176  * macro to improve performance. The cond is checked before deciding whether
 177  * to create a new stack frame for the debug call
 178  * Calls to sm_dbg should not occur in hanging statements - alternatively
 179  * bracket SM_CMD with a do .... while (0)
 180  */
 181 
 182 #define SM_CMD(cond, stmt)      { if (cond) stmt; }
 183 #define sm_dbg(lvl, args)       SM_CMD(sm_ssp->sm_trflag & SM_TRBIT(lvl), \
 184         sm_debug args)
 185 
 186 #define SM_SLOT_RED     3
 187 #define SM_MAX_SLOT_WAIT        3
 188 
 189 #define sm_dev2unit(dev)        (getminor(dev) & ~OUTLINE)
 190 
 191 #define LQI2ASSOC(a, l)                         \
 192         (a)->ttymux_linkid = (l)->sm_linkid;      \
 193         (a)->ttymux_tag = (l)->sm_tag;            \
 194         (a)->ttymux_ioflag = (l)->sm_ioflag;      \
 195         (a)->ttymux_ldev = (l)->sm_dev;           \
 196         (a)->ttymux_udev = ((l)->sm_uqi == 0) ? NODEV :   \
 197             makedevice(ddi_driver_major(sm_ssp->sm_dip), \
 198             (l)->sm_uqi->sm_lunit);                        \
 199         (void) strncpy((a)->ttymux_path, (l)->sm_path, MAXPATHLEN)
 200 
 201 #define LQI2ASSOC32(a, l)                               \
 202         (a)->ttymux32_linkid = (l)->sm_linkid;            \
 203         (a)->ttymux32_tag = (uint32_t)(l)->sm_tag;        \
 204         (a)->ttymux32_ioflag = (l)->sm_ioflag;            \
 205         (void) cmpldev(&(a)->ttymux32_ldev, (l)->sm_dev);\
 206         (a)->ttymux32_udev = ((l)->sm_uqi == 0) ? NODEV32 :       \
 207             ((void) cmpldev(&(a)->ttymux32_udev,         \
 208             makedevice(ddi_driver_major(sm_ssp->sm_dip), \
 209             (l)->sm_uqi->sm_lunit)), \
 210             (a)->ttymux32_udev);     \
 211         (void) strncpy((a)->ttymux32_path, (l)->sm_path, MAXPATHLEN)
 212 
 213 #define CNTRL(c)        ((c)&037)
 214 
 215 /*
 216  * 32 bit eqivalents of structures defined in sys/ttymuxuser.h
 217  */
 218 typedef struct ttymux_association32 {
 219 
 220         dev32_t         ttymux32_udev; /* the upper device to be associated */
 221         dev32_t         ttymux32_ldev;
 222                                 /* the device type of a linked lower stream */
 223         int             ttymux32_linkid;
 224                                 /* the linkid of a linked lower stream */
 225         uint32_t        ttymux32_tag;   /* tagged association */
 226         uint_t          ttymux32_ioflag;        /* FORINPUT FOROUTPUT FORIO */
 227         char            ttymux32_path[MAXPATHLEN];      /* device path */
 228 } ttymux_assoc32_t;
 229 
 230 typedef struct ttymux_associations32 {
 231         uint32_t        ttymux32_nlinks;
 232         caddr32_t       ttymux32_assocs;
 233 } ttymux_assocs32_t;
 234 
 235 #ifdef  __cplusplus
 236 }
 237 #endif
 238 
 239 #endif /* _TTYMUX_IMPL_H */