
/*
 * devices.h: version 3.3 of 6/4/85
 *
 *  devices.h -- Define VIOS device descriptor structures
 *  copyright (c) American Information Systems Corporation
 *	Daniel Steinberg	November, 1984
 */
#ifndef DEVICES
#define DEVICES

#include "viostypes.h"


/* Device Class-Dependent Data Structures */

	/* BLK_ADDR: Random Access Fixed-Length Block Devices */
    /* disks, formatted cartridge tapes, etc. */

typedef struct
	{
	unsigned   blocksize;	/* Number of bytes per block */
	unsigned   blockmax;	/* Total number of blocks in device */
	}  BLKA_DATA;

#define Blka_size(x)		(Classdata(x).blka.blocksize)
#define Blka_max(x)		(Classdata(x).blka.blockmax)

	/* REC_SEQ: Sequential Record Devices */
    /* (terminals, line printers, magtapes, etc.) */


/* Record device/file position */

typedef struct
	{
	int filenumber;	/* number of file markers preceeding position */
	int recnumber;	/* number of records preceeding position in file */
	int bytenumber;	/* number of bytes preceeding position in record */
	}  RECS_PTR;

#define Recs_filenum(x)		(Recs_pos(x).filenumber)
#define Recs_recnum(x)		(Recs_pos(x).recnumber)
#define Recs_bytenum(x)		(Recs_pos(x).bytenumber)


/* Input buffer header (buffer continues past ibufstart) */

typedef struct
	{
	UB16 ibufsize;		/* number of bytes in buffer */
	UB16 ibufctr;		/* number of bytes in use in buffer */
	UB16 ibufptr;		/* ring buffer start offset */
	char ibufstart;		/* variable size buffer */
	}  INP_BUFFER;

#define Ibufsize(x)		((x)->ibufsize)
#define Ibufctr(x)		((x)->ibufctr)
#define Ibufptr(x)		((x)->ibufptr)
#define Ibuffer(x)		((char *) &((x)->ibufstart))


/* Physical Unit Descriptor for REC_SEQ devices */

typedef struct
	{
	union
	    {
	    INP_BUFFER **ibuffer;	/* bufptr to input buffer, if any */
	    int          hbufsize;	/* size of host input buffer */
	    }  _rbuf;
	char istopc;		/* stop input character or code */
	char istartc;		/* restart input character or code */
	char ieofc;		/* input end-of-file character */
	char ostopc;		/* stop output character or code */
	char ostartc;		/* restart output character or code */

	unsigned ibaud     : 4;	/* input baud rate */
	unsigned obaud     : 4;	/* output baud rate */

	unsigned ithrottle : 2;	/* action on input buffer full */
				/* RINGBUFFER : overwrite oldest character */
				/* XONXOFF : transmit stop character */
				/* DEVBUSY : set receiver not ready */

	unsigned istopped  : 1;	/* input stopped */
	unsigned itoggle   : 1;	/* pending toggle of input XON/XOFF */
	unsigned ioverrun  : 1;	/* input buffer overflow */
	unsigned ieofpnd   : 1;	/* EOF will terminate next input */
	unsigned ieotpnd   : 1;	/* EOF accepted...EOT if two in a row */
	unsigned ibrkpnd   : 1;	/* next byte in input buffer is a BREAK */
	unsigned othrottle : 2;	/* throttle mode from output device */
				/* XOFFXON : start/stop characters */
				/* XOFFXANY : any character to restart */
				/* DEVBUSY : receiver ready/not ready */

	unsigned ostopped  : 1;	/* output stopped */
	unsigned carrierin : 1;	/* carrier present */
	unsigned dtrout    : 1;	/* DTR output asserted */
	}  RECS_PUD;

#define Rp_ibuffer(x)		(Devpud(x).recsp._rbuf.ibuffer)
#define Rp_hostbsize(x)		(Devpud(x).recsp._rbuf.hbufsize)
#define Rp_istopc(x)		(Devpud(x).recsp.istopc)
#define Rp_istartc(x)		(Devpud(x).recsp.istartc)
#define Rp_ieofc(x)		(Devpud(x).recsp.ieofc)
#define Rp_ostopc(x)		(Devpud(x).recsp.ostopc)
#define Rp_ostartc(x)		(Devpud(x).recsp.ostartc)
#define Rp_ibaud(x)		(Devpud(x).recsp.ibaud)
#define Rp_obaud(x)		(Devpud(x).recsp.obaud)
#define Rp_ithrottle(x)		(Devpud(x).recsp.ithrottle)
#define Rp_istopped(x)		(Devpud(x).recsp.istopped)
#define Rp_itoggle(x)		(Devpud(x).recsp.itoggle)
#define Rp_ioverrun(x)		(Devpud(x).recsp.ioverrun)
#define Rp_ieofpnd(x)		(Devpud(x).recsp.ieofpnd)
#define Rp_ibrkpnd(x)		(Devpud(x).recsp.ibrkpnd)
#define Rp_ieotpnd(x)		(Devpud(x).recsp.ieotpnd)
#define Rp_othrottle(x)		(Devpud(x).recsp.othrottle)
#define Rp_ostopped(x)		(Devpud(x).recsp.ostopped)
#define Rp_carrier(x)		(Devpud(x).recsp.carrierin)
#define Rp_dtr(x)		(Devpud(x).recsp.dtrout)

/* Class-dependent data for REC_SEQ devices */

typedef struct
	{
	struct VD_DESCRIPTOR **eot_input;	/* pushed input device */
	RECS_PTR rec_position;	/* current device/file position */
	unsigned rec_length;	/* max record length */

	unsigned rwdok   : 1;	/* device can rewind */
	unsigned fdspcok : 1;	/* device can forward space */
	unsigned bkspcok : 1;	/* device can backward space */
	unsigned echook  : 1;	/* device input might require echo */
	unsigned imode   : 1;	/* Block / Stream  -oriented device */
	}  RECS_DATA;

#define Recs_eot(x)		(Classdata(x).recs.eot_input)
#define Recs_pos(x)		(Classdata(x).recs.rec_position)
#define Recs_rlength(x)		(Classdata(x).recs.rec_length)
#define Recs_rwdok(x)		(Classdata(x).recs.rwdok)
#define Recs_fdspcok(x)		(Classdata(x).recs.fdspcok)
#define Recs_bkspcok(x)		(Classdata(x).recs.bkspcok)
#define Recs_echook(x)		(Classdata(x).recs.echook)
#define Recs_imode(x)		(Classdata(x).recs.imode)

/*	R_BLOCK  0	   Block mode for Record-Sequential devices */
/*	R_STREAM 1	   Stream mode for Record-Sequential devices */

	/* BUF_ADDR:  Single buffer-addressible devices */
		/* Bit-mapped display devices, etc. */

/* Physical Unit Descriptor for BUF_ADDR devices */
typedef struct
	{
	unsigned buftype : 2;	/* buffer type code */
	}  BUFA_PUD;

#define Bfp_type(x)	(Devpud(x).bufap.buftype)

#define HOST_MEMORY 1


typedef struct
	{
	int   buffersize;	/* buffer size (in bytes) */
	}  BUFA_DATA;

#define Bufa_size(x)		(Classdata(x).bufa.buffersize)


/* Define unions of Physical Unit Descriptors and Class-Specific PDD Data */

typedef union		/* Physical Unit Descriptors */
	{
	RECS_PUD  recsp;	/* Rec_seq */
	BUFA_PUD  bufap;	/* Buf-addr */
	}  DEV_PUD;


typedef union		/* Physical Device Descriptors Class Data */
	{
	BLKA_DATA  blka;	/* Blk_addr */
	RECS_DATA  recs;	/* Rec_seq */
	BUFA_DATA  bufa;	/* Buf-addr */
	}  DEV_CDATA;

/* Virtual Device Descriptor */

typedef struct VD_DESCRIPTOR
	{
	struct VD_DESCRIPTOR **next;
	struct VD_DESCRIPTOR **last;
	char  **dname;			/* Bufptr to ASCIZ name */
	CLASS_MODULE **class_mod;	/* Bufptr to class dispatch module */
	UB16  attachments;		/* Number of devices pointing to it */
	_IOCOUNT io_outstanding;	/* Number of I/O reqs pointing to it */
	DEV_CDATA   classdata;		/* class-dependent device info */
	UB8   dclass;			/* device class */
	unsigned dtype : 1;		/* VDTYPE (to distinguish from PDD) */
	unsigned r_on_dea : 1;		/* Remove when attachments <- 0 */
	unsigned r_on_comp : 1;		/* Remove when i/o_outstanding <- 0 */
	unsigned rundown : 1;		/* Scheduled for removal */
	unsigned writeok : 1;		/* Write allowed to device */
	unsigned readok  : 1;		/* Read allowed to device */
	OS_IDENT  owner_id;		/* ID of owner O.S. */
	struct VD_DESCRIPTOR **pri_output;	/* primary output device */
	struct VD_DESCRIPTOR **pri_input;	/* primary input device */
	struct VD_DESCRIPTOR **err_input;	/* secondary input device */
	struct VD_DESCRIPTOR **jou_output;	/* output journal device */
	struct VD_DESCRIPTOR **jou_input;	/* input journal device */
	}  VDD, **VDD_PTR;


/* Physical Device Descriptor */

typedef struct PD_DESCRIPTOR
	{
	struct PD_DESCRIPTOR **next;
	struct PD_DESCRIPTOR **last;
	char  **dname;			/* Bufptr to ASCIZ name (path) */
	CLASS_MODULE **class_mod;	/* Bufptr to class dispatch module */
	UB16  attachments;		/* Number of devices pointing to it */
	_IOCOUNT io_outstanding;	/* Number of I/O reqs pointing to it */
	DEV_CDATA   classdata;		/* class-dependent device info */
	UB8  dclass;			/* Device class */
	unsigned dtype : 1;		/* PDTYPE (to distinguish from VDD) */
	unsigned r_on_dea : 1;		/* Remove when attachments <- 0 */
	unsigned r_on_comp : 1;		/* Remove when i/o_outstanding <- 0 */
	unsigned rundown : 1;		/* Scheduled for removal */
	unsigned writeok : 1;		/* Write allowed to device */
	unsigned readok  : 1;		/* Read allowed to device */
	unsigned full_duplex : 1;	/* True if full-duplex device */
	unsigned iobusy : 1;		/* True if i/o in progress */
	unsigned fdbusy : 1;		/* output in progress if full-duplex */
	unsigned shareread : 1;		/* Shareable reading */
	unsigned sharewrite : 1;	/* Shareable writing */
	struct IO_PK **iopktptr;	/* Current i/o packet */
	struct IO_PK **fdpktptr;	/* Current output pkt if full-duplex */
	int (*dspatch)();		/* Handler for device requests */
	DEV_PUD pud;			/* Physical Unit Descriptor */
	unsigned dcsr;			/* CSR address or host device number */
	}  PDD, **PDD_PTR;

/* Define macros that extract fields from device structures */

	/* Virtual/Physical Devices */

#define Devname(x)		((x)->dname)
#define Classmod(x)		((x)->class_mod)
#define Classdispatcher(x)	(C_dispatcher(*Classmod(x)))
#define Attachments(x)		((x)->attachments)
#define Outstanding_IO(x)	((x)->io_outstanding)
#define Classdata(x)		((x)->classdata)
#define Devclass(x)		((x)->dclass)
#define Devtype(x)		((x)->dtype)
#define Detachremove(x)		((x)->r_on_dea)
#define Compremove(x)		((x)->r_on_comp)
#define Rundown(x)		((x)->rundown)
#define Writeable(x)		((x)->writeok)
#define Readable(x)		((x)->readok)

	/* Virtual Devices Only */

#define Ownerid(x)		((x)->owner_id)
#define Primaryinput(x)		((x)->pri_input)
#define Primaryoutput(x)	((x)->pri_output)
#define Errorinput(x)		((x)->err_input)
#define Journalinput(x)		((x)->jou_input)
#define Journaloutput(x)	((x)->jou_output)

	/* Physical Devices Only */

#define Fullduplex(x)		((x)->full_duplex)
#define Devbusy(x)		((x)->iobusy)
#define Devibusy(x)		((x)->iobusy)
#define Devobusy(x)		((x)->fdbusy)
#define Devrdshare(x)		((x)->shareread)
#define Devwtshare(x)		((x)->sharewrite)
#define Devpkt(x)		((x)->iopktptr)
#define Devipkt(x)		((x)->iopktptr)
#define Devopkt(x)		((x)->fdpktptr)
#define Dispatcher(x)		((x)->dspatch)
#define Devpud(x)		((x)->pud)
#define Devcsr(x)		((x)->dcsr)
#define Devhostnum(x)		((x)->dcsr)


/* Define special codes for device class handling module dispatcher */

#define VDCREATE	1		/* Create a virtual device */
#define VDREMOVE	2		/* Remove a virtual device */
#define VDREAD		3		/* Start read on a virtual device */
#define VDWRITE		4		/* Start write on a virtual device */
#define VDIOCTRL	5		/* Start i/o control on a virt device */
#define VDINFO		6		/* Copy device information to buffer */
#define VDMAPPOOL	-1		/* Mark virtual device pool data */


/* Define special codes for physical device configuration module dispatcher */

#define PDCREATE	10		/* Create a physical device */
#define PDREMOVE	11		/* Remove a physical device */
#define STARTIO		12		/* Start i/o on a physical device */
#define PDIOCTRL	13		/* Start i/o control on phys device */
#define PDMAPPOOL	-2		/* Mark physical device pool data */

#endif
