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

📄 com90xx.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
			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;				release_region(*port, ARCNET_TOTAL_SIZE);				*port-- = ports[--numports];				continue;			}		} else {			airq = 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 */			isa_writeb(TESTvalue, shmems[0]);		}#else		inb(_RESET);		mdelay(RESETtime);#endif		for (p = &shmems[0]; p < shmems + numshmems; p++) {			u_long ptr = *p;			if (isa_readb(ptr) == TESTvalue) {	/* found one */				BUGMSG2(D_INIT, "%lXh)\n", *p);				openparen = 0;				/* register the card */				if (com90xx_found(*port, airq, *p) == 0)					found = 1;				numprint = -1;				/* remove shmem from the list */				*p = shmems[--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;		}		if (!found)			release_region(*port, ARCNET_TOTAL_SIZE);		*port-- = ports[--numports];	}	BUGLVL(D_INIT_REASONS) printk("\n");	/* Now put back TESTvalue on all leftover shmems. */	for (p = &shmems[0]; p < shmems + numshmems; p++) {		isa_writeb(TESTvalue, *p);		release_mem_region(*p, BUFFER_SIZE);	}}/* Set up the struct net_device associated with this card.  Called after * probing succeeds. */static int __init com90xx_found(int ioaddr, int airq, u_long shmem){	struct net_device *dev = NULL;	struct arcnet_local *lp;	u_long first_mirror, last_mirror;	int mirror_size;	/* allocate struct net_device */	dev = alloc_arcdev(device);	if (!dev) {		BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");		release_mem_region(shmem, BUFFER_SIZE);		return -ENOMEM;	}	lp = dev->priv;	/* 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;	release_mem_region(shmem, BUFFER_SIZE);	if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))		goto err_free_dev;	/* 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_release_mem;	}	dev->irq = airq;	/* Initialize the rest of the device structure. */	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.owner = THIS_MODULE;	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_irq;	}	/* get and check the station ID from offset 1 in shmem */	dev->dev_addr[0] = readb(lp->mem_start + 1);	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 (register_netdev(dev))		goto err_unmap;	cards[numcards++] = dev;	return 0;err_unmap:	iounmap(lp->mem_start);err_free_irq:	free_irq(dev->irq, dev);err_release_mem:	release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);err_free_dev:	free_netdev(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_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 __iomem *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 __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;	TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));}MODULE_LICENSE("GPL");static int __init com90xx_init(void){	if (irq == 2)		irq = 9;	com90xx_probe();	if (!numcards)		return -EIO;	return 0;}static void __exit com90xx_exit(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);		free_netdev(dev);	}}module_init(com90xx_init);module_exit(com90xx_exit);#ifndef MODULEstatic int __init com90xx_setup(char *s){	int ints[8];	s = get_options(s, 8, ints);	if (!ints[0] && !*s) {		printk("com90xx: Disabled.\n");		return 1;	}	switch (ints[0]) {	default:		/* ERROR */		printk("com90xx: Too many arguments.\n");	case 3:		/* Mem address */		shmem = ints[3];	case 2:		/* IRQ */		irq = ints[2];	case 1:		/* IO address */		io = ints[1];	}	if (*s)		snprintf(device, sizeof(device), "%s", s);	return 1;}__setup("com90xx=", com90xx_setup);#endif

⌨️ 快捷键说明

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