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

📄 3c509.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (i >= MAX_EEPROMBUSY) {		/* printf("3c509: eeprom failed to come ready.\n"); */		printf("3c509: eeprom busy.\n"); /* memory in EPROM is tight */		return (0);	}	return (1);}/* * get_e: gets a 16 bits word from the EEPROM. we must have set the window * before */static intget_e(int offset){	if (!eeprom_rdy())		return (0xffff);	outw(EEPROM_CMD_RD | offset, IS_BASE + EP_W0_EEPROM_COMMAND);	if (!eeprom_rdy())		return (0xffff);	return (inw(IS_BASE + EP_W0_EEPROM_DATA));}static intsend_ID_sequence(int port){	int cx, al;	for (al = 0xff, cx = 0; cx < 255; cx++) {		outb(al, port);		al <<= 1;		if (al & 0x100)			al ^= 0xcf;	}	return (1);}/* * We get eeprom data from the id_port given an offset into the eeprom. * Basically; after the ID_sequence is sent to all of the cards; they enter * the ID_CMD state where they will accept command requests. 0x80-0xbf loads * the eeprom data.  We then read the port 16 times and with every read; the * cards check for contention (ie: if one card writes a 0 bit and another * writes a 1 bit then the host sees a 0. At the end of the cycle; each card * compares the data on the bus; if there is a difference then that card goes * into ID_WAIT state again). In the meantime; one bit of data is returned in * the AX register which is conveniently returned to us by inb().  Hence; we * read 16 times getting one bit of data with each read. */static intget_eeprom_data(int id_port, int offset){	int i, data = 0;	outb(0x80 + offset, id_port);	/* Do we really need this wait? Won't be noticeable anyway */	udelay(10000);	for (i = 0; i < 16; i++)		data = (data << 1) | (inw(id_port) & 1);	return (data);}static void t509_disable(struct nic *nic){	outb(0xc0, EP_ID_PORT);}/**************************************************************************ETH_PROBE - Look for an adapter***************************************************************************/#ifdef	INCLUDE_3C529struct nic *t529_probe(struct nic *nic, unsigned short *probe_addrs)#elsestruct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)#endif{	/* common variables */	int i;	int failcount;#ifdef	INCLUDE_3C529	struct el3_mca_adapters_struct *mcafound = NULL;	int mca_pos4 = 0, mca_pos5 = 0, mca_irq = 0;#endif	t509_disable(nic);		/* in case board was active */					/* note that nic is not used */	for (failcount = 0; failcount < 4000; failcount++) {		int data, j, io_base, id_port;		unsigned short k;		int ep_current_tag;		short *p;#ifdef	INCLUDE_3C529		int curboard;#endif		id_port = EP_ID_PORT;		ep_current_tag = EP_LAST_TAG + 1;	/*********************************************************			Search for 3Com 509 card	***********************************************************/#ifdef	INCLUDE_3C529		/*		 * XXX: We should really check to make sure we have an MCA		 * bus controller before going ahead with this...		 *		 * For now, we avoid any hassle by making it a compile		 * time option.		 *		 */		printf("\nWarning: Assuming presence of MCA bus\n");                /* Make sure motherboard setup is off */                outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);		/* Cycle through slots */		for(curboard=0; curboard<MCA_MAX_SLOT_NR; curboard++) {			int boardid;			int curcard;			outb_p(0x8|(curboard&0xf), MCA_ADAPTER_SETUP_REG);			boardid = inb_p(MCA_POS_REG(0));			boardid += inb_p(MCA_POS_REG(1)) << 8;			curcard = 0;			while (el3_mca_adapters[curcard].name) {				if (el3_mca_adapters[curcard].id == boardid) {					mcafound = &el3_mca_adapters[curcard];					mca_pos4 = inb_p(MCA_POS_REG(4));					mca_pos5 = inb_p(MCA_POS_REG(5));					goto donewithdetect;				}				else					curcard++;			}		}	donewithdetect:		/* Kill all setup modes */		outb_p(0, MCA_ADAPTER_SETUP_REG);		if (mcafound) {			eth_nic_base = ((short)((mca_pos4&0xfc)|0x02)) << 8;			mca_irq = mca_pos5 & 0x0f;			ep_current_tag--;		}		else			printf("MCA Card not found\n");#endif	/* Look for the EISA boards, leave them activated */	/* search for the first card, ignore all others */	for(j = 1; j < 16; j++) {		io_base = (j * EP_EISA_START) | EP_EISA_W0;		if (inw(io_base + EP_W0_MFG_ID) != MFG_ID)			continue;		/* we must have found 0x1f if the board is EISA configurated */		if ((inw(io_base + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)			continue;		/* Reset and Enable the card */		outb(W0_P4_CMD_RESET_ADAPTER, io_base + EP_W0_CONFIG_CTRL);		udelay(1000); /* Must wait 800 祍, be conservative */		outb(W0_P4_CMD_ENABLE_ADAPTER, io_base + EP_W0_CONFIG_CTRL);		/*		 * Once activated, all the registers are mapped in the range		 * x000 - x00F, where x is the slot number.		 */		eth_nic_base = j * EP_EISA_START;		break;	}	ep_current_tag--;	/* Look for the ISA boards. Init and leave them actived */	/* search for the first card, ignore all others */	outb(0xc0, id_port);	/* Global reset */	udelay(1000);		/* wait 1 ms */	for (i = 0; i < EP_MAX_BOARDS; i++) {		outb(0, id_port);		outb(0, id_port);		send_ID_sequence(id_port);		data = get_eeprom_data(id_port, EEPROM_MFG_ID);		if (data != MFG_ID)			break;		/* resolve contention using the Ethernet address */		for (j = 0; j < 3; j++)			data = get_eeprom_data(id_port, j);		eth_nic_base =		    (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;		outb(ep_current_tag, id_port);	/* tags board */		outb(ACTIVATE_ADAPTER_TO_CONFIG, id_port);		ep_current_tag--;		break;	}	if (i >= EP_MAX_BOARDS)		goto no3c509;	/*	* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be	* 0x9[0-f]50	*/	GO_WINDOW(0);	k = get_e(EEPROM_PROD_ID);#ifdef	INCLUDE_3C529	/*	 * On MCA, the PROD_ID matches the MCA card ID (POS0+POS1)	 */	if (mcafound) {		if (mcafound->id != k) {			printf("MCA: PROD_ID in EEPROM does not match MCA card ID! (%hX != %hX)\n", k, mcafound->id);			goto no3c509;		}	} else { /* for ISA/EISA */		if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))			goto no3c509;	}#else	if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))		goto no3c509;#endif#ifdef	INCLUDE_3C529	if (mcafound) {		printf("%s board found on MCA at %#hx IRQ %d -",		       mcafound->name, eth_nic_base, mca_irq);	} else {#endif		if(eth_nic_base >= EP_EISA_START)			printf("3C5x9 board on EISA at %#hx - ",eth_nic_base);		else			printf("3C5x9 board on ISA at %#hx - ",eth_nic_base);#ifdef	INCLUDE_3C529	}#endif	/* test for presence of connectors */	i = inw(IS_BASE + EP_W0_CONFIG_CTRL);	j = (inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14) & 0x3;	switch(j) {		case 0:			if (i & IS_UTP) {				printf("10baseT\n");				connector = utp;				}			else {				printf("10baseT not present\n");				goto no3c509;				}			break;		case 1:			if (i & IS_AUI)				printf("10base5\n");			else {				printf("10base5 not present\n");				goto no3c509;				}			break;		case 3:			if (i & IS_BNC) {				printf("10base2\n");				connector = bnc;				}			else {				printf("10base2 not present\n");				goto no3c509;				}			break;		default:			printf("unknown connector\n");			goto no3c509;		}	/*	* Read the station address from the eeprom	*/	p = (unsigned short *) nic->node_addr;	for (i = 0; i < ETH_ALEN / 2; i++) {		GO_WINDOW(0);		p[i] = htons(get_e(i));		GO_WINDOW(2);		outw(ntohs(p[i]), BASE + EP_W2_ADDR_0 + (i * 2));	}	printf("Ethernet address: %!\n", nic->node_addr);	t509_reset(nic);	nic->reset = t509_reset;	nic->poll = t509_poll;	nic->transmit = t509_transmit;	nic->disable = t509_disable;	return nic;no3c509:	printf("(probe fail)");	}	return 0;}/* * Local variables: *  c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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