typedef struct IOCTLPacket {
     CHAR      IPlen;
     CHAR      IPunit;
     CHAR      IPcommand;
     USHORT    IPstatus;
     ULONG     IPreserved;
     ULONG     IPQlink;
     CHAR      IPcategory;
     CHAR      IPfunction;
     ULONG     IPparameter;
     ULONG     IPdata;
     USHORT    IPsfn;
} IOCTLPACKET;

typedef struct Flat_Pointer {
     USHORT    fp_offlo;
     USHORT    fp_offhi;
     USHORT    fp_sel;
} FLATPOINTER;

typedef struct Stack_Data {
     USHORT    old_bp;
     ULONG     old_cs;
     ULONG     old_ip;
     ULONG     ul2;
     ULONG     ul1;
     ULONG     uFunc;
} STACK_DATA;

typedef struct Device_dependent_VCOM_data {
     USHORT    ret_len;
     USHORT    num_com;
     USHORT    com1;
     USHORT    com2;
     USHORT    com3;
     USHORT    com4;
     USHORT    com1irq;
     USHORT    com2irq;
     USHORT    com3irq;
     USHORT    com4irq;
} DD_VCOM_DATA;

typedef struct IDC_Packet {
     USHORT    Command_Flag;
     USHORT    Com_Port_Num;
     USHORT    Com_Port_Addr;
     USHORT    Com_Port_IRQ;
     USHORT    Return_Code;
} IDC_PACKET;

/**     Machine Identifiers
 *
 *      ABIOS_COM          -   Identifies a ABIOS machine
 *      NON_ABIOS_COM      -   Identifies a non ABIOS machine
 *
 */
#define   NON_ABIOS_COM  1
#define   ABIOS_COM      0

/**     Queue manifests, sizes and hi/lo water marks
 *
 *      Due to the implementation of the character queues, they
 *      must be declared to be one byte greater than their
 *      actual usable size.
 */
#define   QI_SIZE        5121                // input  queue size
#define   QO_SIZE        2049                // output queue size
#define   QI_SIZE_EVEN   (QI_SIZE+1)& ~(0x0001)  // even size for word alignment
#define   QO_SIZE_EVEN   (QO_SIZE+1)& ~(0x0001)

/**     high/low water marks for when to send handshake
 *   when input queue goes above high water, send XOFF and/or drop hardware lines
 *   when input queue goes below low  water, send XON and/or raise hardware lines
 */
#define   RX_HIGH_HS     (QI_SIZE-1)-2048    // RX queue high water mark
#define   RX_LOW_HS      (QI_SIZE-1)/2       // RX queue low water mark

/*   when input queue goes up to this, move data to user buffer            */
#define   RX_MOVE_PROT   200                 // protect mode or below 1 meg
#define   RX_MOVE_REAL   256                 // real mode and above 1 meg

/*   when output queue goes down to this, move data from user buffer       */
#define   TX_MOVE_PROT   64                  // protect mode or below 1 meg
#define   TX_MOVE_REAL   0                   // real mode and above 1 meg

#define   RX_STATE_HOLDING    1         //isr has no more room in buffer
                                        //until consumer removes rx data

#define   RX_STATE_OK         2         //isr has room in buffer for rx data

/*****
 **     ComInfo.ci_dcb_flags1 definitions
 *****/
#define   F1_DTR_MASK         0x03      //DTR control mask
#define   F1_DTR_DISABLE      0x00      //   DTR disable
#define   F1_DTR_ENABLE       0x01      //   DTR enable
#define   F1_DTR_FLOW         0x02      //   DTR input handshaking
#define   F1_DTR_INVALID      0x03      //   DTR invalid mode
#define   F1_OUT_FLOW         0x38      //Output handshaking mask
#define   F1_OUT_CTS_FLOW     0x08      //   output handshaking using CTS
#define   F1_OUT_DSR_FLOW     0x10      //   output handshaking using DSR
#define   F1_OUT_DCD_FLOW     0x20      //   output handshaking using DCD
#define   F1_IN_DSR_SENSE     0x40      //input sensitivity to DSR
#define   F1_RESERVED         0x80      //--reserved--

/*****
 **     ComInfo.ci_dcb_flags2 definitions
 *****/
#define   F2_OUT_XO           0x01      //output XON/XOFF
#define   F2_IN_XO            0x02      //input  XON/XOFF

#define   F2_ERR_CHAR         0x04      //error replacement character
#define   F2_NULL_STRIP       0x08      //null stripping
#define   F2_BRK_CHAR         0x10      //break replacement character
#define   F2_FULL_DUP         0x20      //full duplex auto flow control

#define   F2_RTS_MASK         0xc0      //RTS control mask
#define   F2_RTS_DISABLE      0x00      //   RTS disable
#define   F2_RTS_ENABLE       0x40      //   RTS enable
#define   F2_RTS_FLOW         0x80      //   RTS input handshaking
#define   F2_RTS_TOGGLE       0xC0      //   RTS toggle on transmit

/*****
 **     ComInfo.ci_dcb_flags3 definitions
 *****/
#define   F3_W_INF_TO         0x01      //write infinite timeout

#define   F3_READ_TO_MASK     0x06      //read timeout mask
#define   F3_READ_TO_BAD      0x00      //    read timeout bad
#define   F3_READ_TO_NORM     0x02      //    read timeout normal
#define   F3_READ_TO_WFS      0x04      //    read timeout wait for something
#define   F3_READ_TO_NW       0x06      //    read timeout no wait

#define   F3_FIFO_MASK        0x18      //FIFO mask
#define   F3_FIFO_NA          0x00      //    FIFO not available
#define   F3_FIFO_OFF         0x08      //    FIFO disabled
#define   F3_FIFO_ON          0x10      //    FIFO enabled
#define   F3_FIFO_APO         0x18      //    FIFO auto priority override
#define   F3_FIFO_HW_ON       0x10      //    FIFO HW is on (either ON or APO)

#define   F3_RX_MASK          0x60      //Receive trigger level mask
#define   F3_RX_1             0x00      //    receive trigger level 1
#define   F3_RX_4             0x20      //    receive trigger level 4
#define   F3_RX_8             0x40      //    receive trigger level 8
#define   F3_RX_14            0x60      //    receive trigger level 14

#define   F3_TX_16            0x80      //Transmit buffer load count = 16

#define   F3_FIFO_ALL         0xF1      //All the FIFO bits


/*****
 **     ComInfo.ci_hsflag values
 *****/
#define   HS_XOFF_PENDING     0x01      //XOFF needs to be sent
#define   HS_FLOW_OFF_LOCAL   0x02
#define   HS_XON_PENDING      0x04      //XON needs to be sent
#define   HS_XOFF_RECEIVED    0x08      //XOFF character received
#define   HS_XOFF_SENT        0x10      //XOFF has been sent
#define   HS_BREAK_SET        0x40      //break has been set
#define   HS_TX_IMMED         0x80      //TxImmed character pending

/*****
 *     IOCTL com status definitions
 *
 * Note: TX_IMMED is maintained in ci_hsflag.  All the other fields are
 * calculated only when IOCTL Return Com Status is called.
 *****/
#define   CST_CTS_HOLD        0x01      //TX waiting for CTS to be asserted?
#define   CST_DSR_HOLD        0x02      //TX waiting for DSR to be asserted?
#define   CST_DCD_HOLD        0x04      //TX waiting for DCD to be asserted?
#define   CST_XOFF_HOLD       0x08      //TX waiting, XOff received?
#define   CST_XOFF_SENT       0x10      //TX waiting, XOff transmitted?
#define   CST_BREAK_HOLD      0x20      //TX waiting, break being transmitted?
#define   CST_TX_IMMED        0x40      //char waiting to be transmitted immed?
#define   CST_RX_DSR_HOLD     0x80      //RX waiting for DSR to be asserted?

/*****
 **     ComInfo.ci_comerr (IOCTL com error) definitions
 *****/
#define   CE_SW_OVERRUN       0x01      //receive SW queue overrun error
#define   CE_HW_OVERRUN       0x02      //receive HW overrun error
#define   CE_RX_PARITY        0x04      //receive parity error
#define   CE_FRAME            0x08      //receive framing error

/*****
 **     ComInfo.ci_event (IOCTL com event) definitions
 *****/
#define   EV_RX_CHAR          0x01      //set when any character is received
                                        //and placed in the input queue.
#define   EV_RESERVED         0x02      //reserved
#define   EV_TX_EMPTY         0x04      //set when the last char in the
                                        //transmit queue is transmitted
#define   EV_CTS              0x08      //set when the CTS signal changes state
#define   EV_DSR              0x10      //set when the DSR signal changes state
#define   EV_DCD              0x20      //set when the DCD signal changes state
#define   EV_BREAK            0x40      //set when a Break is detected on input
#define   EV_ERR              0x80      //set when an error occurs
                                        //(parity, framing or HW or SW overrun)
#define   EV_RING             0x100     //set when Ring Indicator is detected

/*****
 **     ComInfo.ci_flagx definitions
 *****/
#define   FX_DATA_MOVED       0x01      //data moved (PhysToVirt) in
                                        //TxInt, so don't move Rx data
                                        //this interrupt
#define   FX_LAST_CLOSE       0x02      //last close in progress,
                                        //so discard received data
#define   FX_RTS_DROP_PENDING 0x04      //drop RTS at the first timer
                                        //tick where the THR and TSR
                                        //are empty
#define   FX_WAITING_TX_EMPTY 0x08
#define   FX_INT_NESTED       0x10      //nested interrupt occured
#define   FX_IN_DSR_OK        0x20      //input DSR mode is off OR
                                        //DSR was high OR DSR is high
                                        //this bit MUST be the same as MS_DSR

#define   FX_CHIP_MASK        0xC0      //chip type 8250, 16450, 16550A
#define   FX_8250             0x00      //8250x (PC chip)
#define   FX_16450            0x40      //16450 or 16550 (bad FIFO)
#define   FX_16550A           0x80      //16550A (good FIFO)

/*****
 **     ComInfo.ci_flagx definitions
 *****/
#define   FX_XO_FOUND         0x20      //flag used in TxFlowDetect
#define   FX_TX_IN_PROG       0x40      //flag used for Tx'ing
#define   FX_INT_TIME         0x80      //flag used mode switching

/*****
 **     ComInfo.ci_Flagx1 definitions
 *****/
#define   FX1_FLUSH_TX_IP     0x01      //flag for TX Flush in progress
#define   FX1_FLUSH_RX_IP     0x02      //flag for RX Flush in progress
#define   FX1_SET_BAUD_IP     0x04      //flag for set baud IOCTL in progress
#define   FX1_PCMCIA_MODEM    0x08      //flag to show this is a special PCMCIA modem

/*****
 *     ComInfo.ci_eflags definitions
 *
 * NOTE: bit positions must match SetEnhancedParmeters IOCtl (54H)
 *       parameter packet format
 *****/
#define   EF_POSSIBLE_ENHANCED     0x01 //port CAN run in enhanced mode
#define   EF_MODE_ENHANCED         0x02 //port is NOW in enhanced mode
#define   EF_RX_REQUEST_NOT_PIO    0x04 //port NOT in rx PIO mode
#define   EF_RX_REQUEST_DEF_DMA    0x08 //port DEFINITELY in rx DMA mode
#define   EF_RX_REQUEST_MASK       0x0C //
#define   EF_TX_REQUEST_NOT_PIO    0x10 //port NOT in rx PIO mode
#define   EF_TX_REQUEST_DEF_DMA    0x20 //port DEFINITELY in rx DMA mode
#define   EF_TX_REQUEST_MASK       0x30 //
#define   EF_LAST_RX_WAS_DMA       0x40 //most recent receive for
                                        //this port was in DMA mode
#define   EF_LAST_TX_WAS_DMA       0x80 //most recent transmit for
                                        //this port was in DMA mode
#define   EF_GET_MASK              0xC1

/*****
 *    Physical address structure
 *****/
typedef struct PhysAddr {
     USHORT    _lo;
     USHORT    _hi;
} PHYSADDR;

/*****
 *    I/O queue structure
 *****/
typedef struct IO_Queue {
     CHAR      ioq_phys[sizeof(PHYSADDR)];
     USHORT    ioq_page;
     USHORT    ioq_base;
     USHORT    ioq_end;
     USHORT    ioq_in;
     USHORT    ioq_out;
     USHORT    ioq_count;
} IO_QUEUE;

typedef struct ComInfo {
//       start of device control block info
//  WARNING: this must at the top of the ComInfo structure.
//  WARNING: this must match the DCB structure exactly.

     USHORT    ci_dcb_writeto;     // write timeout
     USHORT    ci_dcb_readto;      // read  timeout
     CHAR      ci_dcb_flags1;      // first  flags byte
     CHAR      ci_dcb_flags2;      // second flags byte
     CHAR      ci_dcb_flags3;      // third  flags byte
     CHAR      ci_dcb_ErrChar;     // error replacement char
     CHAR      ci_dcb_BrkChar;     // break replacement char
     CHAR      ci_dcb_XonChar;     // XON  character
     CHAR      ci_dcb_XoffChar;    // XOFF character

// end of device control block info

     CHAR      ci_ier;             // word align rest of struc
     USHORT    ci_signature;       // signature ID word
     USHORT    ci_port;            // I/O port, 0 if non-existant
     ULONG     ci_baud;            // baud rate

     CHAR      ci_linec;           // line control
     CHAR      ci_bytesize;        // TX/RX byte size
     CHAR      ci_parity;          // parity
     CHAR      ci_stopbits;        // stop bits
     CHAR      ci_cmask;           // received character mask
     CHAR      ci_tximm;           // transmit immediate character

     CHAR      ci_irq;             // interrupt number
     CHAR      ci_depth;           // interrupt depth
     USHORT    ci_isr;             // interrupt service routine
     USHORT    ci_visr;            // vdm interrupt service routine
     USHORT    ci_badmax;          // bad interrupt maximum

     USHORT    ci_nopens;          // number of outstanding opens
     USHORT    ci_nvdmopens;       // number of outstanding vdm opens CP20D1390
     ULONG     ci_oci_sem;         // open/close/ioctl exclusion sem
     ULONG     ci_oci_sem_own;     // oci_sem owner RP address
     USHORT    ci_comerr;          // I/O error
     USHORT    ci_event;           // event flags

     USHORT    ci_GDTSelRead;      // GDT selectors for the user buffer
     USHORT    ci_GDTSelWrite;     // for use in the interrupt routines

     HADAPTER  ci_hAdapter;
     HLDEV     ci_hLDev;
     HSYSNAME  ci_hSysName;

     CHAR      ci_flagx;           // extra flags
     CHAR      ci_flagx1;          // extra flags
     CHAR      ci_hsflag ;         // handshake flag
     CHAR      ci_hhslines;        // DTR/RTS bits for handshaking
     CHAR      ci_outhhslines;     // output handshake lines

     CHAR      ci_lsrshadow;       // line  status register shadow
     CHAR      ci_msrshadow;       // modem status register shadow
     CHAR      ci_port_number;     // VDM port number of this CIDA
     USHORT    ci_LID;             // to remember LID on PS/2s
     USHORT    ci_flagGA;          // Log Facility Alert conditons
                                   // read request packet list
     ULONG     ci_r_rpl;           // head
     ULONG     ci_r_rpl2;          // tail
     USHORT    ci_r_sig;

                                   // write request packet list
     ULONG     ci_w_rpl;           // head
     ULONG     ci_w_rpl2;          // tail
     USHORT    ci_w_sig;

     ULONG     ci_r_rp;            // current read request
     ULONG     ci_w_rp;            // current write request
     USHORT    ci_r_to_move;       // bytes to move to satisfy r_rp
     USHORT    ci_w_to_move;       // bytes to move to satisfy w_rp

     USHORT    ci_r_to;            // r_rp time out
     USHORT    ci_w_to;            // w_rp time out
     USHORT    ci_r_to_start;      // r_rp time out start value
     USHORT    ci_w_to_start;      // w_rp time out start value

     CHAR      ci_vdm_flag;        // VDM information flag
                                   // VDM BIT 0 - InUse by VDM
                                   // VDM BIT 1 - notify the VCOM Rx
                                   // VDM BIT 2 - notify the VCOM Tx
                                   // VDM BIT 3 - Blocked IOCTL
                                   // VDM BIT 4-7 RESERVED, set to 0

     CHAR      ci_vdm_Rx_State;    // VDM BIT 0&1 - Rx_State
                                   // VDM BIT 2-7 RESERVED, set to 0

     CHAR      ci_vdm_Tx_State;    // VDM BIT 0&1 - Tx_State
                                   // VDM BIT 2-7 RESERVED, set to 0

     CHAR      ci_vdm_Rx_Count;    // VDM count of chars put in Tx
                                   // VDM Queue since XOFF given to
                                   // VDM DOS APP

     CHAR      ci_vdm_Tx_Count;    // VDM count of chars put in Rx
                                   // VDM Queue since XOFF sent to
                                   // VDM device

     CHAR      ci_vdm_LastMSR;     // VDM last MSR given to DOS App
     CHAR      ci_vdm_LastLSR;     // VDM LSR to give to DOS app

     CHAR      ci_dummy3;          // mw put on word boundaries

     CHAR      ci_qin[sizeof(IO_QUEUE)];
     CHAR      ci_qin_q[QI_SIZE_EVEN];

     CHAR      ci_qout[sizeof(IO_QUEUE)];
     CHAR      ci_qout_q[QO_SIZE_EVEN];

     USHORT    ci_fifobaud;        // mw store baud latch values
     USHORT    ci_sid;             // VDM App's Session ID CP20D1390

     USHORT    ci_vdm_OpenError;   // VDM Type of error to return to
                                   // VDM VCOM from Open

     ULONG     ci_vdm_Blocked_IOCTL;// VDM IOCTL/Tx Queue
                                    // VDM serialization mechanism

     CHAR      ci_req_pack[sizeof(IOCTLPACKET)];  // VDM IOCTL request packet

     CHAR      ci_qstat[QI_SIZE];  // VDM LSRQ
     CHAR      ci_int_sharing;     // supports int. sharing
     USHORT    ci_int_data;        // offset of SharedIntData
     USHORT    ci_next_COM;        // ComInfo of next COM on this IRQ line
     CHAR      ci_mult_COMs_IRQ;   // # of other COM ports on this IRQ line

     CHAR      ci_eflags;

     CHAR      dummy;
     CHAR      ci_rx_request;
     CHAR      ci_tx_request;

//*************************************************************
//************                                     ************
//******          Perfview Data Block                    ******
//**************                                   ************
#ifdef PERFVIEW
     CHAR      ci_Data_Block[sizeof(pvdbh_s)];
     ULONG     ci_Read_Time;
     ULONG     ci_Read_Time2;
     ULONG     ci_Write_Time;
     ULONG     ci_Write_Time2;
     ULONG     ci_Num_Reads;
     ULONG     ci_Read_Bytes;
     ULONG     ci_Num_Writes;
     ULONG     ci_Write_Bytes;
     ULONG     ci_HW_Overruns;
     ULONG     ci_SW_Overruns;     // last item! Used to find data_block len

//************                                     ************
//*******  If Adding Counters or Timers then see the     ******
//*******  Number_Tmrs_Ctrs EQU. And change Procedure    ******
//*******  Initialize_PerfView_Data to reference last    ******
//*******  data item                                     ******
//*************************************************************
#endif
} COMINFO;
typedef COMINFO *PCOMINFO;
