/******************************************************************************* * * (c) 1998 by Computone Corporation * ******************************************************************************** * * * PACKAGE: Linux tty Device Driver for IntelliPort II family of multiport * serial I/O controllers. * * DESCRIPTION: Header file for high level library functions * *******************************************************************************/ #ifndef I2LIB_H #define I2LIB_H 1 //------------------------------------------------------------------------------ // I2LIB.H // // IntelliPort-II and IntelliPort-IIEX // // Defines, structure definitions, and external declarations for i2lib.c //------------------------------------------------------------------------------ //-------------------------------------- // Mandatory Includes: //-------------------------------------- #include "ip2types.h" #include "i2ellis.h" #include "i2pack.h" #include "i2cmd.h" #include <linux/workqueue.h> //------------------------------------------------------------------------------ // i2ChanStr -- Channel Structure: // Used to track per-channel information for the library routines using standard // loadware. Note also, a pointer to an array of these structures is patched // into the i2eBordStr (see i2ellis.h) //------------------------------------------------------------------------------ // // If we make some limits on the maximum block sizes, we can avoid dealing with // buffer wrap. The wrapping of the buffer is based on where the start of the // packet is. Then there is always room for the packet contiguously. // // Maximum total length of an outgoing data or in-line command block. The limit // of 36 on data is quite arbitrary and based more on DOS memory limitations // than the board interface. However, for commands, the maximum packet length is // MAX_CMD_PACK_SIZE, because the field size for the count is only a few bits // (see I2PACK.H) in such packets. For data packets, the count field size is not // the limiting factor. As of this writing, MAX_OBUF_BLOCK < MAX_CMD_PACK_SIZE, // but be careful if wanting to modify either. // #define MAX_OBUF_BLOCK 36 // Another note on maximum block sizes: we are buffering packets here. Data is // put into the buffer (if there is room) regardless of the credits from the // board. The board sends new credits whenever it has removed from his buffers a // number of characters equal to 80% of total buffer size. (Of course, the total // buffer size is what is reported when the very first set of flow control // status packets are received from the board. Therefore, to be robust, you must // always fill the board to at least 80% of the current credit limit, else you // might not give it enough to trigger a new report. These conditions are // obtained here so long as the maximum output block size is less than 20% the // size of the board's output buffers. This is true at present by "coincidence" // or "infernal knowledge": the board's output buffers are at least 700 bytes // long (20% = 140 bytes, at least). The 80% figure is "official", so the safest // strategy might be to trap the first flow control report and guarantee that // the effective maxObufBlock is the minimum of MAX_OBUF_BLOCK and 20% of first // reported buffer credit. // #define MAX_CBUF_BLOCK 6 // Maximum total length of a bypass command block #define IBUF_SIZE 512 // character capacity of input buffer per channel #define OBUF_SIZE 1024// character capacity of output buffer per channel #define CBUF_SIZE 10 // character capacity of output bypass buffer typedef struct _i2ChanStr { // First, back-pointers so that given a pointer to this structure, you can // determine the correct board and channel number to reference, (say, when // issuing commands, etc. (Note, channel number is in infl.hd.i2sChannel.) int port_index; // Index of port in channel structure array attached // to board structure. PTTY pTTY; // Pointer to tty structure for port (OS specific) USHORT validity; // Indicates whether the given channel has been // initialized, really exists (or is a missing // channel, e.g. channel 9 on an 8-port box.) i2eBordStrPtr pMyBord; // Back-pointer to this channel's board structure int wopen; // waiting fer carrier int throttled; // Set if upper layer can take no data int flags; // Defined in tty.h PWAITQ open_wait; // Pointer for OS sleep function. PWAITQ close_wait; // Pointer for OS sleep function. PWAITQ delta_msr_wait;// Pointer for OS sleep function. PWAITQ dss_now_wait; // Pointer for OS sleep function. struct timer_list BookmarkTimer; // Used by i2DrainOutput wait_queue_head_t pBookmarkWait; // Used by i2DrainOutput int BaudBase; int BaudDivisor; USHORT ClosingDelay; USHORT ClosingWaitTime; volatile flowIn infl; // This structure is initialized as a completely // formed flow-control command packet, and as such // has the channel number, also the capacity and // "as-of" data needed continuously. USHORT sinceLastFlow; // Counts the number of characters read from input // buffers, since the last time flow control info // was sent. USHORT whenSendFlow; // Determines when new flow control is to be sent to // the board. Note unlike earlier manifestations of // the driver, these packets can be sent from // in-place. USHORT channelNeeds; // Bit map of important things which must be done // for this channel. (See bits below ) volatile flowStat outfl; // Same type of structure is used to hold current // flow control information used to control our // output. "asof" is kept updated as data is sent, // and "room" never goes to zero. // The incoming ring buffer // Unlike the outgoing buffers, this holds raw data, not packets. The two // extra bytes are used to hold the byte-padding when there is room for an // odd number of bytes before we must wrap. // UCHAR Ibuf[IBUF_SIZE + 2]; volatile USHORT Ibuf_stuff; // Stuffing index volatile USHORT Ibuf_strip; // Stripping index // The outgoing ring-buffer: Holds Data and command packets. N.B., even // though these are in the channel structure, the channel is also written // here, the easier to send it to the fifo when ready. HOWEVER, individual // packets here are NOT padded to even length: the routines for writing // blocks to the fifo will pad to even byte counts. // UCHAR Obuf[OBUF_SIZE+MAX_OBUF_BLOCK+4]; volatile USHORT Obuf_stuff; // Stuffing index volatile USHORT Obuf_strip; // Stripping index int Obuf_char_count; // The outgoing bypass-command buffer. Unlike earlier manifestations, the // flow control packets are sent directly from the structures. As above, the // channel number is included in the packet, but they are NOT padded to even // size. // UCHAR Cbuf[CBUF_SIZE+MAX_CBUF_BLOCK+2]; volatile USHORT Cbuf_stuff; // Stuffing index volatile USHORT Cbuf_strip; // Stripping index // The temporary buffer for the Linux tty driver PutChar entry. // UCHAR Pbuf[MAX_OBUF_BLOCK - sizeof (i2DataHeader)]; volatile USHORT Pbuf_stuff; // Stuffing index // The state of incoming data-set signals // USHORT dataSetIn; // Bit-mapped according to below. Also indicates // whether a break has been detected since last // inquiry. // The state of outcoming data-set signals (as far as we can tell!) // USHORT dataSetOut; // Bit-mapped according to below. // Most recent hot-key identifier detected // USHORT hotKeyIn; // Hot key as sent by the board, HOT_CLEAR indicates // no hot key detected since last examined. // Counter of outstanding requests for bookmarks // short bookMarks; // Number of outstanding bookmark requests, (+ive // whenever a bookmark request if queued up, -ive // whenever a bookmark is received). // Misc options // USHORT channelOptions; // See below // To store various incoming special packets // debugStat channelStatus; cntStat channelRcount; cntStat channelTcount; failStat channelFail; // To store the last values for line characteristics we sent to the board. // int speed; int flush_flags; void (*trace)(unsigned short,unsigned char,unsigned char,unsigned long,...); /* * Kernel counters for the 4 input interrupts */ struct async_icount icount; /* * Task queues for processing input packets from the board. */ struct work_struct tqueue_input; struct work_struct tqueue_status; struct work_struct tqueue_hangup; rwlock_t Ibuf_spinlock; rwlock_t Obuf_spinlock; rwlock_t Cbuf_spinlock; rwlock_t Pbuf_spinlock; } i2ChanStr, *i2ChanStrPtr; //--------------------------------------------------- // Manifests and bit-maps for elements in i2ChanStr //--------------------------------------------------- // // flush flags // #define STARTFL_FLAG 1 #define STOPFL_FLAG 2 // validity // #define CHANNEL_MAGIC_BITS 0xff00 #define CHANNEL_MAGIC 0x5300 // (validity & CHANNEL_MAGIC_BITS) == // CHANNEL_MAGIC --> structure good #define CHANNEL_SUPPORT 0x0001 // Indicates channel is supported, exists, // and passed P.O.S.T. // channelNeeds // #define NEED_FLOW 1 // Indicates flow control has been queued #define NEED_INLINE 2 // Indicates inline commands or data queued #define NEED_BYPASS 4 // Indicates bypass commands queued #define NEED_CREDIT 8 // Indicates would be sending except has not sufficient // credit. The data is still in the channel structure, // but the channel is not enqueued in the board // structure again until there is a credit received from // the board. // dataSetIn (Also the bits for i2GetStatus return value) // #define I2_DCD 1 #define I2_CTS 2 #define I2_DSR 4 #define I2_RI 8 // dataSetOut (Also the bits for i2GetStatus return value) // #define I2_DTR 1 #define I2_RTS 2 // i2GetStatus() can optionally clear these bits // #define I2_BRK 0x10 // A break was detected #define I2_PAR 0x20 // A parity error was received #define I2_FRA 0x40 // A framing error was received #define I2_OVR 0x80 // An overrun error was received // i2GetStatus() automatically clears these bits */ // #define I2_DDCD 0x100 // DCD changed from its former value #define I2_DCTS 0x200 // CTS changed from its former value #define I2_DDSR 0x400 // DSR changed from its former value #define I2_DRI 0x800 // RI changed from its former value // hotKeyIn // #define HOT_CLEAR 0x1322 // Indicates that no hot-key has been detected // channelOptions // #define CO_NBLOCK_WRITE 1 // Writes don't block waiting for buffer. (Default // is, they do wait.) // fcmodes // #define I2_OUTFLOW_CTS 0x0001 #define I2_INFLOW_RTS 0x0002 #define I2_INFLOW_DSR 0x0004 #define I2_INFLOW_DTR 0x0008 #define I2_OUTFLOW_DSR 0x0010 #define I2_OUTFLOW_DTR 0x0020 #define I2_OUTFLOW_XON 0x0040 #define I2_OUTFLOW_XANY 0x0080 #define I2_INFLOW_XON 0x0100 #define I2_CRTSCTS (I2_OUTFLOW_CTS|I2_INFLOW_RTS) #define I2_IXANY_MODE (I2_OUTFLOW_XON|I2_OUTFLOW_XANY) //------------------------------------------- // Macros used from user level like functions //------------------------------------------- // Macros to set and clear channel options // #define i2SetOption(pCh, option) pCh->channelOptions |= option #define i2ClrOption(pCh, option) pCh->channelOptions &= ~option // Macro to set fatal-error trap // #define i2SetFatalTrap(pB, routine) pB->i2eFatalTrap = routine //-------------------------------------------- // Declarations and prototypes for i2lib.c //-------------------------------------------- // static int i2InitChannels(i2eBordStrPtr, int, i2ChanStrPtr); static int i2QueueCommands(int, i2ChanStrPtr, int, int, cmdSyntaxPtr,...); static int i2GetStatus(i2ChanStrPtr, int); static int i2Input(i2ChanStrPtr); static int i2InputFlush(i2ChanStrPtr); static int i2Output(i2ChanStrPtr, const char *, int); static int i2OutputFree(i2ChanStrPtr); static int i2ServiceBoard(i2eBordStrPtr); static void i2DrainOutput(i2ChanStrPtr, int); #ifdef IP2DEBUG_TRACE void ip2trace(unsigned short,unsigned char,unsigned char,unsigned long,...); #else #define ip2trace(a,b,c,d...) do {} while (0) #endif // Argument to i2QueueCommands // #define C_IN_LINE 1 #define C_BYPASS 0 #endif // I2LIB_H