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

📄 etherwavelan.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* Pci/pcmcia code for wavelan.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 "wavelan.h"static intwavelanpcmciareset(Ether *ether){	int i;	char *p;	Ctlr *ctlr;	if((ctlr = malloc(sizeof(Ctlr))) == nil)		return -1;	ilock(ctlr);	ctlr->ctlrno = ether->ctlrno;	if (ether->port==0)		ether->port=WDfltIOB;	ctlr->iob = ether->port;	if (ether->irq==0)		ether->irq=WDfltIRQ;	if (ioalloc(ether->port,WIOLen,0,"wavelan")<0){	//	print("#l%d: port 0x%lx in use\n",	//			ether->ctlrno, ether->port);		goto abort1;	}	/*	 * If id= is specified, card must match.  Otherwise try generic.	 */	ctlr->slot = -1;	for(i=0; i<ether->nopt; i++){		if(cistrncmp(ether->opt[i], "id=", 3) == 0){			if((ctlr->slot = pcmspecial(&ether->opt[i][3], ether)) < 0)				goto abort;			break;		}	}	if(ctlr->slot == -1){		for (i=0; wavenames[i]; i++)			if((ctlr->slot = pcmspecial(wavenames[i], ether))>=0)				break;		if(!wavenames[i]){			DEBUG("no wavelan found\n");			goto abort;		}	}	// DEBUG("#l%d: port=0x%lx irq=%ld\n",	//		ether->ctlrno, ether->port, ether->irq);	if(wavelanreset(ether, ctlr) < 0){	abort:		iofree(ether->port);	abort1:		iunlock(ctlr);		free(ctlr);		ether->ctlr = nil;		return -1;	}	for(i = 0; i < ether->nopt; i++){		if(p = strchr(ether->opt[i], '='))			*p = ' ';		w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));	}	iunlock(ctlr);	return 0;}static struct {	int vid;	int did;} wavelanpci[] = {	0x1260, 0x3873,	/* Intersil Prism2.5 */	0x1737,	0x0019,	/* Linksys WPC-11 untested */};static Ctlr *ctlrhead, *ctlrtail;static voidwavelanpciscan(void){	int i;	void *mem;	Pcidev *p;	Ctlr *ctlr;	p = nil;	while(p = pcimatch(p, 0, 0)){		for(i=0; i<nelem(wavelanpci); i++)			if(p->vid == wavelanpci[i].vid && p->did == wavelanpci[i].did)				break;		if(i==nelem(wavelanpci))			continue;		/*		 * On the Prism, bar[0] is the memory-mapped register address (4KB),		 */		if(p->mem[0].size != 4096){			print("wavelanpci: %.4ux %.4ux: unlikely mmio size\n", p->vid, p->did);			continue;		}		ctlr = malloc(sizeof(Ctlr));		ctlr->pcidev = p;		mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);		if(mem == nil){			print("wavelanpci: %.4ux %.4ux: vmap 0x%.8lux %d failed\n", p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);			free(ctlr);			continue;		}		ctlr->mmb = mem;		if(ctlrhead != nil)			ctlrtail->next = ctlr;		else			ctlrhead = ctlr;		ctlrtail = ctlr;		pcisetbme(p);	}}static intwavelanpcireset(Ether *ether){	int i;	char *p;	Ctlr *ctlr;	if(ctlrhead == nil)		wavelanpciscan();	/*	 * Allow plan9.ini to set vid, did?	 */	for(ctlr=ctlrhead; ctlr!=nil; ctlr=ctlr->next)		if(ctlr->active == 0)			break;	if(ctlr == nil)		return -1;	ctlr->active = 1;	ilock(ctlr);	ether->irq = ctlr->pcidev->intl;	ether->tbdf = ctlr->pcidev->tbdf;	/*	 * Really hard reset.	 */	csr_outs(ctlr, WR_PciCor, 0x0080);	delay(250);	csr_outs(ctlr, WR_PciCor, 0x0000);	delay(500);	for(i=0; i<2*10; i++){		if(!(csr_ins(ctlr, WR_Cmd)&WCmdBusy))			break;		delay(100);	}	if(i >= 2*10)		print("wavelan pci %.4ux %.4ux: reset timeout %.4ux\n",			ctlr->pcidev->vid, ctlr->pcidev->did, csr_ins(ctlr, WR_Cmd));	if(wavelanreset(ether, ctlr) < 0){		iunlock(ctlr);		ether->ctlr = nil;		return -1;	}	for(i = 0; i < ether->nopt; i++){		if(p = strchr(ether->opt[i], '='))			*p = ' ';		w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));	}	iunlock(ctlr);	return 0;}	voidetherwavelanlink(void){	addethercard("wavelan", wavelanpcmciareset);	addethercard("wavelanpci", wavelanpcireset);}

⌨️ 快捷键说明

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