~kris/9p

9hist

e26d7c578bddb585770217b229a99cbb94e3e6ef — David du Colombier 31 years ago 9c29f05
Plan 9 from Bell Labs 1994-11-07
1 files changed, 220 insertions(+), 21 deletions(-)

M pc/devastar.c
M pc/devastar.c => pc/devastar.c +220 -21
@@ 10,11 10,11 @@
#include	"../port/netif.h"

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

enum
{


@@ 24,17 24,28 @@ enum
	 ISAid1=	 0x13,
	ISActl1=	1,		/* board control */
	 ISAien=	 1<<7,		/*  interrupt enable */
	 ISAirqm=	 4,		/*  shift for 3 bit irq code */
	 ISAirq=	 7<<4,		/*  mask for 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 */
	 ISAmen=	 1<<4,		/*  enable memory to respond to ISA cycles */
	 ISAmbank=	 0,		/*  shift for 4 bit memory bank */
	ISAmaddr=	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) */

	Maxcards=	3,
};

/* IRQ codes */
static int isairqcode[16] =
{
	-1,	-1,	-1,	0<<4,
	1<<4,	2<<4,	-1,	-1,
	-1,	3<<4,	4<<4,	5<<4,
	6<<4,	-1,	-1,	7<<4,
};

/* control program global control block */


@@ 59,18 70,50 @@ struct GCB
	ushort	cmdserv;	/* channel command service request 'X' */
};

enum
{
	/* GCB.cmd commands/codes */
	Greadycmd=	0,
	Gdiagcmd=	1,
	Gresetcmd=	2,

	/* GCB.status values */
	Gready=		0,
	Gstopped=	1,
	Gramerr=	2,
	Gbadcmd=	3,
	Gbusy=		4,

	/* GCB.type values */
	Gx00m=		0x6,
	G100e=		0xA,
	Gx00i=		0xC,

	/* GCB.status2 bits */
	Ghas232=	(1<<0),
	Ghas422=	(1<<1),
	Ghasmodems=	(1<<2),
	Ghasrj11s=	(1<<7),
	Ghasring=	(1<<8),
	Ghasdcd=	(1<<9),
	Ghasdtr=	(1<<10),
	Ghasdsr=	(1<<11),
	Ghascts=	(1<<12),
	Ghasrts=	(1<<13),
};

/* control program channel control block */
typedef struct CCB CCB;
struct CCB
{
	ushort	baud;		/* baud rate */
	ushort	format;		/* data format */
	ushort	line;		/* line protocol */
	ushort	proto;		/* 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 */
	char	xon[2];		/* xon characters */
	ushort	inhigh;		/* input buffer high water mark */
	ushort	inlow;		/* input buffer low water mark */
	ushort	cmd;		/* channel command */


@@ 89,15 132,90 @@ struct CCB
	ushort	mstat;		/* modem status */
	ushort	bstat;		/* blocking status */
	ushort	rflag;		/* character received flag */
	ushort	xoff;		/* xoff characters */
	char	xoff[2];	/* xoff characters */
	ushort	status2;
	uchort	strip;		/* strip/error characters */
	char	strip[2];	/* strip/error characters */
};

enum
{
	/* special baud rate codes for CCB.baud */
	Cb76800=	0xff00,
	Cb115200=	0xff01,

	/* CCB.format fields */
	C5bit=		0<<0,	/* data bits */
	C6bit=		0<<1,
	C7bit=		0<<2,
	C8bit=		0<<3,
	C1stop=		0<<2,	/* stop bits */
	C2stop=		1<<2,
	Cnopar=		0<<3,	/* parity */
	Coddpar=	1<<3,
	Cevenpar=	3<<3,
	Cmarkpar=	5<<3,
	Cspacepar=	7<<3,
	Cnormal=	0<<6,	/* normal mode */
	Cecho=		1<<6,	/* echo mode */
	Clloop=		2<<6,	/* local loopback */
	Crloop=		3<<6,	/* remote loopback */

	/* CCB.proto fields */
	Cobeyxon=	1<<0,	/* obey received xoff/xon controls */
	Canyxon=	1<<1,	/* any rcvd character restarts xmit */
	Cgenxon=	1<<2,	/* generate xoff/xon controls */
	Cobeycts=	1<<3,	/* obey hardware flow ctl */
	Cgendtr=	1<<4,	/* dtr off when uart rcvr full */
	C½duplex=	1<<5,	/* rts off while xmitting */
	Cgenrts=	1<<6,	/* generate hardware flow ctl */
	Cmctl=		1<<7,	/* direct modem control via CCB.mctl */
	Cstrip=		1<<12,	/* to strip out characters */
	Ceia422=	1<<13,	/* to select eia 422 lines */

	/* CCB.cmd fields */
	Cconfall=	1<<0,	/* configure channel and UART */
	Cconfchan=	1<<1,	/* configure just channel */
	Cflushin=	1<<2,	/* flush input buffer */
	Cflushout=	1<<3,	/* flush output buffer */
	Crcvena=	1<<4,	/* enable receiver */
	Crcvdis=	1<<5,	/* disable receiver */
	Cxmtena=	1<<6,	/* enable transmitter */
	Cxmtdis=	1<<7,	/* disable transmitter */
	Cmreset=	1<<9,	/* reset modem */

	/* CCB.errstat fields */
	Coverrun=	1<<0,
	Cparity=	1<<1,
	Cframing=	1<<2,
	Cbreak=		1<<3,

	/* CCB.mctl fields */
	Cdtrctl=	1<<0,
	Crtsctl=	1<<1,
	Cbreakctl=	1<<4


	/* CCB.mstat fields */
	Cctsstat=	1<<0,
	Cdsrstat=	1<<1,
	Cristat=	1<<2,
	Cdcdstat=	1<<3,

	/* CCB.bstat fields */
	Cbrcvoff=	1<<0,
	Cbxmtoff=	1<<1,
	Clbxoff=	1<<2,	/* transmitter blocked by XOFF */
	Clbcts=		1<<3,	/* transmitter blocked by CTS */
	Crbxoff=	1<<4,	/* remote blocked by xoff */
	Crbrts=		1<<4,	/* remote blocked by rts */
};

/* host per controller info */
struct Astar
{
	int		port;		/* number of first port */
	ISAConf;
	int		id;		/* from plan9.ini */
	int		ramsize;	/* 16k or 256k */
	GCB		*gbc;		/* board comm area */
	Astarchan	*c;		/* channels */
};


@@ 107,8 225,10 @@ struct Astarchan
{
	QLock;

	CCB	*ccb;	/* control block */

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

	Queue	*iq;
	Queue	*oq;



@@ 123,23 243,44 @@ struct Astarchan
	uchar	*oe;
};

/*
 *  Stargate's Avanstar serial port cards.  Currently only the ISA version
 *  is supported.
 */
Astar *a[Maxcard];

int astarsetup(Astar*);

void
avanstarreset(void)
astarreset(void)
{
	int i;
	Astar *a;
	Dirtab *dp;

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

		if(strcmp(a->type, "a100i") == 0 || strcmp(a->type,"A100I") == 0)
			a->ramsize = 16*1024;
		else if(strcmp(a->type, "a200i") == 0 || strcmp(a->type,"A200I") == 0)
			a->ramsize = 256*1024;
		else
			continue;
		if(a->mem == 0)
			a->mem = 0xD0000;
		if(a->irq == 0)
			a->irq = 15;
		a->id = i;

		if(astarsetup(a) < 0){
			xfree(a);
			astar[i] = 0;
			continue;
		}
	}

	ndir = 3*nuart;
	ns16552dir = xalloc(ndir * sizeof(Dirtab));
	dp = ns16552dir;


@@ 159,3 300,61 @@ avanstarreset(void)
		dp++;
	}
}

void
astarinit(void)
{
}

int isaport[] =
	{ 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 };

int
isax00i(int port)
{
	uchar c, c1;

	if(port < 0)
		return 0;

	c = inb(port + ISAid);
	c1 = inb(port + ISAid);
	return (c == ISAid0 && c1 == ISAid1)
		|| (c == ISAid1 && c1 == ISAid0));
}

int
astarsetup(Astar *a)
{
	int i, j, found;

	/* see if the card exists */
	found = 0;
	if(a->port == 0)
		for(i = 0; isaport[i]; i++){
			a->port = isaport[i];
			found = isax00i(isaport[i]);
			if(found){
				isaport[i] = -1;
				break;
			}
		}
	else
		found = isax00i(a->port);
	if(!found){
		print("avanstar %d not found\n", a->id);
		return -1;
	}

	/* set memory address */
	outb(a->port + ISAmaddr, (a->mem>>12) & 0xfc);
	a->gcb = KZERO | a->mem;

	/* set interrupt level */
	if(isairqcode(a->irq) == -1){
		print("Avanstar %d bad irq %d\n", a->id, a->irq);
		return -1;
	}
	c = inb(a->port + ISActl1) & ~ISAirq;
	outb(a->port + ISActl1, c | isairqcode(a->irq));
}