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

📄 com90xx.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
			continue;		}		/* skip this completely if an IRQ was given, because maybe		 * we're on a machine that locks during autoirq!		 */		if (!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);				BUGMSG(D_INIT_REASONS, "Stage 5: ");				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) {			ARCRESET;			JIFFER(RESETtime);		} else {			/* just one shmem and port, assume they match */			writeb(TESTvalue, shmems[0]);		}#else		ARCRESET;		JIFFER(RESETtime);#endif		for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {			u_long ptr;			ptr = (u_long) (*shmem);			if (readb(ptr) == TESTvalue) {	/* found one */				int probe_more;				BUGMSG2(D_INIT, "%lXh)\n", *shmem);				openparen = 0;				/* register the card */				if (init_once == 1 && numshmems > 1)					probe_more = numshmems - 1;				else					probe_more = 0;				retval = arc90xx_found(dev, *port, airq, *shmem, probe_more);				if (retval)					openparen = 0;				/* remove shmem from the list */				*shmem = shmems[numshmems - 1];				numshmems--;				break;			} else {				BUGMSG2(D_INIT_REASONS, "%Xh-", readb(ptr));			}		}		if (openparen) {			BUGMSG2(D_INIT, "no matching shmem)\n");			BUGMSG(D_INIT_REASONS, "Stage 5: ");			BUGLVL(D_INIT_REASONS) numprint = 0;		}		*port = ports[numports - 1];		numports--;		port--;		if (!retval)			break;	}	BUGMSG(D_INIT_REASONS, "\n");	/* Now put back TESTvalue on all leftover shmems.	 */	for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++)		writeb(TESTvalue, *shmem);	if (retval)		BUGMSG(D_NORMAL, "Stage 5: No ARCnet cards found.\n");	return retval;}/* Set up the struct device associated with this card.  Called after * probing succeeds. */__initfunc(static int arc90xx_found(struct device *dev, int ioaddr, int airq, u_long shmem, int more)){	struct arcnet_local *lp;	u_long first_mirror, last_mirror;	int mirror_size;	/* reserve the irq */	if (request_irq(airq, &arcnet_interrupt, 0, "arcnet (90xx)", dev)) {		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);		return -ENODEV;	}	dev->irq = airq;	/* reserve the I/O region - guaranteed to work by check_region */	request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (90xx)");	dev->base_addr = ioaddr;	/* find the real shared memory start/end points, including mirrors */#define BUFFER_SIZE (512)#define MIRROR_SIZE (BUFFER_SIZE*4)	/* 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 (readb(shmem) == TESTvalue	    && readb(shmem - mirror_size) != TESTvalue	    && readb(shmem - 2 * mirror_size) == TESTvalue)		mirror_size *= 2;	first_mirror = last_mirror = shmem;	while (readb(first_mirror) == TESTvalue)		first_mirror -= mirror_size;	first_mirror += mirror_size;	while (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. */	dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);	if (dev->priv == NULL) {		free_irq(airq, dev);		release_region(ioaddr, ARCNET_TOTAL_SIZE);		return -ENOMEM;	}	memset(dev->priv, 0, sizeof(struct arcnet_local));	lp = (struct arcnet_local *) (dev->priv);	lp->card_type = ARC_90xx;	lp->card_type_str = "COM 90xx";	lp->arcnet_reset = arc90xx_reset;	lp->asetmask = arc90xx_setmask;	lp->astatus = arc90xx_status;	lp->acommand = arc90xx_command;	lp->openclose_device = arc90xx_openclose;	lp->prepare_tx = arc90xx_prepare_tx;	lp->inthandler = arc90xx_inthandler;	/* Fill in the fields of the device structure with generic	 * values.	 */	arcnet_setup(dev);	/* And now fill particular fields with arcnet values */	dev->mtu = 1500;	/* completely arbitrary - agrees with ether, though */	dev->hard_header_len = sizeof(struct ClientData);	lp->sequence = 1;	lp->recbuf = 0;	BUGMSG(D_DURING, "ClientData header size is %d.\n",	       sizeof(struct ClientData));	BUGMSG(D_DURING, "HardHeader size is %d.\n",	       sizeof(struct archdr));	/* get and check the station ID from offset 1 in shmem */	lp->stationid = readb(first_mirror + 1);	if (lp->stationid == 0)		BUGMSG(D_NORMAL, "WARNING!  Station address 00 is reserved "		       "for broadcasts!\n");	else if (lp->stationid == 255)		BUGMSG(D_NORMAL, "WARNING!  Station address FF may confuse "		       "DOS networking programs!\n");	dev->dev_addr[0] = lp->stationid;	BUGMSG(D_NORMAL, "ARCnet COM90xx: station %02Xh found at %03lXh, IRQ %d, "	       "ShMem %lXh (%ld*%xh).\n",	       lp->stationid,	       dev->base_addr, dev->irq, dev->mem_start,	 (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);	/* OK. We're finished. If there are probably other cards, add other	 * COM90xx drivers to the device chain, so they get probed later.	 */#ifndef MODULE	while (!com90xx_explicit && more--) {		if (arcnet_num_devs < MAX_ARCNET_DEVS) {			arcnet_devs[arcnet_num_devs].next = dev->next;			dev->next = &arcnet_devs[arcnet_num_devs];			dev = dev->next;			dev->name = (char *) &arcnet_dev_names[arcnet_num_devs];			arcnet_num_devs++;		} else {			BUGMSG(D_NORMAL, "Too many arcnet devices - no more will be probed for.\n");			return 0;		}		arcnet_makename(dev->name);		dev->init = arc90xx_probe;	}#endif	return 0;}/* 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 arc90xx_reset(struct device *dev, int reset_delay){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	short ioaddr = dev->base_addr;	int delayval, recbuf = lp->recbuf;	if (reset_delay == 3) {		ARCRESET;		return 0;	}	/* no IRQ's, please! */	lp->intmask = 0;	SETMASK;	BUGMSG(D_INIT, "Resetting %s (status=%Xh)\n",	       dev->name, ARCSTATUS);	if (reset_delay) {		/* reset the card */		ARCRESET;		JIFFER(RESETtime);	}	ACOMMAND(CFLAGScmd | RESETclear);	/* clear flags & end reset */	ACOMMAND(CFLAGScmd | CONFIGclear);	/* verify that the ARCnet signature byte is present */	if (readb(dev->mem_start) != TESTvalue) {		BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");		return 1;	}	/* clear out status variables */	recbuf = lp->recbuf = 0;	lp->txbuf = 2;	/* enable extended (512-byte) packets */	ACOMMAND(CONFIGcmd | EXTconf);#ifndef SLOW_XMIT_COPY	/* clean out all the memory to make debugging make more sense :) */	BUGLVL(D_DURING)	    memset_io(dev->mem_start, 0x42, 2048);#endif	/* and enable receive of our first packet to the first buffer */	EnableReceiver();	/* re-enable interrupts */	lp->intmask |= NORXflag;#ifdef DETECT_RECONFIGS	lp->intmask |= RECONflag;#endif	SETMASK;	/* done!  return success. */	return 0;}static void arc90xx_openclose(int open){	if (open)		MOD_INC_USE_COUNT;	else		MOD_DEC_USE_COUNT;}static void arc90xx_setmask(struct device *dev, u_char mask){	short ioaddr = dev->base_addr;	AINTMASK(mask);}static u_char arc90xx_status(struct device *dev){	short ioaddr = dev->base_addr;	return ARCSTATUS;}static void arc90xx_command(struct device *dev, u_char cmd){	short ioaddr = dev->base_addr;	ACOMMAND(cmd);}/* The actual interrupt handler routine - handle various IRQ's generated * by the card. */static void arc90xx_inthandler(struct device *dev){	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;	int ioaddr = dev->base_addr, status, boguscount = 3, didsomething;	AINTMASK(0);	BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",	       ARCSTATUS, lp->intmask);	do {		status = ARCSTATUS;		didsomething = 0;		/* RESET flag was enabled - card is resetting and if RX		 * is disabled, it's NOT because we just got a packet.		 */		if (status & RESETflag) {			BUGMSG(D_NORMAL, "spurious reset (status=%Xh)\n",			       status);			arc90xx_reset(dev, 0);			/* all other flag values are just garbage */			break;		}		/* RX is inhibited - we must have received something. */		if (status & lp->intmask & NORXflag) {			int recbuf = lp->recbuf = !lp->recbuf;			BUGMSG(D_DURING, "receive irq (status=%Xh)\n",			       status);			/* enable receive of our next packet */			EnableReceiver();			/* Got a packet. */			arc90xx_rx(dev, !recbuf);			didsomething++;		}		/* it can only be an xmit-done irq if we're xmitting :) */		/*if (status&TXFREEflag && !lp->in_txhandler && lp->sending) */		if (status & lp->intmask & TXFREEflag) {			struct Outgoing *out = &(lp->outgoing);			int was_sending = lp->sending;			lp->intmask &= ~TXFREEflag;			lp->in_txhandler++;			if (was_sending)				lp->sending--;			BUGMSG(D_DURING, "TX IRQ (stat=%Xh, numsegs=%d, segnum=%d, skb=%ph)\n",			    status, out->numsegs, out->segnum, out->skb);			if (was_sending && !(status & TXACKflag)) {				if (lp->lasttrans_dest != 0) {					BUGMSG(D_EXTRA, "transmit was not acknowledged! (status=%Xh, dest=%02Xh)\n",					     status, lp->lasttrans_dest);

⌨️ 快捷键说明

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