⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ether.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "u.h"#include "lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "ip.h"#include "etherif.h"static Ether ether[MaxEther];extern int ether2114xreset(Ether*);extern int elnk3reset(Ether*);extern int i82557reset(Ether*);extern int igbepnp(Ether *);extern int elnk3reset(Ether*);extern int ether589reset(Ether*);extern int ne2000reset(Ether*);extern int wd8003reset(Ether*);extern int ec2treset(Ether*);extern int amd79c970reset(Ether*);extern int rtl8139pnp(Ether*);extern int rtl8169pnp(Ether*);extern int ether83815reset(Ether*);extern int rhinepnp(Ether*);struct {	char	*type;	int	(*reset)(Ether*);	int	noprobe;} ethercards[] = {	{ "21140", ether2114xreset, 0, },	{ "2114x", ether2114xreset, 0, },	{ "i82557", i82557reset, 0, },	{ "igbe",  igbepnp, 0, },	{ "elnk3", elnk3reset, 0, },	{ "3C509", elnk3reset, 0, },	{ "3C575", elnk3reset, 0, },	{ "3C589", ether589reset, 1, },	{ "3C562", ether589reset, 1, },	{ "589E", ether589reset, 1, },	{ "NE2000", ne2000reset, 0, },	{ "WD8003", wd8003reset, 1, },	{ "EC2T", ec2treset, 0, },	{ "AMD79C970", amd79c970reset, 0, },	{ "RTL8139", rtl8139pnp, 0, },	{ "RTL8169", rtl8169pnp, 0, },	{ "83815", ether83815reset, 0, },	{ "rhine", rhinepnp, 0, },	{ 0, }};static void xetherdetach(void);intetherinit(void){	Ether *ctlr;	int ctlrno, i, mask, n, x;	fmtinstall('E', eipfmt);	etherdetach = xetherdetach;	mask = 0;	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){		ctlr = &ether[ctlrno];		memset(ctlr, 0, sizeof(Ether));		if(iniread && isaconfig("ether", ctlrno, ctlr) == 0)			continue;		for(n = 0; ethercards[n].type; n++){			if(!iniread){				if(ethercards[n].noprobe)					continue;				memset(ctlr, 0, sizeof(Ether));				strcpy(ctlr->type, ethercards[n].type);			}			else if(cistrcmp(ethercards[n].type, ctlr->type))				continue;			ctlr->ctlrno = ctlrno;			x = splhi();			if((*ethercards[n].reset)(ctlr)){				splx(x);				if(iniread)					break;				else					continue;			}			ctlr->state = 1;			mask |= 1<<ctlrno;			if(ctlr->irq == 2)				ctlr->irq = 9;			setvec(VectorPIC + ctlr->irq, ctlr->interrupt, ctlr);			print("ether#%d: %s: port 0x%luX irq %lud",				ctlr->ctlrno, ctlr->type, ctlr->port, ctlr->irq);			if(ctlr->mem)				print(" addr 0x%luX", ctlr->mem & ~KZERO);			if(ctlr->size)				print(" size 0x%luX", ctlr->size);			print(": %E\n", ctlr->ea);					if(ctlr->nrb == 0)				ctlr->nrb = Nrb;			ctlr->rb = ialloc(sizeof(RingBuf)*ctlr->nrb, 0);			if(ctlr->ntb == 0)				ctlr->ntb = Ntb;			ctlr->tb = ialloc(sizeof(RingBuf)*ctlr->ntb, 0);			ctlr->rh = 0;			ctlr->ri = 0;			for(i = 0; i < ctlr->nrb; i++)				ctlr->rb[i].owner = Interface;					ctlr->th = 0;			ctlr->ti = 0;			for(i = 0; i < ctlr->ntb; i++)				ctlr->tb[i].owner = Host;			splx(x);			break;		}	}	return mask;}voidetherinitdev(int i, char *s){	sprint(s, "ether%d", i);}voidetherprintdevs(int i){	print(" ether%d", i);}static Ether*attach(int ctlrno){	Ether *ctlr;	if(ctlrno >= MaxEther || ether[ctlrno].state == 0)		return 0;	ctlr = &ether[ctlrno];	if(ctlr->state == 1){		ctlr->state = 2;		(*ctlr->attach)(ctlr);	}	return ctlr;}static voidxetherdetach(void){	Ether *ctlr;	int ctlrno, x;	x = splhi();	for(ctlrno = 0; ctlrno < MaxEther; ctlrno++){		ctlr = &ether[ctlrno];		if(ctlr->detach && ctlr->state != 0)			ctlr->detach(ctlr);	}	splx(x);}uchar*etheraddr(int ctlrno){	Ether *ctlr;	if((ctlr = attach(ctlrno)) == 0)		return 0;	return ctlr->ea;}static intwait(RingBuf* ring, uchar owner, int timo){	ulong start;	start = m->ticks;	while(TK2MS(m->ticks - start) < timo){		if(ring->owner != owner)			return 1;	}	return 0;}intetherrxpkt(int ctlrno, Etherpkt* pkt, int timo){	int n;	Ether *ctlr;	RingBuf *ring;	if((ctlr = attach(ctlrno)) == 0)		return 0;	ring = &ctlr->rb[ctlr->rh];	if(wait(ring, Interface, timo) == 0){		if(debug)			print("ether%d: rx timeout\n", ctlrno);		return 0;	}	n = ring->len;	memmove(pkt, ring->pkt, n);	ring->owner = Interface;	ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);	return n;}intetherrxflush(int ctlrno){	int n;	Ether *ctlr;	RingBuf *ring;	if((ctlr = attach(ctlrno)) == 0)		return 0;	n = 0;	for(;;){		ring = &ctlr->rb[ctlr->rh];		if(wait(ring, Interface, 100) == 0)			break;		ring->owner = Interface;		ctlr->rh = NEXT(ctlr->rh, ctlr->nrb);		n++;	}	return n;}intethertxpkt(int ctlrno, Etherpkt* pkt, int len, int){	Ether *ctlr;	RingBuf *ring;	int s;	if((ctlr = attach(ctlrno)) == 0)		return 0;	ring = &ctlr->tb[ctlr->th];	if(wait(ring, Interface, 1000) == 0){		print("ether%d: tx buffer timeout\n", ctlrno);		return 0;	}	memmove(pkt->s, ctlr->ea, Eaddrlen);	if(debug)		print("%E to %E...\n", pkt->s, pkt->d);	memmove(ring->pkt, pkt, len);	if(len < ETHERMINTU){		memset(ring->pkt+len, 0, ETHERMINTU-len);		len = ETHERMINTU;	}	ring->len = len;	ring->owner = Interface;	ctlr->th = NEXT(ctlr->th, ctlr->ntb);	s = splhi();	(*ctlr->transmit)(ctlr);	splx(s);	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -