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

1994/1112/pc/devastar.c (diff list | history)

1994/1111/sys/src/9/pc/devastar.c:35,411994/1112/sys/src/9/pc/devastar.c:35,44 (short | long | prev | next)
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    
} 


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