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

1992/0407/pc/devether.c (diff list | history)

1992/0406/sys/src/9/pc/devether.c:7,121992/0407/sys/src/9/pc/devether.c:7,13 (short | long | prev | next)
1992/0406    
 *	output 
 *	deal with stalling and restarting output on input overflow 
 *	fix magic ring constants 
1992/0407    
 *	rewrite per SMC doc 
1992/0403    
 */ 
#include "u.h" 
#include "../port/lib.h" 
1992/0406/sys/src/9/pc/devether.c:79,851992/0407/sys/src/9/pc/devether.c:80,87
1992/0404    
struct Ring { 
	uchar	status; 
	uchar	next; 
	ushort	len; 
1992/0407    
	uchar	len0; 
	uchar	len1; 
1992/0404    
	uchar	data[BUFsize-4]; 
1992/0403    
}; 
 
1992/0406/sys/src/9/pc/devether.c:101,1141992/0407/sys/src/9/pc/devether.c:103,119
1992/0403    
struct Ctlr { 
	QLock; 
 
1992/0407    
	Ring	*ring; 
1992/0403    
	Rendez	rr;			/* rendezvous for an input buffer */ 
1992/0407    
	Queue	rq; 
1992/0404    
	uchar	bnry; 
	uchar	curr; 
	uchar	ovw; 
1992/0403    
	Queue	rq; 
 
1992/0407    
	Etherpkt *xpkt; 
1992/0404    
	QLock	xl; 
1992/0403    
	Rendez	xr; 
1992/0407    
	uchar	xbusy; 
1992/0403    
 
	int	iobase;			/* I/O base address */ 
 
1992/0406/sys/src/9/pc/devether.c:132,1371992/0407/sys/src/9/pc/devether.c:137,150
1992/0403    
}; 
static Ctlr ctlr[Nctlr]; 
 
1992/0407    
static int 
isxfree(void *arg) 
{ 
	Ctlr *cp = arg; 
 
	return cp->xbusy == 0 && cp->ovw == 0; 
} 
 
1992/0403    
static void 
etheroput(Queue *q, Block *bp) 
{ 
1992/0406/sys/src/9/pc/devether.c:184,2051992/0407/sys/src/9/pc/devether.c:197,216
1992/0403    
		} 
	} 
 
1992/0406    
panic("etheroput\n"); 
#ifdef notdef 
1992/0403    
	/* 
	 * only one transmitter at a time 
	 */ 
	qlock(&c->xl); 
1992/0407    
	qlock(&cp->xl); 
1992/0403    
	if(waserror()){ 
		qunlock(&c->xl); 
1992/0407    
		qunlock(&cp->xl); 
1992/0403    
		nexterror(); 
	} 
 
	/* 
	 *  Wait till we get an output buffer 
1992/0407    
	 * Wait till we get an output buffer 
1992/0403    
	 */ 
	sleep(&c->xr, isobuf, c); 
	p = enet.xn; 
1992/0407    
	sleep(&cp->xr, isxfree, cp); 
	p = cp->xpkt; 
1992/0403    
 
	/* 
	 * copy message into buffer 
1992/0406/sys/src/9/pc/devether.c:216,2531992/0407/sys/src/9/pc/devether.c:227,255
1992/0403    
	} 
 
	/* 
	 *  pad the packet (zero the pad) 
1992/0407    
	 * pad the packet (zero the pad) 
1992/0403    
	 */ 
	if(len < ETHERMINTU){ 
		memset(((char*)p)+len, 0, ETHERMINTU-len); 
		len = ETHERMINTU; 
	} 
	enet.xn->len = len; 
 
	/* 
	 *  give packet a local address 
1992/0407    
	 * give packet a local address 
1992/0403    
	 */ 
	memmove(p->s, enet.ea, sizeof(enet.ea)); 
1992/0407    
	memmove(p->s, cp->ea, sizeof(cp->ea)); 
1992/0403    
 
	/* 
	 *  give to Chip 
1992/0407    
	 * start the transmission 
1992/0403    
	 */ 
	splhi();		/* sync with interrupt routine */ 
	enet.xn->owner = Chip; 
	if(enet.xmting == 0) 
		ethersend(enet.xn); 
	spllo(); 
1992/0407    
	outb(cp->iobase+Tbcr0, len & 0xFF); 
	outb(cp->iobase+Tbcr1, (len>>8) & 0xFF); 
	outb(cp->iobase+Cr, 0x26);			/* Page0|TXP|STA */ 
	cp->xbusy = 1; 
1992/0403    
 
	/* 
	 *  send 
	 */ 
	enet.xn = XSUCC(enet.xn); 
	freeb(bp); 
	qunlock(&enet.xl); 
1992/0407    
	qunlock(&cp->xl); 
1992/0403    
	poperror(); 
                 
	enet.outpackets++; 
1992/0404    
#endif 
1992/0403    
} 
 
/* 
1992/0406/sys/src/9/pc/devether.c:370,3761992/0407/sys/src/9/pc/devether.c:372,379
1992/0404    
		if(isr & Ptx) 
			cp->outpackets++; 
		if(isr & (Txe|Ptx)){ 
			panic("tx intr\n"); 
1992/0407    
			cp->xbusy = 0; 
			wakeup(&cp->xr); 
1992/0404    
		} 
		/* 
		 * the receive ring is full. 
1992/0406/sys/src/9/pc/devether.c:422,4271992/0407/sys/src/9/pc/devether.c:425,431
1992/0404    
	outb(cp->iobase+Tcr, 0x20);		/* LB0 */ 
	outb(cp->iobase+Bnry, 6); 
	cp->bnry = 6; 
1992/0407    
	cp->ring = (Ring*)(KZERO|RAMbase); 
1992/0404    
	outb(cp->iobase+Pstart, 6);		/* 6*256 */ 
	outb(cp->iobase+Pstop, 32);		/* 8*1024/256 */ 
	outb(cp->iobase+Isr, 0xFF); 
1992/0406/sys/src/9/pc/devether.c:435,4401992/0407/sys/src/9/pc/devether.c:439,445
1992/0404    
 
	outb(cp->iobase+Cr, 0x22);		/* Page0, RD2|STA */ 
	outb(cp->iobase+Tpsr, 0); 
1992/0407    
	cp->xpkt = (Etherpkt*)(KZERO|RAMbase); 
1992/0403    
} 
 
void 
1992/0406/sys/src/9/pc/devether.c:556,5691992/0407/sys/src/9/pc/devether.c:561,573
1992/0406    
		/* 
		 * process any received packets 
		 */ 
		bnry = inb(cp->iobase+Bnry); 
		while(bnry != cp->curr){ 
			rp = &((Ring*)RAMbase)[bnry]; 
printpkt(bnry, rp->len, (Etherpkt*)rp->data); 
1992/0407    
		cp->bnry = inb(cp->iobase+Bnry); 
		while(cp->bnry != cp->curr){ 
			rp = &cp->ring[cp->bnry]; 
1992/0406    
			cp->inpackets++; 
			etherup(cp, (Etherpkt*)rp->data, rp->len-4); 
			bnry = rp->next; 
			outb(cp->iobase+Bnry, bnry); 
1992/0407    
			etherup(cp, (Etherpkt*)rp->data, ((rp->len1<<8)+rp->len0)-4); 
			cp->bnry = rp->next; 
			outb(cp->iobase+Bnry, cp->bnry); 
1992/0406    
		} 
		/* 
		 * if we idled input because of overflow, 
1992/0406/sys/src/9/pc/devether.c:572,5771992/0407/sys/src/9/pc/devether.c:576,582
1992/0406    
		if(cp->ovw){ 
			cp->ovw = 0; 
			outb(cp->iobase+Tcr, 0); 
1992/0407    
			wakeup(&cp->xr); 
1992/0406    
		} 
1992/0403    
	} 
} 


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