return 0; 
err = register_netdev(dev); if (err) free_irq(dev->irq, dev); return err; 
static int __init wd_probe1(struct net_device *dev, int ioaddr){	int i;	int checksum = 0;	int ancient = 0;			/* An old card without config registers. */	int word16 = 0;				/* 0 = 8 bit, 1 = 16 bit */	const char *model_name;	static unsigned version_printed;	for (i = 0; i < 8; i++)		checksum += inb(ioaddr + 8 + i);	if (inb(ioaddr + 8) == 0xff 	/* Extra check to avoid soundcard. */		|| inb(ioaddr + 9) == 0xff		|| (checksum & 0xff) != 0xFF)		return -ENODEV;	/* Check for semi-valid mem_start/end values if supplied. */	if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {		printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");		dev->mem_start = 0;		dev->mem_end = 0;	}	if (ei_debug  &&  version_printed++ == 0)		printk(version);	printk("%s: WD80x3 at %#3x,", dev->name, ioaddr);	for (i = 0; i < 6; i++)		printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));	/* The following PureData probe code was contributed by	   Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software	   configuration differently from others so we have to check for them.	   This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.	   */	if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') {		unsigned char reg5 = inb(ioaddr+5);		switch (inb(ioaddr+2)) {		case 0x03: word16 = 0; model_name = "PDI8023-8";	break;		case 0x05: word16 = 0; model_name = "PDUC8023";	break;		case 0x0a: word16 = 1; model_name = "PDI8023-16"; break;			/* Either 0x01 (dumb) or they've released a new version. */		default:	 word16 = 0; model_name = "PDI8023";	break;		}		dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12;		dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1;	} else {								/* End of PureData probe */		/* This method of checking for a 16-bit board is borrowed from the		   we.c driver.  A simpler method is just to look in ASIC reg. 0x03.		   I'm comparing the two method in alpha test to make certain they		   return the same result. */		/* Check for the old 8 bit board - it has register 0/8 aliasing.		   Do NOT check i>=6 here -- it hangs the old 8003 boards! */		for (i = 0; i < 6; i++)			if (inb(ioaddr+i) != inb(ioaddr+8+i))				break;		if (i >= 6) {			ancient = 1;			model_name = "WD8003-old";			word16 = 0;		} else {			int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */			outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */			if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */				&& (tmp & 0x01) == 0x01	) {				/* In a 16 slot. */				int asic_reg5 = inb(ioaddr+WD_CMDREG5);				/* Magic to set ASIC to word-wide mode. */				outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5);				outb(tmp, ioaddr+1);				model_name = "WD8013";				word16 = 1;		/* We have a 16bit board here! */			} else {				model_name = "WD8003";				word16 = 0;			}			outb(tmp, ioaddr+1);			/* Restore original reg1 value. */		}#ifndef final_version		if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01))			printk("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",				   word16 ? 16 : 8, (inb(ioaddr+1) & 0x01) ? 16 : 8);#endif	}#if defined(WD_SHMEM) && WD_SHMEM > 0x80000	/* Allow a compile-time override.	 */	dev->mem_start = WD_SHMEM;#else	if (dev->mem_start == 0) {		/* Sanity and old 8003 check */		int reg0 = inb(ioaddr);		if (reg0 == 0xff || reg0 == 0) {			/* Future plan: this could check a few likely locations first. */			dev->mem_start = 0xd0000;			printk(" assigning address %#lx", dev->mem_start);		} else {			int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f;			/* Some boards don't have the register 5 -- it returns 0xff. */			if (high_addr_bits == 0x1f || word16 == 0)				high_addr_bits = 0x01;			dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19);		}	}#endif	/* The 8390 isn't at the base address -- the ASIC regs are there! */	dev->base_addr = ioaddr+WD_NIC_OFFSET;	if (dev->irq < 2) {		int irqmap[] = {9,3,5,7,10,11,15,4};		int reg1 = inb(ioaddr+1);		int reg4 = inb(ioaddr+4);		if (ancient || reg1 == 0xff) {	/* Ack!! No way to read the IRQ! */			short nic_addr = ioaddr+WD_NIC_OFFSET;			unsigned long irq_mask;			/* We have an old-style ethercard that doesn't report its IRQ			   line.  Do autoirq to find the IRQ line. Note that this IS NOT			   a reliable way to trigger an interrupt. */			outb_p(E8390_NODMA + E8390_STOP, nic_addr);			outb(0x00, nic_addr+EN0_IMR);	/* Disable all intrs. */						irq_mask = probe_irq_on();			outb_p(0xff, nic_addr + EN0_IMR);	/* Enable all interrupts. */			outb_p(0x00, nic_addr + EN0_RCNTLO);			outb_p(0x00, nic_addr + EN0_RCNTHI);			outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */			mdelay(20);			dev->irq = probe_irq_off(irq_mask);						outb_p(0x00, nic_addr+EN0_IMR);	/* Mask all intrs. again. */			if (ei_debug > 2)				printk(" autoirq is %d", dev->irq);			if (dev->irq < 2)				dev->irq = word16 ? 10 : 5;		} else			dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)];	} else if (dev->irq == 2)		/* Fixup bogosity: IRQ2 is really IRQ9 */		dev->irq = 9;	/* Snarf the interrupt now.  There's no point in waiting since we cannot	   share and the board will usually be enabled. */	i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);	if (i) {		printk (" unable to get IRQ %d.\n", dev->irq);		return i;	}	/* OK, were are certain this is going to work.  Setup the device. */	ei_status.name = model_name;	ei_status.word16 = word16;	ei_status.tx_start_page = WD_START_PG;	ei_status.rx_start_page = WD_START_PG + TX_PAGES;	/* Don't map in the shared memory until the board is actually opened. */	/* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */	if (dev->mem_end != 0) {		ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;		ei_status.priv = dev->mem_end - dev->mem_start;	} else {		ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG;		dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256;		ei_status.priv = (ei_status.stop_page - WD_START_PG)*256;	}	ei_status.mem = ioremap(dev->mem_start, ei_status.priv);	if (!ei_status.mem) {		free_irq(dev->irq, dev);		return -ENOMEM;	}	printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",		   model_name, dev->irq, dev->mem_start, dev->mem_end-1);	ei_status.reset_8390 = &wd_reset_8390;	ei_status.block_input = &wd_block_input;	ei_status.block_output = &wd_block_output;	ei_status.get_8390_hdr = &wd_get_8390_hdr;	dev->open = &wd_open;	dev->stop = &wd_close;#ifdef CONFIG_NET_POLL_CONTROLLER	dev->poll_controller = ei_poll;#endif	NS8390_init(dev, 0);#if 1	/* Enable interrupt generation on softconfig cards -- M.U */	/* .. but possibly potentially unsafe - Donald */	if (inb(ioaddr+14) & 0x20)		outb(inb(ioaddr+4)|0x80, ioaddr+4);#endif	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/b1fc5505e0dbcc3fd7c75bfe6bee39ec50080963/wd.c/clean/drivers/net/wd.c