Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/bitsy/devether.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname bitsy/devether.c 2000/1128
## diff -e /dev/null /n/emeliedump/2000/1128/sys/src/9/bitsy/devether.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "../port/error.h"
#include "../port/netif.h"

#include "etherif.h"

static Ether *etherxx[MaxEther];

Chan*
etherattach(char* spec)
{
	ulong ctlrno;
	char *p;
	Chan *chan;

	ctlrno = 0;
	if(spec && *spec){
		ctlrno = strtoul(spec, &p, 0);
		if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther))
			error(Ebadarg);
	}
	if(etherxx[ctlrno] == 0)
		error(Enodev);

	chan = devattach('l', spec);
	chan->dev = ctlrno;
	if(etherxx[ctlrno]->attach)
		etherxx[ctlrno]->attach(etherxx[ctlrno]);
	return chan;
}

static int
etherwalk(Chan* chan, char* name)
{
	return netifwalk(etherxx[chan->dev], chan, name);
}

static void
etherstat(Chan* chan, char* dp)
{
	netifstat(etherxx[chan->dev], chan, dp);
}

static Chan*
etheropen(Chan* chan, int omode)
{
	return netifopen(etherxx[chan->dev], chan, omode);
}

static void
ethercreate(Chan*, char*, int, ulong)
{
}

static void
etherclose(Chan* chan)
{
	netifclose(etherxx[chan->dev], chan);
}

static long
etherread(Chan* chan, void* buf, long n, vlong off)
{
	Ether *ether;
	ulong offset = off;

	ether = etherxx[chan->dev];
	if((chan->qid.path & CHDIR) == 0 && ether->ifstat){
		/*
		 * With some controllers it is necessary to reach
		 * into the chip to extract statistics.
		 */
		if(NETTYPE(chan->qid.path) == Nifstatqid)
			return ether->ifstat(ether, buf, n, offset);
		else if(NETTYPE(chan->qid.path) == Nstatqid)
			ether->ifstat(ether, buf, 0, offset);
	}

	return netifread(ether, chan, buf, n, offset);
}

static Block*
etherbread(Chan* chan, long n, ulong offset)
{
	return netifbread(etherxx[chan->dev], chan, n, offset);
}

static void
etherremove(Chan*)
{
}

static void
etherwstat(Chan* chan, char* dp)
{
	netifwstat(etherxx[chan->dev], chan, dp);
}

static void
etherrtrace(Netfile* f, Etherpkt* pkt, int len)
{
	int i, n;
	Block *bp;

	if(qwindow(f->in) <= 0)
		return;
	if(len > 58)
		n = 58;
	else
		n = len;
	bp = iallocb(64);
	if(bp == nil)
		return;
	memmove(bp->wp, pkt->d, n);
	i = TK2MS(MACHP(0)->ticks);
	bp->wp[58] = len>>8;
	bp->wp[59] = len;
	bp->wp[60] = i>>24;
	bp->wp[61] = i>>16;
	bp->wp[62] = i>>8;
	bp->wp[63] = i;
	bp->wp += 64;
	qpass(f->in, bp);
}

Block*
etheriq(Ether* ether, Block* bp, int fromwire)
{
	Etherpkt *pkt;
	ushort type;
	int len, multi, tome, fromme;
	Netfile **ep, *f, **fp, *fx;
	Block *xbp;

	ether->inpackets++;

	pkt = (Etherpkt*)bp->rp;
	len = BLEN(bp);
	type = (pkt->type[0]<<8)|pkt->type[1];
	fx = 0;
	ep = &ether->f[Ntypes];

	multi = pkt->d[0] & 1;
	/* check for valid multcast addresses */
	if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){
		if(!activemulti(ether, pkt->d, sizeof(pkt->d))){
			if(fromwire){
				freeb(bp);
				bp = 0;
			}
			return bp;
		}
	}

	/* is it for me? */
	tome = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
	fromme = memcmp(pkt->s, ether->ea, sizeof(pkt->s)) == 0;

	/*
	 * Multiplex the packet to all the connections which want it.
	 * If the packet is not to be used subsequently (fromwire != 0),
	 * attempt to simply pass it into one of the connections, thereby
	 * saving a copy of the data (usual case hopefully).
	 */
	for(fp = ether->f; fp < ep; fp++){
		if(f = *fp)
		if(f->type == type || f->type < 0)
		if(tome || multi || f->prom){
			/* Don't want to hear bridged packets */
			if(f->bridge && !fromwire && !fromme)
				continue;
			if(!f->headersonly){
				if(fromwire && fx == 0)
					fx = f;
				else if(xbp = iallocb(len)){
					memmove(xbp->wp, pkt, len);
					xbp->wp += len;
					qpass(f->in, xbp);
				}
				else
					ether->soverflows++;
			}
			else
				etherrtrace(f, pkt, len);
		}
	}

	if(fx){
		if(qpass(fx->in, bp) < 0)
			ether->soverflows++;
		return 0;
	}
	if(fromwire){
		freeb(bp);
		return 0;
	}

	return bp;
}

static int
etheroq(Ether* ether, Block* bp)
{
	int len, loopback, s;
	Etherpkt *pkt;

	ether->outpackets++;

	/*
	 * Check if the packet has to be placed back onto the input queue,
	 * i.e. if it's a loopback or broadcast packet or the interface is
	 * in promiscuous mode.
	 * If it's a loopback packet indicate to etheriq that the data isn't
	 * needed and return, etheriq will pass-on or free the block.
	 * To enable bridging to work, only packets that were originated
	 * by this interface are fed back.
	 */
	pkt = (Etherpkt*)bp->rp;
	len = BLEN(bp);
	loopback = memcmp(pkt->d, ether->ea, sizeof(pkt->d)) == 0;
	if(loopback || memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) == 0 || ether->prom){
		s = splhi();
		etheriq(ether, bp, 0);
		splx(s);
	}

	if(!loopback){
		qbwrite(ether->oq, bp);
		ether->transmit(ether);
	} else
		freeb(bp);

	return len;
}

static long
etherwrite(Chan* chan, void* buf, long n, vlong)
{
	Ether *ether;
	Block *bp;
	int nn;

	ether = etherxx[chan->dev];
	if(NETTYPE(chan->qid.path) != Ndataqid) {
		nn = netifwrite(ether, chan, buf, n);
		if(nn >= 0)
			return nn;

		if(ether->ctl!=nil)
			return ether->ctl(ether,buf,n);
			
		error(Ebadctl);
	}

	if(n > ether->maxmtu)
		error(Etoobig);
	if(n < ether->minmtu)
		error(Etoosmall);

	bp = allocb(n);
	memmove(bp->rp, buf, n);
	memmove(bp->rp+Eaddrlen, ether->ea, Eaddrlen);
	bp->wp += n;

	return etheroq(ether, bp);
}

static long
etherbwrite(Chan* chan, Block* bp, ulong)
{
	Ether *ether;
	long n;

	n = BLEN(bp);
	if(NETTYPE(chan->qid.path) != Ndataqid){
		if(waserror()) {
			freeb(bp);
			nexterror();
		}
		n = etherwrite(chan, bp->rp, n, 0);
		poperror();
		freeb(bp);
		return n;
	}
	ether = etherxx[chan->dev];

	if(n > ether->maxmtu){
		freeb(bp);
		error(Etoobig);
	}
	if(n < ether->minmtu){
		freeb(bp);
		error(Etoosmall);
	}

	return etheroq(ether, bp);
}

static struct {
	char*	type;
	int	(*reset)(Ether*);
} cards[MaxEther+1];

void
addethercard(char* t, int (*r)(Ether*))
{
	static int ncard;

	if(ncard == MaxEther)
		panic("too many ether cards");
	cards[ncard].type = t;
	cards[ncard].reset = r;
	ncard++;
}

int
parseether(uchar *to, char *from)
{
	char nip[4];
	char *p;
	int i;

	p = from;
	for(i = 0; i < 6; i++){
		if(*p == 0)
			return -1;
		nip[0] = *p++;
		if(*p == 0)
			return -1;
		nip[1] = *p++;
		nip[2] = 0;
		to[i] = strtoul(nip, 0, 16);
		if(*p == ':')
			p++;
	}
	return 0;
}

static void
etherreset(void)
{
	Ether *ether;
	int i, n, ctlrno;
	char name[NAMELEN], buf[128];

	for(ether = 0, ctlrno = 0; ctlrno < MaxEther; ctlrno++){
		if(ether == 0)
			ether = malloc(sizeof(Ether));
		memset(ether, 0, sizeof(Ether));
		ether->ctlrno = ctlrno;
		ether->tbdf = BUSUNKNOWN;
		ether->mbps = 10;
		ether->minmtu = ETHERMINTU;
		ether->maxmtu = ETHERMAXTU;
		if(isaconfig("ether", ctlrno, ether) == 0)
			continue;
		for(n = 0; cards[n].type; n++){
			if(cistrcmp(cards[n].type, ether->type))
				continue;
			for(i = 0; i < ether->nopt; i++){
				if(strncmp(ether->opt[i], "ea=", 3))
					continue;
				if(parseether(ether->ea, &ether->opt[i][3]) == -1)
					memset(ether->ea, 0, Eaddrlen);
			}	
			if(cards[n].reset(ether))
				break;

			/*
			 * IRQ2 doesn't really exist, it's used to gang the interrupt
			 * controllers together. A device set to IRQ2 will appear on
			 * the second interrupt controller as IRQ9.
			 */
			if(ether->irq == 2)
				ether->irq = 9;
			snprint(name, sizeof(name), "ether%d", ctlrno);

			/* If ether->irq is less than 0, it is a hack to indicate no interrupt
			 * used for the second logical ethernet for the wavelan card
			 */
			if(ether->irq >= 0)
				intrenable(ether->irq, ether->interrupt, ether, ether->tbdf, name);

			i = sprint(buf, "#l%d: %s: %dMbps port 0x%luX irq %lud",
				ctlrno, ether->type, ether->mbps, ether->port, ether->irq);
			if(ether->mem)
				i += sprint(buf+i, " addr 0x%luX", PADDR(ether->mem));
			if(ether->size)
				i += sprint(buf+i, " size 0x%luX", ether->size);
			i += sprint(buf+i, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX",
				ether->ea[0], ether->ea[1], ether->ea[2],
				ether->ea[3], ether->ea[4], ether->ea[5]);
			sprint(buf+i, "\n");
			print(buf);

			if(ether->mbps >= 100){
				netifinit(ether, name, Ntypes, 256*1024);
				if(ether->oq == 0)
					ether->oq = qopen(256*1024, 1, 0, 0);
			}
			else{
				netifinit(ether, name, Ntypes, 65*1024);
				if(ether->oq == 0)
					ether->oq = qopen(65*1024, 1, 0, 0);
			}
			if(ether->oq == 0)
				panic("etherreset %s", name);
			ether->alen = Eaddrlen;
			memmove(ether->addr, ether->ea, Eaddrlen);
			memset(ether->bcast, 0xFF, Eaddrlen);

			etherxx[ctlrno] = ether;
			ether = 0;
			break;
		}
	}
	if(ether)
		free(ether);
}

#define POLY 0xedb88320

/* really slow 32 bit crc for ethers */
ulong
ethercrc(uchar *p, int len)
{
	int i, j;
	ulong crc, b;

	crc = 0xffffffff;
	for(i = 0; i < len; i++){
		b = *p++;
		for(j = 0; j < 8; j++){
			crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0);
			b >>= 1;
		}
	}
	return crc;
}

Dev etherdevtab = {
	'l',
	"ether",

	etherreset,
	devinit,
	etherattach,
	devclone,
	etherwalk,
	etherstat,
	etheropen,
	ethercreate,
	etherclose,
	etherread,
	etherbread,
	etherwrite,
	etherbwrite,
	etherremove,
	etherwstat,
};
.
## diffname bitsy/devether.c 2000/1205
## diff -e /n/emeliedump/2000/1128/sys/src/9/bitsy/devether.c /n/emeliedump/2000/1205/sys/src/9/bitsy/devether.c
465a
	nil,		/* no power management */
	etherconfig,
.
348,424d
305,321d
14a
static struct {
	char*	type;
	int	(*reset)(Ether*);
} cards[MaxEther+1];

void
addethercard(char* t, int (*r)(Ether*))
{
	static int ncard;

	if(ncard == MaxEther)
		panic("too many ether cards");
	cards[ncard].type = t;
	cards[ncard].reset = r;
	ncard++;
}

int
etherconfig(int on, char *spec, DevConf *cf)
{
	Ether *ether;
	int n, ctlrno;
	char name[NAMELEN], buf[128];
	char *p, *e;

	/* can't unconfigure yet */
	if(on == 0)
		return -1;

	ctlrno = atoi(spec);
	if(etherxx[ctlrno] != nil)
		return -1;

	ether = malloc(sizeof(Ether));
	if(ether == nil)
		panic("etherconfig");
	memset(ether, 0, sizeof(Ether));
	*(DevConf*)ether = *cf;

print("looking for card type %s\n", ether->type);
	for(n = 0; cards[n].type; n++){
		if(strcmp(cards[n].type, ether->type) != 0)
			continue;
print("found card type %s\n", ether->type);
		if(cards[n].reset(ether))
			break;
		sprint(name, "ether%d", ctlrno);

		if(ether->mbps >= 100){
			netifinit(ether, name, Ntypes, 256*1024);
			if(ether->oq == 0)
				ether->oq = qopen(256*1024, 1, 0, 0);
		}
		else{
			netifinit(ether, name, Ntypes, 65*1024);
			if(ether->oq == 0)
				ether->oq = qopen(65*1024, 1, 0, 0);
		}
		if(ether->oq == 0)
			panic("etherreset %s", name);
		ether->alen = Eaddrlen;
		memmove(ether->addr, ether->ea, Eaddrlen);
		memset(ether->bcast, 0xFF, Eaddrlen);

		if(ether->interrupt != nil)
			intrenable(cf->itype, cf->interrupt, ether->interrupt, ether, name);

		p = buf;
		e = buf+sizeof(buf);
		p = seprint(p, e, "#l%d: %s: %dMbps port 0x%luX",
			ctlrno, ether->type, ether->mbps, ether->port);
		if(ether->mem)
			p = seprint(p, e, " addr 0x%luX", PADDR(ether->mem));
		if(ether->size)
			p = seprint(p, e, " size 0x%luX", ether->size);
		p = seprint(p, e, ": %2.2uX%2.2uX%2.2uX%2.2uX%2.2uX%2.2uX",
			ether->ea[0], ether->ea[1], ether->ea[2],
			ether->ea[3], ether->ea[4], ether->ea[5]);
		seprint(p, e, "\n");
		print(buf);

		etherxx[ctlrno] = ether;
		return 0;
	}

	free(ether);
	return -1;
}



.
## diffname bitsy/devether.c 2000/1206
## diff -e /n/emeliedump/2000/1205/sys/src/9/bitsy/devether.c /n/emeliedump/2000/1206/sys/src/9/bitsy/devether.c
94c
		pprint(buf);
.
77a
		ether->mbps = 10;
		ether->minmtu = ETHERMINTU;
		ether->maxmtu = ETHERMAXTU;
.
58d
54d
## diffname bitsy/devether.c 2001/0529
## diff -e /n/emeliedump/2000/1206/sys/src/9/bitsy/devether.c /n/emeliedump/2001/0529/sys/src/9/bitsy/devether.c
452d
194c
	return netifwstat(etherxx[chan->dev], chan, dp, n);
.
191,192c
static int
etherwstat(Chan* chan, uchar* dp, int n)
.
166c
	if((chan->qid.type & QTDIR) == 0 && ether->ifstat){
.
139c
	return netifstat(etherxx[chan->dev], chan, dp, n);
.
136,137c
static int
etherstat(Chan* chan, uchar* dp, int n)
.
133c
	return netifwalk(etherxx[chan->dev], chan, nchan, name, nname);
.
130,131c
static Walkqid*
etherwalk(Chan* chan, Chan* nchan, char** name, int nname)
.
100a
	if (ether->type)
		free(ether->type);
.
37c
	char name[32], buf[128];
.
## diffname bitsy/devether.c 2001/1204
## diff -e /n/emeliedump/2001/0529/sys/src/9/bitsy/devether.c /n/emeliedump/2001/1204/sys/src/9/bitsy/devether.c
463c
	devremove,
.
188,192d
## diffname bitsy/devether.c 2002/0109
## diff -e /n/emeliedump/2001/1204/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0109/sys/src/9/bitsy/devether.c
447a
	devshutdown,
.
## diffname bitsy/devether.c 2002/0404
## diff -e /n/emeliedump/2002/0109/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0404/sys/src/9/bitsy/devether.c
90c
			p = seprint(p, e, " size 0x%X", ether->size);
.
## diffname bitsy/devether.c 2002/0613
## diff -e /n/emeliedump/2002/0404/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0613/sys/src/9/bitsy/devether.c
389a
	runlock(etherxx[chan->dev]);
.
387a
		runlock(etherxx[chan->dev]);
.
383a
		runlock(etherxx[chan->dev]);
.
379a
	rlock(etherxx[chan->dev]);
.
360c
	l = etheroq(ether, bp);
	runlock(etherxx[chan->dev]);
	return l;
.
354c
	}
.
352c
	}
	if(n < ether->minmtu){
		runlock(etherxx[chan->dev]);
.
350c
	if(n > ether->maxmtu){
		runlock(etherxx[chan->dev]);
.
343,346c
		}
		if(ether->ctl!=nil){
			l = ether->ctl(ether,buf,n);
			runlock(etherxx[chan->dev]);
			return l;
		}
		runlock(etherxx[chan->dev]);
.
341c
		if(nn >= 0){
			runlock(etherxx[chan->dev]);
.
338a
	rlock(etherxx[chan->dev]);
.
336a
	long l;
.
191c
	rlock(etherxx[chan->dev]);
	n = netifwstat(etherxx[chan->dev], chan, dp, n);
	runlock(etherxx[chan->dev]);
	return n;
.
185c
	Block *b;

	rlock(etherxx[chan->dev]);
	b = netifbread(etherxx[chan->dev], chan, n, offset);
	runlock(etherxx[chan->dev]);
	return b;
.
179c
	n = netifread(ether, chan, buf, n, offset);
	runlock(ether);
	return n;
.
167a
	rlock(ether);
.
165a
	long n;
.
158a
	runlock(etherxx[chan->dev]);
.
157a
	rlock(etherxx[chan->dev]);
.
147c
	Chan *c;

	rlock(etherxx[chan->dev]);
	c = netifopen(etherxx[chan->dev], chan, omode);
	runlock(etherxx[chan->dev]);
	return c;
.
141c
	int s;

	rlock(etherxx[chan->dev]);
	s = netifstat(etherxx[chan->dev], chan, dp, n);
	runlock(etherxx[chan->dev]);
	return s;
.
135c
	Walkqid *q;

	rlock(etherxx[chan->dev]);
	q = netifwalk(etherxx[chan->dev], chan, nchan, name, nname);
	runlock(etherxx[chan->dev]);
	return q;
.
128a
	runlock(etherxx[ctlrno]);
.
124a
	rlock(etherxx[ctlrno]);
.
47a
	/* can't unconfigure yet */
	if(on == 0){
		return -1;
	}

.
40,43d
## diffname bitsy/devether.c 2002/0614
## diff -e /n/emeliedump/2002/0613/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0614/sys/src/9/bitsy/devether.c
436,438c
	n = etheroq(ether, bp);
	poperror();
	runlock(ether);
	return n;
.
433d
428d
425c
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether){
		freeb(bp);
		error(Enodev);
	}
.
423d
402c
out:
	poperror();
	runlock(ether);
.
395d
391,393c
	if(n < ether->minmtu)
.
388,389c
	if(n > ether->maxmtu)
.
384d
381,382c
			goto out;
.
374,378c
		l = netifwrite(ether, chan, buf, n);
		if(l >= 0)
			goto out;
.
372c
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
.
368d
220,222c
	Ether *ether;

	ether = etherxx[chan->dev];
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
	n = netifwstat(ether, chan, dp, n);
	poperror();
	runlock(ether);
.
211,213c
	ether = etherxx[chan->dev];
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
	b = netifbread(ether, chan, n, offset);
	poperror();
	runlock(ether);
.
209a
	Ether *ether;
.
199,201c
			n = netifread(ether, chan, buf, n, offset);
		}
	}else
		n = netifread(ether, chan, buf, n, offset);
	poperror();
.
196,197c
			n = ether->ifstat(ether, buf, n, offset);
		else if(NETTYPE(chan->qid.path) == Nstatqid){
.
189a
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
.
188a
	if(ether == &noether)
		error(Enodev);
.
186d
176,178c
	Ether *ether;

	ether = etherxx[chan->dev];
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
	netifclose(ether, chan);
	poperror();
	runlock(ether);
.
162,164c
	ether = etherxx[chan->dev];
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
	c = netifopen(ether, chan, omode);
	poperror();
	runlock(ether);
.
160a
	Ether *ether;
.
151,153c
	ether = etherxx[chan->dev];
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
	s = netifstat(ether, chan, dp, n);
	poperror();
	runlock(ether);
.
149a
	Ether *ether;
.
140,142c
	ether = etherxx[chan->dev];
	if(ether == &noether)
		error(Enodev);
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[chan->dev] == &noether)
		error(Enodev);
	q = netifwalk(ether, chan, nchan, name, nname);
	poperror();
	runlock(ether);
.
138a
	Ether *ether;
.
129,131c
	if(ether->attach)
		ether->attach(ether);
	poperror();
	runlock(ether);
.
125,126c
	rlock(ether);
	if(waserror()) {
		runlock(ether);
		nexterror();
	}
	if(etherxx[ctlrno] == &noether)
		error(Enodev);
.
123c
	ether = etherxx[ctlrno];
	if(ether == 0 || ether == &noether)
.
115a
	Ether *ether;
.
108,109d
48a
	if(etherxx[ctlrno] != nil && etherxx[ctlrno] != &noether)
		return -1;

.
46c
		ether = etherxx[ctlrno];
		if(ether == nil || ether == &noether)
			return -1;
print("unconfigure\n");
		wlock(ether);
		if(waserror()) {
			wunlock(ether);
			nexterror();
		}
		if(ether == &noether)
			error(Enodev);
		etherxx[ctlrno] = &noether;
		wunlock(ether);
		poperror();
print("unconfigure: done\n");
		return 0;
.
44d
41,42d
13c
static Ether noether;
static volatile Ether *etherxx[MaxEther];
.
## diffname bitsy/devether.c 2002/0615
## diff -e /n/emeliedump/2002/0614/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0615/sys/src/9/bitsy/devether.c
98c
			intrenable(cf->itype, cf->intnum, ether->interrupt, ether, name);
.
76d
68d
54a

		if(ether->detach)
			ether->detach(ether);

		if(ether->interrupt != nil)
			intrdisable(ether->itype, ether->intnum, ether->interrupt, ether, name);

.
41a
	sprint(name, "ether%d", ctlrno);
.
## diffname bitsy/devether.c 2002/0617
## diff -e /n/emeliedump/2002/0615/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0617/sys/src/9/bitsy/devether.c
622c
	etherpower,
.
537c
	if(ether == &noether){
.
530,531d
483c
	if(ether == &noether)
.
476,477d
323c
	if(ether == &noether)
.
316,317d
302c
	if(ether == &noether)
.
295d
268c
	if(ether == &noether)
.
261,262d
247c
	if(ether == &noether)
.
240,241d
221c
	if(ether == &noether)
.
214,215d
199c
	if(ether == &noether)
.
192,193d
177c
	if(ether == &noether)
.
170,171d
32a
void
etherpower(int on)
{
	/* Power all ether cards on or off */

	for (i = 0; i < MaxEther; i++){
		ether = etherxx[i];
		if (ether == nil)
			continue;
		if(on){
			if (ether->write == 0){
				print("etherpower: already powered up\n");
				continue;
			}
			if (ether->power)
				ether->power(ether, on);
			wunlock(ether);
			/* Unlock when power restored */
		}else{
			if (ether->write != 0){
				print("etherpower: already powered down\n");
				continue;
			}
			/* Keep locked until power goes back on */
			wlock(ether);
			if (ether == &noether){
				/* Locked an unconfigured card, undo */
				wunlock(ether);
				continue;
			}
			if (ether->power)
				ether->power(ether, on);
		}
	}
}

.
## diffname bitsy/devether.c 2002/0618
## diff -e /n/emeliedump/2002/0617/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0618/sys/src/9/bitsy/devether.c
555,558d
504,505d
346,347d
327,328d
321d
311c
	return r;
.
307,308c
		if(NETTYPE(chan->qid.path) == Nstatqid)
			ether->ifstat(ether, buf, 0, offset);
	}
	r = netifread(ether, chan, buf, n, offset);
out:
.
301,305c
		if(NETTYPE(chan->qid.path) == Nifstatqid){
			r = ether->ifstat(ether, buf, n, offset);
			goto out;
.
294,295d
286a
	long r;
.
275,276d
251,252d
231,232d
211,212d
188,189d
181c
	if(ether == 0)
.
93,106c
	if(etherxx[ctlrno] != nil)
.
80,91c
	if(on == 0)
		return -1;
.
58,62d
52c
			if (ether->writer != 0){
.
43c
			if (ether->writer == 0){
.
37a
print("etherpower %d\n", on);
.
35a
	int i;
	Ether *ether;
.
13d
## diffname bitsy/devether.c 2002/0619
## diff -e /n/emeliedump/2002/0618/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0619/sys/src/9/bitsy/devether.c
310c
	return r;
.
307c
	r = netifwstat(ether, chan, dp, n);
.
299a
	int r;
.
154,155c
	if((ether = etherxx[ctlrno]) == 0)
.
41,42c
		if ((ether = etherxx[i]) == nil)
.
## diffname bitsy/devether.c 2002/0626
## diff -e /n/emeliedump/2002/0619/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0626/sys/src/9/bitsy/devether.c
39c
iprint("etherpower %d\n", on);
.
## diffname bitsy/devether.c 2002/0703
## diff -e /n/emeliedump/2002/0626/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0703/sys/src/9/bitsy/devether.c
113c
			intrenable(cf->itype, cf->irq, ether->interrupt, ether, name);
.
## diffname bitsy/devether.c 2002/0711
## diff -e /n/emeliedump/2002/0703/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0711/sys/src/9/bitsy/devether.c
101c
				ether->oq = qopen(65*1024, Qmsg, 0, 0);
.
96c
				ether->oq = qopen(256*1024, Qmsg, 0, 0);
.
## diffname bitsy/devether.c 2002/0712
## diff -e /n/emeliedump/2002/0711/sys/src/9/bitsy/devether.c /n/emeliedump/2002/0712/sys/src/9/bitsy/devether.c
465a
		if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){
			qnoblock(ether->oq, 1);
			goto out;
		}
.
## diffname bitsy/devether.c 2002/1112
## diff -e /n/emeliedump/2002/0712/sys/src/9/bitsy/devether.c /n/emeliedump/2002/1112/sys/src/9/bitsy/devether.c
121,122c
		if(ether->ports[0].size)
			p = seprint(p, e, " size 0x%X", ether->ports[0].size);
.
118c
			ctlrno, ether->type, ether->mbps, ether->ports[0].port);
.
113c
			intrenable(cf->itype, cf->intnum, ether->interrupt, ether, name);
.
85c
	ether->DevConf = *cf;
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.