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

📄 ether8003.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "../port/error.h"#include "../port/netif.h"#include "etherif.h"#include "ether8390.h"/* * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). * Also handles 8216 cards (Elite Ultra). * Configuration code based on that provided by SMC a long time ago. */enum {					/* 83C584 Bus Interface Controller */	Msr		= 0x00,		/* Memory Select Register */	Icr		= 0x01,		/* Interface Configuration Register */	Iar		= 0x02,		/* I/O Address Register */	Bio		= 0x03,		/* BIOS ROM Address Register */	Ear		= 0x03,		/* EEROM Address Register (shared with Bio) */	Irr		= 0x04,		/* Interrupt Request Register */	Hcr		= 0x04,		/* 8216 hardware control */	Laar		= 0x05,		/* LA Address Register */	Ijr		= 0x06,		/* Initialisation Jumpers */	Gp2		= 0x07,		/* General Purpose Data Register */	Lar		= 0x08,		/* LAN Address Registers */	Id		= 0x0E,		/* Card ID byte */	Cksum		= 0x0F,		/* Checksum */};enum {					/* Msr */	Rst		= 0x80,		/* software reset */	Menb		= 0x40,		/* memory enable */};enum {					/* Icr */	Bit16		= 0x01,		/* 16-bit bus */	Other		= 0x02,		/* other register access */	Ir2		= 0x04,		/* IR2 */	Msz		= 0x08,		/* SRAM size */	Rla		= 0x10,		/* recall LAN address */	Rx7		= 0x20,		/* recall all but I/O and LAN address */	Rio		= 0x40,		/* recall I/O address from EEROM */	Sto		= 0x80,		/* non-volatile EEROM store */};enum {					/* Laar */	ZeroWS16	= 0x20,		/* zero wait states for 16-bit ops */	L16en		= 0x40,		/* enable 16-bit LAN operation */	M16en		= 0x80,		/* enable 16-bit memory access */};enum {					/* Ijr */	Ienable		= 0x01,		/* 8216 interrupt enable */};/* * Mapping from configuration bits to interrupt level. */static int irq8003[8] = {	9, 3, 5, 7, 10, 11, 15, 4,};static int irq8216[8] = {	0, 9, 3, 5, 7, 10, 11, 15,};static voidreset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8]){	Dp8390 *ctlr;	ulong port;	ctlr = ether->ctlr;	port = ether->port;	/*	 * Check for old, dumb 8003E, which doesn't have an interface	 * chip. Only Msr exists out of the 1st eight registers, reads	 * of the others just alias the 2nd eight registers, the LAN	 * address ROM. Can check Icr, Irr and Laar against the ethernet	 * address read above and if they match it's an 8003E (or an	 * 8003EBT, 8003S, 8003SH or 8003WT, doesn't matter), in which	 * case the default irq gets used.	 */	if(memcmp(&ea[1], &ic[1], 5) == 0){		memset(ic, 0, sizeof(ic));		ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;	}	else{		/*		 * As a final sanity check for the 8013EBT, which doesn't have		 * the 83C584 interface chip, but has 2 real registers, write Gp2		 * and if it reads back the same, it's not an 8013EBT.		 */		outb(port+Gp2, 0xAA);		inb(port+Msr);				/* wiggle bus */		if(inb(port+Gp2) != 0xAA){			memset(ic, 0, sizeof(ic));			ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;		}		else			ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];		/*		 * Check if 16-bit card.		 * If Bit16 is read/write, then it's an 8-bit card.		 * If Bit16 is set, it's in a 16-bit slot.		 */		outb(port+Icr, ic[Icr]^Bit16);		inb(port+Msr);				/* wiggle bus */		if((inb(port+Icr) & Bit16) == (ic[Icr] & Bit16)){			ctlr->width = 2;			ic[Icr] &= ~Bit16;		}		outb(port+Icr, ic[Icr]);		if(ctlr->width == 2 && (inb(port+Icr) & Bit16) == 0)			ctlr->width = 1;	}	ether->mem = (ulong)KADDR((ic[Msr] & 0x3F)<<13);	if(ctlr->width == 2)		ether->mem |= (ic[Laar] & 0x1F)<<19;	else		ether->mem |= 0x80000;	if(ic[Icr] & (1<<3))		ether->size = 32*1024;	if(ctlr->width == 2)		ether->size <<= 1;	/*	 * Enable interface RAM, set interface width.	 */	outb(port+Msr, ic[Msr]|Menb);	if(ctlr->width == 2)		outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16);}static voidreset8216(Ether* ether, uchar[8]){	uchar hcr, irq, x;	ulong addr, port;	Dp8390 *ctlr;	ctlr = ether->ctlr;	port = ether->port;	ctlr->width = 2;	/*	 * Switch to the alternate register set and retrieve the memory	 * and irq information.	 */	hcr = inb(port+Hcr);	outb(port+Hcr, 0x80|hcr);	addr = inb(port+0x0B) & 0xFF;	irq = inb(port+0x0D);	outb(port+Hcr, hcr);	ether->mem = (ulong)KADDR(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13));	ether->size = 8192*(1<<((addr>>4) & 0x03));	ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)];	/*	 * Enable interface RAM, set interface width, and enable interrupts.	 */	x = inb(port+Msr) & ~Rst;	outb(port+Msr, Menb|x);	x = inb(port+Laar);	outb(port+Laar, M16en|x);	outb(port+Ijr, Ienable);}/* * Get configuration parameters, enable memory. * There are opportunities here for buckets of code, try to resist. */static intreset(Ether* ether){	int i;	uchar ea[Eaddrlen], ic[8], id, nullea[Eaddrlen], sum;	ulong port;	Dp8390 *ctlr;	/*	 * Set up the software configuration.	 * Use defaults for port, irq, mem and size if not specified.	 * Defaults are set for the dumb 8003E which can't be	 * autoconfigured.	 */	if(ether->port == 0)		ether->port = 0x280;	if(ether->irq == 0)		ether->irq = 3;	if(ether->mem == 0)		ether->mem = 0xD0000;	if(ether->size == 0)		ether->size = 8*1024;	if(ioalloc(ether->port, 0x20, 0, "wd8003") < 0)		return -1;	/*	 * Look for the interface. Read the LAN address ROM	 * and validate the checksum - the sum of all 8 bytes	 * should be 0xFF.	 * At the same time, get the (possible) interface chip	 * registers, they'll be used later to check for aliasing.	 */	port = ether->port;	sum = 0;	for(i = 0; i < sizeof(ea); i++){		ea[i] = inb(port+Lar+i);		sum += ea[i];		ic[i] = inb(port+i);	}	id = inb(port+Id);	sum += id;	sum += inb(port+Cksum);	if(sum != 0xFF){		iofree(ether->port);		return -1;	}	ether->ctlr = malloc(sizeof(Dp8390));	ctlr = ether->ctlr;	ctlr->ram = 1;	if((id & 0xFE) == 0x2A)		reset8216(ether, ic);	else		reset8003(ether, ea, ic);	/*	 * Set the DP8390 ring addresses.	 */	ctlr->port = port+0x10;	ctlr->tstart = 0;	ctlr->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);	ctlr->pstop = HOWMANY(ether->size, Dp8390BufSz);	/*	 * Finally, init the 8390, set the ethernet address	 * and claim the memory used.	 */	dp8390reset(ether);	memset(nullea, 0, Eaddrlen);	if(memcmp(nullea, ether->ea, Eaddrlen) == 0){		for(i = 0; i < sizeof(ether->ea); i++)			ether->ea[i] = ea[i];	}	dp8390setea(ether);	if(umbrwmalloc(PADDR(ether->mem), ether->size, 0) == 0)		print("ether8003: warning - 0x%luX unavailable", PADDR(ether->mem));	return 0;}voidether8003link(void){	addethercard("WD8003", reset);}

⌨️ 快捷键说明

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