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

📄 com90xx.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers) *  * Written 1994-1999 by Avery Pennarun. * Written 1999 by Martin Mares <mj@ucw.cz>. * Derived from skeleton.c by Donald Becker. * * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) *  for sponsoring the further development of this driver. * * ********************** * * The original copyright of skeleton.c was as follows: * * skeleton.c Written 1993 by Donald Becker. * Copyright 1993 United States Government as represented by the * Director, National Security Agency.  This software may only be used * and distributed according to the terms of the GNU General Public License as * modified by SRC, incorporated herein by reference. * * ********************** * * For more details, see drivers/net/arcnet.c * * ********************** */#include <linux/module.h>#include <linux/init.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/netdevice.h>#include <linux/bootmem.h>#include <asm/io.h>#include <linux/arcdevice.h>#define VERSION "arcnet: COM90xx chipset support\n"/* Define this to speed up the autoprobe by assuming if only one io port and * shmem are left in the list at Stage 5, they must correspond to each * other. * * This is undefined by default because it might not always be true, and the * extra check makes the autoprobe even more careful.  Speed demons can turn * it on - I think it should be fine if you only have one ARCnet card * installed. * * If no ARCnet cards are installed, this delay never happens anyway and thus * the option has no effect. */#undef FAST_PROBE/* Internal function declarations */static int com90xx_found(struct net_device *dev, int ioaddr, int airq,			 u_long shmem);static void com90xx_command(struct net_device *dev, int command);static int com90xx_status(struct net_device *dev);static void com90xx_setmask(struct net_device *dev, int mask);static int com90xx_reset(struct net_device *dev, int really_reset);static void com90xx_openclose(struct net_device *dev, bool open);static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,				 void *buf, int count);static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,				   void *buf, int count);/* Known ARCnet cards */static struct net_device *cards[16];static int numcards;/* Handy defines for ARCnet specific stuff *//* The number of low I/O ports used by the card */#define ARCNET_TOTAL_SIZE	16/* Amount of I/O memory used by the card */#define BUFFER_SIZE (512)#define MIRROR_SIZE (BUFFER_SIZE*4)/* COM 9026 controller chip --> ARCnet register addresses */#define _INTMASK (ioaddr+0)	/* writable */#define _STATUS  (ioaddr+0)	/* readable */#define _COMMAND (ioaddr+1)	/* writable, returns random vals on read (?) */#define _CONFIG  (ioaddr+2)	/* Configuration register */#define _RESET   (ioaddr+8)	/* software reset (on read) */#define _MEMDATA (ioaddr+12)	/* Data port for IO-mapped memory */#define _ADDR_HI (ioaddr+15)	/* Control registers for said */#define _ADDR_LO (ioaddr+14)#undef ASTATUS#undef ACOMMAND#undef AINTMASK#define ASTATUS()	inb(_STATUS)#define ACOMMAND(cmd) 	outb((cmd),_COMMAND)#define AINTMASK(msk)	outb((msk),_INTMASK)static int com90xx_skip_probe __initdata = 0;int __init com90xx_probe(struct net_device *dev){	int count, status, ioaddr, numprint, airq, retval = -ENODEV,	 openparen = 0;	unsigned long airqmask;	int ports[(0x3f0 - 0x200) / 16 + 1] =	{0};	u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] =	{0};	int numports, numshmems, *port;	u_long *shmem;	if (!dev && com90xx_skip_probe)		return -ENODEV;#ifndef MODULE	arcnet_init();#endif	BUGLVL(D_NORMAL) printk(VERSION);	/* set up the arrays where we'll store the possible probe addresses */	numports = numshmems = 0;	if (dev && dev->base_addr)		ports[numports++] = dev->base_addr;	else		for (count = 0x200; count <= 0x3f0; count += 16)			ports[numports++] = count;	if (dev && dev->mem_start)		shmems[numshmems++] = dev->mem_start;	else		for (count = 0xA0000; count <= 0xFF800; count += 2048)			shmems[numshmems++] = count;	/* Stage 1: abandon any reserved ports, or ones with status==0xFF	 * (empty), and reset any others by reading the reset port.	 */	numprint = -1;	for (port = &ports[0]; port - ports < numports; port++) {		numprint++;		numprint %= 8;		if (!numprint) {			BUGMSG2(D_INIT, "\n");			BUGMSG2(D_INIT, "S1: ");		}		BUGMSG2(D_INIT, "%Xh ", *port);		ioaddr = *port;		if (check_region(*port, ARCNET_TOTAL_SIZE)) {			BUGMSG2(D_INIT_REASONS, "(check_region)\n");			BUGMSG2(D_INIT_REASONS, "S1: ");			BUGLVL(D_INIT_REASONS) numprint = 0;			*port = ports[numports - 1];			numports--;			port--;			continue;		}		if (ASTATUS() == 0xFF) {			BUGMSG2(D_INIT_REASONS, "(empty)\n");			BUGMSG2(D_INIT_REASONS, "S1: ");			BUGLVL(D_INIT_REASONS) numprint = 0;			*port = ports[numports - 1];			numports--;			port--;			continue;		}		inb(_RESET);	/* begin resetting card */		BUGMSG2(D_INIT_REASONS, "\n");		BUGMSG2(D_INIT_REASONS, "S1: ");		BUGLVL(D_INIT_REASONS) numprint = 0;	}	BUGMSG2(D_INIT, "\n");	if (!numports) {		BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");		return -ENODEV;	}	/* Stage 2: we have now reset any possible ARCnet cards, so we can't	 * do anything until they finish.  If D_INIT, print the list of	 * cards that are left.	 */	numprint = -1;	for (port = &ports[0]; port - ports < numports; port++) {		numprint++;		numprint %= 8;		if (!numprint) {			BUGMSG2(D_INIT, "\n");			BUGMSG2(D_INIT, "S2: ");		}		BUGMSG2(D_INIT, "%Xh ", *port);	}	BUGMSG2(D_INIT, "\n");	mdelay(RESETtime);	/* Stage 3: abandon any shmem addresses that don't have the signature	 * 0xD1 byte in the right place, or are read-only.	 */	numprint = -1;	for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {		u_long ptr = *shmem;		numprint++;		numprint %= 8;		if (!numprint) {			BUGMSG2(D_INIT, "\n");			BUGMSG2(D_INIT, "S3: ");		}		BUGMSG2(D_INIT, "%lXh ", *shmem);		if (check_mem_region(*shmem, BUFFER_SIZE)) {			BUGMSG2(D_INIT_REASONS, "(check_mem_region)\n");			BUGMSG2(D_INIT_REASONS, "Stage 3: ");			BUGLVL(D_INIT_REASONS) numprint = 0;			*shmem = shmems[numshmems - 1];			numshmems--;			shmem--;			continue;		}		if (isa_readb(ptr) != TESTvalue) {			BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",				isa_readb(ptr), TESTvalue);			BUGMSG2(D_INIT_REASONS, "S3: ");			BUGLVL(D_INIT_REASONS) numprint = 0;			*shmem = shmems[numshmems - 1];			numshmems--;			shmem--;			continue;		}		/* By writing 0x42 to the TESTvalue location, we also make		 * sure no "mirror" shmem areas show up - if they occur		 * in another pass through this loop, they will be discarded		 * because *cptr != TESTvalue.		 */		isa_writeb(0x42, ptr);		if (isa_readb(ptr) != 0x42) {			BUGMSG2(D_INIT_REASONS, "(read only)\n");			BUGMSG2(D_INIT_REASONS, "S3: ");			*shmem = shmems[numshmems - 1];			numshmems--;			shmem--;			continue;		}		BUGMSG2(D_INIT_REASONS, "\n");		BUGMSG2(D_INIT_REASONS, "S3: ");		BUGLVL(D_INIT_REASONS) numprint = 0;	}	BUGMSG2(D_INIT, "\n");	if (!numshmems) {		BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");		return -ENODEV;	}	/* Stage 4: something of a dummy, to report the shmems that are	 * still possible after stage 3.	 */	numprint = -1;	for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {		numprint++;		numprint %= 8;		if (!numprint) {			BUGMSG2(D_INIT, "\n");			BUGMSG2(D_INIT, "S4: ");		}		BUGMSG2(D_INIT, "%lXh ", *shmem);	}	BUGMSG2(D_INIT, "\n");	/* Stage 5: for any ports that have the correct status, can disable	 * the RESET flag, and (if no irq is given) generate an autoirq,	 * register an ARCnet device.	 *	 * Currently, we can only register one device per probe, so quit	 * after the first one is found.	 */	numprint = -1;	for (port = &ports[0]; port - ports < numports; port++) {		numprint++;		numprint %= 8;		if (!numprint) {			BUGMSG2(D_INIT, "\n");			BUGMSG2(D_INIT, "S5: ");		}		BUGMSG2(D_INIT, "%Xh ", *port);		ioaddr = *port;		status = ASTATUS();		if ((status & 0x9D)		    != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {			BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);			BUGMSG2(D_INIT_REASONS, "S5: ");			BUGLVL(D_INIT_REASONS) numprint = 0;			*port = ports[numports - 1];			numports--;			port--;			continue;		}		ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);		status = ASTATUS();		if (status & RESETflag) {			BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",				status);			BUGMSG2(D_INIT_REASONS, "S5: ");			BUGLVL(D_INIT_REASONS) numprint = 0;			*port = ports[numports - 1];			numports--;			port--;			continue;		}		/* skip this completely if an IRQ was given, because maybe		 * we're on a machine that locks during autoirq!		 */		if (!dev || !dev->irq) {			/* if we do this, we're sure to get an IRQ since the			 * card has just reset and the NORXflag is on until			 * we tell it to start receiving.			 */			airqmask = probe_irq_on();			AINTMASK(NORXflag);			udelay(1);			AINTMASK(0);			airq = probe_irq_off(airqmask);			if (airq <= 0) {				BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);				BUGMSG2(D_INIT_REASONS, "S5: ");				BUGLVL(D_INIT_REASONS) numprint = 0;				*port = ports[numports - 1];				numports--;				port--;				continue;			}		} else {			airq = dev->irq;		}		BUGMSG2(D_INIT, "(%d,", airq);		openparen = 1;		/* Everything seems okay.  But which shmem, if any, puts		 * back its signature byte when the card is reset?		 *		 * If there are multiple cards installed, there might be		 * multiple shmems still in the list.		 */#ifdef FAST_PROBE		if (numports > 1 || numshmems > 1) {			inb(_RESET);			mdelay(RESETtime);		} else {			/* just one shmem and port, assume they match */

⌨️ 快捷键说明

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