~kris/9p

9hist

9c29f05f4923cb931df4861384713c2e6859e018 — David du Colombier 31 years ago fc08051
Plan 9 from Bell Labs 1994-11-06
2 files changed, 164 insertions(+), 1 deletions(-)

A pc/devastar.c
M pc/ns16552.h
A pc/devastar.c => pc/devastar.c +161 -0
@@ 0,0 1,161 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"../port/error.h"

#include	"devtab.h"
#include	"../port/netif.h"

/*
 *  Stargate's Avanstar serial board.  There are ISA, EISA, microchannel versions.
 *  At the moment we only handle the ISA one.
 */
typedef struct Astar Astar;
typedef struct Astarport Astarchan;

enum
{
	/* ISA control ports */
	ISAid=		0,		/* Id port and its values */
	 ISAid0=	 0xEC,
	 ISAid1=	 0x13,
	ISActl1=	1,		/* board control */
	 ISAien=	 1<<7,		/*  interrupt enable */
	 ISAirqm=	 4,		/*  shift for 3 bit irq code */
	 ISAdl=		 1<<1,		/*  download bit (1 == download) */
	 ISApr=		 1<<0,		/*  program ready */
	ISActl2=	2,		/* board control */
	 ISA186ien=	 1<<7,		/*  I186 irq enable bit state */
	 ISA186idata=	 1<<6,		/*  I186 irq data bit state */
	 ISAmemen=	 1<<4,		/*  enable memory to respond to ISA cycles */
	 ISAmembank=	 0,		/*  shift for 4 bit memory bank */
	ISAmemaddr=	3,		/* bits 14-19 of the boards mem address */
	ISAstat1=	4,		/* board status (1 bit per channel) */
	ISAstat2=	5,		/* board status (1 bit per channel) */
};

/* control program global control block */
typedef struct GCB GCB;
struct GCB
{
	ushort	cmd;		/* command word */
	ushort	status;		/* status word */
	ushort	serv;		/* service request, must be accessed via exchange 'X' */
	ushort	avail;		/* available buffer space */
	ushort	type;		/* board type */
	ushort	cpvers;		/* control program version */
	ushort	ccbc;		/* control channel block count */
	ushort	ccbo;		/* control channel block offset */
	ushort	ccbc;		/* control channel block size */
	ushort	cmd2;		/* command word 2 */
	ushort	status2;	/* status word 2 */
	ushort	errserv;	/* comm error service request 'X' */
	ushort	inserv;		/* input buffer service request 'X' */
	ushort	outserv;	/* output buffer service request 'X' */
	ushort	modemserv;	/* modem change service request 'X' */
	ushort	cmdserv;	/* channel command service request 'X' */
};

/* control program channel control block */
typedef struct CCB CCB;
struct CCB
{
	ushort	baud;		/* baud rate */
	ushort	format;		/* data format */
	ushort	line;		/* line protocol */
	ushort	insize;		/* input buffer size */
	ushort	outsize;	/* output buffer size */
	ushort 	intrigger;	/* input buffer trigger rate */
	ushort	outlow;		/* output buffer low water mark */
	ushort	xon;		/* xon characters */
	ushort	inhigh;		/* input buffer high water mark */
	ushort	inlow;		/* input buffer low water mark */
	ushort	cmd;		/* channel command */
	ushort	status;		/* channel status */
	ushort	inbase;		/* input buffer start addr */
	ushort 	inlim;		/* input buffer ending addr */
	ushort	outbase;	/* output buffer start addr */
	ushort 	outlim;		/* output buffer ending addr */
	ushort	inwp;		/* input read and write pointers */
	ushort	inrp;
	ushort	outwp;		/* output read and write pointers */
	ushort	outrp;
	ushort	errstat;	/* error status */
	ushort	badp;		/* bad character pointer */
	ushort	mctl;		/* modem control */
	ushort	mstat;		/* modem status */
	ushort	bstat;		/* blocking status */
	ushort	rflag;		/* character received flag */
	ushort	xoff;		/* xoff characters */
	ushort	status2;
	uchort	strip;		/* strip/error characters */
};

/* host per controller info */
struct Astar
{
	int		port;		/* number of first port */
	GCB		*gbc;		/* board comm area */
	Astarchan	*c;		/* channels */
};

/* host per channel info */
struct Astarchan
{
	QLock;

	/* buffers */
	int	(*putc)(Queue*, int);
	Queue	*iq;
	Queue	*oq;


	/* staging areas to avoid some of the per character costs */
	uchar	istage[Stagesize];
	uchar	*ip;
	uchar	*ie;

	uchar	ostage[Stagesize];
	uchar	*op;
	uchar	*oe;
};

/*
 *  Stargate's Avanstar serial port cards.  Currently only the ISA version
 *  is supported.
 */
void
avanstarreset(void)
{
	int i;
	Dirtab *dp;

	for(i = 0; i < Maxcard; i++){
		sc = scard[i] = xalloc(sizeof(Scard));
		if(isaconfig("serial", i, sc) == 0){
			xfree(sc);
			break;
		}

	ndir = 3*nuart;
	ns16552dir = xalloc(ndir * sizeof(Dirtab));
	dp = ns16552dir;
	for(i = 0; i < nuart; i++){
		/* 3 directory entries per port */
		sprint(dp->name, "eia%d", i);
		dp->qid.path = NETQID(i, Ndataqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "eia%dctl", i);
		dp->qid.path = NETQID(i, Nctlqid);
		dp->perm = 0660;
		dp++;
		sprint(dp->name, "eia%dstat", i);
		dp->qid.path = NETQID(i, Nstatqid);
		dp->perm = 0444;
		dp++;
	}
}

M pc/ns16552.h => pc/ns16552.h +3 -1
@@ 131,12 131,14 @@ ns16552install(void)
				ns16552setup(port, sc->freq);
				port += 8;
			}
		} else {
		} else if(strcmp(sc->type, "com") == 0 || strcmp(sc->type, "COM") == 0){
			/*
			 *  port gives base port address for the uart
			 *  irq is interrupt
			 *  freq is the baud rate generator frequency
			 */
			if(sc->freq == 0)
				sc->freq = UartFREQ;
			ns16552setup(sc->port, sc->freq);
			setvec(Int0vec+sc->irq, ns16552intrx, (void*)(nuart-1));
		}