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

1990/03042/port/devlance.c (diff list | history)

1990/03011/sys/src/9/port/devlance.c:11,251990/03042/sys/src/9/port/devlance.c:11,28 (short | long | prev | next)
1990/0227    
 */ 
enum { 
	Ntypes=		8,		/* max number of ethernet packet types */ 
1990/03042    
	Ndir=		Ntypes+1,	/* entries in top level directory */ 
1990/0227    
	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 */ 
1990/03042    
	Ndpkt=		1000,		/* number of debug packets */ 
1990/0227    
}; 
#define RSUCC(x) (((x)+1)%Nrrb) 
#define TSUCC(x) (((x)+1)%Ntrb) 
 
1990/03042    
#define NOW (MACHP(0)->ticks) 
 
1990/0227    
/* 
 *  Communication with the lance is via a transmit and receive ring of 
 *  message descriptors.  The Initblock contains pointers to and sizes of 
1990/03011/sys/src/9/port/devlance.c:102,1121990/03042/sys/src/9/port/devlance.c:105,119
1990/0227    
	uchar data[40]; 
} Dpkt; 
typedef struct { 
1990/03042    
	ulong	ticks; 
	char	tag; 
	int	len; 
	Dpkt	p; 
} Trace; 
typedef struct { 
1990/0227    
	Lock; 
	int	next; 
	char	*tag[Ndpkt]; 
	int	len[Ndpkt]; 
	Dpkt	p[Ndpkt]; 
1990/03042    
	Trace	t[Ndpkt]; 
1990/0227    
} Debqueue; 
 
/* 
1990/03011/sys/src/9/port/devlance.c:136,1421990/03042/sys/src/9/port/devlance.c:143,148
1990/0227    
 
	Ethertype e[Ntypes]; 
	int	debug; 
	int	prdebug; 
	int	kstarted; 
	Debqueue dq; 
} Lance; 
1990/03011/sys/src/9/port/devlance.c:215,2281990/03042/sys/src/9/port/devlance.c:221,236
1990/0227    
/* 
 *  print a packet preceded by a message 
 */ 
printpacket(char *tag, Pkt *p, int len) 
1990/03042    
sprintpacket(char *buf, Trace *t) 
1990/0227    
{ 
  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]); 
1990/03042    
	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]); 
1990/0227    
} 
 
/* 
1990/03011/sys/src/9/port/devlance.c:229,2401990/03042/sys/src/9/port/devlance.c:237,252
1990/0227    
 *  save a message in a circular queue for later debugging 
 */ 
void 
lancedebq(char *tag, Pkt *p, int len) 
1990/03042    
lancedebq(char tag, Pkt *p, int len) 
1990/0227    
{ 
1990/03042    
	Trace *t; 
 
1990/0227    
	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)); 
1990/03042    
	t = &l.dq.t[l.dq.next]; 
	t->ticks = NOW; 
	t->tag = tag; 
	t->len = len; 
	memcpy(&(t->p), p, sizeof(Dpkt)); 
1990/0227    
	l.dq.next = (l.dq.next+1) % Ndpkt; 
	unlock(&l.dq); 
} 
1990/03011/sys/src/9/port/devlance.c:351,3571990/03042/sys/src/9/port/devlance.c:363,369
1990/0227    
	len = 0; 
	while(bp = getq(q)){ 
		if(sizeof(Pkt) - len >= (n = bp->wptr - bp->rptr)){ 
			slowcpy(((uchar *)p)+len, bp->rptr, n); 
1990/03042    
			memcpy(((uchar *)p)+len, bp->rptr, n); 
1990/0227    
			len += n; 
		} else 
			print("no room damn it\n"); 
1990/03011/sys/src/9/port/devlance.c:373,3791990/03042/sys/src/9/port/devlance.c:385,391
1990/0227    
	if(len < 60) 
		len = 60; 
 
	lancedebq("out", p, len); 
1990/03042    
	lancedebq('o', p, len); 
1990/0227    
 
	/* 
	 *  set up the ring descriptor and hand to lance 
1990/03011/sys/src/9/port/devlance.c:392,4001990/03042/sys/src/9/port/devlance.c:404,413
1990/0227    
 *  lance directory 
 */ 
enum { 
	Lchanqid = 1 
1990/03042    
	Lchanqid = 1, 
	Ltraceqid = 2, 
1990/0227    
}; 
Dirtab lancedir[Ntypes]; 
1990/03042    
Dirtab lancedir[Ndir]; 
1990/0227    
 
 
/* 
1990/03011/sys/src/9/port/devlance.c:549,5541990/03042/sys/src/9/port/devlance.c:562,571
1990/0227    
		lancedir[i].length = 0; 
		lancedir[i].perm = 0600; 
	} 
1990/03042    
	strcpy(lancedir[Ntypes].name, "trace"); 
	lancedir[Ntypes].qid = Ltraceqid; 
	lancedir[Ntypes].length = 0; 
	lancedir[Ntypes].perm = 0600; 
1990/0227    
} 
 
Chan* 
1990/03011/sys/src/9/port/devlance.c:580,5861990/03042/sys/src/9/port/devlance.c:597,603
1990/0227    
lancewalk(Chan *c, char *name) 
{ 
	if(c->qid == CHDIR) 
		return devwalk(c, name, lancedir, Ntypes, devgen); 
1990/03042    
		return devwalk(c, name, lancedir, Ndir, devgen); 
1990/0227    
	else 
		return devwalk(c, name, 0, 0, streamgen); 
} 
1990/03011/sys/src/9/port/devlance.c:589,5951990/03042/sys/src/9/port/devlance.c:606,612
1990/0227    
lancestat(Chan *c, char *dp) 
{ 
	if(c->qid == CHDIR) 
		devstat(c, dp, lancedir, Ntypes, devgen); 
1990/03042    
		devstat(c, dp, lancedir, Ndir, devgen); 
1990/0227    
	else 
		devstat(c, dp, 0, 0, streamgen); 
} 
1990/03011/sys/src/9/port/devlance.c:602,6121990/03042/sys/src/9/port/devlance.c:619,634
1990/0227    
{ 
	extern Qinfo nonetinfo; 
 
	if(c->qid == CHDIR){ 
1990/03042    
	switch(c->qid){ 
	case CHDIR: 
	case Ltraceqid: 
1990/0227    
		if(omode != OREAD) 
			error(0, Eperm); 
	}else 
1990/03042    
		break; 
	default: 
1990/0227    
		streamopen(c, &lanceinfo); 
1990/03042    
		break; 
	} 
1990/0227    
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
	c->offset = 0; 
1990/03011/sys/src/9/port/devlance.c:623,6391990/03042/sys/src/9/port/devlance.c:645,704
1990/0227    
lanceclose(Chan *c) 
{ 
	/* real closing happens in lancestclose */ 
	if(c->qid != CHDIR) 
1990/03042    
	switch(c->qid){ 
	case CHDIR: 
	case Ltraceqid: 
		break; 
	default: 
1990/0227    
		streamclose(c); 
1990/03042    
		break; 
	} 
1990/0227    
} 
 
1990/03042    
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; 
} 
 
1990/0227    
long	  
lanceread(Chan *c, void *a, long n) 
{ 
	if(c->qid == CHDIR) 
		return devdirread(c, a, n, lancedir, Ntypes, devgen); 
	else 
1990/03042    
	switch(c->qid){ 
	case CHDIR: 
		return devdirread(c, a, n, lancedir, Ndir, devgen); 
	case Ltraceqid: 
		return lancetraceread(c, a, n); 
	default: 
1990/0227    
		return streamread(c, a, n); 
1990/03042    
	} 
1990/0227    
} 
 
long	  
1990/03011/sys/src/9/port/devlance.c:752,7581990/03042/sys/src/9/port/devlance.c:817,823
1990/0227    
			p = l.rp[l.rl]; 
1990/03011    
			t = (p->type[0]<<8) | p->type[1]; 
1990/0227    
			len = m->cntflags - 4; 
			lancedebq("in", p, len); 
1990/03042    
			lancedebq('i', p, len); 
1990/0227    
			for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ 
				if(!canqlock(e)) 
					continue; 
1990/03011/sys/src/9/port/devlance.c:779,7851990/03042/sys/src/9/port/devlance.c:844,850
1990/0227    
				 *  The lock on e makes sure the queue is still there. 
				 */ 
				bp = allocb(len); 
				slowcpy(bp->rptr, (uchar *)p, len); 
1990/03042    
				memcpy(bp->rptr, (uchar *)p, len); 
1990/0227    
				bp->wptr += len; 
				bp->flags |= S_DELIM; 
				PUTNEXT(e->q, bp); 
1990/03011/sys/src/9/port/devlance.c:797,8141990/03042/sys/src/9/port/devlance.c:862,867
1990/0227    
			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); 
	} 
} 
1990/03011/sys/src/9/port/devlance.c:819,8381990/03042/sys/src/9/port/devlance.c:872,875
1990/0227    
	print("lance DRAM parity error lmp=%ux\n", l.lmp); 
	MODEREG->promenet &= ~4; 
	MODEREG->promenet |= 4; 
} 
                 
void 
LANCEDEBUG() 
{ 
	l.debug ^= 1; 
} 
                 
/* 
 *  print the debug queue 
 */ 
void 
LANCEPRDEBQ() 
{ 
	l.prdebug = 1; 
	wakeup(&l.rr); 
} 


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