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

📄 com90xx.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* just one shmem and port, assume they match */			isa_writeb(TESTvalue, shmems[0]);		}#else		inb(_RESET);		mdelay(RESETtime);#endif		for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {			u_long ptr = *shmem;			if (isa_readb(ptr) == TESTvalue) {	/* found one */				BUGMSG2(D_INIT, "%lXh)\n", *shmem);				openparen = 0;				/* register the card */				retval = com90xx_found(dev, *port, airq, *shmem);				numprint = -1;				/* remove shmem from the list */				*shmem = shmems[numshmems - 1];				numshmems--;				break;	/* go to the next I/O port */			} else {				BUGMSG2(D_INIT_REASONS, "%Xh-", isa_readb(ptr));			}		}		if (openparen) {			BUGLVL(D_INIT) printk("no matching shmem)\n");			BUGLVL(D_INIT_REASONS) printk("S5: ");			BUGLVL(D_INIT_REASONS) numprint = 0;		}		*port = ports[numports - 1];		numports--;		port--;	}	BUGLVL(D_INIT_REASONS) printk("\n");	/* Now put back TESTvalue on all leftover shmems. */	for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)		isa_writeb(TESTvalue, *shmem);	if (retval && dev && !numcards)		BUGMSG2(D_NORMAL, "S5: No ARCnet cards found.\n");	return retval;}/* Set up the struct net_device associated with this card.  Called after * probing succeeds. */static int __init com90xx_found(struct net_device *dev0, int ioaddr, int airq,				u_long shmem){	struct net_device *dev = dev0;	struct arcnet_local *lp;	u_long first_mirror, last_mirror;	int mirror_size, err;	/* allocate struct net_device if we don't have one yet */	if (!dev && !(dev = dev_alloc("arc%d", &err))) {		BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");		return err;	}	lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);	if (!lp) {		BUGMSG(D_NORMAL, "Can't allocate device data!\n");		goto err_free_dev;	}	/* find the real shared memory start/end points, including mirrors */	/* guess the actual size of one "memory mirror" - the number of	 * bytes between copies of the shared memory.  On most cards, it's	 * 2k (or there are no mirrors at all) but on some, it's 4k.	 */	mirror_size = MIRROR_SIZE;	if (isa_readb(shmem) == TESTvalue	    && isa_readb(shmem - mirror_size) != TESTvalue	    && isa_readb(shmem - 2 * mirror_size) == TESTvalue)		mirror_size *= 2;	first_mirror = last_mirror = shmem;	while (isa_readb(first_mirror) == TESTvalue)		first_mirror -= mirror_size;	first_mirror += mirror_size;	while (isa_readb(last_mirror) == TESTvalue)		last_mirror += mirror_size;	last_mirror -= mirror_size;	dev->mem_start = first_mirror;	dev->mem_end = last_mirror + MIRROR_SIZE - 1;	dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;	dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;	/* Initialize the rest of the device structure. */	memset(lp, 0, sizeof(struct arcnet_local));	lp->card_name = "COM90xx";	lp->hw.command = com90xx_command;	lp->hw.status = com90xx_status;	lp->hw.intmask = com90xx_setmask;	lp->hw.reset = com90xx_reset;	lp->hw.open_close = com90xx_openclose;	lp->hw.copy_to_card = com90xx_copy_to_card;	lp->hw.copy_from_card = com90xx_copy_from_card;	lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);	if (!lp->mem_start) {		BUGMSG(D_NORMAL, "Can't remap device memory!\n");		goto err_free_dev_priv;	}	/* Fill in the fields of the device structure with generic values. */	arcdev_setup(dev);	/* get and check the station ID from offset 1 in shmem */	dev->dev_addr[0] = readb(lp->mem_start + 1);	/* reserve the irq */	if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);		goto err_unmap;	}	dev->irq = airq;	/* reserve the I/O and memory regions - guaranteed to work by check_region */	request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");	request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");	dev->base_addr = ioaddr;	BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "	       "ShMem %lXh (%ld*%xh).\n",	       dev->dev_addr[0],	       dev->base_addr, dev->irq, dev->mem_start,	 (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);	if (!dev0 && register_netdev(dev))		goto err_release;	cards[numcards++] = dev;	return 0;      err_release:	free_irq(dev->irq, dev);	release_region(dev->base_addr, ARCNET_TOTAL_SIZE);	release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);      err_unmap:	iounmap(lp->mem_start);      err_free_dev_priv:	kfree(dev->priv);      err_free_dev:	if (!dev0)		kfree(dev);	return -EIO;}static void com90xx_command(struct net_device *dev, int cmd){	short ioaddr = dev->base_addr;	ACOMMAND(cmd);}static int com90xx_status(struct net_device *dev){	short ioaddr = dev->base_addr;	return ASTATUS();}static void com90xx_setmask(struct net_device *dev, int mask){	short ioaddr = dev->base_addr;	AINTMASK(mask);}/* * Do a hardware reset on the card, and set up necessary registers. *  * This should be called as little as possible, because it disrupts the * token on the network (causes a RECON) and requires a significant delay. * * However, it does make sure the card is in a defined state. */int com90xx_reset(struct net_device *dev, int really_reset){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	short ioaddr = dev->base_addr;	BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());	if (really_reset) {		/* reset the card */		inb(_RESET);		mdelay(RESETtime);	}	ACOMMAND(CFLAGScmd | RESETclear);	/* clear flags & end reset */	ACOMMAND(CFLAGScmd | CONFIGclear);	/* don't do this until we verify that it doesn't hurt older cards! */	/* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */	/* verify that the ARCnet signature byte is present */	if (readb(lp->mem_start) != TESTvalue) {		if (really_reset)			BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");		return 1;	}	/* enable extended (512-byte) packets */	ACOMMAND(CONFIGcmd | EXTconf);	/* clean out all the memory to make debugging make more sense :) */	BUGLVL(D_DURING)	    memset_io(lp->mem_start, 0x42, 2048);	/* done!  return success. */	return 0;}static void com90xx_openclose(struct net_device *dev, bool open){	if (open)		MOD_INC_USE_COUNT;	else		MOD_DEC_USE_COUNT;}static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,				 void *buf, int count){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	void *memaddr = lp->mem_start + bufnum * 512 + offset;	TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));}static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,				   void *buf, int count){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	void *memaddr = lp->mem_start + bufnum * 512 + offset;	TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));}#ifdef MODULE/* Module parameters */static int io;			/* use the insmod io= irq= shmem= options */static int irq;static int shmem;static char *device;		/* use eg. device=arc1 to change name */MODULE_PARM(io, "i");MODULE_PARM(irq, "i");MODULE_PARM(shmem, "i");MODULE_PARM(device, "s");int init_module(void){	struct net_device *dev;	int err;	if (io || irq || shmem || device) {		dev = dev_alloc(device ? : "arc%d", &err);		if (!dev)			return err;		dev->base_addr = io;		dev->irq = irq;		if (dev->irq == 2)			dev->irq = 9;		dev->mem_start = shmem;		com90xx_probe(dev);	} else		com90xx_probe(NULL);	if (!numcards)		return -EIO;	return 0;}void cleanup_module(void){	struct net_device *dev;	struct arcnet_local *lp;	int count;	for (count = 0; count < numcards; count++) {		dev = cards[count];		lp = (struct arcnet_local *) dev->priv;		unregister_netdev(dev);		free_irq(dev->irq, dev);		iounmap(lp->mem_start);		release_region(dev->base_addr, ARCNET_TOTAL_SIZE);		release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);		kfree(dev->priv);		kfree(dev);	}}#elsestatic int __init com90xx_setup(char *s){	struct net_device *dev;	int ints[8];	com90xx_skip_probe = 1;	s = get_options(s, 8, ints);	if (!ints[0] && !*s) {		printk("com90xx: Disabled.\n");		return 1;	}	dev = alloc_bootmem(sizeof(struct net_device));	memset(dev, 0, sizeof(struct net_device));	dev->init = com90xx_probe;	switch (ints[0]) {	default:		/* ERROR */		printk("com90xx: Too many arguments.\n");	case 3:		/* Mem address */		dev->mem_start = ints[3];	case 2:		/* IRQ */		dev->irq = ints[2];	case 1:		/* IO address */		dev->base_addr = ints[1];	}	if (*s)		strncpy(dev->name, s, 9);	else		strcpy(dev->name, "arc%d");	if (register_netdev(dev))		printk(KERN_ERR "com90xx: Cannot register arcnet device\n");	return 1;}__setup("com90xx=", com90xx_setup);#endif				/* MODULE */

⌨️ 快捷键说明

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