/*
 *  _devdrvr.h   Device Driver Definitions
 *
 *  Copyright (C) by Quantum Software Systems 1990.  All rights reserved.
 */
#ifndef __DEVDRVR_H_INCLUDED

#ifndef __TYPES_H_INCLUDED
 #include <sys/types.h>
#endif

#ifndef _TERMIOS_H_INCLUDED
 #include <termios.h>
#endif

#pragma pack(1);

/*
 * Queue header formats
 */


struct input_buffer {
    char      __far   *buffer;
    short unsigned  length;
    char      __far   *head;
    char      __far   *tail;
    short unsigned  size;
    short int       tty;
    short unsigned  handle;
    long  unsigned  action;
    long  unsigned  mode;
    short unsigned  bcount;
    short unsigned  timer;
    short unsigned  timer_reset;
    char  unsigned  pkt_data;
    char  unsigned  pkt_flag;
    short unsigned  zero[2];
    short unsigned  hw_high_water;
    short unsigned  hw_low_water;
    short unsigned  sw_high_water;
    short unsigned  sw_low_water;
    } ;

struct output_buffer {
    char      __far   *buffer;
    short unsigned  length;
    char      __far   *head;
    char      __far   *tail;
    short unsigned  size;
    short int       tty;
    short unsigned  handle;
    long  unsigned  action;
    long  unsigned  mode;
    short unsigned  bcount;
    short unsigned  timer;
    short unsigned  timer_reset;
    short unsigned  discard;
    short unsigned  rows;
    short unsigned  cols;
    short unsigned  threshold;
    short unsigned  zero[3];
    } ;

struct canon_buffer {
    char      __far   *buffer;
    short unsigned  length;
    char       __far  *head;
    char       __far  *tail;
    short unsigned  size;
    short int       tty;
    short unsigned  handle;
    long  unsigned  action;
    long  unsigned  mode;
    char       __far  *in;
    char       __far  *eol;
    short unsigned  state;
    short unsigned  pcount;
    short unsigned  zero[4];
    } ;

struct driver_ctrl {
    short int       base_tty;
    short int       nttys;
    pid_t           (__far *tti)(int c, int tty, unsigned ds);
    short unsigned  tti_ds;
    pid_t           hw_pid;
    short unsigned  flags;
    short unsigned  ttim_offset; /* (__far *ttim)(int tty, int len, char far *data, unsigned ds) */
#ifdef __386__
    short unsigned  zero[6];
#endif
    } ;

/*
 * driver_ctrl 'flag' bits
 */
#define DRVR_GETS_PIDS	0x0001		/* IOCTL_OPEN passes down pid, fd, etc. */
#define DRVR_IS32		0x0002		/* Uses 32 bit interface */
#define DRVR_SUPP_TTIM	0x0004		/* Supports tti multiple call */

struct device_ctrl {
    short int      tty;
    short unsigned isize;
    short unsigned osize;
    short unsigned csize;
    struct input_buffer  __far *ibuf;
    struct output_buffer __far *obuf;
    struct canon_buffer  __far *cbuf;
    struct termios       __far *termios;
    struct stat          __far *stat;
    short unsigned zero[2];
    } ;



/*
 * Input character "control" bits
 */

#define RCV_BREAK           0x8000
#define RCV_DATAERR         0x4000
#define RCV_PARITY          0x4100
#define RCV_FRAME           0x4200
#define RCV_OVERRUN         0x4400
#define RCV_HW              0x2000
#define RCV_HW_OFF          0x2001
#define RCV_HW_ON           0x2002
#define RCV_HNGUP           0x2004
#define RCV_CARRIER         0x2008
#define RCV_EVENT           0x1000
#define RCV_WINCH           0x1100

/*
 * Packet-mode receive events (PTYS only)
 * these help implement out-of-band data
 */
#define RCV_PKT             0x1000
#define RCV_PKT_FLUSHREAD   0x1001
#define RCV_PKT_FLUSHWRITE  0x1002
#define RCV_PKT_STOP        0x1004
#define RCV_PKT_START       0x1008
#define RCV_PKT_NOSTOP      0x1010
#define RCV_PKT_DOSTOP      0x1020
#define RCV_PKT_IOCTL       0x1040
#define RCV_PKT_SPECIAL     0x1080

/*
 * Actions to be performed as a result of input
 */
#define ACT_NOTHING         0x0000
#define ACT_SIGINT          0x0001
#define ACT_SIGQUIT         0x0002
#define ACT_SIGTSTP         0x0004
#define ACT_OSFLOW_CHG      0x0008
#define ACT_ISFLOW_CHG      0x0010
#define ACT_OSFLOW_STOP     0x0020
#define ACT_ISFLOW_STOP     0x0040
#define ACT_INPUT_READY     0x0080
#define ACT_FLUSH_INPUT     0x0100
#define ACT_FLUSH_OUTPUT    0x0200
#define ACT_INPUT_TIMEOUT   0x0400
#define ACT_IHFLOW_CHG      0x0800
#define ACT_IHFLOW_STOP     0x1000
#define ACT_OHFLOW_CHG      0x2000
#define ACT_OHFLOW_STOP     0x4000
#define ACT_SIGHUP          0x8000
#define ACT_REQ_LOGIN       0x10000L
#define ACT_PKT             0x20000L
#define ACT_RX_READY        0x40000L
#define ACT_SIGWINCH        0x80000L

/*
 * Actions to be performed as a result of output
 */
#define ACT_OUTPUT_READY    0x0001

/*
 * Modes of controlling Input
 */
#define INPUT_STOPPED       0x0002
#define INPUT_STOPPED_HW    0x0004
#define INPUT_NOT_EMPTY     0x0008
#define INPUT_OVERFLOW      0x0010
#define INPUT_TIMER         0x0020
#define INPUT_HW            0x0040
#define INPUT_SFLOW_CHG     0x0080
#define INPUT_HFLOW_CHG     0x0100
#define INPUT_USED          0x0200
#define INPUT_ARMED         0x0400
#define INPUT_RX_TRIGGER    0x0800

/*
 * Modes of controlling Output
 */
#define OUTPUT_STOPPED      0x0001
#define OUTPUT_STOPPED_HW   0x0002
#define OUTPUT_XOFF         0x0004
#define OUTPUT_XON          0x0008
#define OUTPUT_READY        0x0010
#define OUTPUT_HW           0x0020
#define OUTPUT_HFLOW_OFF    0x0040
#define OUTPUT_HFLOW_ON     0x0080
#define OUTPUT_XNL          0x0100
#define OUTPUT_SFLOW_CHG    0x0200
#define OUTPUT_HFLOW_CHG    0x0400
#define OUTPUT_FLUSH        0x0800

/*
 * Input/Output parity definitions
 */
#define PARITY_NONE         0x0000
#define PARITY_EVEN         0x0004
#define PARITY_ODD          0x0005
#define PARITY_SPACE        0x0006
#define PARITY_MARK         0x0007

/*
 * Driver registration flags
 */
#define DRVR_SCAN           0x0001 /* open() with no suffix causes scan for unused unit */
#define DRVR_NOTTY          0x0002 /* Not a terminal device. eg: /dev/null */
#define DRVR_LOCK_HFLOW     0x0004 /* IHFLOW/OHFLOW in c_cflag cannot be changed */
#define DRVR_SINGLE_OPEN    0x0008 /* open() will fail if already opened (pty) */
#define DRVR_HEX_SUFFIX     0x0010 /* suffixes are 00 based hex rather than 01 based decimal (pty) */
#define DRVR_STTY           0x0020 /* Driver gets ALL stty() calls */
#define DRVR_NO_SUFFIX      0x0040 /* Suppress numeric suffix if only 1 device */
#define DRVR_EOFHUP			0x0080 /* Force oneshot end-of-file after receiving HUP (pty) */

/*
 * Define a set of IOCTL commands structures
 * which can be passed between DEV and the Driver
 * via the Ioctl() far-call function
 */

/*
 * IOCTL 'type'
 */
#define IOCTL_OPEN          0x0301 /* I/O channel open -   first open() */
#define IOCTL_CLOSE         0x0302 /* I/O channel closed - last close() */
#define IOCTL_CTL           0x0303 /* qnx_ioctl() */
#define IOCTL_STARTBREAK    0x0304 /* Assert break condition (if possible) */
#define IOCTL_STOPBREAK     0x0305 /* Remove the break condition */
#define IOCTL_STARTDROP     0x0306 /* Lower modem control - drop communications line */
#define IOCTL_STOPDROP      0x0307 /* return modem control to normal */

/*
 * IOCTL 'status'
 */
#define IOCTL_ERROR     (-1)
#define IOCTL_OK        0
#define IOCTL_BAD_UNIT  1
#define IOCTL_NONE_FREE 2

union ioctl_entry {
    short int type;
    short int status;
    struct ioctl_open {
        short int type;   /* IOCTL_OPEN: called before first open */
        short int unit;
		/*
		 * The following are also available since 4.10 (DRVR_GETS_PID)
		 */
        short int      mode;
        pid_t          pid;
		short int      fd;
		short unsigned euid;
		short unsigned egid;
    	struct input_buffer  __far *ibuf;		/* addressable from Dev's context */
    	struct output_buffer __far *obuf;
    	struct canon_buffer  __far *cbuf;
    	struct termios       __far *tios;
    	struct stat          __far *stat;
		unsigned       zero[4];
        } open;
    struct ioctl_open_return {
        short int status; /* IOCTL_OPEN */
        short int unit;
        } open_return;
    struct ioctl_close {
        short int type;   /* IOCTL_CLOSE: called on last close */
        short int unit;
		/*
		 * The following are also available since 4.10
		 */
        pid_t     pid;
		short int fd;
    	struct input_buffer  __far *ibuf;		/* addressable from Dev's context */
    	struct output_buffer __far *obuf;
    	struct canon_buffer  __far *cbuf;
    	struct termios       __far *tios;
    	struct stat          __far *stat;
        } close;
    struct ioctl_close_return {
        short int status; /* IOCTL_CLOSE */
        } close_return;
    struct ioctl_user {
        short int type;   /* User IOCTL */
        short int unit;
        short int zero;
        short int nbytes;
        unsigned char data[32];
        } user;
    struct ioctl_user_return {
        short int status; /* User IOCTL */
        short int zero[2];
        short int nbytes;
        unsigned char data[32];
        } user_return;
    struct ioctl_startbreak {
        short int type;   /* IOCTL_STARTBREAK */
        short int unit;
        } startbreak;
    struct ioctl_startbreak_return {
        short int status;
        } startbreak_return;
    struct ioctl_stopbreak {
        short int type;   /* IOCTL_STOPBREAK */
        short int unit;
        } stopbreak;
    struct ioctl_stopbreak_return {
        short int status;
        } stopbreak_return;
    struct ioctl_startdrop {
        short int type;   /* IOCTL_STARTDROP */
        short int unit;
        } startdrop;
    struct ioctl_startdrop_return {
        short int status;
        } startdrop_return;
    struct ioctl_stopdrop {
        short int type;   /* IOCTL_STOPDROP */
        short int unit;
        } stopdrop;
    struct ioctl_stopdrop_return {
        short int status;
        } stopdrop_return;
    };

/*
 * Message definitions solely for use by drivers
 */

#ifdef __386__
/*
 * 32 bit versions of Dev Support a differeent set of registration messages
 */
#define _DEV_DRIVER_REGISTER    0x0305
#define _DEV_DRIVER_MOUNT       0x0306
#define _DEV_DRIVER_ARM         0x0307
#define _DEV_DRIVER_SHUTDOWN    0x0308
#else
/*
 * 16 bit versions of Dev Support the standard set of registration messages
 */
#define _DEV_DRIVER_REGISTER    0x0301
#define _DEV_DRIVER_MOUNT       0x0302
#define _DEV_DRIVER_ARM         0x0303
#define _DEV_DRIVER_SHUTDOWN    0x0304
#endif

struct _driver_register {
    msg_t                   type;
    char                    name[8];
    char                    prefix[8];
    int                     nttys;
    unsigned                ds;
    unsigned                cs;
    unsigned                kick_addr;
    unsigned                stty_addr;
    unsigned                ctrl_addr;
    unsigned                flags;
    } ;

struct _driver_register_reply {
    msg_t                   status;
    int                     handle;
    struct driver_ctrl      ctrl;
    } ;

struct _driver_mount {
    msg_t                   type;
    int                     handle;
    int                     tty;
    unsigned                isize;
    unsigned                osize;
    unsigned                csize;
    unsigned                seg;
    unsigned                new;
    char                    *offset;
    unsigned                zero[3];
    } ;

struct _driver_mount_reply {
    msg_t                   status;
    unsigned                seg;
    struct device_ctrl      ctrl;
    } ;

struct _driver_arm {
    msg_t                   type;
    int                     tty;
    } ;

struct _driver_arm_reply {
    msg_t                   status;
    } ;

struct _driver_shutdown {
    msg_t                   type;
    int                     handle;
    } ;

struct _driver_shutdown_reply {
    msg_t                   status;
    } ;


/*
 * Calls made from Dev into entry points within driver
 */

#ifdef __386__
#pragma aux _dev_call far parm [es edi] value [eax] modify [eax];
    /*   ds is pre-loaded by dev before making the call.  */    
#else
#pragma aux _dev_call far parm [es di] value [ax] modify [ax];
    /*   ds is pre-loaded by dev before making the call.  */    
#endif


/*
 * Function prototypes
 */

extern short dev_drvr_register(const char *name, const char *prefix, int ntty,
                        int (__far * kick) (struct output_buffer __far *),
                        int (__far * stty) (struct termios __far *),
                        int (__far * ioctl)(union ioctl_entry __far *),
                        struct driver_ctrl *,
                        unsigned);

extern unsigned short dev_drvr_mount(int ,int ,int ,struct device_ctrl *);

extern int dev_drvr_arm( int );

extern int dev_drvr_shutdown( int );


#pragma pack();

#define __DEVDRVR_H_INCLUDED
#endif
