| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /******************************************************************************* | 
|  | 2 | * | 
|  | 3 | *   (c) 1998 by Computone Corporation | 
|  | 4 | * | 
|  | 5 | ******************************************************************************** | 
|  | 6 | * | 
|  | 7 | * | 
|  | 8 | *   PACKAGE:     Linux tty Device Driver for IntelliPort II family of multiport | 
|  | 9 | *                serial I/O controllers. | 
|  | 10 | * | 
|  | 11 | *   DESCRIPTION: Header file for high level library functions | 
|  | 12 | * | 
|  | 13 | *******************************************************************************/ | 
|  | 14 | #ifndef I2LIB_H | 
|  | 15 | #define I2LIB_H   1 | 
|  | 16 | //------------------------------------------------------------------------------ | 
|  | 17 | // I2LIB.H | 
|  | 18 | // | 
|  | 19 | // IntelliPort-II and IntelliPort-IIEX | 
|  | 20 | // | 
|  | 21 | // Defines, structure definitions, and external declarations for i2lib.c | 
|  | 22 | //------------------------------------------------------------------------------ | 
|  | 23 | //-------------------------------------- | 
|  | 24 | // Mandatory Includes: | 
|  | 25 | //-------------------------------------- | 
|  | 26 | #include "ip2types.h" | 
|  | 27 | #include "i2ellis.h" | 
|  | 28 | #include "i2pack.h" | 
|  | 29 | #include "i2cmd.h" | 
|  | 30 | #include <linux/workqueue.h> | 
|  | 31 |  | 
|  | 32 | //------------------------------------------------------------------------------ | 
|  | 33 | // i2ChanStr -- Channel Structure: | 
|  | 34 | // Used to track per-channel information for the library routines using standard | 
|  | 35 | // loadware. Note also, a pointer to an array of these structures is patched | 
|  | 36 | // into the i2eBordStr (see i2ellis.h) | 
|  | 37 | //------------------------------------------------------------------------------ | 
|  | 38 | // | 
|  | 39 | // If we make some limits on the maximum block sizes, we can avoid dealing with | 
|  | 40 | // buffer wrap. The wrapping of the buffer is based on where the start of the | 
|  | 41 | // packet is. Then there is always room for the packet contiguously. | 
|  | 42 | // | 
|  | 43 | // Maximum total length of an outgoing data or in-line command block. The limit | 
|  | 44 | // of 36 on data is quite arbitrary and based more on DOS memory limitations | 
|  | 45 | // than the board interface. However, for commands, the maximum packet length is | 
|  | 46 | // MAX_CMD_PACK_SIZE, because the field size for the count is only a few bits | 
|  | 47 | // (see I2PACK.H) in such packets. For data packets, the count field size is not | 
|  | 48 | // the limiting factor. As of this writing, MAX_OBUF_BLOCK < MAX_CMD_PACK_SIZE, | 
|  | 49 | // but be careful if wanting to modify either. | 
|  | 50 | // | 
|  | 51 | #define MAX_OBUF_BLOCK  36 | 
|  | 52 |  | 
|  | 53 | // Another note on maximum block sizes: we are buffering packets here. Data is | 
|  | 54 | // put into the buffer (if there is room) regardless of the credits from the | 
|  | 55 | // board. The board sends new credits whenever it has removed from his buffers a | 
|  | 56 | // number of characters equal to 80% of total buffer size. (Of course, the total | 
|  | 57 | // buffer size is what is reported when the very first set of flow control | 
|  | 58 | // status packets are received from the board. Therefore, to be robust, you must | 
|  | 59 | // always fill the board to at least 80% of the current credit limit, else you | 
|  | 60 | // might not give it enough to trigger a new report. These conditions are | 
|  | 61 | // obtained here so long as the maximum output block size is less than 20% the | 
|  | 62 | // size of the board's output buffers. This is true at present by "coincidence" | 
|  | 63 | // or "infernal knowledge": the board's output buffers are at least 700 bytes | 
|  | 64 | // long (20% = 140 bytes, at least). The 80% figure is "official", so the safest | 
|  | 65 | // strategy might be to trap the first flow control report and guarantee that | 
|  | 66 | // the effective maxObufBlock is the minimum of MAX_OBUF_BLOCK and 20% of first | 
|  | 67 | // reported buffer credit. | 
|  | 68 | // | 
|  | 69 | #define MAX_CBUF_BLOCK  6	// Maximum total length of a bypass command block | 
|  | 70 |  | 
|  | 71 | #define IBUF_SIZE       512	// character capacity of input buffer per channel | 
|  | 72 | #define OBUF_SIZE       1024// character capacity of output buffer per channel | 
|  | 73 | #define CBUF_SIZE       10	// character capacity of output bypass buffer | 
|  | 74 |  | 
|  | 75 | typedef struct _i2ChanStr | 
|  | 76 | { | 
|  | 77 | // First, back-pointers so that given a pointer to this structure, you can | 
|  | 78 | // determine the correct board and channel number to reference, (say, when | 
|  | 79 | // issuing commands, etc. (Note, channel number is in infl.hd.i2sChannel.) | 
|  | 80 |  | 
|  | 81 | int      port_index;    // Index of port in channel structure array attached | 
|  | 82 | // to board structure. | 
|  | 83 | PTTY     pTTY;          // Pointer to tty structure for port (OS specific) | 
|  | 84 | USHORT   validity;      // Indicates whether the given channel has been | 
|  | 85 | // initialized, really exists (or is a missing | 
|  | 86 | // channel, e.g. channel 9 on an 8-port box.) | 
|  | 87 |  | 
|  | 88 | i2eBordStrPtr  pMyBord; // Back-pointer to this channel's board structure | 
|  | 89 |  | 
|  | 90 | int      wopen;			// waiting fer carrier | 
|  | 91 |  | 
|  | 92 | int      throttled;		// Set if upper layer can take no data | 
|  | 93 |  | 
|  | 94 | int      flags;         // Defined in tty.h | 
|  | 95 |  | 
|  | 96 | PWAITQ   open_wait;     // Pointer for OS sleep function. | 
|  | 97 | PWAITQ   close_wait;    // Pointer for OS sleep function. | 
|  | 98 | PWAITQ   delta_msr_wait;// Pointer for OS sleep function. | 
|  | 99 | PWAITQ   dss_now_wait;	// Pointer for OS sleep function. | 
|  | 100 |  | 
|  | 101 | struct timer_list  BookmarkTimer;   // Used by i2DrainOutput | 
|  | 102 | wait_queue_head_t pBookmarkWait;   // Used by i2DrainOutput | 
|  | 103 |  | 
|  | 104 | int      BaudBase; | 
|  | 105 | int      BaudDivisor; | 
|  | 106 |  | 
|  | 107 | USHORT   ClosingDelay; | 
|  | 108 | USHORT   ClosingWaitTime; | 
|  | 109 |  | 
|  | 110 | volatile | 
|  | 111 | flowIn   infl;	// This structure is initialized as a completely | 
|  | 112 | // formed flow-control command packet, and as such | 
|  | 113 | // has the channel number, also the capacity and | 
|  | 114 | // "as-of" data needed continuously. | 
|  | 115 |  | 
|  | 116 | USHORT   sinceLastFlow; // Counts the number of characters read from input | 
|  | 117 | // buffers, since the last time flow control info | 
|  | 118 | // was sent. | 
|  | 119 |  | 
|  | 120 | USHORT   whenSendFlow;  // Determines when new flow control is to be sent to | 
|  | 121 | // the board. Note unlike earlier manifestations of | 
|  | 122 | // the driver, these packets can be sent from | 
|  | 123 | // in-place. | 
|  | 124 |  | 
|  | 125 | USHORT   channelNeeds;  // Bit map of important things which must be done | 
|  | 126 | // for this channel. (See bits below ) | 
|  | 127 |  | 
|  | 128 | volatile | 
|  | 129 | flowStat outfl;         // Same type of structure is used to hold current | 
|  | 130 | // flow control information used to control our | 
|  | 131 | // output. "asof" is kept updated as data is sent, | 
|  | 132 | // and "room" never goes to zero. | 
|  | 133 |  | 
|  | 134 | // The incoming ring buffer | 
|  | 135 | // Unlike the outgoing buffers, this holds raw data, not packets. The two | 
|  | 136 | // extra bytes are used to hold the byte-padding when there is room for an | 
|  | 137 | // odd number of bytes before we must wrap. | 
|  | 138 | // | 
|  | 139 | UCHAR    Ibuf[IBUF_SIZE + 2]; | 
|  | 140 | volatile | 
|  | 141 | USHORT   Ibuf_stuff;     // Stuffing index | 
|  | 142 | volatile | 
|  | 143 | USHORT   Ibuf_strip;     // Stripping index | 
|  | 144 |  | 
|  | 145 | // The outgoing ring-buffer: Holds Data and command packets. N.B., even | 
|  | 146 | // though these are in the channel structure, the channel is also written | 
|  | 147 | // here, the easier to send it to the fifo when ready. HOWEVER, individual | 
|  | 148 | // packets here are NOT padded to even length: the routines for writing | 
|  | 149 | // blocks to the fifo will pad to even byte counts. | 
|  | 150 | // | 
|  | 151 | UCHAR	Obuf[OBUF_SIZE+MAX_OBUF_BLOCK+4]; | 
|  | 152 | volatile | 
|  | 153 | USHORT	Obuf_stuff;     // Stuffing index | 
|  | 154 | volatile | 
|  | 155 | USHORT	Obuf_strip;     // Stripping index | 
|  | 156 | int	Obuf_char_count; | 
|  | 157 |  | 
|  | 158 | // The outgoing bypass-command buffer. Unlike earlier manifestations, the | 
|  | 159 | // flow control packets are sent directly from the structures. As above, the | 
|  | 160 | // channel number is included in the packet, but they are NOT padded to even | 
|  | 161 | // size. | 
|  | 162 | // | 
|  | 163 | UCHAR    Cbuf[CBUF_SIZE+MAX_CBUF_BLOCK+2]; | 
|  | 164 | volatile | 
|  | 165 | USHORT   Cbuf_stuff;     // Stuffing index | 
|  | 166 | volatile | 
|  | 167 | USHORT   Cbuf_strip;     // Stripping index | 
|  | 168 |  | 
|  | 169 | // The temporary buffer for the Linux tty driver PutChar entry. | 
|  | 170 | // | 
|  | 171 | UCHAR    Pbuf[MAX_OBUF_BLOCK - sizeof (i2DataHeader)]; | 
|  | 172 | volatile | 
|  | 173 | USHORT   Pbuf_stuff;     // Stuffing index | 
|  | 174 |  | 
|  | 175 | // The state of incoming data-set signals | 
|  | 176 | // | 
|  | 177 | USHORT   dataSetIn;     // Bit-mapped according to below. Also indicates | 
|  | 178 | // whether a break has been detected since last | 
|  | 179 | // inquiry. | 
|  | 180 |  | 
|  | 181 | // The state of outcoming data-set signals (as far as we can tell!) | 
|  | 182 | // | 
|  | 183 | USHORT   dataSetOut;     // Bit-mapped according to below. | 
|  | 184 |  | 
|  | 185 | // Most recent hot-key identifier detected | 
|  | 186 | // | 
|  | 187 | USHORT   hotKeyIn;      // Hot key as sent by the board, HOT_CLEAR indicates | 
|  | 188 | // no hot key detected since last examined. | 
|  | 189 |  | 
|  | 190 | // Counter of outstanding requests for bookmarks | 
|  | 191 | // | 
|  | 192 | short   bookMarks;	// Number of outstanding bookmark requests, (+ive | 
|  | 193 | // whenever a bookmark request if queued up, -ive | 
|  | 194 | // whenever a bookmark is received). | 
|  | 195 |  | 
|  | 196 | // Misc options | 
|  | 197 | // | 
|  | 198 | USHORT   channelOptions;   // See below | 
|  | 199 |  | 
|  | 200 | // To store various incoming special packets | 
|  | 201 | // | 
|  | 202 | debugStat   channelStatus; | 
|  | 203 | cntStat     channelRcount; | 
|  | 204 | cntStat     channelTcount; | 
|  | 205 | failStat    channelFail; | 
|  | 206 |  | 
|  | 207 | // To store the last values for line characteristics we sent to the board. | 
|  | 208 | // | 
|  | 209 | int	speed; | 
|  | 210 |  | 
|  | 211 | int flush_flags; | 
|  | 212 |  | 
|  | 213 | void (*trace)(unsigned short,unsigned char,unsigned char,unsigned long,...); | 
|  | 214 |  | 
|  | 215 | /* | 
|  | 216 | * Kernel counters for the 4 input interrupts | 
|  | 217 | */ | 
|  | 218 | struct async_icount icount; | 
|  | 219 |  | 
|  | 220 | /* | 
|  | 221 | *	Task queues for processing input packets from the board. | 
|  | 222 | */ | 
|  | 223 | struct work_struct	tqueue_input; | 
|  | 224 | struct work_struct	tqueue_status; | 
|  | 225 | struct work_struct	tqueue_hangup; | 
|  | 226 |  | 
|  | 227 | rwlock_t Ibuf_spinlock; | 
|  | 228 | rwlock_t Obuf_spinlock; | 
|  | 229 | rwlock_t Cbuf_spinlock; | 
|  | 230 | rwlock_t Pbuf_spinlock; | 
|  | 231 |  | 
|  | 232 | } i2ChanStr, *i2ChanStrPtr; | 
|  | 233 |  | 
|  | 234 | //--------------------------------------------------- | 
|  | 235 | // Manifests and bit-maps for elements in i2ChanStr | 
|  | 236 | //--------------------------------------------------- | 
|  | 237 | // | 
|  | 238 | // flush flags | 
|  | 239 | // | 
|  | 240 | #define STARTFL_FLAG 1 | 
|  | 241 | #define STOPFL_FLAG  2 | 
|  | 242 |  | 
|  | 243 | // validity | 
|  | 244 | // | 
|  | 245 | #define CHANNEL_MAGIC_BITS 0xff00 | 
|  | 246 | #define CHANNEL_MAGIC      0x5300   // (validity & CHANNEL_MAGIC_BITS) == | 
|  | 247 | // CHANNEL_MAGIC --> structure good | 
|  | 248 |  | 
|  | 249 | #define CHANNEL_SUPPORT    0x0001   // Indicates channel is supported, exists, | 
|  | 250 | // and passed P.O.S.T. | 
|  | 251 |  | 
|  | 252 | // channelNeeds | 
|  | 253 | // | 
|  | 254 | #define NEED_FLOW    1  // Indicates flow control has been queued | 
|  | 255 | #define NEED_INLINE  2  // Indicates inline commands or data queued | 
|  | 256 | #define NEED_BYPASS  4  // Indicates bypass commands queued | 
|  | 257 | #define NEED_CREDIT  8  // Indicates would be sending except has not sufficient | 
|  | 258 | // credit. The data is still in the channel structure, | 
|  | 259 | // but the channel is not enqueued in the board | 
|  | 260 | // structure again until there is a credit received from | 
|  | 261 | // the board. | 
|  | 262 |  | 
|  | 263 | // dataSetIn (Also the bits for i2GetStatus return value) | 
|  | 264 | // | 
|  | 265 | #define I2_DCD 1 | 
|  | 266 | #define I2_CTS 2 | 
|  | 267 | #define I2_DSR 4 | 
|  | 268 | #define I2_RI  8 | 
|  | 269 |  | 
|  | 270 | // dataSetOut (Also the bits for i2GetStatus return value) | 
|  | 271 | // | 
|  | 272 | #define I2_DTR 1 | 
|  | 273 | #define I2_RTS 2 | 
|  | 274 |  | 
|  | 275 | // i2GetStatus() can optionally clear these bits | 
|  | 276 | // | 
|  | 277 | #define I2_BRK    0x10  // A break was detected | 
|  | 278 | #define I2_PAR    0x20  // A parity error was received | 
|  | 279 | #define I2_FRA    0x40  // A framing error was received | 
|  | 280 | #define I2_OVR    0x80  // An overrun error was received | 
|  | 281 |  | 
|  | 282 | // i2GetStatus() automatically clears these bits */ | 
|  | 283 | // | 
|  | 284 | #define I2_DDCD   0x100 // DCD changed from its  former value | 
|  | 285 | #define I2_DCTS   0x200 // CTS changed from its former value | 
|  | 286 | #define I2_DDSR   0x400 // DSR changed from its former value | 
|  | 287 | #define I2_DRI    0x800 // RI changed from its former value | 
|  | 288 |  | 
|  | 289 | // hotKeyIn | 
|  | 290 | // | 
|  | 291 | #define HOT_CLEAR 0x1322   // Indicates that no hot-key has been detected | 
|  | 292 |  | 
|  | 293 | // channelOptions | 
|  | 294 | // | 
|  | 295 | #define CO_NBLOCK_WRITE 1  	// Writes don't block waiting for buffer. (Default | 
|  | 296 | // is, they do wait.) | 
|  | 297 |  | 
|  | 298 | // fcmodes | 
|  | 299 | // | 
|  | 300 | #define I2_OUTFLOW_CTS  0x0001 | 
|  | 301 | #define I2_INFLOW_RTS   0x0002 | 
|  | 302 | #define I2_INFLOW_DSR   0x0004 | 
|  | 303 | #define I2_INFLOW_DTR   0x0008 | 
|  | 304 | #define I2_OUTFLOW_DSR  0x0010 | 
|  | 305 | #define I2_OUTFLOW_DTR  0x0020 | 
|  | 306 | #define I2_OUTFLOW_XON  0x0040 | 
|  | 307 | #define I2_OUTFLOW_XANY 0x0080 | 
|  | 308 | #define I2_INFLOW_XON   0x0100 | 
|  | 309 |  | 
|  | 310 | #define I2_CRTSCTS      (I2_OUTFLOW_CTS|I2_INFLOW_RTS) | 
|  | 311 | #define I2_IXANY_MODE   (I2_OUTFLOW_XON|I2_OUTFLOW_XANY) | 
|  | 312 |  | 
|  | 313 | //------------------------------------------- | 
|  | 314 | // Macros used from user level like functions | 
|  | 315 | //------------------------------------------- | 
|  | 316 |  | 
|  | 317 | // Macros to set and clear channel options | 
|  | 318 | // | 
|  | 319 | #define i2SetOption(pCh, option) pCh->channelOptions |= option | 
|  | 320 | #define i2ClrOption(pCh, option) pCh->channelOptions &= ~option | 
|  | 321 |  | 
|  | 322 | // Macro to set fatal-error trap | 
|  | 323 | // | 
|  | 324 | #define i2SetFatalTrap(pB, routine) pB->i2eFatalTrap = routine | 
|  | 325 |  | 
|  | 326 | //-------------------------------------------- | 
|  | 327 | // Declarations and prototypes for i2lib.c | 
|  | 328 | //-------------------------------------------- | 
|  | 329 | // | 
|  | 330 | static int  i2InitChannels(i2eBordStrPtr, int, i2ChanStrPtr); | 
|  | 331 | static int  i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); | 
|  | 332 | static int  i2GetStatus(i2ChanStrPtr, int); | 
|  | 333 | static int  i2Input(i2ChanStrPtr); | 
|  | 334 | static int  i2InputFlush(i2ChanStrPtr); | 
|  | 335 | static int  i2Output(i2ChanStrPtr, const char *, int, int); | 
|  | 336 | static int  i2OutputFree(i2ChanStrPtr); | 
|  | 337 | static int  i2ServiceBoard(i2eBordStrPtr); | 
|  | 338 | static void i2DrainOutput(i2ChanStrPtr, int); | 
|  | 339 |  | 
|  | 340 | #ifdef IP2DEBUG_TRACE | 
|  | 341 | void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...); | 
|  | 342 | #else | 
|  | 343 | #define ip2trace(a,b,c,d...) do {} while (0) | 
|  | 344 | #endif | 
|  | 345 |  | 
|  | 346 | // Argument to i2QueueCommands | 
|  | 347 | // | 
|  | 348 | #define C_IN_LINE 1 | 
|  | 349 | #define C_BYPASS  0 | 
|  | 350 |  | 
|  | 351 | #endif   // I2LIB_H |