~kris/9p

9hist

88c36e8e0f7fc54f589dcedb1be7f8b3452c2fe6 — David du Colombier 34 years ago a538d06
Plan 9 from Bell Labs 1992-09-17
3 files changed, 149 insertions(+), 50 deletions(-)

M pc/devether.c
M pc/l.s
M port/stasync.c
M pc/devether.c => pc/devether.c +107 -37
@@ 13,7 13,7 @@ typedef struct Type Type;
typedef struct Ctlr Ctlr;

struct Hw {
	void	(*reset)(Ctlr*);
	int	(*reset)(Ctlr*);
	void	(*init)(Ctlr*);
	void	(*mode)(Ctlr*, int);
	void	(*online)(Ctlr*, int);


@@ 77,6 77,7 @@ struct Ctlr {
	QLock;

	Hw	*hw;
	int	present;

	ushort	nrb;		/* number of software receive buffers */
	ushort	ntb;		/* number of software transmit buffers */


@@ 116,6 117,8 @@ static Ctlr ctlr[Nctlr];
Chan*
etherattach(char *spec)
{
	if(ctlr[0].present == 0)
		error(Enodev);
	return devattach('l', spec);
}



@@ 498,7 501,11 @@ etherreset(void)

	cp = &ctlr[0];
	cp->hw = &wd8013;
	(*cp->hw->reset)(cp);
	if((*cp->hw->reset)(cp) < 0){
		cp->present = 0;
		return;
	}
	cp->present = 1;

	memset(cp->ba, 0xFF, sizeof(cp->ba));



@@ 524,6 531,9 @@ etherinit(void)
	Ctlr *cp = &ctlr[ctlrno];
	int i;

	if(cp->present == 0)
		return;

	cp->rh = 0;
	cp->ri = 0;
	for(i = 0; i < cp->nrb; i++)


@@ 601,14 611,49 @@ typedef struct {
			uchar	curr;
			uchar	mar[8];
		};
		struct {			/* Page2, read */
			uchar	cr;
			uchar	pstart;
			uchar	pstop;
			uchar	dummy1[1];
			uchar	tstart;
			uchar	next;
			uchar	block;
			uchar	enh;
			uchar	dummy2[4];
			uchar	rcon;
			uchar	tcon;
			uchar	dcon;
			uchar	intmask;
		} r2;
		struct {			/* Page2, write */
			uchar	cr;
			uchar	trincrl;
			uchar	trincrh;
			uchar	dummy1[2];
			uchar	next;
			uchar	block;
			uchar	enh;
		} w2;
	};
} Wd8013;

enum {
	MENB		= 0x40,			/* memory enable */

	L16EN		= 0x40,			/* enable 16-bit LAN operation */
	M16EN		= 0x80,			/* enable 16-bit memory access */
	/* bit definitions for laar */
	ZeroWS16	= (1<<5),		/* zero wait states for 16-bit ops */
	L16EN		= (1<<6),		/* enable 16-bit LAN operation */
	M16EN		= (1<<7),		/* enable 16-bit memory access */

	/* bit defintitions for DP8390/83C690 cr */
	Page0		= (0<<6),
	Page1		= (1<<6),
	Page2		= (2<<6),
	RD2		= (4<<3),
	TXP		= (1<<2),
	STA		= (1<<1),
	STP		= (1<<0),
};

#define IN(hw, m)	inb((hw)->addr+OFFSETOF(Wd8013, m))


@@ 648,10 693,11 @@ int intrmap[] =
	9, 3, 5, 7, 10, 11, 15, 4,
};


/*
 *  get configuration parameters, enable memory
 */
static void
static int
wd8013reset(Ctlr *cp)
{
	Hw *hw = cp->hw;


@@ 662,6 708,14 @@ wd8013reset(Ctlr *cp)
	uchar irr;
	ulong ram;

	msr = IN(hw, msr);
	icr = IN(hw, icr);
	irr = IN(hw, irr);
	laar = IN(hw, laar);

	if(msr == 0xff || icr == 0xff || irr == 0xff || laar == 0xff)
		return -1;

	if(cp->rb == 0){
		cp->rb = xspanalloc(sizeof(Buffer)*Nrb, BY2PG, 0);
		cp->nrb = Nrb;


@@ 669,11 723,6 @@ wd8013reset(Ctlr *cp)
		cp->ntb = Ntb;
	}

	msr = IN(hw, msr);
	icr = IN(hw, icr);
	irr = IN(hw, irr);
	laar = IN(hw, laar);

	/* ethernet address */
	for(i = 0; i < sizeof(cp->ea); i++)
		cp->ea[i] = IN(hw, lan[i]);


@@ 708,10 757,11 @@ wd8013reset(Ctlr *cp)
	/* enable interface RAM, set interface width */
	OUT(hw, msr, MENB|msr);
	if(hw->bt16)
		OUT(hw, laar, laar|L16EN|M16EN);
		OUT(hw, laar, laar|L16EN|M16EN|ZeroWS16);

	(*hw->init)(cp);
	setvec(Int0vec + hw->lvl, hw->intr);
	return 0;
}

static void


@@ 719,11 769,11 @@ dp8390rinit(Ctlr *cp)
{
	Hw *hw = cp->hw;

	OUT(hw, w.cr, 0x21);			/* Page0|RD2|STP */
	OUT(hw, w.cr, Page0|RD2|STP);
	OUT(hw, w.bnry, hw->pstart);
	OUT(hw, w.cr, 0x61);			/* Page1|RD2|STP */
	OUT(hw, w.cr, Page1|RD2|STP);
	OUT(hw, curr, hw->pstart+1);
	OUT(hw, w.cr, 0x22);			/* Page0|RD2|STA */
	OUT(hw, w.cr, Page0|RD2|STA);
}

/*


@@ 736,9 786,9 @@ dp8390init(Ctlr *cp)
	Hw *hw = cp->hw;
	int i;

	OUT(hw, w.cr, 0x21);			/* Page0|RD2|STP */
	OUT(hw, w.cr, Page0|RD2|STP);
	if(hw->bt16)
		OUT(hw, w.dcr, 0x01);		/* 16 bit interface */
		OUT(hw, w.dcr, (1<<0)|(3<<5));	/* 16 bit interface, 12 byte DMA burst */
	else
		OUT(hw, w.dcr, 0x48);		/* FT1|LS */
	OUT(hw, w.rbcr0, 0);


@@ 755,12 805,12 @@ dp8390init(Ctlr *cp)
	OUT(hw, w.isr, 0xFF);
	OUT(hw, w.imr, 0x1F);			/* OVWE|TXEE|RXEE|PTXE|PRXE */

	OUT(hw, w.cr, 0x61);			/* Page1|RD2|STP */
	OUT(hw, w.cr, Page1|RD2|STP);
	for(i = 0; i < sizeof(cp->ea); i++)
		OUT(hw, par[i], cp->ea[i]);
	OUT(hw, curr, hw->pstart+1);

	OUT(hw, w.cr, 0x22);			/* Page0|RD2|STA */
	OUT(hw, w.cr, Page0|RD2|STA);
	OUT(hw, w.tpsr, 0);
}



@@ 810,6 860,29 @@ wd8013tweek(Ctlr *cp)
	splx(s);
}

/*
 *  hack to keep away from the card's memory while it is receiving
 *  a packet.  This is only a problem on the NCR 3170 safari.
 *
 *  we peek at the DMA registers and, if they are changing, wait.
 */
void
waitfordma(Hw *hw)
{
	uchar a,b,c;

	for(;;delay(10)){
		a = IN(hw, r.clda0);
		b = IN(hw, r.clda0);
		if(a != b)
			continue;
		c = IN(hw, r.clda0);
		if(c != b)
			continue;
		break;
	}
}

static void
wd8013receive(Ctlr *cp)
{


@@ 817,29 890,28 @@ wd8013receive(Ctlr *cp)
	Buffer *rb;
	uchar bnry, curr, next;
	Ring *p;
	int len;
	int i, len;

	bnry = IN(hw, r.bnry);
	next = bnry+1;
	if(next >= hw->pstop)
		next = hw->pstart;
	for(;;){
		OUT(hw, w.cr, 0x62);		/* Page1|RD2|STA */
	for(i = 0; ; i++){
		OUT(hw, w.cr, Page1|RD2|STA);
		curr = IN(hw, curr);
		OUT(hw, w.cr, 0x22);		/* Page0|RD2|STA */
		OUT(hw, w.cr, Page0|RD2|STA);
		if(next == curr)
			break;
		waitfordma(hw);
		cp->inpackets++;
		p = &((Ring*)hw->ram)[next];
		len = ((p->len1<<8)|p->len0)-4;
		if(p->next < hw->pstart || p->next >= hw->pstop || len < 60){
/*			print("%d/%d : #%2.2ux #%2.2ux  #%2.2ux #%2.2ux\n", next, len,
			/*print("%d/%d : #%2.2ux #%2.2ux  #%2.2ux #%2.2ux\n", next, len,
				p->status, p->next, p->len0, p->len1);/**/
			delay(100);
			dp8390rinit(cp);
			break;
		}

		rb = &cp->rb[cp->ri];
		if(rb->owner == Interface){
			rb->len = len;


@@ 853,14 925,12 @@ wd8013receive(Ctlr *cp)
			rb->owner = Host;
			cp->ri = NEXT(cp->ri, cp->nrb);
		}

		p->status = 0;
		next = p->next;
		bnry = next-1;
		if(bnry < hw->pstart)
			bnry = hw->pstop-1;
		OUT(hw, w.bnry, bnry);
		break;
	}
}



@@ 878,7 948,7 @@ wd8013transmit(Ctlr *cp)
		memmove(hw->ram, tb->pkt, tb->len);
		OUT(hw, w.tbcr0, tb->len & 0xFF);
		OUT(hw, w.tbcr1, (tb->len>>8) & 0xFF);
		OUT(hw, w.cr, 0x26);		/* Page0|RD2|TXP|STA */
		OUT(hw, w.cr, Page0|RD2|TXP|STA);
		tb->busy = 1;
	}
	splx(s);


@@ 895,6 965,15 @@ wd8013intr(Ureg *ur)
	USED(ur);
	while(isr = IN(hw, r.isr)){
		OUT(hw, w.isr, isr);
		/*
		 * we have received packets.
		 */
		if(isr & (0x04|0x01)){		/* Rxe|Prx - packet received */
			(*cp->hw->receive)(cp);
			wakeup(&cp->rr);
		}
		if(isr & 0x10)			/* Ovw - overwrite warning */
			cp->overflows++;
		if(isr & 0x08)			/* Txe - transmit error */
			cp->oerrs++;
		if(isr & 0x04){			/* Rxe - receive error */


@@ 917,15 996,6 @@ wd8013intr(Ureg *ur)
			(*cp->hw->transmit)(cp);
			wakeup(&cp->tr);
		}
		if(isr & 0x10)			/* Ovw - overwrite warning */
			cp->overflows++;
		/*
		 * we have received packets.
		 */
		if(isr & (0x04|0x01)){		/* Rxe|Prx - packet received */
			(*cp->hw->receive)(cp);
			wakeup(&cp->rr);
		}
	}
}


M pc/l.s => pc/l.s +37 -11
@@ 220,27 220,21 @@ TEXT	outb(SB),$0
	RET

/*
 * input a short
 * input a short from a port
 */
TEXT ins(SB), $0
TEXT	ins(SB), $0

	MOVL	p+0(FP), DX
	XORL	AX, AX
	OP16; INSL
	INL
	RET

/*
 * output a short
 */
TEXT outs(SB), $0
	MOVL	p+0(FP), DX
	MOVL	s+4(FP), AX
	OP16; OUTSL
	RET

/*
 *  input a string of shorts from a port
 */
TEXT	inss(SB),$0

	MOVL	p+0(FP),DX
	MOVL	a+4(FP),DI
	MOVL	c+8(FP),CX


@@ 248,9 242,30 @@ TEXT	inss(SB),$0
	RET

/*
 *  input a string of longs from a port
 */
TEXT	insl(SB),$0

	MOVL	p+0(FP),DX
	MOVL	a+4(FP),DI
	MOVL	c+8(FP),CX
	CLD; REP; INSL
	RET

/*
 * output a short to a port
 */
TEXT	outs(SB), $0
	MOVL	p+0(FP), DX
	MOVL	s+4(FP), AX
	OUTL
	RET

/*
 *  output a string of shorts to a port
 */
TEXT	outss(SB),$0

	MOVL	p+0(FP),DX
	MOVL	a+4(FP),SI
	MOVL	c+8(FP),CX


@@ 258,6 273,17 @@ TEXT	outss(SB),$0
	RET

/*
 *  output a string of longs to a port
 */
TEXT	outsl(SB),$0

	MOVL	p+0(FP),DX
	MOVL	a+4(FP),SI
	MOVL	c+8(FP),CX
	CLD; REP; OUTSL
	RET

/*
 *  test and set
 */
TEXT	tas(SB),$0

M port/stasync.c => port/stasync.c +5 -2
@@ 265,9 265,12 @@ asyncoput(Queue *q, Block *bp)
	Block *msg;

	if(bp->type != M_DATA){
		if(streamparse("debug", bp))
		if(streamparse("debug", bp)){
			asyncdebug = 3;
		freeb(bp);
			freeb(bp);
		} else {
			PUTNEXT(q, bp);
		}
		return;
	}