~kris/9p

9hist

1e4aa83fb98ece7178ca0ae87cd154a2736c273e — David du Colombier 26 years ago 945d713
Plan 9 from Bell Labs 2000-06-05
5 files changed, 211 insertions(+), 124 deletions(-)

M ip/rudp.c
M pc/devi82365.c
M pc/ether589.c
M pc/etherec2t.c
M pc/fns.h
M ip/rudp.c => ip/rudp.c +21 -12
@@ 181,15 181,16 @@ struct Rudpcb
/*
 * local functions 
 */
void	relsendack(Conv *, Reliable *, int);
int	reliput(Conv *, Block *, uchar *, ushort);
Reliable *relstate(Rudpcb *, uchar *, ushort, char *from);
void	relput(Reliable *);
void	relforget(Conv *, uchar *, int, int);
void	relsendack(Conv*, Reliable*, int);
int	reliput(Conv*, Block*, uchar*, ushort);
Reliable *relstate(Rudpcb*, uchar*, ushort, char*);
void	relput(Reliable*);
void	relforget(Conv *, uchar*, int, int);
void	relackproc(void *);
void	relackq(Reliable *, Block *);
void	relhangup(Conv *, Reliable *);
void	relrexmit(Conv *, Reliable *);
void	relackq(Reliable *, Block*);
void	relhangup(Conv *, Reliable*);
void	relrexmit(Conv *, Reliable*);
void	relput(Reliable*);

static void
rudpstartackproc(Proto *rudp)


@@ 295,7 296,6 @@ rudpclose(Conv *c)
	ucb->r = 0;

	qunlock(ucb);

	qunlock(c);
}



@@ 445,6 445,12 @@ rudpkick(Conv *c, int)

	doipoput(c, f, bp, 0, c->ttl, c->tos);

	if(waserror()) {
		relput(r);
		qunlock(&r->lock);
		nexterror();
	}

	/* flow control of sorts */
	qlock(&r->lock);
	if(UNACKED(r) > Maxunacked){


@@ 452,9 458,10 @@ rudpkick(Conv *c, int)
		sleep(&r->vous, flow, r);
		r->blocked = 0;
	}
	qunlock(&r->lock);

	qunlock(&r->lock);
	relput(r);
	poperror();
}

void


@@ 554,7 561,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp)

	len -= (UDP_RHDRSIZE-UDP_PHDRSIZE);
	bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len);
	if(bp == nil){
	if(bp == nil) {
		netlog(f, Logrudp, "rudp: len err %I.%d -> %I.%d\n", 
			raddr, rport, laddr, lport);
		DPRINT("rudp: len err %I.%d -> %I.%d\n", 


@@ 607,7 614,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp)
	if(bp->next)
		bp = concatblock(bp);

	if(qfull(c->rq)){
	if(qfull(c->rq)) {
		netlog(f, Logrudp, "rudp: qfull %I.%d -> %I.%d\n", raddr, rport,
			laddr, lport);
		freeblist(bp);


@@ 810,6 817,7 @@ relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from)
	if(r == nil){
		while(generation == 0)
			generation = rand();

		DPRINT("from %s new state %lud for %I!%ud\n", 
		        from, generation, addr, port);



@@ 832,6 840,7 @@ relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from)

		*l = r;
	}

	incref(r);
	return r;
}

M pc/devi82365.c => pc/devi82365.c +152 -99
@@ 104,6 104,7 @@ enum
typedef struct I82365	I82365;
typedef struct Slot	Slot;
typedef struct Conftab	Conftab;
typedef struct Cisdat Cisdat;

/* a controller */
enum


@@ 144,6 145,15 @@ struct Conftab
	ulong	otherwait;
};

/* cis memory walking */
struct Cisdat
{
	uchar	*cisbase;
	int	cispos;
	int	cisskip;
	int	cislen;
};

/* a card slot */
struct Slot
{


@@ 175,8 185,7 @@ struct Slot
	Conftab	*def;		/* default conftab */

	/* for walking through cis */
	int	cispos;		/* current position scanning cis */
	uchar	*cisbase;
	Cisdat;

	/* memory maps */
	Lock	mlock;		/* lock down the maps */


@@ 1046,67 1055,111 @@ pcmio(int slotno, ISAConf *isa)
 *  read and crack the card information structure enough to set
 *  important parameters like power
 */
static void	tcfig(Slot*, int);
static void	tentry(Slot*, int);
static void	tvers1(Slot*, int);

static void (*parse[256])(Slot*, int) =
{
[0x15]	tvers1,
[0x1A]	tcfig,
[0x1B]	tentry,
static void	tcfig(Slot*, Cisdat*, int);
static void	tentry(Slot*, Cisdat*, int);
static void	tvers1(Slot*, Cisdat*, int);

struct {
	int n;
	void (*parse)(Slot*, Cisdat*, int);
} cistab[] = {
	0x15, tvers1,
	0x1A, tcfig,
	0x1B, tentry,
};

static int
readc(Slot *pp, uchar *x)
readc(Cisdat *pp, uchar *x)
{
	if(pp->cispos >= Mchunk)
	if(pp->cispos >= pp->cislen)
		return 0;
	*x = pp->cisbase[2*pp->cispos];
	*x = pp->cisbase[pp->cisskip*pp->cispos];
	pp->cispos++;
	return 1;
}

static void
cisread(Slot *pp)
static int
xcistuple(int slotno, int tuple, void *v, int nv, int attr)
{
	uchar link;
	uchar type;
	int this, i;
	PCMmap *m;
	Cisdat cis;
	int i, l;
	uchar *p;
	uchar type, link;
	int this;

	memset(pp->ctab, 0, sizeof(pp->ctab));
	pp->caddr = 0;
	pp->cpresent = 0;
	pp->configed = 0;
	pp->nctab = 0;

	m = pcmmap(pp->slotno, 0, 0, 1);
	m = pcmmap(slotno, 0, 0, attr);
	if(m == 0)
		return;
	pp->cisbase = KADDR(m->isa);
	pp->cispos = 0;
		return -1;

	cis.cisbase = KADDR(m->isa);
	cis.cispos = 0;
	cis.cisskip = attr ? 2 : 1;
	cis.cislen = Mchunk;

	/* loop through all the tuples */
	for(i = 0; i < 1000; i++){
		this = pp->cispos;
		if(readc(pp, &type) != 1)
		this = cis.cispos;
		if(readc(&cis, &type) != 1)
			break;
		if(type == 0xFF)
			break;
		if(readc(pp, &link) != 1)
		if(readc(&cis, &link) != 1)
			break;
		if(parse[type])
			(*parse[type])(pp, type);
		if(link == 0xff)
		if(link == 0xFF)
			break;
		pp->cispos = this + (2+link);
		if(type == tuple) {
			p = v;
			for(l=0; l<nv && l<link; l++)
				if(readc(&cis, p++) != 1)
					break;
			pcmunmap(slotno, m);
			return nv;
		}
		cis.cispos = this + (2+link);
	}
	pcmunmap(slotno, m);
	return -1;
}

int
pcmcistuple(int slotno, int tuple, void *v, int nv)
{
	int n;

	/* try attribute space, then memory */
	if((n = xcistuple(slotno, tuple, v, nv, 1)) >= 0)
		return n;
	return xcistuple(slotno, tuple, v, nv, 0);
}

static void
cisread(Slot *pp)
{
	uchar v[256];
	int i, nv;
	Cisdat cis;

	memset(pp->ctab, 0, sizeof(pp->ctab));
	pp->caddr = 0;
	pp->cpresent = 0;
	pp->configed = 0;
	pp->nctab = 0;

	for(i = 0; i < nelem(cistab); i++) {
		if((nv = pcmcistuple(pp->slotno, cistab[i].n, v, sizeof(v))) >= 0) {
			cis.cisbase = v;
			cis.cispos = 0;
			cis.cisskip = 1;
			cis.cislen = nv;
			
			(*cistab[i].parse)(pp, &cis, cistab[i].n);
		}
	}
	pcmunmap(pp->slotno, m);
}

static ulong
getlong(Slot *pp, int size)
getlong(Cisdat *cis, int size)
{
	uchar c;
	int i;


@@ 1114,7 1167,7 @@ getlong(Slot *pp, int size)

	x = 0;
	for(i = 0; i < size; i++){
		if(readc(pp, &c) != 1)
		if(readc(cis, &c) != 1)
			break;
		x |= c<<(i*8);
	}


@@ 1122,19 1175,19 @@ getlong(Slot *pp, int size)
}

static void
tcfig(Slot *pp, int )
tcfig(Slot *pp, Cisdat *cis, int )
{
	uchar size, rasize, rmsize;
	uchar last;

	if(readc(pp, &size) != 1)
	if(readc(cis, &size) != 1)
		return;
	rasize = (size&0x3) + 1;
	rmsize = ((size>>2)&0xf) + 1;
	if(readc(pp, &last) != 1)
	if(readc(cis, &last) != 1)
		return;
	pp->caddr = getlong(pp, rasize);
	pp->cpresent = getlong(pp, rmsize);
	pp->caddr = getlong(cis, rasize);
	pp->cpresent = getlong(cis, rmsize);
}

static ulong vexp[8] =


@@ 1147,18 1200,18 @@ static ulong vmant[16] =
};

static ulong
microvolt(Slot *pp)
microvolt(Cisdat *cis)
{
	uchar c;
	ulong microvolts;
	ulong exp;

	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return 0;
	exp = vexp[c&0x7];
	microvolts = vmant[(c>>3)&0xf]*exp;
	while(c & 0x80){
		if(readc(pp, &c) != 1)
		if(readc(cis, &c) != 1)
			return 0;
		switch(c){
		case 0x7d:


@@ 1176,16 1229,16 @@ microvolt(Slot *pp)
}

static ulong
nanoamps(Slot *pp)
nanoamps(Cisdat *cis)
{
	uchar c;
	ulong nanoamps;

	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return 0;
	nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf];
	while(c & 0x80){
		if(readc(pp, &c) != 1)
		if(readc(cis, &c) != 1)
			return 0;
		if(c == 0x7d || c == 0x7e || c == 0x7f)
			nanoamps = 0;


@@ 1197,28 1250,28 @@ nanoamps(Slot *pp)
 *  only nominal voltage is important for config
 */
static ulong
power(Slot *pp)
power(Cisdat *cis)
{
	uchar feature;
	ulong mv;

	mv = 0;
	if(readc(pp, &feature) != 1)
	if(readc(cis, &feature) != 1)
		return 0;
	if(feature & 1)
		mv = microvolt(pp);
		mv = microvolt(cis);
	if(feature & 2)
		microvolt(pp);
		microvolt(cis);
	if(feature & 4)
		microvolt(pp);
		microvolt(cis);
	if(feature & 8)
		nanoamps(pp);
		nanoamps(cis);
	if(feature & 0x10)
		nanoamps(pp);
		nanoamps(cis);
	if(feature & 0x20)
		nanoamps(pp);
		nanoamps(cis);
	if(feature & 0x40)
		nanoamps(pp);
		nanoamps(cis);
	return mv/1000000;
}



@@ 1229,12 1282,12 @@ static ulong exponent[8] =
{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, };

static ulong
ttiming(Slot *pp, int scale)
ttiming(Cisdat *cis, int scale)
{
	uchar unscaled;
	ulong nanosecs;

	if(readc(pp, &unscaled) != 1)
	if(readc(cis, &unscaled) != 1)
		return 0;
	nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10;
	nanosecs = nanosecs * vexp[scale];


@@ 1242,31 1295,31 @@ ttiming(Slot *pp, int scale)
}

static void
timing(Slot *pp, Conftab *ct)
timing(Cisdat *cis, Conftab *ct)
{
	uchar c, i;

	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return;
	i = c&0x3;
	if(i != 3)
		ct->maxwait = ttiming(pp, i);		/* max wait */
		ct->maxwait = ttiming(cis, i);		/* max wait */
	i = (c>>2)&0x7;
	if(i != 7)
		ct->readywait = ttiming(pp, i);		/* max ready/busy wait */
		ct->readywait = ttiming(cis, i);		/* max ready/busy wait */
	i = (c>>5)&0x7;
	if(i != 7)
		ct->otherwait = ttiming(pp, i);		/* reserved wait */
		ct->otherwait = ttiming(cis, i);		/* reserved wait */
}

static void
iospaces(Slot *pp, Conftab *ct)
iospaces(Cisdat *cis, Conftab *ct)
{
	uchar c;
	int i, nio;

	ct->nio = 0;
	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return;

	ct->bit16 = ((c>>5)&3) >= 2;


@@ 1277,55 1330,55 @@ iospaces(Slot *pp, Conftab *ct)
		return;
	}

	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return;

	nio = (c&0xf)+1;
	for(i = 0; i < nio; i++){
		ct->io[i].start = getlong(pp, (c>>4)&0x3);
		ct->io[0].len = getlong(pp, (c>>6)&0x3);
		ct->io[i].start = getlong(cis, (c>>4)&0x3);
		ct->io[0].len = getlong(cis, (c>>6)&0x3);
	}
	ct->nio = nio;
}

static void
irq(Slot *pp, Conftab *ct)
irq(Cisdat *cis, Conftab *ct)
{
	uchar c;

	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return;
	ct->irqtype = c & 0xe0;
	if(c & 0x10)
		ct->irqs = getlong(pp, 2);
		ct->irqs = getlong(cis, 2);
	else
		ct->irqs = 1<<(c&0xf);
	ct->irqs &= 0xDEB8;		/* levels available to card */
}

static void
memspace(Slot *pp, int asize, int lsize, int host)
memspace(Cisdat *cis, int asize, int lsize, int host)
{
	ulong haddress, address, len;

	len = getlong(pp, lsize)*256;
	address = getlong(pp, asize)*256;
	len = getlong(cis, lsize)*256;
	address = getlong(cis, asize)*256;
	USED(len, address);
	if(host){
		haddress = getlong(pp, asize)*256;
		haddress = getlong(cis, asize)*256;
		USED(haddress);
	}
}

static void
tentry(Slot *pp, int )
tentry(Slot *pp, Cisdat *cis, int )
{
	uchar c, i, feature;
	Conftab *ct;

	if(pp->nctab >= Maxctab)
		return;
	if(readc(pp, &c) != 1)
	if(readc(cis, &c) != 1)
		return;
	ct = &pp->ctab[pp->nctab++];



@@ 1341,65 1394,65 @@ tentry(Slot *pp, int )

	/* memory wait specified? */
	if(c & 0x80){
		if(readc(pp, &i) != 1)
		if(readc(cis, &i) != 1)
			return;
		if(i&0x80)
			ct->memwait = 1;
	}

	if(readc(pp, &feature) != 1)
	if(readc(cis, &feature) != 1)
		return;
	switch(feature&0x3){
	case 1:
		ct->vpp1 = ct->vpp2 = power(pp);
		ct->vpp1 = ct->vpp2 = power(cis);
		break;
	case 2:
		power(pp);
		ct->vpp1 = ct->vpp2 = power(pp);
		power(cis);
		ct->vpp1 = ct->vpp2 = power(cis);
		break;
	case 3:
		power(pp);
		ct->vpp1 = power(pp);
		ct->vpp2 = power(pp);
		power(cis);
		ct->vpp1 = power(cis);
		ct->vpp2 = power(cis);
		break;
	default:
		break;
	}
	if(feature&0x4)
		timing(pp, ct);
		timing(cis, ct);
	if(feature&0x8)
		iospaces(pp, ct);
		iospaces(cis, ct);
	if(feature&0x10)
		irq(pp, ct);
		irq(cis, ct);
	switch((feature>>5)&0x3){
	case 1:
		memspace(pp, 0, 2, 0);
		memspace(cis, 0, 2, 0);
		break;
	case 2:
		memspace(pp, 2, 2, 0);
		memspace(cis, 2, 2, 0);
		break;
	case 3:
		if(readc(pp, &c) != 1)
		if(readc(cis, &c) != 1)
			return;
		for(i = 0; i <= (c&0x7); i++)
			memspace(pp, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
			memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80);
		break;
	}
	pp->configed++;
}

static void
tvers1(Slot *pp, int )
tvers1(Slot *pp, Cisdat *cis, int )
{
	uchar c, major, minor;
	int  i;

	if(readc(pp, &major) != 1)
	if(readc(cis, &major) != 1)
		return;
	if(readc(pp, &minor) != 1)
	if(readc(cis, &minor) != 1)
		return;
	for(i = 0; i < sizeof(pp->verstr)-1; i++){
		if(readc(pp, &c) != 1)
		if(readc(cis, &c) != 1)
			return;
		if(c == 0)
			c = '\n';

M pc/ether589.c => pc/ether589.c +36 -6
@@ 2,8 2,6 @@
 * 3C589 and 3C562.
 * To do:
 *	check xcvr10Base2 still works (is GlobalReset necessary?).
 *	pull the station address out of the card space for the 3C562,
 *	it has no EEPROM.
 */
#include "u.h"
#include "../port/lib.h"


@@ 82,6 80,13 @@ enum {						/* Window 4 - diagnostic */

extern int etherelnk3reset(Ether*);

static char *tcmpcmcia[] = {
	"3C589",			/* 3COM 589[ABCD] */
	"3C562",			/* 3COM 562 */
	"589E",				/* 3COM Megahertz 589E */
	nil,
};

static int
configASIC(Ether* ether, int port, int xcvr)
{


@@ 111,10 116,12 @@ configASIC(Ether* ether, int port, int xcvr)
static int
reset(Ether* ether)
{
	int i, slot;
	int i, t, slot;
	char *type;
	int port;
	enum { WantAny, Want10BT, Want10B2 };
	int want;
	uchar ea[6];
	char *p;

	if(ether->irq == 0)


@@ 126,12 133,35 @@ reset(Ether* ether)
	if(ioalloc(port, 0x10, 0, "3C589") < 0)
		return -1;

	if((slot = pcmspecial(ether->type, ether)) < 0){
	type = nil;
	slot = -1;
	for(i = 0; tcmpcmcia[i] != nil; i++){
		type = tcmpcmcia[i];
		if((slot = pcmspecial(type, ether)) >= 0)
			break;
	}
	if(slot < 0){
		iofree(port);
		return -1;
	}

	/*
	 * Read Ethernet address from card memory
	 * on 3C562, but only if the user has not 
	 * overridden it.
	 */
	memset(ea, 0, sizeof ea);
	if(memcmp(ea, ether->ea, 6) == 0 && strcmp(type, "3C562") == 0) {
		if(pcmcistuple(slot, 0x88, ea, 6) == 6) {
			for(i = 0; i < 6; i += 2){
				t = ea[i];
				ea[i] = ea[i+1];
				ea[i+1] = t;
			}
			memmove(ether->ea, ea, 6);
		}
	}
	/*
	 * Allow user to specify desired media in plan9.ini
	 */
	want = WantAny;


@@ 156,7 186,7 @@ reset(Ether* ether)
		COMMAND(port, SelectRegisterWindow, Wdiagnostic);
		if((ins(port+MediaStatus)&linkBeatDetect) || want==Want10BT){
			COMMAND(port, SelectRegisterWindow, Wop);
			print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type);
			print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, type);
			return 0;
		}
	}


@@ 169,7 199,7 @@ reset(Ether* ether)
			iofree(port);
			return -1;
		}
		print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type);
		print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, type);
		return 0;
	}
	return -1;		/* not reached */

M pc/etherec2t.c => pc/etherec2t.c +1 -7
@@ 79,13 79,7 @@ reset(Ether* ether)
	ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
	ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz);

	ctlr->dummyrr = 1;
	for(i = 0; i < ether->nopt; i++){
		if(strcmp(ether->opt[i], "nodummyrr"))
			continue;
		ctlr->dummyrr = 0;
		break;
	}
	ctlr->dummyrr = 0;

	/*
	 * Reset the board. This is done by doing a read

M pc/fns.h => pc/fns.h +1 -0
@@ 89,6 89,7 @@ Pcidev* pcimatch(Pcidev*, int, int);
Pcidev* pcimatchtbdf(int);
void	pcireset(void);
void	pcisetbme(Pcidev*);
int	pcmcistuple(int, int, void*, int);
PCMmap*	pcmmap(int, ulong, int, int);
int	pcmspecial(char*, ISAConf*);
void	pcmspecialclose(int);