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

📄 ee_init.c,v

📁 用TCP/IP进行网际互连这本书得源代码,偶得,希望大家喜欢.推荐下载
💻 C,V
字号:
head	1.3;access;symbols;locks	dls:1.3; strict;comment	@ * @;1.3date	97.09.21.19.25.55;	author dls;	state Dist;branches;next	1.2;1.2date	95.02.05.21.46.32;	author dls;	state Broken;branches;next	1.1;1.1date	94.09.24.01.00.41;	author dls;	state Works;branches;next	;desc@@1.3log@pre-3e code@text@/* ee_init.c - ee_init */#include <conf.h>#include <kernel.h>#include <network.h>#include <i386.h>#include <ee.h>#include <q.h>static unsigned char	eeirq[] = {255, 9, 3, 4, 5, 10, 11, 255 };unsigned char eecf[] = { 0x0c, 0x08, 0x00, 0x2e, 0x00, 0x60, 0x00, 0xf2,	0x00, 0x00, 0x40, 0x00 };/*------------------------------------------------------------------------ * ee_init - startup initialization of Intel EtherExpress device *------------------------------------------------------------------------ */intee_init(pdev)struct devsw	*pdev;{	struct etdev	*ped;	unsigned short	eedat, wtmp, *pw;	unsigned char	irq, tmp, memc, mempc, memdec;	int		i, offset, ee_int();	unsigned char	*pdbuf;	unsigned short	rom[64];	struct cbl	*pcbl;	struct iscp	*piscp;	struct scb	*pscb;	struct rfd	*prfd;	struct rbd	*prbd;	struct tbd	*ptbd;	pdev->dvioblk = (char *) ped = &ee[pdev->dvminor];	ped->ed_pdev = pdev;	ped->ed_outq = newq(ETOUTQSZ, QF_NOWAIT);	ped->ed_ifnum = -1;	ped->ed_descr = "Intel EtherExpress";	ped->ed_mcc = 0;	ped->ed_xpending = 0;	/* read ROM data */	for (i=0; i<EE_ROMSIZE; ++i)		rom[i] = ee_romread(pdev->dvcsr, i);	for (i=0; i<16; ++i)		if ((inb(pdev->dvcsr + AID) & 0xf) != i)			break;	if (i < 16) {		kprintf("ee_init: no EtherExpress at 0x%03x\n", pdev->dvcsr);		return SYSERR;	}	/* set IRQ */	irq = pdev->dvivec - IRQBASE;	for (i=0; i<sizeof(eeirq); ++i)		if (eeirq[i] == irq) {			ped->ed_irq = i;			break;		}	if (i == sizeof(eeirq)) {		kprintf("ee%d: invalid IRQ (%d)\n", pdev->dvminor, irq);		return SYSERR;	} else {		eedat = rom[EE_BOARD];		eedat >>= 13;		if (eeirq[eedat] != irq)			kprintf("ee%d: WARNING ROM IRQ (%d) differs\n",				pdev->dvminor, eeirq[eedat]);		ped->ed_irq = eedat;		irq = eeirq[eedat];	}	set_evec(pdev->dvivec, ee_int);#ifdef notdef/*XXX */	/* test & set BUS timing */	tmp = inb(pdev->dvcsr + CONFIG);	outb(pdev->dvcsr + CONFIG, tmp | CONFIG_IOTE);	/* do an I/O for the test */	outb(pdev->dvcsr + RDPTR, 0);	inw(pdev->dvcsr + DXREG);	tmp = inb(pdev->dvcsr + CONFIG);	if (tmp & CONFIG_TOGGLE) {		if (tmp & CONFIG_ICLATE)			tmp &= ~CONFIG_16EN;	/* force 8-bit mode */		else			tmp |= CONFIG_ICLATE;	}	tmp &= ~(CONFIG_IOTE|CONFIG_TOGGLE);	outb(pdev->dvcsr + CONFIG, tmp);#endif	/* "warm up" DRAMS-- requires 16 bytes buf access */	outb(pdev->dvcsr + RDPTR, 0);	for (i=0; i<16; ++i)		inw(pdev->dvcsr + DXREG);	/* set up SCP */	outw(pdev->dvcsr+WRPTR, SCP);	outw(pdev->dvcsr+DXREG, SYSBUS_16);	/* 16-bit bus */	outw(pdev->dvcsr+DXREG, 0);	/* skip unused words */	outw(pdev->dvcsr+DXREG, 0);	outw(pdev->dvcsr+DXREG, ISCP & 0xffff);	outw(pdev->dvcsr+DXREG, ISCP >> 16);	outb(pdev->dvcsr + EEC, EEC_586R);	/* reset 82586		*/	outb(pdev->dvcsr + EEC, 0);		/* clear reset		*/	/* set buffer memory map */	eedat = rom[EE_MEM1];	memc = eedat & 0xff;	mempc = eedat >> 8;	memdec = rom[EE_MEM2];	mempc = ~memdec;	tmp = 0x80;	for (i=7; i>=0; --i, tmp >>= 1)		if (memdec & tmp) {			ped->ed_iomem = 0xc0000 + i * 0x4000;			break;		}	if (i < 0) {		ped->ed_iomem = 0xcc000;		kprintf("invalid ROM configuration, setting to iomem %X\n", 			ped->ed_iomem);		memdec = 0x8;		memc = 0x1c;	}#ifdef notdef	/* test and set mempc */	pw = (unsigned short *)0xc0000;	mempc = 0;	for (i=0; i<8; ++i) {		mempc >>= 1;		outb(pdev->dvcsr + CONFIG, CONFIG_MCS16);		wtmp = *pw;	/* reference it */		mempc |= inb(pdev->dvcsr + CONFIG) & 0x80;		pw += 8192;	}	outb(pdev->dvcsr + CONFIG, CONFIG_MCS16);	wtmp = *(unsigned short *)0xf0000;	if (inb(pdev->dvcsr + CONFIG) & 0x80)		memc |= MEMC_MCS16;	else		memc &= ~MEMC_MCS16;#endif	outb(pdev->dvcsr + MEMDEC, memdec);	outb(pdev->dvcsr + MEMC, memc);	outb(pdev->dvcsr + MEMPC, mempc);	for (i=0; i<EP_ALEN/2 ; ++i) {		eedat = rom[EE_EADDR + i];		ped->ed_paddr[EP_ALEN - 2*i -1] = eedat & 0xff;		ped->ed_paddr[EP_ALEN - 2*i -2] = eedat >> 8;		ped->ed_bcast[2*i] = ~0;		ped->ed_bcast[2*i+1] = ~0;	}	kprintf("ee%d: etheraddr %02x:%02x:%02x:%02x:%02x:%02x ",		pdev->dvminor,		ped->ed_paddr[0] & 0xff,		ped->ed_paddr[1] & 0xff,		ped->ed_paddr[2] & 0xff,		ped->ed_paddr[3] & 0xff,		ped->ed_paddr[4] & 0xff,		ped->ed_paddr[5] & 0xff);	kprintf("irq %d iomem %X\n", irq, ped->ed_iomem);	piscp = (struct iscp *) (ped->ed_iomem + ISCP);	piscp->iscp_busy = 1;	piscp->iscp_scboff = SCB;	piscp->iscp_scbbase = 0;	pscb = (struct scb *)(ped->ed_iomem + SCB);	ped->ed_scb = pscb;	bzero(pscb, sizeof(struct scb));	offset = (unsigned int)pscb + sizeof(struct scb);	/* allocate space for a command block */	pcbl = (struct cbl *)offset;	ped->ed_cbl = pcbl;	pcbl->cbl_next = 0xffff;	offset += sizeof(struct cbl);	/* allocate transmit buffer */	ptbd = ped->ed_tbd = (struct tbd *)offset;	ptbd->tbd_count = 0;	ptbd->tbd_eof = 1;	ptbd->tbd_next = H2IO(ped, ptbd);	offset += sizeof(struct tbd);	ped->ed_xmbuf = (unsigned char *)offset;	ptbd->tbd_buf = H2IO(ped, ped->ed_xmbuf);	offset += EDLEN;	/* initialize receive buffers */	ped->ed_rfd = (struct rfd *)offset;	offset += EE_NRX * sizeof(struct rfd);	ped->ed_rbd = (struct rbd *)offset;	offset += EE_NRX * sizeof(struct rbd);	pdbuf = (unsigned char *)offset;	prfd = ped->ed_rfd;	prbd = ped->ed_rbd;	for (i=0; i<EE_NRX; ++i) {		prfd->rfd_status = 0;		prfd->rfd_cmd = 0;		prfd->rfd_next = H2IO(ped, prfd + 1);		prfd->rfd_rbd = H2IO(ped, prbd);		prbd->rbd_count = 0;		prbd->rbd_valid = 0;		prbd->rbd_eof = 0;		prbd->rbd_next = H2IO(ped, prbd + 1);		prbd->rbd_buf = H2IO(ped, pdbuf);		prbd->rbd_size = EDLEN;		prbd->rbd_el = 0;		prfd++;		prbd++;		pdbuf += EDLEN;	}	prfd--; prbd--;	/* go back to last one */	prfd->rfd_cmd = EECMD_EL;	/* mark end of receive FD list	*/	prfd->rfd_next = H2IO(ped, ped->ed_rfd);	ped->ed_rfdend = prfd;	prbd->rbd_el = 1;	prbd->rbd_next = H2IO(ped, ped->ed_rbd);	ped->ed_rbdend = prbd;	pscb->scb_rfaoff = H2IO(ped, ped->ed_rfd);	outb(pdev->dvcsr + CAC, 0);		/* start the 82586	*/	for (i=0; i<200; ++i) {		if (!piscp->iscp_busy)			break;		delay(1);	}	if (i == 200) {		kprintf("ee%d: failed initialization\n", pdev->dvminor);		return SYSERR;	}	for (i=0; i<200; ++i) {		if (pscb->scb_status == STAT_CX|STAT_CNA)			break;		delay(1);	}	if (i == 200) {		kprintf("ee%d: failed status check (status %x)\n",			pdev->dvminor, pscb->scb_status);		return SYSERR;	}	/* configure */	ee_cmd(ped, EECMD_CONFIG, eecf);	ee_ack(ped, pscb->scb_status);	/* set station address */	ee_cmd(ped, EECMD_IASET, ped->ed_paddr);	ee_ack(ped, pscb->scb_status);	/* start frame reception */	ee_wait(ped);	pscb->scb_cmd = (pscb->scb_status & 0xf000) | SCBCMD_RUS;	pscb->scb_status = 0;	outb(pdev->dvcsr + CAC, 0);	/* start the 82586	*/	outb(pdev->dvcsr+SIRQ, ped->ed_irq | SIRQ_IEN);	/* enable interrupts */	return OK;}inteedump(ped)struct etdev *ped;{	struct iscp	*piscp = (struct iscp *)ped->ed_iomem;	struct scb	*pscb = ped->ed_scb;	struct cbl	*pcbl = ped->ed_cbl;	struct rfd	*prfd = ped->ed_rfd;	struct rbd	*prbd = ped->ed_rbd;	struct tbd	*ptbd = ped->ed_tbd;	int		i;	kprintf("\n\nprfd %X prfdend %X prbd %X prbdend %X ptbd %X\n",		ped->ed_rfd, ped->ed_rfdend, ped->ed_rbd, ped->ed_rbdend,		ped->ed_tbd);	kprintf("ISCP: host %X IO %X busy %x scboff %X scbbase %X\n",		piscp, H2IO(ped, piscp), piscp->iscp_busy, piscp->iscp_scboff,		piscp->iscp_scbbase);	kprintf("SCB: host %X IO %X status %x cmd %x cbloff %x rfaoff %x\n",		pscb, H2IO(ped, pscb),		pscb->scb_status, pscb->scb_cmd, pscb->scb_cbloff,		pscb->scb_rfaoff);	kprintf("SCB: errors: crc %d align %d resource %d over %d\n",		pscb->scb_ecrc, pscb->scb_ealign, pscb->scb_eresource,		pscb->scb_eover);	kprintf("CBL: status %x cmd %x next %x size %d\n", pcbl->cbl_status,		pcbl->cbl_cmd, pcbl->cbl_next, sizeof(struct cbl));	kprintf("TBD: count %d eof %d next %X buf %X\n", ptbd->tbd_count,		ptbd->tbd_eof, ptbd->tbd_next, ptbd->tbd_buf);	for (i=0; i<EE_NRX; ++i) {		kprintf("RFD%d: host %X IO %X status %x cmd %x next %x ",			i, prfd, H2IO(ped, prfd), prfd->rfd_status,			prfd->rfd_cmd, prfd->rfd_next);		kprintf("rbd %x\n", prfd->rfd_rbd);		prfd = (struct rfd *)IO2H(ped, prfd->rfd_next);	}	for (i=0; i<EE_NRX; ++i) {		kprintf("RBD%d: host %X IO %X count %d valid %d eof %d ",			i, prbd, H2IO(ped, prbd), prbd->rbd_count,			prbd->rbd_valid, prbd->rbd_eof);		kprintf("next %x buf %X bsize %d el %d\n",			prbd->rbd_next, prbd->rbd_buf, prbd->rbd_size,			prbd->rbd_el);		prbd = (struct rbd *)IO2H(ped, prbd->rbd_next);	}	kprintf("\n\n");}@1.2log@*** empty log message ***@text@a40 2	ped->ed_cmutex = screate(1);	ped->ed_mcset = 0;d42 1d81 7a87 2	outb(pdev->dvcsr + CONFIG, CONFIG_IOTE);	inb(pdev->dvcsr);d91 1a91 1			tmp &= ~CONFIG_ICLATE;d95 1a95 2	if (tmp & CONFIG_BUS16)		tmp |= CONFIG_16EN;a96 1/*XXX*/a97 1d122 1a122 1mempc = ~memdec;d250 1a250 1		DELAY(1);d259 1a259 1		DELAY(1);@1.1log@Initial revision@text@a9 3#define	H2IO(x)		((unsigned short)((char *)(x) - ped->ed_iomem))#define	IO2H(x)		(ped->ed_iomem + (int)(x))a29 1	struct scp	*pscp;d41 3a43 1	ped->ed_xpending = 0;d66 1a66 1		kprintf("ee%d: invalid IRQ (%d)\n", irq);d199 1a199 1	ptbd->tbd_next = H2IO(ptbd);d202 1a202 1	ptbd->tbd_buf = H2IO(ped->ed_xmbuf);d217 2a218 2		prfd->rfd_next = H2IO(prfd + 1);		prfd->rfd_rbd = H2IO(prbd);d223 2a224 2		prbd->rbd_next = H2IO(prbd + 1);		prbd->rbd_buf = H2IO(pdbuf);d235 1a235 1	prfd->rfd_next = H2IO(ped->ed_rfd);d239 1a239 1	prbd->rbd_next = H2IO(ped->ed_rbd);d242 1a242 1	pscb->scb_rfaoff = H2IO(ped->ed_rfd);d287 1a287 61ee_cmd(ped, cmd, arg1, arg2, arg3)struct etdev	*ped;unsigned short	cmd;char		*arg1, *arg2, *arg3;{	struct devsw	*pdev = ped->ed_pdev;	struct scb	*pscb = ped->ed_scb;	struct cbl	*pcbl = ped->ed_cbl;	ee_wait(ped);	/* build command block */	pcbl->cbl_status = 0;	pcbl->cbl_cmd = cmd | EECMD_EL;	switch (cmd & EECMD_MASK) {	case EECMD_CONFIG:		blkcopy(pcbl->cbl_cfg, arg1, CFLEN);	case EECMD_IASET:		blkcopy(pcbl->cbl_addr, arg1, EP_ALEN);		break;	case EECMD_TX:		pcbl->cbl_tbd = H2IO(ped->ed_tbd);		break;	case EECMD_NOP:		break;	/* not implemented yet */	}	pscb->scb_cmd = SCBCMD_CUS;	pscb->scb_status = 0;	pscb->scb_cbloff = H2IO(pcbl);	outb(pdev->dvcsr + CAC, 0);	/* start the 82586	*/}ee_wait(ped)struct etdev	*ped;{	struct devsw	*pdev = ped->ed_pdev;	struct scb	*pscb = ped->ed_scb;	int		i;		for (i=0; i<5000; ++i)		if (!pscb->scb_cmd)			return;	kprintf("ee%d: ee_wait timed out, SCB status %x cmd %x\n",		pdev->dvminor, pscb->scb_status, pscb->scb_cmd);}ee_ack(ped, status)struct etdev	*ped;unsigned short	status;{	struct devsw	*pdev = ped->ed_pdev;	struct scb	*pscb = ped->ed_scb;	ee_wait(ped);	pscb->scb_cmd = status & 0xf000;	outb(pdev->dvcsr+CAC, 0);}d297 1a297 1	int		i, j;d303 1a303 1		piscp, H2IO(piscp), piscp->iscp_busy, piscp->iscp_scboff,d306 1a306 1		pscb, H2IO(pscb),d318 2a319 2			i, prfd, H2IO(prfd), prfd->rfd_status, prfd->rfd_cmd,			prfd->rfd_next);d321 1a321 1		prfd = (struct rfd *)IO2H(prfd->rfd_next);d325 2a326 2			i, prbd, H2IO(prbd), prbd->rbd_count, prbd->rbd_valid,			prbd->rbd_eof);d330 1a330 1		prbd = (struct rbd *)IO2H(prbd->rbd_next);@

⌨️ 快捷键说明

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