~kris/9p

9hist

3afa7e7b0372d3635892d107eb969e31e68ef616 — David du Colombier 36 years ago 045b850
Plan 9 from Bell Labs 1990-03-06
6 files changed, 151 insertions(+), 104 deletions(-)

M port/devcons.c
M port/devenv.c
M port/devlance.c
M port/devmnt.c
M power/dat.h
M power/devbit.c
M port/devcons.c => port/devcons.c +0 -4
@@ 238,10 238,6 @@ echo(int c)
	 */
	if(c == 0x14)
		DEBUG();
	else if(c == 0x0c)
		LANCEDEBUG();
	else if(c == 0x02)
		LANCEPRDEBQ();
	if(c == 0x15)
		putstrn("^U\n", 3);
	else{

M port/devenv.c => port/devenv.c +1 -0
@@ 299,6 299,7 @@ envopen(Chan *c, int omode)
		if(waserror()){
			unlock(e);
			unlock(&envalloc);
			unlock(pg);
			nexterror();
		}
		if(e->pgref == 0)

M port/devlance.c => port/devlance.c +95 -58
@@ 11,15 11,18 @@
 */
enum {
	Ntypes=		8,		/* max number of ethernet packet types */
	Ndir=		Ntypes+1,	/* entries in top level directory */
	LogNrrb=	7,		/* log of number of receive buffers */
	Nrrb=		(1<<LogNrrb),	/* number of recieve buffers */
	LogNtrb=	7,		/* log of number of transmit buffers */
	Ntrb=		(1<<LogNtrb),	/* number of transmit buffers */
	Ndpkt=		30,		/* number of debug packets */
	Ndpkt=		1000,		/* number of debug packets */
};
#define RSUCC(x) (((x)+1)%Nrrb)
#define TSUCC(x) (((x)+1)%Ntrb)

#define NOW (MACHP(0)->ticks)

/*
 *  Communication with the lance is via a transmit and receive ring of
 *  message descriptors.  The Initblock contains pointers to and sizes of


@@ 102,11 105,15 @@ typedef struct {
	uchar data[40];
} Dpkt;
typedef struct {
	ulong	ticks;
	char	tag;
	int	len;
	Dpkt	p;
} Trace;
typedef struct {
	Lock;
	int	next;
	char	*tag[Ndpkt];
	int	len[Ndpkt];
	Dpkt	p[Ndpkt];
	Trace	t[Ndpkt];
} Debqueue;

/*


@@ 136,7 143,6 @@ typedef struct {

	Ethertype e[Ntypes];
	int	debug;
	int	prdebug;
	int	kstarted;
	Debqueue dq;
} Lance;


@@ 215,26 221,32 @@ void lancekproc(void *);
/*
 *  print a packet preceded by a message
 */
printpacket(char *tag, Pkt *p, int len)
sprintpacket(char *buf, Trace *t)
{
  print("%s: %d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%ux %ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n",
	tag, len,
	p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5],
	p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1],
	p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5],
	p->data[6], p->data[7], p->data[8], p->data[9], p->data[10], p->data[11]);
	Dpkt *p = &t->p;

	sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n",
	    t->tag, t->ticks, t->len,
	    p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5],
	    p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0],p->type[1],
	    p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5],
	    p->data[6], p->data[7], p->data[8], p->data[9], p->data[10], p->data[11]);
}

/*
 *  save a message in a circular queue for later debugging
 */
void
lancedebq(char *tag, Pkt *p, int len)
lancedebq(char tag, Pkt *p, int len)
{
	Trace *t;

	lock(&l.dq);
	l.dq.tag[l.dq.next] = tag;
	l.dq.len[l.dq.next] = len;
	memcpy(&l.dq.p[l.dq.next], p, sizeof(Dpkt));
	t = &l.dq.t[l.dq.next];
	t->ticks = NOW;
	t->tag = tag;
	t->len = len;
	memcpy(&(t->p), p, sizeof(Dpkt));
	l.dq.next = (l.dq.next+1) % Ndpkt;
	unlock(&l.dq);
}


@@ 351,7 363,7 @@ lanceoput(Queue *q, Block *bp )
	len = 0;
	while(bp = getq(q)){
		if(sizeof(Pkt) - len >= (n = bp->wptr - bp->rptr)){
			slowcpy(((uchar *)p)+len, bp->rptr, n);
			memcpy(((uchar *)p)+len, bp->rptr, n);
			len += n;
		} else
			print("no room damn it\n");


@@ 373,7 385,7 @@ lanceoput(Queue *q, Block *bp )
	if(len < 60)
		len = 60;

	lancedebq("out", p, len);
	lancedebq('o', p, len);

	/*
	 *  set up the ring descriptor and hand to lance


@@ 392,9 404,10 @@ lanceoput(Queue *q, Block *bp )
 *  lance directory
 */
enum {
	Lchanqid = 1
	Lchanqid = 1,
	Ltraceqid = 2,
};
Dirtab lancedir[Ntypes];
Dirtab lancedir[Ndir];


/*


@@ 549,6 562,10 @@ lanceinit(void)
		lancedir[i].length = 0;
		lancedir[i].perm = 0600;
	}
	strcpy(lancedir[Ntypes].name, "trace");
	lancedir[Ntypes].qid = Ltraceqid;
	lancedir[Ntypes].length = 0;
	lancedir[Ntypes].perm = 0600;
}

Chan*


@@ 580,7 597,7 @@ int
lancewalk(Chan *c, char *name)
{
	if(c->qid == CHDIR)
		return devwalk(c, name, lancedir, Ntypes, devgen);
		return devwalk(c, name, lancedir, Ndir, devgen);
	else
		return devwalk(c, name, 0, 0, streamgen);
}


@@ 589,7 606,7 @@ void
lancestat(Chan *c, char *dp)
{
	if(c->qid == CHDIR)
		devstat(c, dp, lancedir, Ntypes, devgen);
		devstat(c, dp, lancedir, Ndir, devgen);
	else
		devstat(c, dp, 0, 0, streamgen);
}


@@ 602,11 619,16 @@ lanceopen(Chan *c, int omode)
{
	extern Qinfo nonetinfo;

	if(c->qid == CHDIR){
	switch(c->qid){
	case CHDIR:
	case Ltraceqid:
		if(omode != OREAD)
			error(0, Eperm);
	}else
		break;
	default:
		streamopen(c, &lanceinfo);
		break;
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;


@@ 623,17 645,60 @@ void
lanceclose(Chan *c)
{
	/* real closing happens in lancestclose */
	if(c->qid != CHDIR)
	switch(c->qid){
	case CHDIR:
	case Ltraceqid:
		break;
	default:
		streamclose(c);
		break;
	}
}

static long
lancetraceread(Chan *c, void *a, long n)
{
	char buf[512];
	long rv;
	int i;
	char *ca = a;
	int offset;
	Trace *t;
	int plen;

	rv = 0;
	sprintpacket(buf, l.dq.t);
	plen = strlen(buf);
	offset = c->offset % plen;
	for(t = &l.dq.t[c->offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){
		if(t->tag == 0)
			break;
		lock(&l.dq);
		sprintpacket(buf, t);
		unlock(&l.dq);
		i = plen - offset;
		if(i > n)
			i = n;
		memcpy(ca, buf + offset, i);
		n -= i;
		ca += i;
		rv += i;
		offset = 0;
	}
	return rv;
}

long	 
lanceread(Chan *c, void *a, long n)
{
	if(c->qid == CHDIR)
		return devdirread(c, a, n, lancedir, Ntypes, devgen);
	else
	switch(c->qid){
	case CHDIR:
		return devdirread(c, a, n, lancedir, Ndir, devgen);
	case Ltraceqid:
		return lancetraceread(c, a, n);
	default:
		return streamread(c, a, n);
	}
}

long	 


@@ 752,7 817,7 @@ lancekproc(void *arg)
			p = l.rp[l.rl];
			t = (p->type[0]<<8) | p->type[1];
			len = m->cntflags - 4;
			lancedebq("in", p, len);
			lancedebq('i', p, len);
			for(e = &l.e[0]; e < &l.e[Ntypes]; e++){
				if(!canqlock(e))
					continue;


@@ 779,7 844,7 @@ lancekproc(void *arg)
				 *  The lock on e makes sure the queue is still there.
				 */
				bp = allocb(len);
				slowcpy(bp->rptr, (uchar *)p, len);
				memcpy(bp->rptr, (uchar *)p, len);
				bp->wptr += len;
				bp->flags |= S_DELIM;
				PUTNEXT(e->q, bp);


@@ 797,18 862,6 @@ stage:
			m->flags = OWN|HADDR(l.rp[l.rc]);
			l.rc = RSUCC(l.rc);
		}
		if(l.prdebug){
			lock(&l.dq);
			i = l.dq.next;
			do {
				if(l.dq.tag[i])
					printpacket(l.dq.tag[i], (Pkt *)&l.dq.p[i],
						l.dq.len[i]);
				i = (i+1) % Ndpkt;
			} while(i != l.dq.next);
			unlock(&l.dq);
			l.prdebug = 0;
		}
		sleep(&l.rr, isinput, 0);
	}
}


@@ 820,19 873,3 @@ lanceparity(void)
	MODEREG->promenet &= ~4;
	MODEREG->promenet |= 4;
}

void
LANCEDEBUG()
{
	l.debug ^= 1;
}

/*
 *  print the debug queue
 */
void
LANCEPRDEBQ()
{
	l.prdebug = 1;
	wakeup(&l.rr);
}

M port/devmnt.c => port/devmnt.c +10 -3
@@ 554,6 554,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
	ulong n;
	Mntbuf *mbr, *mbw;
	Chan *mntpt;
	int isbit;

	mbr = mballoc();
	mbw = mballoc();


@@ 568,10 569,15 @@ mntxmit(Mnt *m, Mnthdr *mh)
		qunlock(m);
		error(0, Eshutdown);
	}
	qlock(m->msg);
	isbit = 0;
	if(devchar[m->msg->type] == 'b')
		isbit = 1;
	if(!isbit)
		qlock(m->msg);
	if(waserror()){
		qunlock(m);
		qunlock(m->msg);
		if(!isbit)
			qunlock(m->msg);
		nexterror();
	}
	if((*devtab[m->msg->type].write)(m->msg, mbw->buf, n) != n){


@@ 584,7 590,8 @@ mntxmit(Mnt *m, Mnthdr *mh)
	 */
	n = (*devtab[m->msg->type].read)(m->msg, mbr->buf, BUFSIZE);
	qunlock(m);
	qunlock(m->msg);
	if(!isbit)
		qunlock(m->msg);
	poperror();

	if(convM2S(mbr->buf, &mh->rhdr, n) == 0){

M power/dat.h => power/dat.h +13 -0
@@ 1,4 1,5 @@
typedef struct Alarm	Alarm;
typedef struct Bitmsg	Bitmsg;
typedef struct Blist	Blist;
typedef struct Block	Block;
typedef struct Chan	Chan;


@@ 75,6 76,13 @@ struct Alarm
	void	*arg;
};

struct Bitmsg
{
	ulong	cmd;
	ulong	addr;
	ulong	count;
};

#define	CHDIR	0x80000000L
#define	QPATH	0x0000FFFFL
struct Chan


@@ 328,6 336,11 @@ struct User
	Chan	*fd[NFD];
	int	maxfd;			/* highest fd in use */
	/*
	 * I/O point for bit interface.  This is the easiest way to allocate
	 * them, but not the prettiest or most general.
	 */
	Bitmsg	bit;
	/*
	 * Rest of structure controlled by devproc.c and friends.
	 * lock(&p->debug) to modify.
	 */

M power/devbit.c => power/devbit.c +32 -39
@@ 8,20 8,10 @@

#include	"io.h"

typedef struct Bitmsg Bitmsg;
struct Bitmsg
{
	ulong	cmd;
	ulong	addr;
	ulong	count;
	ulong	result;
};

static struct
{
	QLock;
	int	open;
	Bitmsg	msg;
	char	buf[10*1024];
}bit;



@@ 36,23 26,17 @@ enum
};

void
bitsend(ulong cmd, void *addr, ulong count)
bitsend(Bitmsg *bp, ulong cmd, void *addr, ulong count)
{
	bit.msg.cmd = cmd;
	bit.msg.addr = (ulong)addr;
	bit.msg.count = count;
	bp->cmd = cmd;
	bp->addr = (ulong)addr;
	bp->count = count;
	if(*BITADDR)
		panic("bitsend");
	*BITADDR = &bit.msg;
	*BITADDR = bp;
	wbflush();
	*BITINTR = 0x20;
}

void
bitsync(void)
{
	while(*BITADDR)
		;
	do; while(*BITADDR);
}

void


@@ 102,6 86,9 @@ bitstat(Chan *c, char *dp)
Chan*
bitopen(Chan *c, int omode)
{
	Bitmsg *bp;

	bp = &((User*)(u->p->upage->pa|KZERO))->bit;
	if(c->qid!=1 || omode!=ORDWR)
		error(0, Eperm);
	qlock(&bit);


@@ 110,9 97,7 @@ bitopen(Chan *c, int omode)
print("multiple bit open\n");
		error(0, Einuse);
	}
	bitsync();
	bitsend(RESET, 0, 0);
	bitsync();
	bitsend(bp, RESET, 0, 0);
	bit.open = 1;
	qunlock(&bit);
	c->mode = openmode(omode);


@@ 146,21 131,28 @@ bitclose(Chan *c)
long	 
bitread(Chan *c, void *buf, long n)
{
	Bitmsg *bp;
	int docpy;

	bp = &((User*)(u->p->upage->pa|KZERO))->bit;
	switch(c->qid){
	case 1:
		if(n > sizeof bit.buf)
			error(0, Egreg);
		docpy = 0;
		qlock(&bit);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){
			bitsend(READ, buf, n);
			bitsync();
		}else{
			bitsend(READ, bit.buf, n);
			bitsync();
			memcpy(buf, bit.buf, n);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0)
			bitsend(bp, READ, buf, n);
		else{
			bitsend(bp, READ, bit.buf, n);
			docpy = 1;
		}
		n = bit.msg.result;
		qunlock(&bit);
		do
			n = bp->count;
		while(n == 0);
		if(docpy)
			memcpy(buf, bit.buf, n);
		return n;
	}
	error(0, Egreg);


@@ 170,18 162,19 @@ bitread(Chan *c, void *buf, long n)
long	 
bitwrite(Chan *c, void *buf, long n)
{
	Bitmsg *bp;

	bp = &((User*)(u->p->upage->pa|KZERO))->bit;
	switch(c->qid){
	case 1:
		if(n > sizeof bit.buf)
			error(0, Egreg);
		qlock(&bit);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0){
			bitsend(WRITE, buf, n);
			bitsync();
		}else{
		if((((ulong)buf)&(KSEGM|3)) == KSEG0)
			bitsend(bp, WRITE, buf, n);
		else{
			memcpy(bit.buf, buf, n);
			bitsend(WRITE, bit.buf, n);
			bitsync();
			bitsend(bp, WRITE, bit.buf, n);
		}
		qunlock(&bit);
		return n;