/*	Convergent Technologies - System V - Sep 1983	*/
/*	"@(#)cl.h	1.8"	*/

#ifndef cl_h
#define cl_h
#include "sys/param.h"
/*  These parameters may be changed reltively freely.  Note that 	*/
/*  SNRMSPERSEC should divide evenly into POLLSPERSEC to derive 	*/
/*  the number of polls per snrm (see cl_to).  Also note that NACK	*/
/*  should be an even number for those DMA controllers which cannot	*/
/*  do odd-byte transfers, etc.						*/

/*
 * The number of lines is determined in cf/conf.c + sys/space.h
 * It is held in cl_lines
 */

#define NXBUF			2	/* the number of xbufs per drop */
#define NXDATA		    2*512	/* number of data bytes/xbuf	*/
#define DOSIZE		       32	/* max num of stacked do routines */
#define NACK			6	/* data bytes for small bufs	*/
#define POLLSPERSEC	       10	/* number of polls/second/drop	*/
#define SNRMSPERSEC		5	/* number of snrms/second/line	*/
#define NRETRIES		5	/* number of retries		*/
#define NTRACE		       16	/* number of trace entries	*/

/*  The following times are in 100 microsecond units			*/
/*  These numbers are chosen somewhat empirically.  T_OUT values 	*/
/*  of about 50 (5ms) are known to cause problems in some cluster	*/
/*  devices.  100 (10ms) seems to be fine for everything.		*/
/*  The T_OUT_DELAY speicifes how long the cluster code should delay	*/
/*  after an io completion before using the line again.  This gives	*/
/*  slower drops time to set up a receive.				*/

#define T_OUT_SNRM	      100	/* polling inactive expects ua	*/
#define T_OUT_SIM	      300	/* sent sim, waiting for xid	*/
#define T_OUT_DISC	      300	/* sent disc, waiting for ua	*/
#define T_OUT_UP	      300	/* send up, waiting for ua	*/
#define T_OUT_UI	      1000	/* sent ui, waiting for ua	*/
#define T_OUT_RNR	      300	/* rnr expects rr/rnr		*/
#define T_OUT_I		      1000	/* i expects rr			*/
#define T_OUT_RR	      1000	/* rr expect i or rr		*/
#define T_OUT_DELAY	      20	/* delay after iocomplete	*/


/* values for x_pool */
#define XRD			1	/* a read xbuf */
#define XWT			2	/* a general purpose xbuf */
#define XSWT			3	/* a small write xbuf unused */
#define XBSWT			4	/* a small write xbuf busy */

struct xbuf				/* transmission buffer		*/
{
    struct xbuf		*x_next;	/* next pointer			*/
    short		x_size;		/* number of bytes in the xbuf	*/
    char		x_pool;		/* is this a read or a write xbuf */
    char		x_wndw;		/* window number for this xbuf */
    char		x_addr;		/* comm-level (ADCCP) address	*/
    char		x_cntl;		/* comm-level (ADCCP) control	*/
    char		x_data[NXDATA];	/* data bytes			*/
};



struct dblk				/* drop descriptor block	*/
{
    struct dblk		*d_next;	/* next drop in list		*/
    struct lblk		*d_l;		/* up ptr to this dblk's lblk	*/
    struct xbuf		*d_xbuflist;	/* queue of xbufs to be sent	*/
    short		d_state;	/* drop state (see below)	*/
    char		d_addr;		/* drop number (0,1,...NDROPS)	*/
    char		d_num;		/* logical number of this drop	*/
    unsigned char	d_vr;		/* V(r) - receive sequence num	*/
    unsigned char	d_vs;		/* V(s) - send sequence num	*/
    char		d_busy;		/* drop has sent RNR		*/
    char		d_alxbs;	/* current number of allocated xbufs */
};

struct ltrace
{
    char		lt_saddr;	/* send address			*/
    char		lt_scntl;	/* send control			*/
    char		lt_raddr;	/* recv address			*/
    char		lt_rcntl;	/* recv control			*/
};

struct lblk				/* line descriptor block	*/
{
    struct dblk		*l_actlist;	/* linked list - active drops	*/
    struct dblk		*l_inactlist;	/* linked list - inactive drops	*/
    struct dblk		*l_bootlist;	/* linked list - booting drops	*/ 
    struct dblk		*l_snrmdrop;	/* ptr to next drop to snrm	*/
    struct dblk		*l_polldrop;	/* ptr to next drop to poll	*/
    struct dblk		*l_senddrop;	/* ptr to last drop sent iframe */
    struct dblk		*l_bootdrop;	/* ptr to last drop send ui	*/
    struct dblk		*l_iodblk;	/* current dblk doing I/O	*/
    char		*l_poutbuf;	/* pointer to current output	*/
    char		*l_pinbuf;	/* pointer to current input	*/
    struct xbuf		*l_pinxbuf;	/* ptr to input xbuf		*/
    int			l_itrace;	/* index into trace buffer	*/
    short		l_state;	/* state of line (see below)	*/
    short		l_retrycount;	/* retry counter		*/
    short		l_snrmtimer;	/* down-counter for snrming	*/
    short		l_coutbuf;	/* size of output		*/
    short		l_cinbuf;	/* size of input		*/
    short		l_cinmax;	/* maximum input size		*/
    short		l_timeout;	/* timeout for the i/o		*/
    short		l_speed;	/* speed flag for RS-422	*/
    short		l_completionstatus;  /* completion status	*/
    char		l_ackin[NACK];	/* small read area		*/
    char		l_ackout[NACK];	/* small write area		*/
    char		l_num;		/* line number (0,1,...NLINES)	*/
    char		l_fneedsnrm;	/* true if need to send snrm	*/
    char		l_fairness;	/* used by startnew		*/
    struct ltrace	l_trace[NTRACE];/* trace buffer			*/
};

/* 
 *	The pt_flags keep the state of the fast comm operation.
 *	The flags are mutually exclusive. To clear the set of 
 *	them use ptDmaDisable().
 */

struct pt_flags {
	char	fRWait;	/* true if we are waiting for a free line to receive*/
	char	fRcv;	/* true if we are currently receiving */
	char	fTWait; /* true if we are waiting for a free transmit line */
	char	fTrans; /* true if we are currently transmitting */
};

#ifndef space_h
/*  Line states in lblk.l_state						*/

#define LSTAT_IDLE		0	/* line is not doing anything	*/
#define LSTAT_RR		1	/* sent rr			*/
#define LSTAT_RNR		2	/* sent rnr			*/
#define LSTAT_I			3	/* sent i			*/
#define LSTAT_SNRM		4	/* sent snrm			*/
#define LSTAT_SIM		5	/* sent sim			*/
#define LSTAT_UP		6	/* sent up			*/
#define LSTAT_UI		7	/* sent ui			*/
#define LSTAT_DISC		8	/* sent disc			*/
#define LSTAT_IRNR		9	/* sent rnr during recovery	*/


/*  Line speeds in lblk.l_speed						*/

#define LSPEED_307		0	/* 307kbs			*/
#define LSPEED_18		1	/* 1.8mbs			*/

/*  Special trace entries						*/

#define LTRACE_INITIAL		0xFF	/* initial value		*/
#define LTRACE_TIMEOUT		0xEE	/* read timed out		*/

/*  State definitions in dblk.d_state					*/

#define DSTAT_DOWN		0	/* the drop is down		*/
#define DSTAT_UP		1	/* the drop is up		*/
#define DSTAT_BOOTING		2	/* the drop is booting		*/

/*  Error codes returned						*/

#define CLERR_BADLU		100	/* bad logical unit arg		*/

/* Frame definitions							*/

#define MASK_I			0x11
#define FRAME_I			0x10
#define MASK_RR			0x1F
#define FRAME_RR		0x11
#define MASK_RNR		MASK_RR
#define FRAME_RNR		0x15
#define MASK_SNRM		0xFF
#define FRAME_SNRM		0x93
#define MASK_UA			MASK_SNRM
#define FRAME_UA		0x73
#define MASK_UP			MASK_SNRM
#define FRAME_UP		0x33
#define MASK_UI			MASK_SNRM
#define FRAME_UI		0x13
#define MASK_RIM		MASK_SNRM
#define FRAME_RIM		0x17
#define MASK_SIM		MASK_SNRM
#define FRAME_SIM		FRAME_RIM
#define MASK_XID		MASK_SNRM
#define FRAME_XID		0xBF
#define MASK_DISC		MASK_SNRM
#define FRAME_DISC		0x53

#define SHIFT_NS		1
#define SHIFT_NR		5

#define framens(d)		(((d)->d_vs)<<SHIFT_NS)
#define framenr(d)		(((d)->d_vr)<<SHIFT_NR)
#define xtractns(c)		(((c)>>SHIFT_NS)&7)
#define xtractnr(c)		(((c)>>SHIFT_NR)&7)
#endif space_h

/*  Miscellaneous definitions						*/

struct qelem
{
    struct qelem		*q_next;
};

#define QELEM			struct qelem *

#define XNULL			((struct xbuf *)0)
#define DNULL			((struct dblk *)0)
#define LNULL			((struct lblk *)0)

#define modinc(n)		(((n)+1)&7)
#define moddec(n)		(((n)-1)&7)
#define true			(1)
#define false			(0)

#define fatal(x)		panic(x)
#ifndef HZ
#define HZ			60		/* clock ticks/second	*/
#endif

/*  This is the statically-allocated area for line and drop blocks.	*/

#ifndef space_h
extern struct lblk ltab[];
extern struct dblk dtab[];
extern struct dblk *lutab[];
extern short cl_lines;		/* # RS-422 lines for cluster operation */
extern short cl_drops;		/* # drops permissable per line */
#endif
/*
 * some defines to convert line #s and drop #s to/from a minor node number
 */
#define cldrop(x)	((unsigned char)((x) % cl_drops))
#define clline(x)	((unsigned char)(((x) / cl_drops) & 0x3)) /* why the 0x3? */
#define cldev(l,d)	((short)((((short)l) * (short)cl_drops) + ((short)d)))
#endif cl_h
