plan 9 kernel history: overview | file list | diff list

1999/0819/pc/devastar.c (diff list | history)

1994/1106/sys/src/9/pc/devastar.c:10,201994/1107/sys/src/9/pc/devastar.c:10,20 (short | long)
Still writing driver.
rsc Fri Mar 4 12:44:25 2005
1994/1106    
#include	"../port/netif.h" 
 
/* 
 *  Stargate's Avanstar serial board.  There are ISA, EISA, microchannel versions. 
 *  At the moment we only handle the ISA one. 
1994/1107    
 *  Stargate's Avanstar serial board.  There are ISA, EISA, microchannel 
 *  versions.  We only handle the ISA one. 
1994/1106    
 */ 
typedef struct Astar Astar; 
typedef struct Astarport Astarchan; 
1994/1107    
typedef struct Astarchan Astarchan; 
1994/1106    
 
enum 
{ 
1994/1106/sys/src/9/pc/devastar.c:24,421994/1107/sys/src/9/pc/devastar.c:24,53
1994/1106    
	 ISAid1=	 0x13, 
	ISActl1=	1,		/* board control */ 
	 ISAien=	 1<<7,		/*  interrupt enable */ 
	 ISAirqm=	 4,		/*  shift for 3 bit irq code */ 
1994/1107    
	 ISAirq=	 7<<4,		/*  mask for irq code */ 
1994/1106    
	 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 */ 
1994/1107    
	 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 */ 
1994/1106    
	ISAstat1=	4,		/* board status (1 bit per channel) */ 
	ISAstat2=	5,		/* board status (1 bit per channel) */ 
1994/1107    
 
	Maxcards=	3, 
1994/1106    
}; 
 
1994/1107    
/* 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, 
}; 
 
1994/1106    
/* control program global control block */ 
typedef struct GCB GCB; 
struct GCB 
1994/1106/sys/src/9/pc/devastar.c:59,641994/1107/sys/src/9/pc/devastar.c:70,107
1994/1106    
	ushort	cmdserv;	/* channel command service request 'X' */ 
}; 
 
1994/1107    
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), 
}; 
 
1994/1106    
/* control program channel control block */ 
typedef struct CCB CCB; 
struct CCB 
1994/1106/sys/src/9/pc/devastar.c:65,761994/1107/sys/src/9/pc/devastar.c:108,119
1994/1106    
{ 
	ushort	baud;		/* baud rate */ 
	ushort	format;		/* data format */ 
	ushort	line;		/* line protocol */ 
1994/1107    
	ushort	proto;		/* line protocol */ 
1994/1106    
	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 */ 
1994/1107    
	char	xon[2];		/* xon characters */ 
1994/1106    
	ushort	inhigh;		/* input buffer high water mark */ 
	ushort	inlow;		/* input buffer low water mark */ 
	ushort	cmd;		/* channel command */ 
1994/1106/sys/src/9/pc/devastar.c:89,1031994/1107/sys/src/9/pc/devastar.c:132,221
1994/1106    
	ushort	mstat;		/* modem status */ 
	ushort	bstat;		/* blocking status */ 
	ushort	rflag;		/* character received flag */ 
	ushort	xoff;		/* xoff characters */ 
1994/1107    
	char	xoff[2];	/* xoff characters */ 
1994/1106    
	ushort	status2; 
	uchort	strip;		/* strip/error characters */ 
1994/1107    
	char	strip[2];	/* strip/error characters */ 
1994/1106    
}; 
 
1994/1107    
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 */ 
}; 
 
1994/1106    
/* host per controller info */ 
struct Astar 
{ 
	int		port;		/* number of first port */ 
1994/1107    
	ISAConf; 
	int		id;		/* from plan9.ini */ 
	int		ramsize;	/* 16k or 256k */ 
1994/1106    
	GCB		*gbc;		/* board comm area */ 
	Astarchan	*c;		/* channels */ 
}; 
1994/1106/sys/src/9/pc/devastar.c:107,1141994/1107/sys/src/9/pc/devastar.c:225,234
1994/1106    
{ 
	QLock; 
 
1994/1107    
	CCB	*ccb;	/* control block */ 
 
1994/1106    
	/* buffers */ 
	int	(*putc)(Queue*, int); 
1994/1107    
 
1994/1106    
	Queue	*iq; 
	Queue	*oq; 
 
1994/1106/sys/src/9/pc/devastar.c:123,1451994/1107/sys/src/9/pc/devastar.c:243,286
1994/1106    
	uchar	*oe; 
}; 
 
/* 
 *  Stargate's Avanstar serial port cards.  Currently only the ISA version 
 *  is supported. 
 */ 
1994/1107    
Astar *a[Maxcard]; 
 
int astarsetup(Astar*); 
 
1994/1106    
void 
avanstarreset(void) 
1994/1107    
astarreset(void) 
1994/1106    
{ 
	int i; 
1994/1107    
	Astar *a; 
1994/1106    
	Dirtab *dp; 
 
	for(i = 0; i < Maxcard; i++){ 
		sc = scard[i] = xalloc(sizeof(Scard)); 
		if(isaconfig("serial", i, sc) == 0){ 
			xfree(sc); 
1994/1107    
		a = astar[i] = xalloc(sizeof(Astar)); 
		if(isaconfig("serial", i, &a) == 0){ 
			xfree(a); 
			astar[i] = 0; 
1994/1106    
			break; 
		} 
 
1994/1107    
		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; 
		} 
	} 
 
1994/1106    
	ndir = 3*nuart; 
	ns16552dir = xalloc(ndir * sizeof(Dirtab)); 
	dp = ns16552dir; 
1994/1106/sys/src/9/pc/devastar.c:158,1611994/1107/sys/src/9/pc/devastar.c:299,360
1994/1106    
		dp->perm = 0444; 
		dp++; 
	} 
1994/1107    
} 
 
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)); 
1994/1106    
} 
1994/1107/sys/src/9/pc/devastar.c:228,2341994/1108/sys/src/9/pc/devastar.c:228,233 (short | long)
Change default memory location.
rsc Fri Mar 4 12:44:25 2005
1994/1107    
	CCB	*ccb;	/* control block */ 
 
1994/1106    
	/* buffers */ 
1994/1107    
                 
1994/1106    
	Queue	*iq; 
	Queue	*oq; 
 
1994/1107/sys/src/9/pc/devastar.c:268,2751994/1108/sys/src/9/pc/devastar.c:267,275
1994/1107    
			a->ramsize = 256*1024; 
		else 
			continue; 
1994/1108    
 
1994/1107    
		if(a->mem == 0) 
			a->mem = 0xD0000; 
1994/1108    
			a->mem = 0xD4000; 
1994/1107    
		if(a->irq == 0) 
			a->irq = 15; 
		a->id = i; 
1994/1108/sys/src/9/pc/devastar.c:225,2301994/1109/sys/src/9/pc/devastar.c:225,231 (short | long)
1994/1106    
{ 
	QLock; 
 
1994/1109    
	Astar	*a;	/* controller */ 
1994/1107    
	CCB	*ccb;	/* control block */ 
 
1994/1106    
	/* buffers */ 
1994/1108/sys/src/9/pc/devastar.c:242,2501994/1109/sys/src/9/pc/devastar.c:243,252
1994/1106    
	uchar	*oe; 
}; 
 
1994/1107    
Astar *a[Maxcard]; 
1994/1109    
Astar *astar[Maxcard]; 
int nastar; 
1994/1107    
 
int astarsetup(Astar*); 
1994/1109    
static int astarsetup(Astar*); 
1994/1107    
 
1994/1106    
void 
1994/1107    
astarreset(void) 
1994/1108/sys/src/9/pc/devastar.c:254,2631994/1109/sys/src/9/pc/devastar.c:256,265
1994/1106    
	Dirtab *dp; 
 
	for(i = 0; i < Maxcard; i++){ 
1994/1107    
		a = astar[i] = xalloc(sizeof(Astar)); 
1994/1109    
		a = astar[nastar] = xalloc(sizeof(Astar)); 
1994/1107    
		if(isaconfig("serial", i, &a) == 0){ 
			xfree(a); 
			astar[i] = 0; 
1994/1109    
			astar[nastar] = 0; 
1994/1106    
			break; 
		} 
 
1994/1108/sys/src/9/pc/devastar.c:276,2841994/1109/sys/src/9/pc/devastar.c:278,287
1994/1107    
 
		if(astarsetup(a) < 0){ 
			xfree(a); 
			astar[i] = 0; 
1994/1109    
			astar[nastar] = 0; 
1994/1107    
			continue; 
		} 
1994/1109    
		nastar++; 
1994/1107    
	} 
 
1994/1106    
	ndir = 3*nuart; 
1994/1108/sys/src/9/pc/devastar.c:306,3161994/1109/sys/src/9/pc/devastar.c:309,319
1994/1107    
{ 
} 
 
int isaport[] = 
	{ 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 }; 
1994/1109    
/* isa ports an ax00i can appear at */ 
int isaport[] = { 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 }; 
1994/1107    
 
int 
isax00i(int port) 
1994/1109    
static int 
astarprobe(int port) 
1994/1107    
{ 
	uchar c, c1; 
 
1994/1108/sys/src/9/pc/devastar.c:323,3291994/1109/sys/src/9/pc/devastar.c:326,332
1994/1107    
		|| (c == ISAid1 && c1 == ISAid0)); 
} 
 
int 
1994/1109    
static int 
1994/1107    
astarsetup(Astar *a) 
{ 
	int i, j, found; 
1994/1108/sys/src/9/pc/devastar.c:333,3391994/1109/sys/src/9/pc/devastar.c:336,342
1994/1107    
	if(a->port == 0) 
		for(i = 0; isaport[i]; i++){ 
			a->port = isaport[i]; 
			found = isax00i(isaport[i]); 
1994/1109    
			found = astarprobe(isaport[i]); 
1994/1107    
			if(found){ 
				isaport[i] = -1; 
				break; 
1994/1108/sys/src/9/pc/devastar.c:357,3601994/1109/sys/src/9/pc/devastar.c:360,365
1994/1107    
	} 
	c = inb(a->port + ISActl1) & ~ISAirq; 
	outb(a->port + ISActl1, c | isairqcode(a->irq)); 
1994/1109    
 
	return 0; 
1994/1106    
} 
1994/1109/sys/src/9/pc/devastar.c:7,131994/1111/sys/src/9/pc/devastar.c:7,12 (short | long)
1994/1106    
#include	"../port/error.h" 
 
#include	"devtab.h" 
#include	"../port/netif.h" 
 
/* 
1994/1107    
 *  Stargate's Avanstar serial board.  There are ISA, EISA, microchannel 
1994/1109/sys/src/9/pc/devastar.c:215,2231994/1111/sys/src/9/pc/devastar.c:214,223
1994/1106    
{ 
1994/1107    
	ISAConf; 
	int		id;		/* from plan9.ini */ 
1994/1111    
	int		nchan;		/* number of channels */ 
	Astarchan	*c;		/* channels */ 
1994/1107    
	int		ramsize;	/* 16k or 256k */ 
1994/1106    
	GCB		*gbc;		/* board comm area */ 
	Astarchan	*c;		/* channels */ 
}; 
 
/* host per channel info */ 
1994/1109/sys/src/9/pc/devastar.c:227,2531994/1111/sys/src/9/pc/devastar.c:227,315
1994/1106    
 
1994/1109    
	Astar	*a;	/* controller */ 
1994/1107    
	CCB	*ccb;	/* control block */ 
1994/1111    
	int	perm; 
1994/1107    
 
1994/1106    
	/* buffers */ 
	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; 
}; 
 
1994/1109    
Astar *astar[Maxcard]; 
int nastar; 
1994/1111    
static int nastar; 
1994/1107    
 
1994/1111    
enum 
{ 
	Qmem=	0, 
	Qdata, 
	Qctl, 
	Qstat, 
}; 
#define TYPE(x)		((x)&0xff) 
#define BOARD(x)	((((x)&~CHDIR)>>16)&0xff) 
#define CHAN(x)		((((x)&~CHDIR)>>8)&0xff) 
#define QID(b,c,t)	(((b)<<16)|((c)<<8)|(t)) 
 
1994/1109    
static int astarsetup(Astar*); 
1994/1107    
 
1994/1111    
int 
devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db) 
{ 
	int dev, sofar, ch, t; 
 
	USED(tab, ntab); 
	sofar = 0; 
 
	for(dev = 0; dev < nstar; dev++){ 
		if(sofar == i){ 
			sprint(db->name, "atar%dmem", astar[dev].id); 
			db->qid = QID(dev, 0, Qmem); 
			db->mode = 0660; 
			break; 
		} 
 
		if(i < sofar + 3*astar[dev].nchan){ 
			i -= sofar; 
			ch = i/3; 
			t = i%3; 
			switch(t){ 
			case 0: 
				sprint(db->name, "eia%d%2.2d", dev, ch); 
				db->mode = astar[dev]->c[ch].perm; 
				db->qid = QID(dev, 0, Qdata); 
				break; 
			case 1: 
				sprint(db->name, "eia%d%2.2dctl", dev, ch); 
				db->mode = astar[dev]->c[ch].perm; 
				db->qid = QID(dev, 0, Qctl); 
				break; 
			case 2: 
				sprint(db->name, "eia%d%2.2dstat", dev, ch); 
				db->mode = 0444; 
				db->qid = QID(dev, 0, Qstat); 
				break; 
			break; 
		} 
 
		sofar += 1 + 3*astar[dev].nchan; 
	} 
 
	if(j == nstar) 
		return -1; 
 
	db->atime = seconds(); 
	db->mtime = kerndate; 
	db->hlength = 0; 
	db->length = length; 
	memmove(db->uid, eve, NAMELEN); 
	memmove(db->gid, eve, NAMELEN); 
	db->type = devchar[c->type]; 
	db->dev = c->dev; 
	if(c->flag&CMSG) 
		db->mode |= CHMOUNT; 
 
	return 1; 
} 
 
1994/1106    
void 
1994/1107    
astarreset(void) 
1994/1106    
{ 
1994/1109/sys/src/9/pc/devastar.c:283,3141994/1111/sys/src/9/pc/devastar.c:345,352
1994/1107    
		} 
1994/1109    
		nastar++; 
1994/1107    
	} 
                 
1994/1106    
	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++; 
	} 
1994/1107    
} 
 
void 
astarinit(void) 
{ 
} 
                 
1994/1109    
/* isa ports an ax00i can appear at */ 
int isaport[] = { 0x200, 0x208, 0x300, 0x308, 0x600, 0x608, 0x700, 0x708, 0 }; 
1994/1107    
 
1994/1109/sys/src/9/pc/devastar.c:360,3651994/1111/sys/src/9/pc/devastar.c:398,488
1994/1107    
	} 
	c = inb(a->port + ISActl1) & ~ISAirq; 
	outb(a->port + ISActl1, c | isairqcode(a->irq)); 
1994/1111    
 
	return 0; 
} 
 
void 
astarinit(void) 
{ 
} 
 
Chan* 
astarattach(char *spec) 
{ 
	return devattach('g', spec); 
} 
 
Chan* 
astarclone(Chan *c, Chan *nc) 
{ 
	return devclone(c, nc); 
} 
 
int 
astarwalk(Chan *c, char *name) 
{ 
	return devwalk(c, name, 0, 0, astargen); 
} 
 
void 
astarstat(Chan *c, char *dp) 
{ 
	devstat(c, dp, 0, 0, astargen); 
} 
 
Chan* 
astaropen(Chan *c, int omode) 
{ 
	Uart *p; 
 
	c = devopen(c, omode, 0, 0, astargen); 
 
	return c; 
} 
 
void 
astarcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
	USED(c, name, omode, perm); 
	error(Eperm); 
} 
 
void 
astarclose(Chan *c) 
{ 
	USED(c); 
} 
 
long 
astarread(Chan *c, void *buf, long n, ulong offset) 
{ 
	Astar *a; 
 
	if(c->qid.path & CHDIR) 
		return devdirread(c, buf, n, 0, 0, astargen); 
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
		a = astar[ 
		return qread(p->iq, buf, n); 
	} 
 
	return 0; 
} 
 
long 
astarwrite(Chan *c, void *buf, long n, ulong offset) 
{ 
	Uart *p; 
 
	if(c->qid.path & CHDIR) 
		error(Eperm); 
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
		return qread(p->iq, buf, n); 
	} 
1994/1109    
 
	return 0; 
1994/1106    
} 
1994/1111/sys/src/9/pc/devastar.c:35,411994/1112/sys/src/9/pc/devastar.c:35,44 (short | long)
1994/1106    
	ISAstat1=	4,		/* board status (1 bit per channel) */ 
	ISAstat2=	5,		/* board status (1 bit per channel) */ 
1994/1107    
 
	Maxcards=	3, 
1994/1112    
	Maxcard=	8, 
	Pramsize=	64*1024,	/* size of program ram */ 
	Footshift=	14,		/* footprint of card mem in ISA space */ 
	Footprint=	1<<Footshift, 
1994/1106    
}; 
 
1994/1107    
/* IRQ codes */ 
1994/1111/sys/src/9/pc/devastar.c:191,1971994/1112/sys/src/9/pc/devastar.c:194,200
1994/1107    
	/* CCB.mctl fields */ 
	Cdtrctl=	1<<0, 
	Crtsctl=	1<<1, 
	Cbreakctl=	1<<4 
1994/1112    
	Cbreakctl=	1<<4, 
1994/1107    
 
 
	/* CCB.mstat fields */ 
1994/1111/sys/src/9/pc/devastar.c:212,2231994/1112/sys/src/9/pc/devastar.c:215,230
1994/1106    
/* host per controller info */ 
struct Astar 
{ 
1994/1112    
	QLock; 
 
1994/1107    
	ISAConf; 
	int		id;		/* from plan9.ini */ 
1994/1111    
	int		nchan;		/* number of channels */ 
1994/1112    
	Rendez		r; 
1994/1111    
	Astarchan	*c;		/* channels */ 
1994/1107    
	int		ramsize;	/* 16k or 256k */ 
1994/1106    
	GCB		*gbc;		/* board comm area */ 
1994/1112    
	char		*addr;		/* memory area */ 
1994/1106    
}; 
 
/* host per channel info */ 
1994/1111/sys/src/9/pc/devastar.c:228,2331994/1112/sys/src/9/pc/devastar.c:235,241
1994/1109    
	Astar	*a;	/* controller */ 
1994/1107    
	CCB	*ccb;	/* control block */ 
1994/1111    
	int	perm; 
1994/1112    
	int	opens; 
1994/1107    
 
1994/1106    
	/* buffers */ 
	Queue	*iq; 
1994/1111/sys/src/9/pc/devastar.c:240,2451994/1112/sys/src/9/pc/devastar.c:248,254
1994/1111    
enum 
{ 
	Qmem=	0, 
1994/1112    
	Qbctl, 
1994/1111    
	Qdata, 
	Qctl, 
	Qstat, 
1994/1111/sys/src/9/pc/devastar.c:252,2731994/1112/sys/src/9/pc/devastar.c:261,292
1994/1109    
static int astarsetup(Astar*); 
1994/1107    
 
1994/1111    
int 
devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db) 
1994/1112    
astargen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db) 
1994/1111    
{ 
	int dev, sofar, ch, t; 
1994/1112    
	extern ulong kerndate; 
1994/1111    
 
	USED(tab, ntab); 
	sofar = 0; 
 
	for(dev = 0; dev < nstar; dev++){ 
1994/1112    
	for(dev = 0; dev < nastar; dev++){ 
1994/1111    
		if(sofar == i){ 
			sprint(db->name, "atar%dmem", astar[dev].id); 
			db->qid = QID(dev, 0, Qmem); 
1994/1112    
			sprint(db->name, "atar%dmem", astar[dev]->id); 
			db->qid.path = QID(dev, 0, Qmem); 
1994/1111    
			db->mode = 0660; 
			break; 
		} 
1994/1112    
		sofar++; 
1994/1111    
 
		if(i < sofar + 3*astar[dev].nchan){ 
1994/1112    
		if(sofar == i){ 
			sprint(db->name, "atar%dctl", astar[dev]->id); 
			db->qid.path = QID(dev, 0, Qbctl); 
			db->mode = 0660; 
			break; 
		} 
		sofar++; 
 
		if(i - sofar < 3*astar[dev]->nchan){ 
1994/1111    
			i -= sofar; 
			ch = i/3; 
			t = i%3; 
1994/1111/sys/src/9/pc/devastar.c:275,3051994/1112/sys/src/9/pc/devastar.c:294,324
1994/1111    
			case 0: 
				sprint(db->name, "eia%d%2.2d", dev, ch); 
				db->mode = astar[dev]->c[ch].perm; 
				db->qid = QID(dev, 0, Qdata); 
1994/1112    
				db->qid.path = QID(dev, 0, Qdata); 
1994/1111    
				break; 
			case 1: 
				sprint(db->name, "eia%d%2.2dctl", dev, ch); 
				db->mode = astar[dev]->c[ch].perm; 
				db->qid = QID(dev, 0, Qctl); 
1994/1112    
				db->qid.path = QID(dev, 0, Qctl); 
1994/1111    
				break; 
			case 2: 
				sprint(db->name, "eia%d%2.2dstat", dev, ch); 
				db->mode = 0444; 
				db->qid = QID(dev, 0, Qstat); 
1994/1112    
				db->qid.path = QID(dev, 0, Qstat); 
1994/1111    
				break; 
1994/1112    
			} 
1994/1111    
			break; 
		} 
                 
		sofar += 1 + 3*astar[dev].nchan; 
1994/1112    
		sofar += 3*astar[dev]->nchan; 
1994/1111    
	} 
 
	if(j == nstar) 
1994/1112    
	if(dev == nastar) 
1994/1111    
		return -1; 
 
	db->atime = seconds(); 
	db->mtime = kerndate; 
	db->hlength = 0; 
	db->length = length; 
1994/1112    
	db->length = 0;				/* update ???? */ 
1994/1111    
	memmove(db->uid, eve, NAMELEN); 
	memmove(db->gid, eve, NAMELEN); 
	db->type = devchar[c->type]; 
1994/1111/sys/src/9/pc/devastar.c:315,3251994/1112/sys/src/9/pc/devastar.c:334,343
1994/1106    
{ 
	int i; 
1994/1107    
	Astar *a; 
1994/1106    
	Dirtab *dp; 
 
	for(i = 0; i < Maxcard; i++){ 
1994/1109    
		a = astar[nastar] = xalloc(sizeof(Astar)); 
1994/1107    
		if(isaconfig("serial", i, &a) == 0){ 
1994/1112    
		if(isaconfig("serial", i, a) == 0){ 
1994/1107    
			xfree(a); 
1994/1109    
			astar[nastar] = 0; 
1994/1106    
			break; 
1994/1111/sys/src/9/pc/devastar.c:343,3481994/1112/sys/src/9/pc/devastar.c:361,367
1994/1109    
			astar[nastar] = 0; 
1994/1107    
			continue; 
		} 
1994/1112    
		print("serial%d avanstar addr %lux irq %d\n", i, a->addr, a->irq); 
1994/1109    
		nastar++; 
1994/1107    
	} 
} 
1994/1111/sys/src/9/pc/devastar.c:361,3731994/1112/sys/src/9/pc/devastar.c:380,392
1994/1107    
	c = inb(port + ISAid); 
	c1 = inb(port + ISAid); 
	return (c == ISAid0 && c1 == ISAid1) 
		|| (c == ISAid1 && c1 == ISAid0)); 
1994/1112    
		|| (c == ISAid1 && c1 == ISAid0); 
1994/1107    
} 
 
1994/1109    
static int 
1994/1107    
astarsetup(Astar *a) 
{ 
	int i, j, found; 
1994/1112    
	int i, found; 
1994/1107    
 
	/* see if the card exists */ 
	found = 0; 
1994/1111/sys/src/9/pc/devastar.c:381,3871994/1112/sys/src/9/pc/devastar.c:400,406
1994/1107    
			} 
		} 
	else 
		found = isax00i(a->port); 
1994/1112    
		found = astarprobe(a->port); 
1994/1107    
	if(!found){ 
		print("avanstar %d not found\n", a->id); 
		return -1; 
1994/1111/sys/src/9/pc/devastar.c:389,4031994/1112/sys/src/9/pc/devastar.c:408,421
1994/1107    
 
	/* set memory address */ 
	outb(a->port + ISAmaddr, (a->mem>>12) & 0xfc); 
	a->gcb = KZERO | a->mem; 
1994/1112    
	a->gbc = (GCB*)(KZERO | a->mem); 
	a->addr = (char*)(KZERO | a->mem); 
1994/1107    
 
	/* set interrupt level */ 
	if(isairqcode(a->irq) == -1){ 
1994/1112    
	if(isairqcode[a->irq] == -1){ 
1994/1107    
		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)); 
1994/1111    
 
	return 0; 
} 
1994/1111/sys/src/9/pc/devastar.c:434,4631994/1112/sys/src/9/pc/devastar.c:452,510
1994/1111    
Chan* 
astaropen(Chan *c, int omode) 
{ 
	Uart *p; 
1994/1112    
	Astar *a; 
1994/1111    
 
	c = devopen(c, omode, 0, 0, astargen); 
 
1994/1112    
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
	case Qbctl: 
		if(!iseve()) 
			error(Eperm); 
		break; 
	} 
 
1994/1111    
	return c; 
} 
 
void 
astarcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
	USED(c, name, omode, perm); 
	error(Eperm); 
} 
                 
void 
astarclose(Chan *c) 
{ 
	USED(c); 
1994/1112    
	Astar *a; 
	int i; 
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
		a = astar[BOARD(c->qid.path)]; 
		qlock(a); 
		if(--a->opens == 0){ 
			/* take board out of download mode and enable IRQ */ 
			outb(a->port + ISActl1, ISAien|isairqcode[a->irq]); 
 
			/* enable ISA access to first 16k */ 
			outb(a->port + ISActl2, ISAmen|0); 
 
			/* wait for program ready */ 
			for(i = 0; i < 21; i++){ 
				if(inb(a->port + ISActl1) & ISApr) 
					break; 
				tsleep(&r, return0, 0, 500); 
			} 
			if((inb(a->port + ISActl1) & ISApr) == 0) 
				print("astar%d program not ready\n", a->id); 
		} 
		qunlock(a); 
		break; 
	} 
1994/1111    
} 
 
long 
astarread(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1112    
	int i; 
1994/1111    
	Astar *a; 
1994/1112    
	char *to, *from, *e; 
	char status[128]; 
1994/1111    
 
	if(c->qid.path & CHDIR) 
		return devdirread(c, buf, n, 0, 0, astargen); 
1994/1111/sys/src/9/pc/devastar.c:464,4711994/1112/sys/src/9/pc/devastar.c:511,556
1994/1111    
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
		a = astar[ 
		return qread(p->iq, buf, n); 
1994/1112    
		a = astar[BOARD(c->qid.path)]; 
		if(offset+n > Pramsize){ 
			if(offset >= Pramsize) 
				return 0; 
			n = Pramsize - offset; 
		} 
 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		qlock(a); 
		from = buf; 
		while(n > 0){ 
			/* map in right piece of memory */ 
			outb(a->port + ISActl2, ISAmen|(offset>>Footshift)); 
			i = offset%Footprint; 
			to = a->addr + i; 
			i = Footprint - i; 
			if(i > n) 
				i = n; 
			 
			/* byte at a time so endian doesn't matter */ 
			for(e = from + i; from < e;) 
				*to++ = *from++; 
 
			n -= i; 
		} 
		qunlock(a); 
		poperror(); 
		break; 
	case Qbctl: 
		a = astar[BOARD(c->qid.path)]; 
		sprint(status, "id %2.2ux%2.2ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %2.2ux%2.2ux", 
			inb(a->port+ISAid), inb(a->port+ISAid), 
			inb(a->port+ISActl1), inb(a->port+ISActl2),  
			inb(a->port+ISAmaddr), 
			inb(a->port+ISAstat2), inb(a->port+ISAstat1)); 
		n = readstr(offset, buf, n, status); 
		break; 
1994/1111    
	} 
 
	return 0; 
1994/1111/sys/src/9/pc/devastar.c:474,4801994/1112/sys/src/9/pc/devastar.c:559,568
1994/1111    
long 
astarwrite(Chan *c, void *buf, long n, ulong offset) 
{ 
	Uart *p; 
1994/1112    
	Astar *a; 
	char *to, *from, *e; 
	int i; 
	char cmsg[32]; 
1994/1111    
 
	if(c->qid.path & CHDIR) 
		error(Eperm); 
1994/1111/sys/src/9/pc/devastar.c:481,4881994/1112/sys/src/9/pc/devastar.c:569,666
1994/1111    
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
		return qread(p->iq, buf, n); 
1994/1112    
		a = astar[BOARD(c->qid.path)]; 
		if(offset+n > Pramsize){ 
			if(offset >= Pramsize) 
				return 0; 
			n = Pramsize - offset; 
		} 
 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		qlock(a); 
		to = buf; 
		while(n > 0){ 
			/* map in right piece of memory */ 
			outb(a->port + ISActl2, ISAmen|(offset>>Footshift)); 
			i = offset%Footprint; 
			from = a->addr + i; 
			i = Footprint - i; 
			if(i > n) 
				i = n; 
			 
			/* byte at a time so endian doesn't matter */ 
			for(e = from + i; from < e;) 
				*to++ = *from++; 
 
			n -= i; 
		} 
		qunlock(a); 
		poperror(); 
		break; 
	case Qbctl: 
		if(n > sizeof cmsg) 
			n = sizeof(cmsg) - 1; 
		memmove(cmsg, buf, n); 
		cmsg[n] = 0; 
 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		qlock(a); 
		if(strncmp(cmsg, "download", 8) == 0){ 
			/* put board in download mode */ 
			outb(a->port + ISActl1, ISAdl); 
 
			/* enable ISA access to first 16k */ 
			outb(a->port + ISActl2, ISAmen); 
 
		} else if(strncmp(cmsg, "run", 3) == 0){ 
			/* take board out of download mode and enable IRQ */ 
			outb(a->port + ISActl1, ISAien|isairqcode[a->irq]); 
 
			/* enable ISA access to first 16k */ 
			outb(a->port + ISActl2, ISAmen); 
 
			/* wait for control program to signal life */ 
			for(i = 0; i < 21; i++){ 
				if(inb(a->port + ISActl1) & ISApr) 
					break; 
				tsleep(&a->r, return0, 0, 500); 
			} 
			if((inb(a->port + ISActl1) & ISApr) == 0) 
				print("astar%d program not ready\n", a->id); 
 
		} else 
			error(Ebadarg); 
		qunlock(a); 
		poperror(); 
		break; 
1994/1111    
	} 
1994/1109    
 
	return 0; 
1994/1112    
} 
 
void 
astarcreate(Chan *c, char *name, int omode, ulong perm) 
{ 
	USED(c, name, omode, perm); 
	error(Eperm); 
} 
 
void 
astarremove(Chan *c) 
{ 
	USED(c); 
	error(Eperm); 
} 
 
void 
astarwstat(Chan *c, char *dp) 
{ 
	USED(c, dp); 
	error(Eperm); 
1994/1106    
} 
1994/1112/sys/src/9/pc/devastar.c:11,171994/1113/sys/src/9/pc/devastar.c:11,30 (short | long)
1994/1106    
/* 
1994/1107    
 *  Stargate's Avanstar serial board.  There are ISA, EISA, microchannel 
 *  versions.  We only handle the ISA one. 
1994/1113    
 * 
 *  At the expense of performance, I've tried to be careful about 
 *  endian-ness to make this convertable to other ISA bus machines. 
 *  However, xchngus() is in assembler and will have to be translated. 
1994/1106    
 */ 
1994/1113    
#define LENDIAN 1 
 
/* unsigned short little endian representation */ 
#ifdef LENDIAN 
#define LEUS(x) (x) 
#else 
#define LEUS(x) ( (((x)<<8)&0xff00) | (((x)>>8)&0xff) ) 
#endif LENDIAN 
 
1994/1106    
typedef struct Astar Astar; 
1994/1107    
typedef struct Astarchan Astarchan; 
1994/1106    
 
1994/1112/sys/src/9/pc/devastar.c:37,461994/1113/sys/src/9/pc/devastar.c:50,62
1994/1107    
 
1994/1112    
	Maxcard=	8, 
	Pramsize=	64*1024,	/* size of program ram */ 
	Footshift=	14,		/* footprint of card mem in ISA space */ 
	Footprint=	1<<Footshift, 
1994/1113    
	Pageshift=	14,		/* footprint of card mem in ISA space */ 
	Pagesize=	1<<Pageshift, 
	Pagemask=	Pagesize-1, 
1994/1106    
}; 
 
1994/1113    
#define APAGE(x) ((x)>>Pageshift) 
 
1994/1107    
/* IRQ codes */ 
static int isairqcode[16] = 
{ 
1994/1112/sys/src/9/pc/devastar.c:60,681994/1113/sys/src/9/pc/devastar.c:76,84
1994/1106    
	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 */ 
1994/1113    
	ushort	ccbn;		/* control channel block count */ 
	ushort	ccboff;		/* control channel block offset */ 
	ushort	ccbsz;		/* control channel block size */ 
1994/1106    
	ushort	cmd2;		/* command word 2 */ 
	ushort	status2;	/* status word 2 */ 
	ushort	errserv;	/* comm error service request 'X' */ 
1994/1112/sys/src/9/pc/devastar.c:146,1551994/1113/sys/src/9/pc/devastar.c:162,168
1994/1107    
	Cb115200=	0xff01, 
 
	/* CCB.format fields */ 
	C5bit=		0<<0,	/* data bits */ 
	C6bit=		0<<1, 
	C7bit=		0<<2, 
	C8bit=		0<<3, 
1994/1113    
	Clenmask=	3<<0,	/* data bits */ 
1994/1107    
	C1stop=		0<<2,	/* stop bits */ 
	C2stop=		1<<2, 
	Cnopar=		0<<3,	/* parity */ 
1994/1112/sys/src/9/pc/devastar.c:157,1621994/1113/sys/src/9/pc/devastar.c:170,176
1994/1107    
	Cevenpar=	3<<3, 
	Cmarkpar=	5<<3, 
	Cspacepar=	7<<3, 
1994/1113    
	Cparmask=	7<<3, 
1994/1107    
	Cnormal=	0<<6,	/* normal mode */ 
	Cecho=		1<<6,	/* echo mode */ 
	Clloop=		2<<6,	/* local loopback */ 
1994/1112/sys/src/9/pc/devastar.c:220,2301994/1113/sys/src/9/pc/devastar.c:234,248
1994/1107    
	ISAConf; 
	int		id;		/* from plan9.ini */ 
1994/1111    
	int		nchan;		/* number of channels */ 
1994/1112    
	Rendez		r; 
1994/1111    
	Astarchan	*c;		/* channels */ 
1994/1107    
	int		ramsize;	/* 16k or 256k */ 
1994/1106    
	GCB		*gbc;		/* board comm area */ 
1994/1112    
	char		*addr;		/* memory area */ 
1994/1113    
	int		memsize;	/* size of memory currently mapped */ 
	int		page;		/* page currently mapped */ 
	GCB		*gbc;		/* global board comm area */ 
	uchar		*addr;		/* base of memory area */ 
	int		running; 
 
	Rendez		r;		/* when waiting for board */ 
1994/1106    
}; 
 
/* host per channel info */ 
1994/1112/sys/src/9/pc/devastar.c:233,2391994/1113/sys/src/9/pc/devastar.c:251,257
1994/1106    
	QLock; 
 
1994/1109    
	Astar	*a;	/* controller */ 
1994/1107    
	CCB	*ccb;	/* control block */ 
1994/1113    
	CCB	*ccb;	/* channel control block */ 
1994/1111    
	int	perm; 
1994/1112    
	int	opens; 
1994/1107    
 
1994/1112/sys/src/9/pc/devastar.c:240,2451994/1113/sys/src/9/pc/devastar.c:258,264
1994/1106    
	/* buffers */ 
	Queue	*iq; 
	Queue	*oq; 
1994/1113    
	Rendez	r; 
1994/1106    
}; 
 
1994/1109    
Astar *astar[Maxcard]; 
1994/1112/sys/src/9/pc/devastar.c:260,2651994/1113/sys/src/9/pc/devastar.c:279,302
1994/1111    
 
1994/1109    
static int astarsetup(Astar*); 
1994/1107    
 
1994/1113    
/* 
 *  Only 16k maps into ISA space 
 */ 
void 
setpage(Astar *a, ulong offset) 
{ 
	int i; 
 
	i = APAGE(offset); 
	if(i == a->page) 
		return; 
	outb(a->port+ISActl2, ISAmen|i); 
	a->page = i; 
} 
 
/* 
 *  generate the astar directory entries 
 */ 
1994/1111    
int 
1994/1112    
astargen(Chan *c, Dirtab *tab, int ntab, int i, Dir *db) 
1994/1111    
{ 
1994/1112/sys/src/9/pc/devastar.c:355,3601994/1113/sys/src/9/pc/devastar.c:392,398
1994/1107    
		if(a->irq == 0) 
			a->irq = 15; 
		a->id = i; 
1994/1113    
		a->page = -1; 
1994/1107    
 
		if(astarsetup(a) < 0){ 
			xfree(a); 
1994/1112/sys/src/9/pc/devastar.c:377,3841994/1113/sys/src/9/pc/devastar.c:415,422
1994/1107    
	if(port < 0) 
		return 0; 
 
	c = inb(port + ISAid); 
	c1 = inb(port + ISAid); 
1994/1113    
	c = inb(port+ISAid); 
	c1 = inb(port+ISAid); 
1994/1107    
	return (c == ISAid0 && c1 == ISAid1) 
1994/1112    
		|| (c == ISAid1 && c1 == ISAid0); 
1994/1107    
} 
1994/1112/sys/src/9/pc/devastar.c:407,4131994/1113/sys/src/9/pc/devastar.c:445,451
1994/1107    
	} 
 
	/* set memory address */ 
	outb(a->port + ISAmaddr, (a->mem>>12) & 0xfc); 
1994/1113    
	outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc); 
1994/1112    
	a->gbc = (GCB*)(KZERO | a->mem); 
	a->addr = (char*)(KZERO | a->mem); 
1994/1107    
 
1994/1112/sys/src/9/pc/devastar.c:479,4961994/1113/sys/src/9/pc/devastar.c:517,534
1994/1112    
		qlock(a); 
		if(--a->opens == 0){ 
			/* take board out of download mode and enable IRQ */ 
			outb(a->port + ISActl1, ISAien|isairqcode[a->irq]); 
1994/1113    
			outb(a->port+ISActl1, ISAien|isairqcode[a->irq]); 
1994/1112    
 
			/* enable ISA access to first 16k */ 
			outb(a->port + ISActl2, ISAmen|0); 
1994/1113    
			outb(a->port+ISActl2, ISAmen|0); 
1994/1112    
 
			/* wait for program ready */ 
			for(i = 0; i < 21; i++){ 
				if(inb(a->port + ISActl1) & ISApr) 
1994/1113    
				if(inb(a->port+ISActl1) & ISApr) 
1994/1112    
					break; 
				tsleep(&r, return0, 0, 500); 
			} 
			if((inb(a->port + ISActl1) & ISApr) == 0) 
1994/1113    
			if((inb(a->port+ISActl1) & ISApr) == 0) 
1994/1112    
				print("astar%d program not ready\n", a->id); 
		} 
		qunlock(a); 
1994/1112/sys/src/9/pc/devastar.c:498,5101994/1113/sys/src/9/pc/devastar.c:536,595
1994/1112    
	} 
1994/1111    
} 
 
1994/1113    
static long 
memread(Astar *a, uchar *to, long n, ulong offset) 
{ 
	uchar *from, *e; 
	int i, rem; 
 
	if(offset+n > a->memsize){ 
		if(offset >= a->memsize) 
			return 0; 
		n = a->memsize - offset; 
	} 
 
	if(waserror()){ 
		qunlock(a); 
		nexterror(); 
	} 
	qlock(a); 
 
	for(rem = n; rem > 0; rem -= i){ 
 
		/* map in right piece of memory */ 
		setpage(a, offset); 
		i = offset&Pagemask; 
		to = a->addr + i; 
		i = Pagesize - i; 
		if(i > rem) 
			i = rem; 
		 
		/* byte at a time so endian doesn't matter */ 
		for(e = from + i; from < e;) 
			*to++ = *from++; 
	} 
 
	qunlock(a); 
	poperror(); 
	return n; 
} 
 
static long 
bctlread(Chan *c, void *buf, long n, ulong offset) 
{ 
	char s[128]; 
 
	sprint(s, "id %4.4ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %4.4ux", 
		(inb(a->port+ISAid)<<8)|inb(a->port+ISAid), 
		inb(a->port+ISActl1), inb(a->port+ISActl2),  
		inb(a->port+ISAmaddr), 
		(inb(a->port+ISAstat2)<<8)|inb(a->port+ISAstat1)); 
	return readstr(offset, buf, n, s); 
} 
 
1994/1111    
long 
astarread(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1112    
	int i; 
1994/1111    
	Astar *a; 
1994/1112    
	char *to, *from, *e; 
	char status[128]; 
1994/1111    
 
	if(c->qid.path & CHDIR) 
		return devdirread(c, buf, n, 0, 0, astargen); 
1994/1112/sys/src/9/pc/devastar.c:511,6441994/1113/sys/src/9/pc/devastar.c:596,897
1994/1111    
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
1994/1112    
		a = astar[BOARD(c->qid.path)]; 
		if(offset+n > Pramsize){ 
			if(offset >= Pramsize) 
				return 0; 
			n = Pramsize - offset; 
		} 
1994/1113    
		return memread(astar[BOARD(c->qid.path)], buf, n, offset); 
	case Qbctl: 
		return bctlread(astar[BOARD(c->qid.path)], buf, n, offset); 
	} 
1994/1112    
 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		qlock(a); 
		from = buf; 
		while(n > 0){ 
			/* map in right piece of memory */ 
			outb(a->port + ISActl2, ISAmen|(offset>>Footshift)); 
			i = offset%Footprint; 
			to = a->addr + i; 
			i = Footprint - i; 
			if(i > n) 
				i = n; 
			                 
			/* byte at a time so endian doesn't matter */ 
			for(e = from + i; from < e;) 
				*to++ = *from++; 
1994/1113    
	return 0; 
} 
1994/1112    
 
			n -= i; 
1994/1113    
static long 
memwrite(Astar *a, uchar *from, long n, ulong offset) 
{ 
	uchar *to, *e; 
	int i, rem; 
 
	if(offset+n > a->memsize){ 
		if(offset >= a->memsize) 
			return 0; 
		n = a->memsize - offset; 
	} 
 
	if(waserror()){ 
		qunlock(a); 
		nexterror(); 
	} 
	qlock(a); 
 
	for(rem = n; rem > 0; rem -= i){ 
 
		/* map in right piece of memory */ 
		setpage(a, offset); 
		i = offset&Pagemask; 
		from = a->addr + i; 
		i = Pagesize - i; 
		if(i > rem) 
			i = rem; 
		 
		/* byte at a time so endian doesn't matter */ 
		for(e = from + i; from < e;) 
			*to++ = *from++; 
	} 
 
	qunlock(a); 
	poperror(); 
	return n; 
} 
 
/* 
 *  setup a channel 
 */ 
static void 
chansetup(Astar *a, Astarchan *ac, void *ccb) 
{ 
	ac->a = a; 
	ac->ccb = ccb; 
	ac->iq = qopen(4*1024, 0, 0, 0); 
	ac->oq = qopen(4*1024, 0, astarkick, p); 
} 
 
/* 
 *  start control progarm 
 */ 
static void 
startcp(Astar *a) 
{ 
	int n, i, sz; 
	uchar *x; 
	CCB *ccb; 
 
	if(a->running) 
		error(Eio); 
 
	/* take board out of download mode and enable IRQ */ 
	outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl); 
	a->memsize = a->ramsize; 
 
	/* wait for control program to signal life */ 
	for(i = 0; i < 21; i++){ 
		if(inb(a->port+ISActl1) & ISApr) 
			break; 
		tsleep(&a->r, return0, 0, 500); 
	} 
	if((inb(a->port+ISActl1) & ISApr) == 0){ 
		print("astar%d program not ready\n", a->id); 
		error(Eio); 
	} 
 
	setpage(a, 0); 
	i = LEUS(a->gcb->type); 
	switch(i){ 
	default: 
		print("astar%d wrong board type %ux\n", a->id, i); 
		error(Eio); 
	case 0xc: 
		break; 
	} 
 
	/* check assumptions */ 
	n = LEUS(a->gcb->ccbn); 
	if(n != 8 && n != 16){ 
		print("astar%d had %d channels?\n", a->id, i); 
		error(Eio); 
	} 
	x = a->addr + LEUS(a->gcb->ccboff); 
	sz = LEUS(a->gcb->ccbsz); 
	if(x+n*sz > a->addr+Pagesize){ 
		print("astar%d ccb's not in 1st page\n", a->id); 
		error(Eio); 
	} 
	for(i = 0; i < n; i++){ 
		ccb = (CCB*)(x + i*sz); 
		if(APAGE(LEUS(ccb->inbase)) != APAGE(LEUS(ccb->inlim)) || 
		   APAGE(LEUS(ccb->outbase)) != APAGE(LEUS(ccb->outlim))){ 
			print("astar%d chan buffer spans pages\n", a->id); 
			error(Eio); 
1994/1112    
		} 
1994/1113    
	} 
 
	/* setup the channels */ 
	a->running = 1; 
	a->nchan = i; 
	a->c = xalloc(a->nchan * sizeof(Astarchan)); 
	for(i = 0; i < a->nchan; i++){ 
		chansetup(a, &a->c[i], (CCB*)x); 
		x += sz; 
	} 
} 
 
static long 
bctlwrite(Astar *a, char *msg) 
{ 
	int i; 
	uchar c; 
 
	if(waserror()){ 
1994/1112    
		qunlock(a); 
		poperror(); 
1994/1113    
		nexterror(); 
	} 
	qlock(a); 
 
	if(strncmp(cmsg, "download", 8) == 0){ 
		if(a->running) 
			error(Eio); 
 
		/* put board in download mode */ 
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c & ~ISAnotdl); 
		a->memsize = Pramsize; 
 
		/* enable ISA access to first 16k */ 
		outb(a->port+ISActl2, ISAmen); 
 
	} else if(strncmp(cmsg, "run", 3) == 0){ 
		if(a->running) 
			error(Eio); 
		startcp(a); 
 
	} else 
		error(Ebadarg); 
 
	qunlock(a); 
	poperror(); 
	return n; 
} 
 
/* 
 *  change channel parameters 
 */ 
void 
astarctl(Astarchan *ac, char *cmd) 
{ 
	int i, n; 
	int command; 
 
	/* let output drain for a while */ 
	for(i = 0; i < 16 && qlen(ac->oq); i++) 
		tsleep(&ac->r, qlen, ac->oq, 125); 
 
	if(strncmp(cmd, "break", 5) == 0) 
		cmd = "k"; 
 
	command = 0; 
	n = atoi(cmd+1); 
	switch(*cmd){ 
	case 'B': 
	case 'b': 
		switch(n){ 
		case 76800: 
			ac->ccb->baud = LEUS(Cb76800); 
			break; 
		case 115200: 
			ac->ccb->baud = LEUS(Cb115200); 
			break; 
		default: 
			ac->ccb->baud = LEUS(n); 
			break; 
		} 
		command = Cconfall; 
1994/1112    
		break; 
	case Qbctl: 
		a = astar[BOARD(c->qid.path)]; 
		sprint(status, "id %2.2ux%2.2ux ctl1 %2.2ux ctl2 %2.2ux maddr %2.2ux stat %2.2ux%2.2ux", 
			inb(a->port+ISAid), inb(a->port+ISAid), 
			inb(a->port+ISActl1), inb(a->port+ISActl2),  
			inb(a->port+ISAmaddr), 
			inb(a->port+ISAstat2), inb(a->port+ISAstat1)); 
		n = readstr(offset, buf, n, status); 
1994/1113    
	case 'D': 
	case 'd': 
1994/1112    
		break; 
1994/1113    
	case 'f': 
	case 'F': 
		qflush(ac->oq); 
		break; 
	case 'H': 
	case 'h': 
		qhangup(ac->iq); 
		qhangup(ac->oq); 
		break; 
	case 'L': 
	case 'l': 
		n -= 5; 
		if(n < 0 || n > 3) 
			error(Ebadarg); 
		n |= LEUS(ac->ccb->format) & ~Clenmask; 
		ac->ccb->format = LEUS(n); 
		command = Cconfall; 
		break; 
	case 'm': 
	case 'M': 
		n = LEUS(ac->ccb->format) | Cobeycts; 
		ac->ccb->proto = LEUS(n); 
		command = Cconfall; 
		break; 
	case 'n': 
	case 'N': 
		qnoblock(p->oq, n); 
		break; 
	case 'P': 
	case 'p': 
		switch(*(cmd+1)){ 
		case 'e': 
			n = Cevenpar; 
			break; 
		case 'o': 
			n = Coddpar; 
			break; 
		default: 
			n = Cnopar; 
			break; 
		} 
		n |= LEUS(ac->ccb->format) & ~Cparmask; 
		ac->ccb->format = LEUS(n); 
		command = Cconfall; 
		break; 
	case 'K': 
	case 'k': 
		break; 
	case 'R': 
	case 'r': 
		break; 
	case 'Q': 
	case 'q': 
		qsetlimit(ac->iq, n); 
		qsetlimit(ac->oq, n); 
		break; 
	case 'X': 
	case 'x': 
		n = LEUS(ac->ccb->format) | Cobeyxon; 
		ac->ccb->proto = LEUS(n); 
		command = Cconfall; 
		break; 
1994/1111    
	} 
                 
	return 0; 
} 
 
1994/1113    
 
1994/1111    
long 
astarwrite(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1112    
	Astar *a; 
	char *to, *from, *e; 
	int i; 
1994/1113    
	Astarchan *ac; 
1994/1112    
	char cmsg[32]; 
1994/1111    
 
	if(c->qid.path & CHDIR) 
		error(Eperm); 
 
1994/1113    
	a = astar[BOARD(c->qid.path)]; 
1994/1111    
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
1994/1112    
		a = astar[BOARD(c->qid.path)]; 
		if(offset+n > Pramsize){ 
			if(offset >= Pramsize) 
				return 0; 
			n = Pramsize - offset; 
		} 
                 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		qlock(a); 
		to = buf; 
		while(n > 0){ 
			/* map in right piece of memory */ 
			outb(a->port + ISActl2, ISAmen|(offset>>Footshift)); 
			i = offset%Footprint; 
			from = a->addr + i; 
			i = Footprint - i; 
			if(i > n) 
				i = n; 
			                 
			/* byte at a time so endian doesn't matter */ 
			for(e = from + i; from < e;) 
				*to++ = *from++; 
                 
			n -= i; 
		} 
		qunlock(a); 
		poperror(); 
		break; 
1994/1113    
		return memwrite(a, buf, n, offset); 
1994/1112    
	case Qbctl: 
		if(n > sizeof cmsg) 
			n = sizeof(cmsg) - 1; 
		memmove(cmsg, buf, n); 
		cmsg[n] = 0; 
                 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		qlock(a); 
		if(strncmp(cmsg, "download", 8) == 0){ 
			/* put board in download mode */ 
			outb(a->port + ISActl1, ISAdl); 
                 
			/* enable ISA access to first 16k */ 
			outb(a->port + ISActl2, ISAmen); 
                 
		} else if(strncmp(cmsg, "run", 3) == 0){ 
			/* take board out of download mode and enable IRQ */ 
			outb(a->port + ISActl1, ISAien|isairqcode[a->irq]); 
                 
			/* enable ISA access to first 16k */ 
			outb(a->port + ISActl2, ISAmen); 
                 
			/* wait for control program to signal life */ 
			for(i = 0; i < 21; i++){ 
				if(inb(a->port + ISActl1) & ISApr) 
					break; 
				tsleep(&a->r, return0, 0, 500); 
			} 
			if((inb(a->port + ISActl1) & ISApr) == 0) 
				print("astar%d program not ready\n", a->id); 
                 
		} else 
			error(Ebadarg); 
		qunlock(a); 
		poperror(); 
		break; 
1994/1113    
		return bctlwrite(a, cmsg); 
	case Qdata: 
		ac = a->c + CHAN(c->qid.path); 
		return qwrite(ac->oq, buf, n); 
	case Qctl: 
		if(n > sizeof cmsg) 
			n = sizeof(cmsg) - 1; 
		memmove(cmsg, buf, n); 
		cmsg[n] = 0; 
		return astarctl(a, msg); 
1994/1111    
	} 
1994/1109    
 
	return 0; 
1994/1112/sys/src/9/pc/devastar.c:664,6661994/1113/sys/src/9/pc/devastar.c:917,920
1994/1112    
	USED(c, dp); 
	error(Eperm); 
1994/1106    
} 
1994/1113    
 
1994/1113/sys/src/9/pc/devastar.c:107,1121994/1114/sys/src/9/pc/devastar.c:107,115 (short | long)
1994/1107    
	G100e=		0xA, 
	Gx00i=		0xC, 
 
1994/1114    
	/* GCB.cmd2 bit */ 
	Gintack=	0x1, 
 
1994/1107    
	/* GCB.status2 bits */ 
	Ghas232=	(1<<0), 
	Ghas422=	(1<<1), 
1994/1113/sys/src/9/pc/devastar.c:229,2541994/1114/sys/src/9/pc/devastar.c:232,259
1994/1106    
/* host per controller info */ 
struct Astar 
{ 
1994/1112    
	QLock; 
1994/1114    
	QLock;				/* lock for rendez */ 
	Rendez		r;		/* waiting for command completion */ 
1994/1112    
 
1994/1107    
	ISAConf; 
1994/1114    
	Lock		pagelock;	/* lock for setting page */ 
	int		page;		/* page currently mapped */ 
1994/1107    
	int		id;		/* from plan9.ini */ 
1994/1111    
	int		nchan;		/* number of channels */ 
	Astarchan	*c;		/* channels */ 
1994/1107    
	int		ramsize;	/* 16k or 256k */ 
1994/1113    
	int		memsize;	/* size of memory currently mapped */ 
	int		page;		/* page currently mapped */ 
	GCB		*gbc;		/* global board comm area */ 
	uchar		*addr;		/* base of memory area */ 
	int		running; 
 
	Rendez		r;		/* when waiting for board */ 
1994/1106    
}; 
 
/* host per channel info */ 
struct Astarchan 
{ 
	QLock; 
1994/1114    
	QLock;		/* lock for rendez */ 
	Rendez	r;	/* waiting for command completion */ 
1994/1106    
 
1994/1109    
	Astar	*a;	/* controller */ 
1994/1113    
	CCB	*ccb;	/* channel control block */ 
1994/1113/sys/src/9/pc/devastar.c:255,2641994/1114/sys/src/9/pc/devastar.c:260,267
1994/1111    
	int	perm; 
1994/1112    
	int	opens; 
1994/1107    
 
1994/1106    
	/* buffers */ 
	Queue	*iq; 
	Queue	*oq; 
1994/1113    
	Rendez	r; 
1994/1106    
}; 
 
1994/1109    
Astar *astar[Maxcard]; 
1994/1113/sys/src/9/pc/devastar.c:277,2881994/1114/sys/src/9/pc/devastar.c:280,295
1994/1111    
#define CHAN(x)		((((x)&~CHDIR)>>8)&0xff) 
#define QID(b,c,t)	(((b)<<16)|((c)<<8)|(t)) 
 
1994/1109    
static int astarsetup(Astar*); 
1994/1114    
static int	astarsetup(Astar*); 
static void	astarintr(Ureg*, void*); 
static void	astarkick(Astarchan*); 
static void	enable(Astarchan*); 
static void	disable(Astarchan*); 
1994/1107    
 
1994/1113    
/* 
 *  Only 16k maps into ISA space 
 */ 
void 
1994/1114    
static void 
1994/1113    
setpage(Astar *a, ulong offset) 
{ 
	int i; 
1994/1113/sys/src/9/pc/devastar.c:401,4061994/1114/sys/src/9/pc/devastar.c:408,415
1994/1107    
		} 
1994/1112    
		print("serial%d avanstar addr %lux irq %d\n", i, a->addr, a->irq); 
1994/1109    
		nastar++; 
1994/1114    
 
		setvec(Int0vec + a->irq, astarintr, a); 
1994/1107    
	} 
} 
 
1994/1113/sys/src/9/pc/devastar.c:500,5051994/1114/sys/src/9/pc/devastar.c:509,526
1994/1112    
		if(!iseve()) 
			error(Eperm); 
		break; 
1994/1114    
	case Qdata: 
	case Qctl: 
		qlock(ac); 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
		} 
		if(ac->opens++ == 0) 
			enable(ac); 
		qunlock(ac); 
		poperror(); 
		break; 
1994/1112    
	} 
 
1994/1111    
	return c; 
1994/1113/sys/src/9/pc/devastar.c:513,5461994/1114/sys/src/9/pc/devastar.c:534,564
1994/1112    
 
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
		a = astar[BOARD(c->qid.path)]; 
		qlock(a); 
		if(--a->opens == 0){ 
			/* take board out of download mode and enable IRQ */ 
1994/1113    
			outb(a->port+ISActl1, ISAien|isairqcode[a->irq]); 
1994/1112    
                 
			/* enable ISA access to first 16k */ 
1994/1113    
			outb(a->port+ISActl2, ISAmen|0); 
1994/1112    
                 
			/* wait for program ready */ 
			for(i = 0; i < 21; i++){ 
1994/1113    
				if(inb(a->port+ISActl1) & ISApr) 
1994/1112    
					break; 
				tsleep(&r, return0, 0, 500); 
			} 
1994/1113    
			if((inb(a->port+ISActl1) & ISApr) == 0) 
1994/1112    
				print("astar%d program not ready\n", a->id); 
1994/1114    
		break; 
	case Qdata: 
	case Qctl: 
		qlock(ac); 
		if(waserror()){ 
			qunlock(a); 
			nexterror(); 
1994/1112    
		} 
		qunlock(a); 
1994/1114    
		if(--ac->opens == 0) 
			disable(ac); 
		qunlock(ac); 
		poperror(); 
1994/1112    
		break; 
	} 
1994/1111    
} 
 
1994/1114    
/* 
 *  read ISA mapped memory 
 */ 
1994/1113    
static long 
memread(Astar *a, uchar *to, long n, ulong offset) 
{ 
	uchar *from, *e; 
1994/1114    
	uchar *from, *e, *tp; 
1994/1113    
	int i, rem; 
1994/1114    
	uchar tmp[256]; 
1994/1113    
 
	if(offset+n > a->memsize){ 
		if(offset >= a->memsize) 
1994/1113/sys/src/9/pc/devastar.c:548,5791994/1114/sys/src/9/pc/devastar.c:566,602
1994/1113    
		n = a->memsize - offset; 
	} 
 
	if(waserror()){ 
		qunlock(a); 
		nexterror(); 
	} 
	qlock(a); 
                 
	for(rem = n; rem > 0; rem -= i){ 
 
		/* map in right piece of memory */ 
		setpage(a, offset); 
		i = offset&Pagemask; 
		to = a->addr + i; 
1994/1114    
		from = a->addr + i; 
1994/1113    
		i = Pagesize - i; 
		if(i > rem) 
			i = rem; 
		                 
		/* byte at a time so endian doesn't matter */ 
1994/1114    
		if(i > sizeof tmp) 
			i = sizeof tmp; 
 
		/* 
		 *  byte at a time so endian doesn't matter, 
		 *  go via tmp to avoid pagefaults while ilock'd 
		 */ 
		tp = tmp; 
		ilock(&a->pagelock); 
		setpage(a, offset); 
1994/1113    
		for(e = from + i; from < e;) 
			*to++ = *from++; 
1994/1114    
			*tp++ = *from++; 
		iunlock(&a->pagelock); 
		memmove(to, tmp, i); 
		to += i; 
1994/1113    
	} 
 
	qunlock(a); 
	poperror(); 
	return n; 
} 
 
1994/1114    
/* 
 *  read ISA status 
 */ 
1994/1113    
static long 
bctlread(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1113/sys/src/9/pc/devastar.c:604,6141994/1114/sys/src/9/pc/devastar.c:627,641
1994/1113    
	return 0; 
} 
1994/1112    
 
1994/1114    
/* 
 *  write ISA mapped memory 
 */ 
1994/1113    
static long 
memwrite(Astar *a, uchar *from, long n, ulong offset) 
{ 
	uchar *to, *e; 
1994/1114    
	uchar *to, *e, *tp; 
1994/1113    
	int i, rem; 
1994/1114    
	uchar tmp[256]; 
1994/1113    
 
	if(offset+n > a->memsize){ 
		if(offset >= a->memsize) 
1994/1113/sys/src/9/pc/devastar.c:616,6601994/1114/sys/src/9/pc/devastar.c:643,677
1994/1113    
		n = a->memsize - offset; 
	} 
 
	if(waserror()){ 
		qunlock(a); 
		nexterror(); 
	} 
	qlock(a); 
                 
	for(rem = n; rem > 0; rem -= i){ 
 
		/* map in right piece of memory */ 
		setpage(a, offset); 
		i = offset&Pagemask; 
		from = a->addr + i; 
1994/1114    
		to = a->addr + i; 
1994/1113    
		i = Pagesize - i; 
		if(i > rem) 
			i = rem; 
1994/1114    
		if(i > sizeof tmp) 
			i = sizeof tmp; 
1994/1113    
		 
		/* byte at a time so endian doesn't matter */ 
1994/1114    
		/* 
		 *  byte at a time so endian doesn't matter, 
		 *  go via tmp to avoid pagefaults while ilock'd 
		 */ 
		memmove(tmp, from, i); 
		tp = tmp; 
		ilock(&a->pagelock); 
		setpage(a, offset); 
1994/1113    
		for(e = from + i; from < e;) 
			*to++ = *from++; 
1994/1114    
			*to++ = *tp++; 
		iunlock(&a->pagelock); 
		from += i; 
1994/1113    
	} 
 
	qunlock(a); 
	poperror(); 
	return n; 
} 
 
/* 
 *  setup a channel 
 */ 
static void 
chansetup(Astar *a, Astarchan *ac, void *ccb) 
{ 
	ac->a = a; 
	ac->ccb = ccb; 
	ac->iq = qopen(4*1024, 0, 0, 0); 
	ac->oq = qopen(4*1024, 0, astarkick, p); 
} 
                 
/* 
 *  start control progarm 
 */ 
static void 
1994/1113/sys/src/9/pc/devastar.c:663,6681994/1114/sys/src/9/pc/devastar.c:680,686
1994/1113    
	int n, i, sz; 
	uchar *x; 
	CCB *ccb; 
1994/1114    
	Astarchan *ac; 
1994/1113    
 
	if(a->running) 
		error(Eio); 
1994/1113/sys/src/9/pc/devastar.c:682,6871994/1114/sys/src/9/pc/devastar.c:700,710
1994/1113    
		error(Eio); 
	} 
 
1994/1114    
	if(waserror()){ 
		iunlock(&a->pagelock); 
		poperror(); 
	} 
	ilock(&a->pagelock); 
1994/1113    
	setpage(a, 0); 
	i = LEUS(a->gcb->type); 
	switch(i){ 
1994/1113/sys/src/9/pc/devastar.c:712,7171994/1114/sys/src/9/pc/devastar.c:735,742
1994/1113    
			error(Eio); 
1994/1112    
		} 
1994/1113    
	} 
1994/1114    
	iunlock(&a->pagelock); 
	poperror(); 
1994/1113    
 
	/* setup the channels */ 
	a->running = 1; 
1994/1113/sys/src/9/pc/devastar.c:718,7241994/1114/sys/src/9/pc/devastar.c:743,753
1994/1113    
	a->nchan = i; 
	a->c = xalloc(a->nchan * sizeof(Astarchan)); 
	for(i = 0; i < a->nchan; i++){ 
		chansetup(a, &a->c[i], (CCB*)x); 
1994/1114    
		ac = &a->c[i]; 
		ac->a = a; 
		ac->ccb = (CCB*)x; 
		ac->iq = qopen(4*1024, 0, 0, 0); 
		ac->oq = qopen(4*1024, 0, astarkick, ac); 
1994/1113    
		x += sz; 
	} 
} 
1994/1113/sys/src/9/pc/devastar.c:761,7731994/1114/sys/src/9/pc/devastar.c:790,894
1994/1113    
} 
 
/* 
1994/1114    
 *  Send a command to a channel 
 *  (must be called with ac qlocked) 
 */ 
static int 
chancmddone(void *arg) 
{ 
	CCB *ccb = arg; 
	int x; 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	x = ccb->cmd; 
	iunlock(&ac->a->pagelock); 
 
	return x; 
} 
static void 
chancmd(Astarchan *ac, int cmd) 
{ 
	int i; 
	CCB *ccb; 
 
	ccb = ac->ccb; 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	ccb->cmd = cmd; 
	iunlock(&ac->a->pagelock); 
 
	/* wait outside of lock */ 
	tsleep(&ac->r, chancmddone, ccb, 1000); 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	if(ccb->cmd){ 
		print("astar%d cmd didn't terminate\n", ac->a->id); 
		error(Eio); 
	} 
	if(ccb->status){ 
		print("astar%d cmd status %ux\n", ac->a->id, ccb->status); 
		error(Eio); 
	} 
	iunlock(&ac->a->pagelock); 
} 
 
/* 
 *  enable a channel for IO, set standard params. 
 *  (must be called with ac qlocked) 
 */ 
static void 
enable(Astarchan *ac) 
{ 
	Astar qÍ*a = ac->a; 
	/* make sure we control RTS, DTR and break */ 
	ilock(&a->pagelock); 
	setpage(a, 0); 
	n = LEUS(ac->ccb->proto) | Cmctl; 
	ac->ccb->proto = LEUS(n); 
	iunlock(&a->pagelock); 
 
	chancmd(ac, Crcvena|Cxmtena|Cflushin|Cflushout|Confall); 
 
	astarctl(ac, "b9600"); 
	astarctl(ac, "l8"); 
	astarctl(ac, "p0"); 
	astarctl(ac, "d1"); 
	astarctl(ac, "r1"); 
} 
 
/* 
 *  disable a channel for IO 
 *  (must be called with ac qlocked) 
 */ 
static void 
disable(Astarchan *ac) 
{ 
	astarctl(ac, "d0"); 
	astarctl(ac, "r0"); 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	ccb->intrigger = 8; 
	ccb->outlow = 32; 
	iunlock(&ac->a->pagelock); 
 
	chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); 
} 
 
/* 
1994/1113    
 *  change channel parameters 
1994/1114    
 *  (must be called with ac qlocked) 
1994/1113    
 */ 
void 
1994/1114    
static void 
1994/1113    
astarctl(Astarchan *ac, char *cmd) 
{ 
	int i, n; 
	int command; 
1994/1114    
	CCB *ccb; 
	Astar *a; 
1994/1113    
 
	/* let output drain for a while */ 
	for(i = 0; i < 16 && qlen(ac->oq); i++) 
1994/1113/sys/src/9/pc/devastar.c:776,7951994/1114/sys/src/9/pc/devastar.c:897,920
1994/1113    
	if(strncmp(cmd, "break", 5) == 0) 
		cmd = "k"; 
 
1994/1114    
	ccb = ac->ccb; 
1994/1113    
	command = 0; 
	n = atoi(cmd+1); 
1994/1114    
	i = atoi(cmd+1); 
	a = ac->a; 
	ilock(&a->pagelock); 
	setpage(a, 0); 
1994/1113    
	switch(*cmd){ 
	case 'B': 
	case 'b': 
		switch(n){ 
1994/1114    
		switch(i){ 
1994/1113    
		case 76800: 
			ac->ccb->baud = LEUS(Cb76800); 
1994/1114    
			ccb->baud = LEUS(Cb76800); 
1994/1113    
			break; 
		case 115200: 
			ac->ccb->baud = LEUS(Cb115200); 
1994/1114    
			ccb->baud = LEUS(Cb115200); 
1994/1113    
			break; 
		default: 
			ac->ccb->baud = LEUS(n); 
1994/1114    
			ccb->baud = LEUS(n); 
1994/1113    
			break; 
		} 
		command = Cconfall; 
1994/1113/sys/src/9/pc/devastar.c:796,8011994/1114/sys/src/9/pc/devastar.c:921,932
1994/1112    
		break; 
1994/1113    
	case 'D': 
	case 'd': 
1994/1114    
		n = LEUS(ccb->mctl); 
		if(i) 
			 n |= Cdtrctl; 
		else 
			 n &= ~Cdtrctl; 
		ccb->mctl = LEUS(n); 
1994/1112    
		break; 
1994/1113    
	case 'f': 
	case 'F': 
1994/1113/sys/src/9/pc/devastar.c:811,8241994/1114/sys/src/9/pc/devastar.c:942,965
1994/1113    
		n -= 5; 
		if(n < 0 || n > 3) 
			error(Ebadarg); 
		n |= LEUS(ac->ccb->format) & ~Clenmask; 
		ac->ccb->format = LEUS(n); 
1994/1114    
		n |= LEUS(ccb->format) & ~Clenmask; 
		ccb->format = LEUS(n); 
1994/1113    
		command = Cconfall; 
		break; 
	case 'm': 
	case 'M': 
		n = LEUS(ac->ccb->format) | Cobeycts; 
		ac->ccb->proto = LEUS(n); 
1994/1114    
		/* turn on cts */ 
		n = LEUS(ccb->proto); 
		if(i) 
			n |= Cobeycts; 
		else 
			n &= ~Cobeycts; 
		ccb->proto = LEUS(n); 
 
		/* set fifo sizes */ 
		ccb->intrigger = 8; 
		ccb->outlow = 32; 
 
1994/1113    
		command = Cconfall; 
		break; 
	case 'n': 
1994/1113/sys/src/9/pc/devastar.c:838,8521994/1114/sys/src/9/pc/devastar.c:979,1011
1994/1113    
			n = Cnopar; 
			break; 
		} 
		n |= LEUS(ac->ccb->format) & ~Cparmask; 
		ac->ccb->format = LEUS(n); 
1994/1114    
		n |= LEUS(ccb->format) & ~Cparmask; 
		ccb->format = LEUS(n); 
1994/1113    
		command = Cconfall; 
		break; 
	case 'K': 
	case 'k': 
1994/1114    
		if(i <= 0) 
			i = 250; 
		n = LEUS(ccb->mctl) | Cbreakctl; 
		ccb->mctl = LEUS(n); 
		iunlock(&a->pagelock); 
 
		tsleep(&ac->r, return0, 0, i); 
 
		ilock(&a->pagelock); 
		setpage(a, 0); 
		n &= ~Cbreakctl; 
		ccb->mctl = LEUS(n); 
1994/1113    
		break; 
	case 'R': 
	case 'r': 
1994/1114    
		n = LEUS(ccb->mctl); 
		if(i) 
			 n |= Crtsctl; 
		else 
			 n &= ~Crtsctl; 
		ccb->mctl = LEUS(n); 
1994/1113    
		break; 
	case 'Q': 
	case 'q': 
1994/1113/sys/src/9/pc/devastar.c:855,8681994/1114/sys/src/9/pc/devastar.c:1014,1034
1994/1113    
		break; 
	case 'X': 
	case 'x': 
		n = LEUS(ac->ccb->format) | Cobeyxon; 
		ac->ccb->proto = LEUS(n); 
1994/1114    
		n = LEUS(ccb->proto); 
		if(i) 
			n |= Cobeyxon; 
		else 
			n &= ~Cobeyxon; 
		ccb->proto = LEUS(n); 
1994/1113    
		command = Cconfall; 
		break; 
1994/1111    
	} 
1994/1114    
	iunlock(&a->pagelock); 
 
	if(command) 
		chancmd(ac, command); 
1994/1111    
} 
 
1994/1113    
                 
1994/1111    
long 
astarwrite(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1113/sys/src/9/pc/devastar.c:887,8971994/1114/sys/src/9/pc/devastar.c:1053,1072
1994/1113    
		ac = a->c + CHAN(c->qid.path); 
		return qwrite(ac->oq, buf, n); 
	case Qctl: 
1994/1114    
		ac = a->c + CHAN(c->qid.path); 
1994/1113    
		if(n > sizeof cmsg) 
			n = sizeof(cmsg) - 1; 
		memmove(cmsg, buf, n); 
		cmsg[n] = 0; 
		return astarctl(a, msg); 
1994/1114    
 
		if(waserror()){ 
			qunlock(ac); 
			nexterror(); 
		} 
		qlock(ac); 
		astarctl(ac, msg); 
		qunlock(ac); 
		poperror(); 
1994/1111    
	} 
1994/1109    
 
	return 0; 
1994/1113/sys/src/9/pc/devastar.c:918,9201994/1114/sys/src/9/pc/devastar.c:1093,1166
1994/1112    
	error(Eperm); 
1994/1106    
} 
1994/1113    
 
1994/1114    
/* 
 *  get output going 
 */ 
static void 
astarkick1(Astarchan *ac) 
{ 
	Astar *a = ac->a; 
	CCB *ccb = a->ccb; 
	uchar tmp[256]; 
	int n; 
 
	for(;;){ 
		setpage(a, 0); 
	} 
} 
static void 
astarkick(Astarchan *ac) 
{ 
	ilock(&ac->a->pagelock); 
	astarkick(ac); 
	iunlock(&ac->a->pagelock); 
} 
 
/* 
 *  handle an interrupt 
 */ 
static void 
astarintr(Ureg *ur, void *arg) 
{ 
	Astar *a = arg; 
	Astarchan *ac; 
	ulong vec, invec, outvec, errvec, mvec, cmdvec; 
	int i; 
 
	USED(ur); 
	lock(&a->pagelock); 
	setpage(a, 0); 
 
	/* get causes */ 
	invec = LEUS(xchgw(&a->gcb->inserv, 0)); 
	outvec = LEUS(xchgw(&a->gcb->outserv, 0)); 
	errvec = LEUS(xchgw(&a->gcb->errserv, 0)); 
	mvec = LEUS(xchgw(&a->gcb->modemserv, 0)); 
	cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0)); 
 
	/* reenable interrupts */ 
	a->cmd2 = LEUS(Gintack); 
 
	/* service interrupts */ 
	ac = a->c; 
	for(vec = LEUS(xchgw(&a->gcb->inserv, 0)); vec; vec >>= 1){ 
		if(vec&1){ 
		} 
		setpage(a, 0); 
		ac++; 
	} 
	ac = a->c; 
	for(vec = LEUS(xchgw(&a->gcb->outserv, 0)); vec; vec >>= 1){ 
		if(vec&1) 
			astarkick1(ac); 
		setpage(a, 0); 
		ac++; 
	} 
	ac = a->c; 
	for(vec = LEUS(xchgw(&a->gcb->cmdserv, 0)); vec; vec >>= 1){ 
		if(vec&1) 
			wakeup(&ac->r); 
		ac++; 
	} 
	unlock(&a->pagelock); 
} 
1994/1114/sys/src/9/pc/devastar.c:37,431994/1115/sys/src/9/pc/devastar.c:37,43 (short | long)
1994/1106    
	ISActl1=	1,		/* board control */ 
	 ISAien=	 1<<7,		/*  interrupt enable */ 
1994/1107    
	 ISAirq=	 7<<4,		/*  mask for irq code */ 
1994/1106    
	 ISAdl=		 1<<1,		/*  download bit (1 == download) */ 
1994/1115    
	 ISAnotdl=	 1<<1,		/*  download bit (0 == download) */ 
1994/1106    
	 ISApr=		 1<<0,		/*  program ready */ 
	ISActl2=	2,		/* board control */ 
	 ISA186ien=	 1<<7,		/*  I186 irq enable bit state */ 
1994/1114/sys/src/9/pc/devastar.c:213,2191994/1115/sys/src/9/pc/devastar.c:213,218
1994/1107    
	Crtsctl=	1<<1, 
1994/1112    
	Cbreakctl=	1<<4, 
1994/1107    
 
                 
	/* CCB.mstat fields */ 
	Cctsstat=	1<<0, 
	Cdsrstat=	1<<1, 
1994/1114/sys/src/9/pc/devastar.c:243,2491994/1115/sys/src/9/pc/devastar.c:242,248
1994/1111    
	Astarchan	*c;		/* channels */ 
1994/1107    
	int		ramsize;	/* 16k or 256k */ 
1994/1113    
	int		memsize;	/* size of memory currently mapped */ 
	GCB		*gbc;		/* global board comm area */ 
1994/1115    
	GCB		*gcb;		/* global board comm area */ 
1994/1113    
	uchar		*addr;		/* base of memory area */ 
	int		running; 
 
1994/1114/sys/src/9/pc/devastar.c:285,2901994/1115/sys/src/9/pc/devastar.c:284,290
1994/1114    
static void	astarkick(Astarchan*); 
static void	enable(Astarchan*); 
static void	disable(Astarchan*); 
1994/1115    
static void	astarctl(Astarchan*, char*); 
1994/1107    
 
1994/1113    
/* 
 *  Only 16k maps into ISA space 
1994/1114/sys/src/9/pc/devastar.c:310,3291994/1115/sys/src/9/pc/devastar.c:310,332
1994/1111    
	int dev, sofar, ch, t; 
1994/1112    
	extern ulong kerndate; 
1994/1111    
 
1994/1115    
	memset(db, 0, sizeof(Dir)); 
 
1994/1111    
	USED(tab, ntab); 
	sofar = 0; 
 
1994/1112    
	for(dev = 0; dev < nastar; dev++){ 
1994/1111    
		if(sofar == i){ 
1994/1112    
			sprint(db->name, "atar%dmem", astar[dev]->id); 
1994/1115    
			sprint(db->name, "astar%dmem", astar[dev]->id); 
1994/1112    
			db->qid.path = QID(dev, 0, Qmem); 
1994/1111    
			db->mode = 0660; 
1994/1115    
			db->length = astar[dev]->memsize; 
1994/1111    
			break; 
		} 
1994/1112    
		sofar++; 
1994/1111    
 
1994/1112    
		if(sofar == i){ 
			sprint(db->name, "atar%dctl", astar[dev]->id); 
1994/1115    
			sprint(db->name, "astar%dctl", astar[dev]->id); 
1994/1112    
			db->qid.path = QID(dev, 0, Qbctl); 
			db->mode = 0660; 
			break; 
1994/1114/sys/src/9/pc/devastar.c:338,3541994/1115/sys/src/9/pc/devastar.c:341,357
1994/1111    
			case 0: 
				sprint(db->name, "eia%d%2.2d", dev, ch); 
				db->mode = astar[dev]->c[ch].perm; 
1994/1112    
				db->qid.path = QID(dev, 0, Qdata); 
1994/1115    
				db->qid.path = QID(dev, ch, Qdata); 
1994/1111    
				break; 
			case 1: 
				sprint(db->name, "eia%d%2.2dctl", dev, ch); 
				db->mode = astar[dev]->c[ch].perm; 
1994/1112    
				db->qid.path = QID(dev, 0, Qctl); 
1994/1115    
				db->qid.path = QID(dev, ch, Qctl); 
1994/1111    
				break; 
			case 2: 
				sprint(db->name, "eia%d%2.2dstat", dev, ch); 
				db->mode = 0444; 
1994/1112    
				db->qid.path = QID(dev, 0, Qstat); 
1994/1115    
				db->qid.path = QID(dev, ch, Qstat); 
1994/1111    
				break; 
1994/1112    
			} 
1994/1111    
			break; 
1994/1114/sys/src/9/pc/devastar.c:359,3681994/1115/sys/src/9/pc/devastar.c:362,370
1994/1112    
	if(dev == nastar) 
1994/1111    
		return -1; 
 
1994/1115    
	db->qid.vers = 0; 
1994/1111    
	db->atime = seconds(); 
	db->mtime = kerndate; 
	db->hlength = 0; 
1994/1112    
	db->length = 0;				/* update ???? */ 
1994/1111    
	memmove(db->uid, eve, NAMELEN); 
	memmove(db->gid, eve, NAMELEN); 
	db->type = devchar[c->type]; 
1994/1114/sys/src/9/pc/devastar.c:376,3821994/1115/sys/src/9/pc/devastar.c:378,384
1994/1106    
void 
1994/1107    
astarreset(void) 
1994/1106    
{ 
	int i; 
1994/1115    
	int i, c; 
1994/1107    
	Astar *a; 
1994/1106    
 
	for(i = 0; i < Maxcard; i++){ 
1994/1114/sys/src/9/pc/devastar.c:394,3991994/1115/sys/src/9/pc/devastar.c:396,405
1994/1107    
		else 
			continue; 
1994/1108    
 
1994/1115    
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c | ISAnotdl); 
		a->memsize = a->ramsize; 
 
1994/1107    
		if(a->mem == 0) 
1994/1108    
			a->mem = 0xD4000; 
1994/1107    
		if(a->irq == 0) 
1994/1114/sys/src/9/pc/devastar.c:406,4121994/1115/sys/src/9/pc/devastar.c:412,419
1994/1109    
			astar[nastar] = 0; 
1994/1107    
			continue; 
		} 
1994/1112    
		print("serial%d avanstar addr %lux irq %d\n", i, a->addr, a->irq); 
1994/1115    
		print("serial%d avanstar port %d addr %lux irq %d\n", i, a->port, 
			a->addr, a->irq); 
1994/1109    
		nastar++; 
1994/1114    
 
		setvec(Int0vec + a->irq, astarintr, a); 
1994/1114/sys/src/9/pc/devastar.c:455,4621994/1115/sys/src/9/pc/devastar.c:462,469
1994/1107    
 
	/* set memory address */ 
1994/1113    
	outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc); 
1994/1112    
	a->gbc = (GCB*)(KZERO | a->mem); 
	a->addr = (char*)(KZERO | a->mem); 
1994/1115    
	a->gcb = (GCB*)(KZERO | a->mem); 
	a->addr = (uchar*)(KZERO | a->mem); 
1994/1107    
 
	/* set interrupt level */ 
1994/1112    
	if(isairqcode[a->irq] == -1){ 
1994/1114/sys/src/9/pc/devastar.c:475,4811994/1115/sys/src/9/pc/devastar.c:482,488
1994/1111    
Chan* 
astarattach(char *spec) 
{ 
	return devattach('g', spec); 
1994/1115    
	return devattach('G', spec); 
1994/1111    
} 
 
Chan* 
1994/1114/sys/src/9/pc/devastar.c:500,5071994/1115/sys/src/9/pc/devastar.c:507,516
1994/1111    
astaropen(Chan *c, int omode) 
{ 
1994/1112    
	Astar *a; 
1994/1115    
	Astarchan *ac; 
1994/1111    
 
	c = devopen(c, omode, 0, 0, astargen); 
1994/1115    
	a = astar[BOARD(c->qid.path)]; 
1994/1111    
 
1994/1112    
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
1994/1114/sys/src/9/pc/devastar.c:511,5191994/1115/sys/src/9/pc/devastar.c:520,529
1994/1112    
		break; 
1994/1114    
	case Qdata: 
	case Qctl: 
1994/1115    
		ac = a->c + CHAN(c->qid.path); 
1994/1114    
		qlock(ac); 
		if(waserror()){ 
			qunlock(a); 
1994/1115    
			qunlock(ac); 
1994/1114    
			nexterror(); 
		} 
		if(ac->opens++ == 0) 
1994/1114/sys/src/9/pc/devastar.c:530,5491994/1115/sys/src/9/pc/devastar.c:540,565
1994/1111    
astarclose(Chan *c) 
{ 
1994/1112    
	Astar *a; 
	int i; 
1994/1115    
	Astarchan *ac; 
1994/1112    
 
1994/1115    
	a = astar[BOARD(c->qid.path)]; 
 
1994/1112    
	switch(TYPE(c->qid.path)){ 
	case Qmem: 
1994/1114    
		break; 
	case Qdata: 
	case Qctl: 
1994/1115    
		ac = a->c + CHAN(c->qid.path); 
1994/1114    
		qlock(ac); 
		if(waserror()){ 
			qunlock(a); 
1994/1115    
			qunlock(ac); 
1994/1114    
			nexterror(); 
1994/1112    
		} 
1994/1114    
		if(--ac->opens == 0) 
1994/1115    
		if(--ac->opens == 0){ 
1994/1114    
			disable(ac); 
1994/1115    
			qclose(ac->iq); 
			qclose(ac->oq); 
		} 
1994/1114    
		qunlock(ac); 
		poperror(); 
1994/1112    
		break; 
1994/1114/sys/src/9/pc/devastar.c:574,5811994/1115/sys/src/9/pc/devastar.c:590,597
1994/1113    
		i = Pagesize - i; 
		if(i > rem) 
			i = rem; 
1994/1114    
		if(i > sizeof tmp) 
			i = sizeof tmp; 
1994/1115    
		if(i > sizeof(tmp)) 
			i = sizeof(tmp); 
1994/1114    
 
		/* 
		 *  byte at a time so endian doesn't matter, 
1994/1114/sys/src/9/pc/devastar.c:584,5941994/1115/sys/src/9/pc/devastar.c:600,612
1994/1114    
		tp = tmp; 
		ilock(&a->pagelock); 
		setpage(a, offset); 
1994/1113    
		for(e = from + i; from < e;) 
1994/1115    
		for(e = tp + i; tp < e;) 
1994/1114    
			*tp++ = *from++; 
		iunlock(&a->pagelock); 
		memmove(to, tmp, i); 
		to += i; 
1994/1115    
 
		offset += i; 
1994/1113    
	} 
 
	return n; 
1994/1114/sys/src/9/pc/devastar.c:598,6041994/1115/sys/src/9/pc/devastar.c:616,622
1994/1114    
 *  read ISA status 
 */ 
1994/1113    
static long 
bctlread(Chan *c, void *buf, long n, ulong offset) 
1994/1115    
bctlread(Astar *a, void *buf, long n, ulong offset) 
1994/1113    
{ 
	char s[128]; 
 
1994/1114/sys/src/9/pc/devastar.c:613,6181994/1115/sys/src/9/pc/devastar.c:631,638
1994/1111    
long 
astarread(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1115    
	Astar *a; 
	Astarchan *ac; 
1994/1111    
 
	if(c->qid.path & CHDIR) 
		return devdirread(c, buf, n, 0, 0, astargen); 
1994/1114/sys/src/9/pc/devastar.c:622,6271994/1115/sys/src/9/pc/devastar.c:642,651
1994/1113    
		return memread(astar[BOARD(c->qid.path)], buf, n, offset); 
	case Qbctl: 
		return bctlread(astar[BOARD(c->qid.path)], buf, n, offset); 
1994/1115    
	case Qdata: 
		a = astar[BOARD(c->qid.path)]; 
		ac = a->c + CHAN(c->qid.path); 
		return qread(ac->oq, buf, n); 
1994/1113    
	} 
1994/1112    
 
1994/1113    
	return 0; 
1994/1114/sys/src/9/pc/devastar.c:651,6581994/1115/sys/src/9/pc/devastar.c:675,682
1994/1113    
		i = Pagesize - i; 
		if(i > rem) 
			i = rem; 
1994/1114    
		if(i > sizeof tmp) 
			i = sizeof tmp; 
1994/1115    
		if(i > sizeof(tmp)) 
			i = sizeof(tmp); 
1994/1113    
		 
1994/1114    
		/* 
		 *  byte at a time so endian doesn't matter, 
1994/1114/sys/src/9/pc/devastar.c:662,6711994/1115/sys/src/9/pc/devastar.c:686,697
1994/1114    
		tp = tmp; 
		ilock(&a->pagelock); 
		setpage(a, offset); 
1994/1113    
		for(e = from + i; from < e;) 
1994/1115    
		for(e = tp + i; tp < e;) 
1994/1114    
			*to++ = *tp++; 
		iunlock(&a->pagelock); 
		from += i; 
1994/1115    
 
		offset += i; 
1994/1113    
	} 
 
	return n; 
1994/1114/sys/src/9/pc/devastar.c:746,7611994/1115/sys/src/9/pc/devastar.c:772,790
1994/1114    
		ac = &a->c[i]; 
		ac->a = a; 
		ac->ccb = (CCB*)x; 
1994/1115    
		ac->perm = 0660; 
1994/1114    
		ac->iq = qopen(4*1024, 0, 0, 0); 
		ac->oq = qopen(4*1024, 0, astarkick, ac); 
1994/1113    
		x += sz; 
	} 
1994/1115    
 
	/* reenable interrupts */ 
	a->gcb->cmd2 = LEUS(Gintack); 
1994/1113    
} 
 
static long 
bctlwrite(Astar *a, char *msg) 
1994/1115    
static void 
bctlwrite(Astar *a, char *cmsg) 
1994/1113    
{ 
	int i; 
	uchar c; 
 
	if(waserror()){ 
1994/1114/sys/src/9/pc/devastar.c:764,7731994/1115/sys/src/9/pc/devastar.c:793,802
1994/1113    
	} 
	qlock(a); 
 
	if(strncmp(cmsg, "download", 8) == 0){ 
		if(a->running) 
			error(Eio); 
1994/1115    
	if(a->running) 
		error(Eio); 
1994/1113    
 
1994/1115    
	if(strncmp(cmsg, "download", 8) == 0){ 
1994/1113    
		/* put board in download mode */ 
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c & ~ISAnotdl); 
1994/1114/sys/src/9/pc/devastar.c:776,7841994/1115/sys/src/9/pc/devastar.c:805,821
1994/1113    
		/* enable ISA access to first 16k */ 
		outb(a->port+ISActl2, ISAmen); 
 
1994/1115    
	} else if(strncmp(cmsg, "sharedmem", 9) == 0){ 
		/* map shared memory */ 
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c | ISAnotdl); 
		a->memsize = a->ramsize; 
 
		/* enable ISA access to first 16k */ 
		outb(a->port+ISActl2, ISAmen); 
 
1994/1113    
	} else if(strncmp(cmsg, "run", 3) == 0){ 
		if(a->running) 
			error(Eio); 
1994/1115    
		/* start up downloaded program */ 
1994/1113    
		startcp(a); 
 
	} else 
1994/1114/sys/src/9/pc/devastar.c:786,7921994/1115/sys/src/9/pc/devastar.c:823,828
1994/1113    
 
	qunlock(a); 
	poperror(); 
	return n; 
} 
 
/* 
1994/1114/sys/src/9/pc/devastar.c:796,8161994/1115/sys/src/9/pc/devastar.c:832,852
1994/1114    
static int 
chancmddone(void *arg) 
{ 
	CCB *ccb = arg; 
1994/1115    
	Astarchan *ac = arg; 
1994/1114    
	int x; 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	x = ccb->cmd; 
1994/1115    
	x = ac->ccb->cmd; 
1994/1114    
	iunlock(&ac->a->pagelock); 
 
	return x; 
1994/1115    
	return !x; 
1994/1114    
} 
static void 
chancmd(Astarchan *ac, int cmd) 
{ 
	int i; 
	CCB *ccb; 
1994/1115    
	int status; 
1994/1114    
 
	ccb = ac->ccb; 
 
1994/1114/sys/src/9/pc/devastar.c:820,8381994/1115/sys/src/9/pc/devastar.c:856,876
1994/1114    
	iunlock(&ac->a->pagelock); 
 
	/* wait outside of lock */ 
	tsleep(&ac->r, chancmddone, ccb, 1000); 
1994/1115    
	tsleep(&ac->r, chancmddone, ac, 1000); 
1994/1114    
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	if(ccb->cmd){ 
1994/1115    
	status = ccb->status; 
	cmd = ccb->cmd; 
	iunlock(&ac->a->pagelock); 
	if(cmd){ 
1994/1114    
		print("astar%d cmd didn't terminate\n", ac->a->id); 
		error(Eio); 
	} 
	if(ccb->status){ 
		print("astar%d cmd status %ux\n", ac->a->id, ccb->status); 
1994/1115    
	if(status){ 
		print("astar%d cmd status %ux\n", ac->a->id, status); 
1994/1114    
		error(Eio); 
	} 
	iunlock(&ac->a->pagelock); 
} 
 
/* 
1994/1114/sys/src/9/pc/devastar.c:842,8621994/1115/sys/src/9/pc/devastar.c:880,904
1994/1114    
static void 
enable(Astarchan *ac) 
{ 
	Astar qÍ*a = ac->a; 
1994/1115    
	Astar *a = ac->a; 
	int n; 
 
1994/1114    
	/* make sure we control RTS, DTR and break */ 
	ilock(&a->pagelock); 
	setpage(a, 0); 
	n = LEUS(ac->ccb->proto) | Cmctl; 
	ac->ccb->proto = LEUS(n); 
1994/1115    
	ac->ccb->outlow = 64; 
1994/1114    
	iunlock(&a->pagelock); 
1994/1115    
	chancmd(ac, Cconfall); 
1994/1114    
 
	chancmd(ac, Crcvena|Cxmtena|Cflushin|Cflushout|Confall); 
                 
	astarctl(ac, "b9600"); 
	astarctl(ac, "l8"); 
	astarctl(ac, "p0"); 
	astarctl(ac, "d1"); 
	astarctl(ac, "r1"); 
1994/1115    
 
	chancmd(ac, Crcvena|Cxmtena|Cconfall); 
1994/1114    
} 
 
/* 
1994/1114/sys/src/9/pc/devastar.c:871,8781994/1115/sys/src/9/pc/devastar.c:913,919
1994/1114    
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
	ccb->intrigger = 8; 
	ccb->outlow = 32; 
1994/1115    
	ac->ccb->intrigger = 0; 
1994/1114    
	iunlock(&ac->a->pagelock); 
 
	chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); 
1994/1114/sys/src/9/pc/devastar.c:900,9081994/1115/sys/src/9/pc/devastar.c:941,951
1994/1114    
	ccb = ac->ccb; 
1994/1113    
	command = 0; 
1994/1114    
	i = atoi(cmd+1); 
1994/1115    
 
1994/1114    
	a = ac->a; 
	ilock(&a->pagelock); 
	setpage(a, 0); 
1994/1115    
 
1994/1113    
	switch(*cmd){ 
	case 'B': 
	case 'b': 
1994/1114/sys/src/9/pc/devastar.c:914,9201994/1115/sys/src/9/pc/devastar.c:957,963
1994/1114    
			ccb->baud = LEUS(Cb115200); 
1994/1113    
			break; 
		default: 
1994/1114    
			ccb->baud = LEUS(n); 
1994/1115    
			ccb->baud = LEUS(i); 
1994/1113    
			break; 
		} 
		command = Cconfall; 
1994/1114/sys/src/9/pc/devastar.c:939,9451994/1115/sys/src/9/pc/devastar.c:982,988
1994/1113    
		break; 
	case 'L': 
	case 'l': 
		n -= 5; 
1994/1115    
		n = i - 5; 
1994/1113    
		if(n < 0 || n > 3) 
			error(Ebadarg); 
1994/1114    
		n |= LEUS(ccb->format) & ~Clenmask; 
1994/1114/sys/src/9/pc/devastar.c:958,9701994/1115/sys/src/9/pc/devastar.c:1001,1012
1994/1114    
 
		/* set fifo sizes */ 
		ccb->intrigger = 8; 
		ccb->outlow = 32; 
 
1994/1113    
		command = Cconfall; 
		break; 
	case 'n': 
	case 'N': 
		qnoblock(p->oq, n); 
1994/1115    
		qnoblock(ac->oq, i); 
1994/1113    
		break; 
	case 'P': 
	case 'p': 
1994/1114/sys/src/9/pc/devastar.c:1009,10161994/1115/sys/src/9/pc/devastar.c:1051,1058
1994/1113    
		break; 
	case 'Q': 
	case 'q': 
		qsetlimit(ac->iq, n); 
		qsetlimit(ac->oq, n); 
1994/1115    
		qsetlimit(ac->iq, i); 
		qsetlimit(ac->oq, i); 
1994/1113    
		break; 
	case 'X': 
	case 'x': 
1994/1114/sys/src/9/pc/devastar.c:1048,10541994/1115/sys/src/9/pc/devastar.c:1090,1097
1994/1112    
			n = sizeof(cmsg) - 1; 
		memmove(cmsg, buf, n); 
		cmsg[n] = 0; 
1994/1113    
		return bctlwrite(a, cmsg); 
1994/1115    
		bctlwrite(a, cmsg); 
		return n; 
1994/1113    
	case Qdata: 
		ac = a->c + CHAN(c->qid.path); 
		return qwrite(ac->oq, buf, n); 
1994/1114/sys/src/9/pc/devastar.c:1064,10701994/1115/sys/src/9/pc/devastar.c:1107,1113
1994/1114    
			nexterror(); 
		} 
		qlock(ac); 
		astarctl(ac, msg); 
1994/1115    
		astarctl(ac, cmsg); 
1994/1114    
		qunlock(ac); 
		poperror(); 
1994/1111    
	} 
1994/1114/sys/src/9/pc/devastar.c:1089,10961994/1115/sys/src/9/pc/devastar.c:1132,1151
1994/1112    
void 
astarwstat(Chan *c, char *dp) 
{ 
	USED(c, dp); 
	error(Eperm); 
1994/1115    
	Dir d; 
	Astarchan *ac; 
 
	if(!iseve()) 
		error(Eperm); 
	if(CHDIR & c->qid.path) 
		error(Eperm); 
	if(TYPE(c->qid.path) != Qdata && TYPE(c->qid.path) != Qctl) 
		error(Eperm); 
	ac = astar[BOARD(c->qid.path)]->c + CHAN(c->qid.path); 
 
	convM2D(dp, &d); 
	d.mode &= 0666; 
	ac->perm = d.mode; 
1994/1106    
} 
1994/1113    
 
1994/1114    
/* 
1994/1114/sys/src/9/pc/devastar.c:1100,11111994/1115/sys/src/9/pc/devastar.c:1155,1191
1994/1114    
astarkick1(Astarchan *ac) 
{ 
	Astar *a = ac->a; 
	CCB *ccb = a->ccb; 
	uchar tmp[256]; 
1994/1115    
	CCB *ccb = ac->ccb; 
	uchar buf[256]; 
	uchar *rp, *wp, *bp, *ep, *p, *e; 
1994/1114    
	int n; 
 
1994/1115    
	setpage(a, 0); 
	ep = a->addr; 
	rp = ep + LEUS(ccb->outrp); 
	wp = ep + LEUS(ccb->outwp); 
	bp = ep + LEUS(ccb->outbase); 
	ep = ep + LEUS(ccb->outlim); 
1994/1114    
	for(;;){ 
1994/1115    
		n = rp - wp - 1; 
		if(n < 0) 
			n += ep - bp + 1; 
		if(n == 0) 
			break; 
		if(n > sizeof(buf)) 
			n = sizeof(buf); 
		n = qconsume(ac->oq, buf, n); 
		if(n <= 0) 
			break; 
		setpage(a, bp - a->addr); 
		e = buf + n; 
		for(p = buf; p < e;){ 
			*wp++ = *p++; 
			if(wp > ep) 
				wp = bp; 
		} 
1994/1114    
		setpage(a, 0); 
1994/1115    
		ccb->outwp = LEUS(wp - a->addr); 
1994/1114    
	} 
} 
static void 
1994/1114/sys/src/9/pc/devastar.c:1112,11221994/1115/sys/src/9/pc/devastar.c:1192,1241
1994/1114    
astarkick(Astarchan *ac) 
{ 
	ilock(&ac->a->pagelock); 
	astarkick(ac); 
1994/1115    
	astarkick1(ac); 
1994/1114    
	iunlock(&ac->a->pagelock); 
} 
 
/* 
1994/1115    
 *  process input 
 */ 
static void 
astarinput(Astarchan *ac) 
{ 
	Astar *a = ac->a; 
	CCB *ccb = ac->ccb; 
	uchar buf[256]; 
	uchar *rp, *wp, *bp, *ep, *p, *e; 
	int n; 
 
	setpage(a, 0); 
	ep = a->addr; 
	rp = ep + LEUS(ccb->inrp); 
	wp = ep + LEUS(ccb->inwp); 
	bp = ep + LEUS(ccb->inbase); 
	ep = ep + LEUS(ccb->inlim); 
	for(;;){ 
		n = wp - rp; 
		if(n == 0) 
			break; 
		if(n < 0) 
			n += ep - bp + 1; 
		if(n > sizeof(buf)) 
			n = sizeof(buf); 
		setpage(a, bp - a->addr); 
		e = buf + n; 
		for(p = buf; p < e;){ 
			*p++ = *rp++; 
			if(rp > ep) 
				rp = bp; 
		} 
		qproduce(ac->iq, buf, n); 
	} 
	setpage(a, 0); 
	ccb->inrp = LEUS(rp - a->addr); 
} 
 
/* 
1994/1114    
 *  handle an interrupt 
 */ 
static void 
1994/1114/sys/src/9/pc/devastar.c:1125,11311994/1115/sys/src/9/pc/devastar.c:1244,1249
1994/1114    
	Astar *a = arg; 
	Astarchan *ac; 
	ulong vec, invec, outvec, errvec, mvec, cmdvec; 
	int i; 
 
	USED(ur); 
	lock(&a->pagelock); 
1994/1114/sys/src/9/pc/devastar.c:1137,11631994/1115/sys/src/9/pc/devastar.c:1255,1282
1994/1114    
	errvec = LEUS(xchgw(&a->gcb->errserv, 0)); 
	mvec = LEUS(xchgw(&a->gcb->modemserv, 0)); 
	cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0)); 
1994/1115    
	USED(mvec); 
	USED(cmdvec); 
	USED(errvec); 
1994/1114    
 
	/* reenable interrupts */ 
	a->cmd2 = LEUS(Gintack); 
1994/1115    
	a->gcb->cmd2 = LEUS(Gintack); 
1994/1114    
 
	/* service interrupts */ 
	ac = a->c; 
	for(vec = LEUS(xchgw(&a->gcb->inserv, 0)); vec; vec >>= 1){ 
		if(vec&1){ 
		} 
		setpage(a, 0); 
1994/1115    
	for(vec = invec; vec; vec >>= 1){ 
		if(vec&1) 
			astarinput(ac); 
1994/1114    
		ac++; 
	} 
	ac = a->c; 
	for(vec = LEUS(xchgw(&a->gcb->outserv, 0)); vec; vec >>= 1){ 
1994/1115    
	for(vec = outvec; vec; vec >>= 1){ 
1994/1114    
		if(vec&1) 
			astarkick1(ac); 
		setpage(a, 0); 
		ac++; 
	} 
	ac = a->c; 
	for(vec = LEUS(xchgw(&a->gcb->cmdserv, 0)); vec; vec >>= 1){ 
1994/1115    
	for(vec = cmdvec; vec; vec >>= 1){ 
1994/1114    
		if(vec&1) 
			wakeup(&ac->r); 
		ac++; 
1994/1115/sys/src/9/pc/devastar.c:57,621994/1116/sys/src/9/pc/devastar.c:57,65 (short | long)
1994/1106    
 
1994/1113    
#define APAGE(x) ((x)>>Pageshift) 
 
1994/1116    
#define LOCKPAGE(a, o) if((a)->needpage){ilock(&(a)->pagelock);setpage(a, o);} 
#define UNLOCKPAGE(a) if((a)->needpage)iunlock(&(a)->pagelock) 
 
1994/1107    
/* IRQ codes */ 
static int isairqcode[16] = 
{ 
1994/1115/sys/src/9/pc/devastar.c:242,2511994/1116/sys/src/9/pc/devastar.c:245,254
1994/1111    
	Astarchan	*c;		/* channels */ 
1994/1107    
	int		ramsize;	/* 16k or 256k */ 
1994/1113    
	int		memsize;	/* size of memory currently mapped */ 
1994/1116    
	int		needpage; 
1994/1115    
	GCB		*gcb;		/* global board comm area */ 
1994/1113    
	uchar		*addr;		/* base of memory area */ 
	int		running; 
                 
1994/1106    
}; 
 
/* host per channel info */ 
1994/1115/sys/src/9/pc/devastar.c:258,2631994/1116/sys/src/9/pc/devastar.c:261,267
1994/1113    
	CCB	*ccb;	/* channel control block */ 
1994/1111    
	int	perm; 
1994/1112    
	int	opens; 
1994/1116    
	int	baud; 
1994/1107    
 
1994/1106    
	Queue	*iq; 
	Queue	*oq; 
1994/1115/sys/src/9/pc/devastar.c:282,2871994/1116/sys/src/9/pc/devastar.c:286,292
1994/1114    
static int	astarsetup(Astar*); 
static void	astarintr(Ureg*, void*); 
static void	astarkick(Astarchan*); 
1994/1116    
static void	astarkickin(Astarchan*); 
1994/1114    
static void	enable(Astarchan*); 
static void	disable(Astarchan*); 
1994/1115    
static void	astarctl(Astarchan*, char*); 
1994/1115/sys/src/9/pc/devastar.c:526,5331994/1116/sys/src/9/pc/devastar.c:531,541
1994/1115    
			qunlock(ac); 
1994/1114    
			nexterror(); 
		} 
		if(ac->opens++ == 0) 
1994/1116    
		if(ac->opens++ == 0){ 
1994/1114    
			enable(ac); 
1994/1116    
			qreopen(ac->iq); 
			qreopen(ac->oq); 
		} 
1994/1114    
		qunlock(ac); 
		poperror(); 
		break; 
1994/1115/sys/src/9/pc/devastar.c:598,6081994/1116/sys/src/9/pc/devastar.c:606,615
1994/1114    
		 *  go via tmp to avoid pagefaults while ilock'd 
		 */ 
		tp = tmp; 
		ilock(&a->pagelock); 
		setpage(a, offset); 
1994/1116    
		LOCKPAGE(a, offset); 
1994/1115    
		for(e = tp + i; tp < e;) 
1994/1114    
			*tp++ = *from++; 
		iunlock(&a->pagelock); 
1994/1116    
		UNLOCKPAGE(a); 
1994/1114    
		memmove(to, tmp, i); 
		to += i; 
1994/1115    
 
1994/1115/sys/src/9/pc/devastar.c:645,6511994/1116/sys/src/9/pc/devastar.c:652,658
1994/1115    
	case Qdata: 
		a = astar[BOARD(c->qid.path)]; 
		ac = a->c + CHAN(c->qid.path); 
		return qread(ac->oq, buf, n); 
1994/1116    
		return qread(ac->iq, buf, n); 
1994/1113    
	} 
1994/1112    
 
1994/1113    
	return 0; 
1994/1115/sys/src/9/pc/devastar.c:684,6941994/1116/sys/src/9/pc/devastar.c:691,700
1994/1114    
		 */ 
		memmove(tmp, from, i); 
		tp = tmp; 
		ilock(&a->pagelock); 
		setpage(a, offset); 
1994/1116    
		LOCKPAGE(a, offset); 
1994/1115    
		for(e = tp + i; tp < e;) 
1994/1114    
			*to++ = *tp++; 
		iunlock(&a->pagelock); 
1994/1116    
		UNLOCKPAGE(a); 
1994/1114    
		from += i; 
1994/1115    
 
		offset += i; 
1994/1115/sys/src/9/pc/devastar.c:714,7191994/1116/sys/src/9/pc/devastar.c:720,730
1994/1113    
	/* take board out of download mode and enable IRQ */ 
	outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl); 
	a->memsize = a->ramsize; 
1994/1116    
	setpage(a, 0); 
	if(a->memsize <= Pagesize) 
		a->needpage = 0; 
	else 
		a->needpage = 1; 
1994/1113    
 
	/* wait for control program to signal life */ 
	for(i = 0; i < 21; i++){ 
1994/1115/sys/src/9/pc/devastar.c:727,7371994/1116/sys/src/9/pc/devastar.c:738,747
1994/1113    
	} 
 
1994/1114    
	if(waserror()){ 
		iunlock(&a->pagelock); 
1994/1116    
		UNLOCKPAGE(a); 
1994/1114    
		poperror(); 
	} 
	ilock(&a->pagelock); 
1994/1113    
	setpage(a, 0); 
1994/1116    
	LOCKPAGE(a, 0); 
1994/1113    
	i = LEUS(a->gcb->type); 
	switch(i){ 
	default: 
1994/1115/sys/src/9/pc/devastar.c:761,7671994/1116/sys/src/9/pc/devastar.c:771,778
1994/1113    
			error(Eio); 
1994/1112    
		} 
1994/1113    
	} 
1994/1114    
	iunlock(&a->pagelock); 
1994/1116    
 
	UNLOCKPAGE(a); 
1994/1114    
	poperror(); 
1994/1113    
 
	/* setup the channels */ 
1994/1115/sys/src/9/pc/devastar.c:773,7851994/1116/sys/src/9/pc/devastar.c:784,798
1994/1114    
		ac->a = a; 
		ac->ccb = (CCB*)x; 
1994/1115    
		ac->perm = 0660; 
1994/1114    
		ac->iq = qopen(4*1024, 0, 0, 0); 
1994/1116    
		ac->iq = qopen(4*1024, 0, astarkickin, ac); 
1994/1114    
		ac->oq = qopen(4*1024, 0, astarkick, ac); 
1994/1113    
		x += sz; 
	} 
1994/1115    
 
	/* reenable interrupts */ 
1994/1116    
	/* enable control program interrupt generation */ 
	LOCKPAGE(a, 0); 
1994/1115    
	a->gcb->cmd2 = LEUS(Gintack); 
1994/1116    
	UNLOCKPAGE(a); 
1994/1113    
} 
 
1994/1115    
static void 
1994/1115/sys/src/9/pc/devastar.c:801,8091994/1116/sys/src/9/pc/devastar.c:814,823
1994/1113    
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c & ~ISAnotdl); 
		a->memsize = Pramsize; 
1994/1116    
		a->needpage = 1; 
1994/1113    
 
		/* enable ISA access to first 16k */ 
		outb(a->port+ISActl2, ISAmen); 
1994/1116    
		setpage(a, 0); 
1994/1113    
 
1994/1115    
	} else if(strncmp(cmsg, "sharedmem", 9) == 0){ 
		/* map shared memory */ 
1994/1115/sys/src/9/pc/devastar.c:835,8441994/1116/sys/src/9/pc/devastar.c:849,857
1994/1115    
	Astarchan *ac = arg; 
1994/1114    
	int x; 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
1994/1116    
	LOCKPAGE(ac->a, 0); 
1994/1115    
	x = ac->ccb->cmd; 
1994/1114    
	iunlock(&ac->a->pagelock); 
1994/1116    
	UNLOCKPAGE(ac->a); 
1994/1114    
 
1994/1115    
	return !x; 
1994/1114    
} 
1994/1115/sys/src/9/pc/devastar.c:850,8681994/1116/sys/src/9/pc/devastar.c:863,879
1994/1114    
 
	ccb = ac->ccb; 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
1994/1116    
	LOCKPAGE(ac->a, 0); 
1994/1114    
	ccb->cmd = cmd; 
	iunlock(&ac->a->pagelock); 
1994/1116    
	UNLOCKPAGE(ac->a); 
1994/1114    
 
	/* wait outside of lock */ 
1994/1115    
	tsleep(&ac->r, chancmddone, ac, 1000); 
1994/1114    
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
1994/1116    
	LOCKPAGE(ac->a, 0); 
1994/1115    
	status = ccb->status; 
	cmd = ccb->cmd; 
	iunlock(&ac->a->pagelock); 
1994/1116    
	UNLOCKPAGE(ac->a); 
1994/1115    
	if(cmd){ 
1994/1114    
		print("astar%d cmd didn't terminate\n", ac->a->id); 
		error(Eio); 
1994/1115/sys/src/9/pc/devastar.c:884,8951994/1116/sys/src/9/pc/devastar.c:895,905
1994/1115    
	int n; 
 
1994/1114    
	/* make sure we control RTS, DTR and break */ 
	ilock(&a->pagelock); 
	setpage(a, 0); 
1994/1116    
	LOCKPAGE(a, 0); 
1994/1114    
	n = LEUS(ac->ccb->proto) | Cmctl; 
	ac->ccb->proto = LEUS(n); 
1994/1115    
	ac->ccb->outlow = 64; 
1994/1114    
	iunlock(&a->pagelock); 
1994/1116    
	UNLOCKPAGE(a); 
1994/1115    
	chancmd(ac, Cconfall); 
1994/1114    
 
	astarctl(ac, "b9600"); 
1994/1115/sys/src/9/pc/devastar.c:911,9211994/1116/sys/src/9/pc/devastar.c:921,926
1994/1114    
	astarctl(ac, "d0"); 
	astarctl(ac, "r0"); 
 
	ilock(&ac->a->pagelock); 
	setpage(ac->a, 0); 
1994/1115    
	ac->ccb->intrigger = 0; 
1994/1114    
	iunlock(&ac->a->pagelock); 
                 
	chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); 
} 
 
1994/1115/sys/src/9/pc/devastar.c:943,9541994/1116/sys/src/9/pc/devastar.c:948,959
1994/1114    
	i = atoi(cmd+1); 
1994/1115    
 
1994/1114    
	a = ac->a; 
	ilock(&a->pagelock); 
	setpage(a, 0); 
1994/1116    
	LOCKPAGE(a, 0); 
1994/1115    
 
1994/1113    
	switch(*cmd){ 
	case 'B': 
	case 'b': 
1994/1116    
		/* set baud rate (high rates are special - only 16 bits) */ 
1994/1114    
		switch(i){ 
1994/1113    
		case 76800: 
1994/1114    
			ccb->baud = LEUS(Cb76800); 
1994/1115/sys/src/9/pc/devastar.c:960,9651994/1116/sys/src/9/pc/devastar.c:965,979
1994/1115    
			ccb->baud = LEUS(i); 
1994/1113    
			break; 
		} 
1994/1116    
		ac->baud = i; 
 
		/* set trigger level to about 50  per second */ 
		n = i/500; 
		i = (LEUS(ccb->inlim) - LEUS(ccb->inbase))/2; 
		if(n > i) 
			n = i; 
		ccb->intrigger = LEUS(n); 
 
1994/1113    
		command = Cconfall; 
1994/1112    
		break; 
1994/1113    
	case 'D': 
1994/1115/sys/src/9/pc/devastar.c:993,10071994/1116/sys/src/9/pc/devastar.c:1007,1021
1994/1113    
	case 'M': 
1994/1114    
		/* turn on cts */ 
		n = LEUS(ccb->proto); 
		if(i) 
			n |= Cobeycts; 
		else 
			n &= ~Cobeycts; 
1994/1116    
		if(i){ 
			n |= Cobeycts|Cgenrts; 
			n &= ~Cmctl; 
		} else { 
			n &= ~(Cobeycts|Cgenrts); 
			n |= Cmctl; 
		} 
1994/1114    
		ccb->proto = LEUS(n); 
 
		/* set fifo sizes */ 
		ccb->intrigger = 8; 
                 
1994/1113    
		command = Cconfall; 
		break; 
	case 'n': 
1994/1115/sys/src/9/pc/devastar.c:1031,10421994/1116/sys/src/9/pc/devastar.c:1045,1055
1994/1114    
			i = 250; 
		n = LEUS(ccb->mctl) | Cbreakctl; 
		ccb->mctl = LEUS(n); 
		iunlock(&a->pagelock); 
1994/1116    
		UNLOCKPAGE(a); 
1994/1114    
 
		tsleep(&ac->r, return0, 0, i); 
 
		ilock(&a->pagelock); 
		setpage(a, 0); 
1994/1116    
		LOCKPAGE(a, 0); 
1994/1114    
		n &= ~Cbreakctl; 
		ccb->mctl = LEUS(n); 
1994/1113    
		break; 
1994/1115/sys/src/9/pc/devastar.c:1065,10711994/1116/sys/src/9/pc/devastar.c:1078,1084
1994/1113    
		command = Cconfall; 
		break; 
1994/1111    
	} 
1994/1114    
	iunlock(&a->pagelock); 
1994/1116    
	UNLOCKPAGE(a); 
1994/1114    
 
	if(command) 
		chancmd(ac, command); 
1994/1115/sys/src/9/pc/devastar.c:1160,11661994/1116/sys/src/9/pc/devastar.c:1173,1180
1994/1115    
	uchar *rp, *wp, *bp, *ep, *p, *e; 
1994/1114    
	int n; 
 
1994/1115    
	setpage(a, 0); 
1994/1116    
	if(a->needpage) 
		setpage(a, 0); 
1994/1115    
	ep = a->addr; 
	rp = ep + LEUS(ccb->outrp); 
	wp = ep + LEUS(ccb->outwp); 
1994/1115/sys/src/9/pc/devastar.c:1177,11831994/1116/sys/src/9/pc/devastar.c:1191,1198
1994/1115    
		n = qconsume(ac->oq, buf, n); 
		if(n <= 0) 
			break; 
		setpage(a, bp - a->addr); 
1994/1116    
		if(a->needpage) 
			setpage(a, bp - a->addr); 
1994/1115    
		e = buf + n; 
		for(p = buf; p < e;){ 
			*wp++ = *p++; 
1994/1115/sys/src/9/pc/devastar.c:1184,11901994/1116/sys/src/9/pc/devastar.c:1199,1206
1994/1115    
			if(wp > ep) 
				wp = bp; 
		} 
1994/1114    
		setpage(a, 0); 
1994/1116    
		if(a->needpage) 
			setpage(a, 0); 
1994/1115    
		ccb->outwp = LEUS(wp - a->addr); 
1994/1114    
	} 
} 
1994/1115/sys/src/9/pc/devastar.c:1208,12141994/1116/sys/src/9/pc/devastar.c:1224,1231
1994/1115    
	uchar *rp, *wp, *bp, *ep, *p, *e; 
	int n; 
 
	setpage(a, 0); 
1994/1116    
	if(a->needpage) 
		setpage(a, 0); 
1994/1115    
	ep = a->addr; 
	rp = ep + LEUS(ccb->inrp); 
	wp = ep + LEUS(ccb->inwp); 
1994/1115/sys/src/9/pc/devastar.c:1222,12281994/1116/sys/src/9/pc/devastar.c:1239,1246
1994/1115    
			n += ep - bp + 1; 
		if(n > sizeof(buf)) 
			n = sizeof(buf); 
		setpage(a, bp - a->addr); 
1994/1116    
		if(a->needpage) 
			setpage(a, bp - a->addr); 
1994/1115    
		e = buf + n; 
		for(p = buf; p < e;){ 
			*p++ = *rp++; 
1994/1115/sys/src/9/pc/devastar.c:1229,12411994/1116/sys/src/9/pc/devastar.c:1247,1274
1994/1115    
			if(rp > ep) 
				rp = bp; 
		} 
		qproduce(ac->iq, buf, n); 
1994/1116    
		if(qroduce(ac->iq, buf, n) < 0) 
			break;	/* flow controlled */ 
		if(a->needpage) 
			setpage(a, 0); 
		ccb->inrp = LEUS(rp - a->addr); 
1994/1115    
	} 
	setpage(a, 0); 
	ccb->inrp = LEUS(rp - a->addr); 
1994/1116    
	if(a->needpage) 
		setpage(a, 0); 
1994/1115    
} 
 
/* 
1994/1116    
 *  get flow controlled input going again 
 */ 
static void 
astarkick(Astarchan *ac) 
{ 
	ilock(&ac->a->pagelock); 
	astarinput(ac); 
	iunlock(&ac->a->pagelock); 
} 
 
/* 
1994/1114    
 *  handle an interrupt 
 */ 
static void 
1994/1115/sys/src/9/pc/devastar.c:1247,12531994/1116/sys/src/9/pc/devastar.c:1280,1287
1994/1114    
 
	USED(ur); 
	lock(&a->pagelock); 
	setpage(a, 0); 
1994/1116    
	if(a->needpage) 
		setpage(a, 0); 
1994/1114    
 
	/* get causes */ 
	invec = LEUS(xchgw(&a->gcb->inserv, 0)); 
1994/1116/sys/src/9/pc/devastar.c:344,3601994/1117/sys/src/9/pc/devastar.c:344,360 (short | long)
1994/1111    
			t = i%3; 
			switch(t){ 
			case 0: 
				sprint(db->name, "eia%d%2.2d", dev, ch); 
1994/1117    
				sprint(db->name, "eia%d%2.2d", dev, ch+1); 
1994/1111    
				db->mode = astar[dev]->c[ch].perm; 
1994/1115    
				db->qid.path = QID(dev, ch, Qdata); 
1994/1111    
				break; 
			case 1: 
				sprint(db->name, "eia%d%2.2dctl", dev, ch); 
1994/1117    
				sprint(db->name, "eia%d%2.2dctl", dev, ch+1); 
1994/1111    
				db->mode = astar[dev]->c[ch].perm; 
1994/1115    
				db->qid.path = QID(dev, ch, Qctl); 
1994/1111    
				break; 
			case 2: 
				sprint(db->name, "eia%d%2.2dstat", dev, ch); 
1994/1117    
				sprint(db->name, "eia%d%2.2dstat", dev, ch+1); 
1994/1111    
				db->mode = 0444; 
1994/1115    
				db->qid.path = QID(dev, ch, Qstat); 
1994/1111    
				break; 
1994/1116/sys/src/9/pc/devastar.c:918,9261994/1117/sys/src/9/pc/devastar.c:918,932
1994/1114    
static void 
disable(Astarchan *ac) 
{ 
1994/1117    
	int n; 
 
1994/1114    
	astarctl(ac, "d0"); 
	astarctl(ac, "r0"); 
 
1994/1117    
	LOCKPAGE(ac->a, 0); 
	n = LEUS(ac->ccb->proto) | Cmctl; 
	ac->ccb->proto = LEUS(n); 
	UNLOCKPAGE(ac->a); 
1994/1114    
	chancmd(ac, Crcvdis|Cxmtdis|Cflushin|Cflushout|Cconfall); 
} 
 
1994/1116/sys/src/9/pc/devastar.c:1165,11711994/1117/sys/src/9/pc/devastar.c:1171,1177
1994/1114    
 *  get output going 
 */ 
static void 
astarkick1(Astarchan *ac) 
1994/1117    
astaroutput(Astarchan *ac) 
1994/1114    
{ 
	Astar *a = ac->a; 
1994/1115    
	CCB *ccb = ac->ccb; 
1994/1116/sys/src/9/pc/devastar.c:1208,12141994/1117/sys/src/9/pc/devastar.c:1214,1220
1994/1114    
astarkick(Astarchan *ac) 
{ 
	ilock(&ac->a->pagelock); 
1994/1115    
	astarkick1(ac); 
1994/1117    
	astaroutput(ac); 
1994/1114    
	iunlock(&ac->a->pagelock); 
} 
 
1994/1116/sys/src/9/pc/devastar.c:1247,12531994/1117/sys/src/9/pc/devastar.c:1253,1259
1994/1115    
			if(rp > ep) 
				rp = bp; 
		} 
1994/1116    
		if(qroduce(ac->iq, buf, n) < 0) 
1994/1117    
		if(qproduce(ac->iq, buf, n) < 0) 
1994/1116    
			break;	/* flow controlled */ 
		if(a->needpage) 
			setpage(a, 0); 
1994/1116/sys/src/9/pc/devastar.c:1261,12671994/1117/sys/src/9/pc/devastar.c:1267,1273
1994/1116    
 *  get flow controlled input going again 
 */ 
static void 
astarkick(Astarchan *ac) 
1994/1117    
astarkickin(Astarchan *ac) 
1994/1116    
{ 
	ilock(&ac->a->pagelock); 
	astarinput(ac); 
1994/1116/sys/src/9/pc/devastar.c:1306,13121994/1117/sys/src/9/pc/devastar.c:1312,1318
1994/1114    
	ac = a->c; 
1994/1115    
	for(vec = outvec; vec; vec >>= 1){ 
1994/1114    
		if(vec&1) 
			astarkick1(ac); 
1994/1117    
			astaroutput(ac); 
1994/1114    
		ac++; 
	} 
	ac = a->c; 
1994/1117/sys/src/9/pc/devastar.c:344,3601994/1118/sys/src/9/pc/devastar.c:344,360 (short | long)
1994/1111    
			t = i%3; 
			switch(t){ 
			case 0: 
1994/1117    
				sprint(db->name, "eia%d%2.2d", dev, ch+1); 
1994/1118    
				sprint(db->name, "eia%d%2.2d", dev, ch); 
1994/1111    
				db->mode = astar[dev]->c[ch].perm; 
1994/1115    
				db->qid.path = QID(dev, ch, Qdata); 
1994/1111    
				break; 
			case 1: 
1994/1117    
				sprint(db->name, "eia%d%2.2dctl", dev, ch+1); 
1994/1118    
				sprint(db->name, "eia%d%2.2dctl", dev, ch); 
1994/1111    
				db->mode = astar[dev]->c[ch].perm; 
1994/1115    
				db->qid.path = QID(dev, ch, Qctl); 
1994/1111    
				break; 
			case 2: 
1994/1117    
				sprint(db->name, "eia%d%2.2dstat", dev, ch+1); 
1994/1118    
				sprint(db->name, "eia%d%2.2dstat", dev, ch); 
1994/1111    
				db->mode = 0444; 
1994/1115    
				db->qid.path = QID(dev, ch, Qstat); 
1994/1111    
				break; 
1994/1117/sys/src/9/pc/devastar.c:391,3971994/1118/sys/src/9/pc/devastar.c:391,397
1994/1112    
		if(isaconfig("serial", i, a) == 0){ 
1994/1107    
			xfree(a); 
1994/1109    
			astar[nastar] = 0; 
1994/1106    
			break; 
1994/1118    
			continue; 
1994/1106    
		} 
 
1994/1107    
		if(strcmp(a->type, "a100i") == 0 || strcmp(a->type,"A100I") == 0) 
1994/1117/sys/src/9/pc/devastar.c:398,4161994/1118/sys/src/9/pc/devastar.c:398,414
1994/1107    
			a->ramsize = 16*1024; 
		else if(strcmp(a->type, "a200i") == 0 || strcmp(a->type,"A200I") == 0) 
			a->ramsize = 256*1024; 
		else 
1994/1118    
		else { 
			xfree(a); 
			astar[nastar] = 0; 
1994/1107    
			continue; 
1994/1118    
		} 
1994/1108    
 
1994/1115    
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c | ISAnotdl); 
		a->memsize = a->ramsize; 
                 
1994/1107    
		if(a->mem == 0) 
1994/1108    
			a->mem = 0xD4000; 
1994/1107    
		if(a->irq == 0) 
			a->irq = 15; 
		a->id = i; 
1994/1113    
		a->page = -1; 
1994/1107    
 
		if(astarsetup(a) < 0){ 
			xfree(a); 
1994/1117/sys/src/9/pc/devastar.c:421,4271994/1118/sys/src/9/pc/devastar.c:419,431
1994/1115    
			a->addr, a->irq); 
1994/1109    
		nastar++; 
1994/1114    
 
		setvec(Int0vec + a->irq, astarintr, a); 
1994/1118    
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c & ~ISAnotdl); 
		a->memsize = Pramsize; 
 
		c = inb(a->port+ISActl2); 
		outb(a->port+ISActl2, c & ~ISAmen); 
		a->page = -1; 
1994/1107    
	} 
} 
 
1994/1117/sys/src/9/pc/devastar.c:790,7951994/1118/sys/src/9/pc/devastar.c:794,800
1994/1113    
	} 
1994/1115    
 
1994/1116    
	/* enable control program interrupt generation */ 
1994/1118    
	setvec(Int0vec + a->irq, astarintr, a); 
1994/1116    
	LOCKPAGE(a, 0); 
1994/1115    
	a->gcb->cmd2 = LEUS(Gintack); 
1994/1116    
	UNLOCKPAGE(a); 
1994/1118/sys/src/9/pc/devastar.c:415,4311994/1119/sys/src/9/pc/devastar.c:415,435 (short | long)
1994/1109    
			astar[nastar] = 0; 
1994/1107    
			continue; 
		} 
1994/1115    
		print("serial%d avanstar port %d addr %lux irq %d\n", i, a->port, 
1994/1119    
		print("serial%d avanstar port 0x%lux addr %lux irq %d\n", i, a->port, 
1994/1115    
			a->addr, a->irq); 
1994/1109    
		nastar++; 
1994/1114    
 
1994/1119    
		/* disable ISA memory response */ 
		c = inb(a->port+ISActl2); 
		outb(a->port+ISActl2, c & ~ISAmen); 
 
		/* download mode to turn off cpu */ 
1994/1118    
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c & ~ISAnotdl); 
		a->memsize = Pramsize; 
                 
		c = inb(a->port+ISActl2); 
		outb(a->port+ISActl2, c & ~ISAmen); 
		a->page = -1; 
1994/1119    
 
		setvec(Int0vec + a->irq, astarintr, a); 
1994/1107    
	} 
} 
 
1994/1118/sys/src/9/pc/devastar.c:722,7271994/1119/sys/src/9/pc/devastar.c:726,732
1994/1113    
		error(Eio); 
 
	/* take board out of download mode and enable IRQ */ 
1994/1119    
print("out of download\n"); 
1994/1113    
	outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl); 
	a->memsize = a->ramsize; 
1994/1116    
	setpage(a, 0); 
1994/1118/sys/src/9/pc/devastar.c:731,7361994/1119/sys/src/9/pc/devastar.c:736,742
1994/1116    
		a->needpage = 1; 
1994/1113    
 
	/* wait for control program to signal life */ 
1994/1119    
print("waiting for cp\n"); 
1994/1113    
	for(i = 0; i < 21; i++){ 
		if(inb(a->port+ISActl1) & ISApr) 
			break; 
1994/1118/sys/src/9/pc/devastar.c:745,7501994/1119/sys/src/9/pc/devastar.c:751,757
1994/1116    
		UNLOCKPAGE(a); 
1994/1114    
		poperror(); 
	} 
1994/1119    
 
1994/1116    
	LOCKPAGE(a, 0); 
1994/1113    
	i = LEUS(a->gcb->type); 
	switch(i){ 
1994/1118/sys/src/9/pc/devastar.c:776,7831994/1119/sys/src/9/pc/devastar.c:783,794
1994/1112    
		} 
1994/1113    
	} 
1994/1116    
 
1994/1119    
	/* enable control program interrupt generation */ 
	a->gcb->cmd2 = LEUS(Gintack); 
 
1994/1116    
	UNLOCKPAGE(a); 
1994/1114    
	poperror(); 
1994/1119    
print("setting up channels\n"); 
1994/1113    
 
	/* setup the channels */ 
	a->running = 1; 
1994/1118/sys/src/9/pc/devastar.c:792,8031994/1119/sys/src/9/pc/devastar.c:803,808
1994/1114    
		ac->oq = qopen(4*1024, 0, astarkick, ac); 
1994/1113    
		x += sz; 
	} 
1994/1115    
                 
1994/1116    
	/* enable control program interrupt generation */ 
1994/1118    
	setvec(Int0vec + a->irq, astarintr, a); 
1994/1116    
	LOCKPAGE(a, 0); 
1994/1115    
	a->gcb->cmd2 = LEUS(Gintack); 
1994/1116    
	UNLOCKPAGE(a); 
1994/1113    
} 
 
1994/1115    
static void 
1994/1118/sys/src/9/pc/devastar.c:1293,12981994/1119/sys/src/9/pc/devastar.c:1298,1307
1994/1114    
	lock(&a->pagelock); 
1994/1116    
	if(a->needpage) 
		setpage(a, 0); 
1994/1119    
	if(a->running == 0){ 
		print("astar interrupt but cp not running\n"); 
		return; 
	} 
1994/1114    
 
	/* get causes */ 
	invec = LEUS(xchgw(&a->gcb->inserv, 0)); 
1994/1119/sys/src/9/pc/devastar.c:43,491994/1120/sys/src/9/pc/devastar.c:43,49 (short | long)
1994/1106    
	 ISA186ien=	 1<<7,		/*  I186 irq enable bit state */ 
	 ISA186idata=	 1<<6,		/*  I186 irq data bit state */ 
1994/1107    
	 ISAmen=	 1<<4,		/*  enable memory to respond to ISA cycles */ 
	 ISAmbank=	 0,		/*  shift for 4 bit memory bank */ 
1994/1120    
	 ISAmbank=	 0xf<<0,		/*  shift for 4 bit memory bank */ 
1994/1107    
	ISAmaddr=	3,		/* bits 14-19 of the boards mem address */ 
1994/1106    
	ISAstat1=	4,		/* board status (1 bit per channel) */ 
	ISAstat2=	5,		/* board status (1 bit per channel) */ 
1994/1119/sys/src/9/pc/devastar.c:297,3081994/1120/sys/src/9/pc/devastar.c:297,310
1994/1114    
static void 
1994/1113    
setpage(Astar *a, ulong offset) 
{ 
	int i; 
1994/1120    
	int i, c; 
1994/1113    
 
	i = APAGE(offset); 
	if(i == a->page) 
		return; 
	outb(a->port+ISActl2, ISAmen|i); 
1994/1120    
 
	c = inb(a->port+ISActl2) & ~ISAmbank; 
	outb(a->port+ISActl2, ISAmen|i|c); 
1994/1113    
	a->page = i; 
} 
 
1994/1119/sys/src/9/pc/devastar.c:394,3991994/1120/sys/src/9/pc/devastar.c:396,402
1994/1118    
			continue; 
1994/1106    
		} 
 
1994/1120    
		/* check all possible names */ 
1994/1107    
		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) 
1994/1119/sys/src/9/pc/devastar.c:404,4091994/1120/sys/src/9/pc/devastar.c:407,413
1994/1107    
			continue; 
1994/1118    
		} 
1994/1108    
 
1994/1120    
		/* defaults */ 
1994/1107    
		if(a->mem == 0) 
1994/1108    
			a->mem = 0xD4000; 
1994/1107    
		if(a->irq == 0) 
1994/1119/sys/src/9/pc/devastar.c:415,4351994/1120/sys/src/9/pc/devastar.c:419,427
1994/1109    
			astar[nastar] = 0; 
1994/1107    
			continue; 
		} 
1994/1119    
		print("serial%d avanstar port 0x%lux addr %lux irq %d\n", i, a->port, 
1994/1120    
		print("serial%d avanstar port 0x%lux addr %lux irq %d\n", a->id, a->port, 
1994/1115    
			a->addr, a->irq); 
1994/1109    
		nastar++; 
1994/1114    
                 
1994/1119    
		/* disable ISA memory response */ 
		c = inb(a->port+ISActl2); 
		outb(a->port+ISActl2, c & ~ISAmen); 
                 
		/* download mode to turn off cpu */ 
1994/1118    
		c = inb(a->port+ISActl1); 
		outb(a->port+ISActl1, c & ~ISAnotdl); 
		a->memsize = Pramsize; 
		a->page = -1; 
1994/1119    
                 
		setvec(Int0vec + a->irq, astarintr, a); 
1994/1107    
	} 
} 
 
1994/1119/sys/src/9/pc/devastar.c:453,4591994/1120/sys/src/9/pc/devastar.c:445,451
1994/1109    
static int 
1994/1107    
astarsetup(Astar *a) 
{ 
1994/1112    
	int i, found; 
1994/1120    
	int i, c, found; 
1994/1107    
 
	/* see if the card exists */ 
	found = 0; 
1994/1119/sys/src/9/pc/devastar.c:473,4891994/1120/sys/src/9/pc/devastar.c:465,494
1994/1107    
		return -1; 
	} 
 
	/* set memory address */ 
1994/1113    
	outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc); 
1994/1115    
	a->gcb = (GCB*)(KZERO | a->mem); 
	a->addr = (uchar*)(KZERO | a->mem); 
1994/1107    
                 
	/* set interrupt level */ 
1994/1120    
	/* check interrupt level */ 
1994/1112    
	if(isairqcode[a->irq] == -1){ 
1994/1107    
		print("Avanstar %d bad irq %d\n", a->id, a->irq); 
		return -1; 
	} 
1994/1111    
 
1994/1120    
	/* set ISA memory address */ 
	outb(a->port+ISAmaddr, (a->mem>>12) & 0xfc); 
	a->gcb = (GCB*)(KZERO | a->mem); 
	a->addr = (uchar*)(KZERO | a->mem); 
 
	/* set up interrupt level, reset processor, leave interrupts off */ 
	c = inb(a->port+ISActl1); 
	c &= ~(ISAnotdl|ISAien|ISAirq); 
	c |= isairqcode[a->irq]; 
	outb(a->port+ISActl1, c); 
	setvec(Int0vec + a->irq, astarintr, a); 
 
	/* disable ISA memory response */ 
	c = inb(a->port+ISActl2); 
	outb(a->port+ISActl2, c & ~ISAmen); 
	a->memsize = 0; 
	a->page = -1; 
 
1994/1111    
	return 0; 
} 
 
1994/1119/sys/src/9/pc/devastar.c:717,7231994/1120/sys/src/9/pc/devastar.c:722,728
1994/1113    
static void 
startcp(Astar *a) 
{ 
	int n, i, sz; 
1994/1120    
	int c, n, i, sz; 
1994/1113    
	uchar *x; 
	CCB *ccb; 
1994/1114    
	Astarchan *ac; 
1994/1119/sys/src/9/pc/devastar.c:727,7351994/1120/sys/src/9/pc/devastar.c:732,740
1994/1113    
 
	/* take board out of download mode and enable IRQ */ 
1994/1119    
print("out of download\n"); 
1994/1113    
	outb(a->port+ISActl1, ISAien|isairqcode[a->irq]|ISAnotdl); 
1994/1120    
	c = inb(a->port+ISActl1); 
	outb(a->port+ISActl1, c|ISAien|ISAnotdl); 
1994/1113    
	a->memsize = a->ramsize; 
1994/1116    
	setpage(a, 0); 
	if(a->memsize <= Pagesize) 
		a->needpage = 0; 
	else 
1994/1119/sys/src/9/pc/devastar.c:827,8321994/1120/sys/src/9/pc/devastar.c:832,838
1994/1116    
		a->needpage = 1; 
1994/1113    
 
		/* enable ISA access to first 16k */ 
1994/1120    
		a->page = -1; 
1994/1116    
		setpage(a, 0); 
1994/1113    
 
1994/1115    
	} else if(strncmp(cmsg, "sharedmem", 9) == 0){ 
1994/1119/sys/src/9/pc/devastar.c:836,8421994/1120/sys/src/9/pc/devastar.c:842,849
1994/1115    
		a->memsize = a->ramsize; 
 
		/* enable ISA access to first 16k */ 
		outb(a->port+ISActl2, ISAmen); 
1994/1120    
		a->page = -1; 
		setpage(a, 0); 
1994/1115    
 
1994/1113    
	} else if(strncmp(cmsg, "run", 3) == 0){ 
1994/1115    
		/* start up downloaded program */ 
1994/1120/sys/src/9/pc/devastar.c:43,491994/1121/sys/src/9/pc/devastar.c:43,49 (short | long)
1994/1106    
	 ISA186ien=	 1<<7,		/*  I186 irq enable bit state */ 
	 ISA186idata=	 1<<6,		/*  I186 irq data bit state */ 
1994/1107    
	 ISAmen=	 1<<4,		/*  enable memory to respond to ISA cycles */ 
1994/1120    
	 ISAmbank=	 0xf<<0,		/*  shift for 4 bit memory bank */ 
1994/1121    
	 ISAmbank=	 0xf<<0,	/*  shift for 4 bit memory bank */ 
1994/1107    
	ISAmaddr=	3,		/* bits 14-19 of the boards mem address */ 
1994/1106    
	ISAstat1=	4,		/* board status (1 bit per channel) */ 
	ISAstat2=	5,		/* board status (1 bit per channel) */ 
1994/1120/sys/src/9/pc/devastar.c:254,2671994/1121/sys/src/9/pc/devastar.c:254,270
1994/1106    
/* host per channel info */ 
struct Astarchan 
{ 
1994/1114    
	QLock;		/* lock for rendez */ 
	Rendez	r;	/* waiting for command completion */ 
1994/1121    
	QLock;			/* lock for rendez */ 
	Rendez	r;		/* waiting for command completion */ 
1994/1106    
 
1994/1109    
	Astar	*a;	/* controller */ 
1994/1113    
	CCB	*ccb;	/* channel control block */ 
1994/1121    
	Astar	*a;		/* controller */ 
	CCB	*ccb;		/* channel control block */ 
1994/1111    
	int	perm; 
1994/1112    
	int	opens; 
1994/1116    
	int	baud; 
1994/1121    
	int	baud;		/* baud rate */ 
	int	framing;	/* framing errors */ 
	int	overrun;	/* overruns */ 
	int	dtr;		/* non-zero means dtr on */ 
1994/1107    
 
1994/1106    
	Queue	*iq; 
	Queue	*oq; 
1994/1120/sys/src/9/pc/devastar.c:297,3101994/1121/sys/src/9/pc/devastar.c:300,312
1994/1114    
static void 
1994/1113    
setpage(Astar *a, ulong offset) 
{ 
1994/1120    
	int i, c; 
1994/1121    
	int i; 
1994/1113    
 
	i = APAGE(offset); 
	if(i == a->page) 
		return; 
1994/1120    
 
	c = inb(a->port+ISActl2) & ~ISAmbank; 
	outb(a->port+ISActl2, ISAmen|i|c); 
1994/1121    
	outb(a->port+ISActl2, ISAmen|i); 
1994/1113    
	a->page = i; 
} 
 
1994/1120/sys/src/9/pc/devastar.c:346,3621994/1121/sys/src/9/pc/devastar.c:348,364
1994/1111    
			t = i%3; 
			switch(t){ 
			case 0: 
1994/1118    
				sprint(db->name, "eia%d%2.2d", dev, ch); 
1994/1121    
				sprint(db->name, "eia%d%2.2d", astar[dev]->id, ch); 
1994/1111    
				db->mode = astar[dev]->c[ch].perm; 
1994/1115    
				db->qid.path = QID(dev, ch, Qdata); 
1994/1111    
				break; 
			case 1: 
1994/1118    
				sprint(db->name, "eia%d%2.2dctl", dev, ch); 
1994/1121    
				sprint(db->name, "eia%d%2.2dctl", astar[dev]->id, ch); 
1994/1111    
				db->mode = astar[dev]->c[ch].perm; 
1994/1115    
				db->qid.path = QID(dev, ch, Qctl); 
1994/1111    
				break; 
			case 2: 
1994/1118    
				sprint(db->name, "eia%d%2.2dstat", dev, ch); 
1994/1121    
				sprint(db->name, "eia%d%2.2dstat", astar[dev]->id, ch); 
1994/1111    
				db->mode = 0444; 
1994/1115    
				db->qid.path = QID(dev, ch, Qstat); 
1994/1111    
				break; 
1994/1120/sys/src/9/pc/devastar.c:385,3911994/1121/sys/src/9/pc/devastar.c:387,393
1994/1106    
void 
1994/1107    
astarreset(void) 
1994/1106    
{ 
1994/1115    
	int i, c; 
1994/1121    
	int i; 
1994/1107    
	Astar *a; 
1994/1106    
 
	for(i = 0; i < Maxcard; i++){ 
1994/1120/sys/src/9/pc/devastar.c:421,4261994/1121/sys/src/9/pc/devastar.c:423,431
1994/1107    
		} 
1994/1120    
		print("serial%d avanstar port 0x%lux addr %lux irq %d\n", a->id, a->port, 
1994/1115    
			a->addr, a->irq); 
1994/1121    
		print("\tctl1 %ux ctl2 %ux maddr %ux stat1 %ux stat2 %ux\n", inb(a->port+ISActl1), 
			inb(a->port+ISActl2), inb(a->port+ISAmaddr), inb(a->port+ISAstat1), 
			inb(a->port+ISAstat2)); 
1994/1109    
		nastar++; 
1994/1107    
	} 
} 
1994/1120/sys/src/9/pc/devastar.c:445,4511994/1121/sys/src/9/pc/devastar.c:450,456
1994/1109    
static int 
1994/1107    
astarsetup(Astar *a) 
{ 
1994/1120    
	int i, c, found; 
1994/1121    
	int i, found; 
1994/1107    
 
	/* see if the card exists */ 
	found = 0; 
1994/1120/sys/src/9/pc/devastar.c:476,4941994/1121/sys/src/9/pc/devastar.c:481,494
1994/1120    
	a->gcb = (GCB*)(KZERO | a->mem); 
	a->addr = (uchar*)(KZERO | a->mem); 
 
	/* set up interrupt level, reset processor, leave interrupts off */ 
	c = inb(a->port+ISActl1); 
	c &= ~(ISAnotdl|ISAien|ISAirq); 
	c |= isairqcode[a->irq]; 
	outb(a->port+ISActl1, c); 
	setvec(Int0vec + a->irq, astarintr, a); 
                 
	/* disable ISA memory response */ 
	c = inb(a->port+ISActl2); 
	outb(a->port+ISActl2, c & ~ISAmen); 
1994/1121    
	outb(a->port+ISActl2, 0); 
1994/1120    
	a->memsize = 0; 
	a->page = -1; 
 
1994/1121    
	/* reset processor */ 
	outb(a->port+ISActl1, 0); 
 
1994/1111    
	return 0; 
} 
 
1994/1120/sys/src/9/pc/devastar.c:648,6531994/1121/sys/src/9/pc/devastar.c:648,682
1994/1113    
	return readstr(offset, buf, n, s); 
} 
 
1994/1121    
static long 
statread(Astarchan *ac, void *buf, long n, ulong offset) 
{ 
	char s[128]; 
	int mstat, bstat; 
 
	LOCKPAGE(ac->a, 0); 
	mstat = LEUS(ac->ccb->mstat); 
	bstat = LEUS(ac->ccb->bstat); 
	UNLOCKPAGE(ac->a); 
 
	/* CCB.mstat fields */ 
	sprint(s, "ferr %d oerr %d baud %d", ac->framing, ac->overrun, ac->baud); 
	if(mstat & Cctsstat) 
		strcat(s, " cts"); 
	if(mstat & Cdsrstat) 
		strcat(s, " dsr"); 
	if(mstat & Cristat) 
		strcat(s, " ring"); 
	if(mstat & Cdcdstat) 
		strcat(s, " dcd"); 
	if(ac->opens) 
		strcat(s, " dtr"); 
	if((bstat & Crbrts) == 0) 
		strcat(s, " rts"); 
 
	return readstr(offset, buf, n, s); 
} 
 
1994/1111    
long 
astarread(Chan *c, void *buf, long n, ulong offset) 
{ 
1994/1120/sys/src/9/pc/devastar.c:658,6631994/1121/sys/src/9/pc/devastar.c:687,695
1994/1111    
		return devdirread(c, buf, n, 0, 0, astargen); 
 
	switch(TYPE(c->qid.path)){ 
1994/1121    
	case Qstat: 
		a = astar[BOARD(c->qid.path)]; 
		return statread(a->c + CHAN(c->qid.path), buf, n, offset); 
1994/1111    
	case Qmem: 
1994/1113    
		return memread(astar[BOARD(c->qid.path)], buf, n, offset); 
	case Qbctl: 
1994/1120/sys/src/9/pc/devastar.c:731,7371994/1121/sys/src/9/pc/devastar.c:763,768
1994/1113    
		error(Eio); 
 
	/* take board out of download mode and enable IRQ */ 
1994/1119    
print("out of download\n"); 
1994/1120    
	c = inb(a->port+ISActl1); 
	outb(a->port+ISActl1, c|ISAien|ISAnotdl); 
1994/1113    
	a->memsize = a->ramsize; 
1994/1120/sys/src/9/pc/devastar.c:739,7471994/1121/sys/src/9/pc/devastar.c:770,779
1994/1116    
		a->needpage = 0; 
	else 
		a->needpage = 1; 
1994/1121    
	a->page = -1; 
	setpage(a, 0); 
1994/1113    
 
	/* wait for control program to signal life */ 
1994/1119    
print("waiting for cp\n"); 
1994/1113    
	for(i = 0; i < 21; i++){ 
		if(inb(a->port+ISActl1) & ISApr) 
			break; 
1994/1120/sys/src/9/pc/devastar.c:788,8041994/1121/sys/src/9/pc/devastar.c:820,832
1994/1112    
		} 
1994/1113    
	} 
1994/1116    
 
1994/1119    
	/* enable control program interrupt generation */ 
	a->gcb->cmd2 = LEUS(Gintack); 
                 
1994/1116    
	UNLOCKPAGE(a); 
1994/1114    
	poperror(); 
1994/1119    
print("setting up channels\n"); 
1994/1113    
 
	/* setup the channels */ 
	a->running = 1; 
	a->nchan = i; 
	a->c = xalloc(a->nchan * sizeof(Astarchan)); 
1994/1121    
	a->c = smalloc(a->nchan * sizeof(Astarchan)); 
1994/1113    
	for(i = 0; i < a->nchan; i++){ 
1994/1114    
		ac = &a->c[i]; 
		ac->a = a; 
1994/1120/sys/src/9/pc/devastar.c:808,8131994/1121/sys/src/9/pc/devastar.c:836,854
1994/1114    
		ac->oq = qopen(4*1024, 0, astarkick, ac); 
1994/1113    
		x += sz; 
	} 
1994/1121    
 
	/* set up interrupt level, enable interrupts */ 
	c = inb(a->port+ISActl1); 
	c &= ~ISAirq; 
	c |= ISAien|isairqcode[a->irq]; 
	outb(a->port+ISActl1, c); 
 
	setvec(Int0vec + a->irq, astarintr, a); 
 
	/* enable control program interrupt generation */ 
	LOCKPAGE(a, 0); 
	a->gcb->cmd2 = LEUS(Gintack); 
	UNLOCKPAGE(a); 
1994/1113    
} 
 
1994/1115    
static void 
1994/1120/sys/src/9/pc/devastar.c:1006,10111994/1121/sys/src/9/pc/devastar.c:1047,1053
1994/1114    
			 n |= Cdtrctl; 
		else 
			 n &= ~Cdtrctl; 
1994/1121    
		ac->dtr = n; 
1994/1114    
		ccb->mctl = LEUS(n); 
1994/1112    
		break; 
1994/1113    
	case 'f': 
1994/1120/sys/src/9/pc/devastar.c:1300,13141994/1121/sys/src/9/pc/devastar.c:1342,1356
1994/1114    
	Astar *a = arg; 
	Astarchan *ac; 
	ulong vec, invec, outvec, errvec, mvec, cmdvec; 
1994/1121    
	int c; 
1994/1114    
 
	USED(ur); 
1994/1121    
	if(a->running == 0) 
		panic("astar interrupt but cp not running\n"); 
 
1994/1114    
	lock(&a->pagelock); 
1994/1116    
	if(a->needpage) 
		setpage(a, 0); 
1994/1119    
	if(a->running == 0){ 
		print("astar interrupt but cp not running\n"); 
		return; 
	} 
1994/1114    
 
	/* get causes */ 
	invec = LEUS(xchgw(&a->gcb->inserv, 0)); 
1994/1120/sys/src/9/pc/devastar.c:1318,13241994/1121/sys/src/9/pc/devastar.c:1360,1365
1994/1114    
	cmdvec = LEUS(xchgw(&a->gcb->cmdserv, 0)); 
1994/1115    
	USED(mvec); 
	USED(cmdvec); 
	USED(errvec); 
1994/1114    
 
	/* reenable interrupts */ 
1994/1115    
	a->gcb->cmd2 = LEUS(Gintack); 
1994/1120/sys/src/9/pc/devastar.c:1340,13451994/1121/sys/src/9/pc/devastar.c:1381,1395
1994/1115    
	for(vec = cmdvec; vec; vec >>= 1){ 
1994/1114    
		if(vec&1) 
			wakeup(&ac->r); 
1994/1121    
		ac++; 
	} 
	ac = a->c; 
	for(vec = errvec; vec; vec >>= 1){ 
		c = LEUS(ac->ccb->errstat); 
		if(c & Cframing) 
			ac->framing++; 
		if(c & Coverrun) 
			ac->overrun++; 
1994/1114    
		ac++; 
	} 
	unlock(&a->pagelock); 
1994/1121/sys/src/9/pc/devastar.c:265,2701994/1122/sys/src/9/pc/devastar.c:265,271 (short | long)
1994/1121    
	int	framing;	/* framing errors */ 
	int	overrun;	/* overruns */ 
	int	dtr;		/* non-zero means dtr on */ 
1994/1122    
	int	rts;		/* non-zero means rts on */ 
1994/1107    
 
1994/1106    
	Queue	*iq; 
	Queue	*oq; 
1994/1121/sys/src/9/pc/devastar.c:282,2891994/1122/sys/src/9/pc/devastar.c:283,290
1994/1111    
	Qstat, 
}; 
#define TYPE(x)		((x)&0xff) 
#define BOARD(x)	((((x)&~CHDIR)>>16)&0xff) 
#define CHAN(x)		((((x)&~CHDIR)>>8)&0xff) 
1994/1122    
#define BOARD(x)	(((x)>>16)&0xff) 
#define CHAN(x)		(((x)>>8)&0xff) 
1994/1111    
#define QID(b,c,t)	(((b)<<16)|((c)<<8)|(t)) 
 
1994/1114    
static int	astarsetup(Astar*); 
1994/1121/sys/src/9/pc/devastar.c:576,5821994/1122/sys/src/9/pc/devastar.c:577,583
1994/1115    
			qunlock(ac); 
1994/1114    
			nexterror(); 
1994/1112    
		} 
1994/1115    
		if(--ac->opens == 0){ 
1994/1122    
		if(--(ac->opens) == 0){ 
1994/1114    
			disable(ac); 
1994/1115    
			qclose(ac->iq); 
			qclose(ac->oq); 
1994/1121/sys/src/9/pc/devastar.c:660,6661994/1122/sys/src/9/pc/devastar.c:661,668
1994/1121    
	UNLOCKPAGE(ac->a); 
 
	/* CCB.mstat fields */ 
	sprint(s, "ferr %d oerr %d baud %d", ac->framing, ac->overrun, ac->baud); 
1994/1122    
	sprint(s, "opens %d ferr %d oerr %d baud %d", ac->opens, ac->framing, 
		ac->overrun, ac->baud); 
1994/1121    
	if(mstat & Cctsstat) 
		strcat(s, " cts"); 
	if(mstat & Cdsrstat) 
1994/1121/sys/src/9/pc/devastar.c:669,6781994/1122/sys/src/9/pc/devastar.c:671,681
1994/1121    
		strcat(s, " ring"); 
	if(mstat & Cdcdstat) 
		strcat(s, " dcd"); 
	if(ac->opens) 
1994/1122    
	if(ac->dtr) 
1994/1121    
		strcat(s, " dtr"); 
	if((bstat & Crbrts) == 0) 
1994/1122    
	if(ac->rts && (bstat & Crbrts) == 0) 
1994/1121    
		strcat(s, " rts"); 
1994/1122    
	strcat(s, "\n"); 
1994/1121    
 
	return readstr(offset, buf, n, s); 
} 
1994/1121/sys/src/9/pc/devastar.c:831,8361994/1122/sys/src/9/pc/devastar.c:834,840
1994/1114    
		ac = &a->c[i]; 
		ac->a = a; 
		ac->ccb = (CCB*)x; 
1994/1122    
		ac->baud = 9600;	/* a100i default */ 
1994/1115    
		ac->perm = 0660; 
1994/1116    
		ac->iq = qopen(4*1024, 0, astarkickin, ac); 
1994/1114    
		ac->oq = qopen(4*1024, 0, astarkick, ac); 
1994/1121/sys/src/9/pc/devastar.c:960,9661994/1122/sys/src/9/pc/devastar.c:964,969
1994/1116    
	UNLOCKPAGE(a); 
1994/1115    
	chancmd(ac, Cconfall); 
1994/1114    
 
	astarctl(ac, "b9600"); 
	astarctl(ac, "l8"); 
	astarctl(ac, "p0"); 
	astarctl(ac, "d1"); 
1994/1121/sys/src/9/pc/devastar.c:1047,10531994/1122/sys/src/9/pc/devastar.c:1050,1056
1994/1114    
			 n |= Cdtrctl; 
		else 
			 n &= ~Cdtrctl; 
1994/1121    
		ac->dtr = n; 
1994/1122    
		ac->dtr = i; 
1994/1114    
		ccb->mctl = LEUS(n); 
1994/1112    
		break; 
1994/1113    
	case 'f': 
1994/1121/sys/src/9/pc/devastar.c:1126,11311994/1122/sys/src/9/pc/devastar.c:1129,1135
1994/1114    
		else 
			 n &= ~Crtsctl; 
		ccb->mctl = LEUS(n); 
1994/1122    
		ac->rts = i; 
1994/1113    
		break; 
	case 'Q': 
	case 'q': 
1994/1122/sys/src/9/pc/devastar.c:417,4221994/1210/sys/src/9/pc/devastar.c:417,425 (short | long)
1994/1107    
			a->irq = 15; 
		a->id = i; 
 
1994/1210    
		if(isaget(a->mem, Pagesize, 0) == 0) 
			panic("astarreset: %lux", a->mem); 
 
1994/1107    
		if(astarsetup(a) < 0){ 
			xfree(a); 
1994/1109    
			astar[nastar] = 0; 
1994/1210/sys/src/9/pc/devastar.c:417,4231994/1218/sys/src/9/pc/devastar.c:417,423 (short | long)
1994/1107    
			a->irq = 15; 
		a->id = i; 
 
1994/1210    
		if(isaget(a->mem, Pagesize, 0) == 0) 
1994/1218    
		if(getisa(a->mem, Pagesize, 0) == 0) 
1994/1210    
			panic("astarreset: %lux", a->mem); 
 
1994/1107    
		if(astarsetup(a) < 0){ 
1994/1218/sys/src/9/pc/devastar.c:411,4241995/0106/sys/src/9/pc/devastar.c:411,424 (short | long)
1994/1118    
		} 
1994/1108    
 
1994/1120    
		/* defaults */ 
1994/1107    
		if(a->mem == 0) 
1994/1108    
			a->mem = 0xD4000; 
1994/1107    
		if(a->irq == 0) 
			a->irq = 15; 
		a->id = i; 
 
1994/1218    
		if(getisa(a->mem, Pagesize, 0) == 0) 
1995/0106    
		a->mem = getisa(a->mem, Pagesize, Pagesize); 
		if(a->mem == 0) 
1994/1210    
			panic("astarreset: %lux", a->mem); 
1995/0106    
		a->mem & ~KZERO; 
1994/1210    
 
1994/1107    
		if(astarsetup(a) < 0){ 
			xfree(a); 
1995/0106/sys/src/9/pc/devastar.c:709,7141995/0108/sys/src/9/pc/devastar.c:709,720 (short | long)
1994/1113    
	return 0; 
} 
1994/1112    
 
1995/0108    
Block* 
astarbread(Chan *c, long n, ulong offset) 
{ 
	return devbread(c, n, offset); 
} 
 
1994/1114    
/* 
 *  write ISA mapped memory 
 */ 
1995/0106/sys/src/9/pc/devastar.c:1198,12031995/0108/sys/src/9/pc/devastar.c:1204,1215
1994/1111    
	} 
1994/1109    
 
	return 0; 
1995/0108    
} 
 
long 
astarbwrite(Chan *c, Block *bp, ulong offset) 
{ 
	return devbwrite(c, bp, offset); 
1994/1112    
} 
 
void 
1995/0108/sys/src/9/pc/devastar.c:418,4241995/0115/sys/src/9/pc/devastar.c:418,424 (short | long)
1995/0106    
		a->mem = getisa(a->mem, Pagesize, Pagesize); 
		if(a->mem == 0) 
1994/1210    
			panic("astarreset: %lux", a->mem); 
1995/0106    
		a->mem & ~KZERO; 
1995/0115    
		a->mem &= ~KZERO; 
1994/1210    
 
1994/1107    
		if(astarsetup(a) < 0){ 
			xfree(a); 
1995/0115/sys/src/9/pc/devastar.c:546,5511995/0127/sys/src/9/pc/devastar.c:546,552 (short | long)
1994/1114    
		qlock(ac); 
		if(waserror()){ 
1994/1115    
			qunlock(ac); 
1995/0127    
			ac->qopens--; 
1994/1114    
			nexterror(); 
		} 
1994/1116    
		if(ac->opens++ == 0){ 
1995/0127/sys/src/9/pc/devastar.c:546,5521995/0207/sys/src/9/pc/devastar.c:546,552 (short | long)
1994/1114    
		qlock(ac); 
		if(waserror()){ 
1994/1115    
			qunlock(ac); 
1995/0127    
			ac->qopens--; 
1995/0207    
			ac->opens--; 
1994/1114    
			nexterror(); 
		} 
1994/1116    
		if(ac->opens++ == 0){ 
1995/0207/sys/src/9/pc/devastar.c:762,7681995/0505/sys/src/9/pc/devastar.c:762,768 (short | long)
1994/1113    
} 
 
/* 
 *  start control progarm 
1995/0505    
 *  start control program 
1994/1113    
 */ 
static void 
startcp(Astar *a) 
1995/0505/sys/src/9/pc/devastar.c:1214,12221995/0726/sys/src/9/pc/devastar.c:1214,1221 (short | long)
1994/1112    
} 
 
void 
astarcreate(Chan *c, char *name, int omode, ulong perm) 
1995/0726    
astarcreate(Chan*, char*, int, ulong) 
1994/1112    
{ 
	USED(c, name, omode, perm); 
	error(Eperm); 
} 
 
1995/0726/sys/src/9/pc/devastar.c:6,121996/0223/sys/src/9/pc/devastar.c:6,11 (short | long)
1994/1106    
#include	"io.h" 
#include	"../port/error.h" 
 
#include	"devtab.h" 
 
/* 
1994/1107    
 *  Stargate's Avanstar serial board.  There are ISA, EISA, microchannel 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)