xref: /openbmc/linux/drivers/net/ethernet/8390/wd.c (revision 64288aa9)
1 /* wd.c: A WD80x3 ethernet driver for linux. */
2 /*
3 	Written 1993-94 by Donald Becker.
4 
5 	Copyright 1993 United States Government as represented by the
6 	Director, National Security Agency.
7 
8 	This software may be used and distributed according to the terms
9 	of the GNU General Public License, incorporated herein by reference.
10 
11 	The author may be reached as becker@scyld.com, or C/O
12 	Scyld Computing Corporation
13 	410 Severn Ave., Suite 210
14 	Annapolis MD 21403
15 
16 	This is a driver for WD8003 and WD8013 "compatible" ethercards.
17 
18 	Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013.
19 
20 	Changelog:
21 
22 	Paul Gortmaker	: multiple card support for module users, support
23 			  for non-standard memory sizes.
24 
25 
26 */
27 
28 static const char version[] =
29 	"wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
30 
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
35 #include <linux/init.h>
36 #include <linux/interrupt.h>
37 #include <linux/delay.h>
38 #include <linux/netdevice.h>
39 #include <linux/etherdevice.h>
40 
41 #include <asm/io.h>
42 
43 #include "8390.h"
44 
45 #define DRV_NAME "wd"
46 
47 /* A zero-terminated list of I/O addresses to be probed. */
48 static unsigned int wd_portlist[] __initdata =
49 {0x300, 0x280, 0x380, 0x240, 0};
50 
51 static int wd_probe1(struct net_device *dev, int ioaddr);
52 
53 static int wd_open(struct net_device *dev);
54 static void wd_reset_8390(struct net_device *dev);
55 static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
56 						int ring_page);
57 static void wd_block_input(struct net_device *dev, int count,
58 						  struct sk_buff *skb, int ring_offset);
59 static void wd_block_output(struct net_device *dev, int count,
60 							const unsigned char *buf, int start_page);
61 static int wd_close(struct net_device *dev);
62 
63 static u32 wd_msg_enable;
64 
65 #define WD_START_PG		0x00	/* First page of TX buffer */
66 #define WD03_STOP_PG	0x20	/* Last page +1 of RX ring */
67 #define WD13_STOP_PG	0x40	/* Last page +1 of RX ring */
68 
69 #define WD_CMDREG		0		/* Offset to ASIC command register. */
70 #define	 WD_RESET		0x80	/* Board reset, in WD_CMDREG. */
71 #define	 WD_MEMENB		0x40	/* Enable the shared memory. */
72 #define WD_CMDREG5		5		/* Offset to 16-bit-only ASIC register 5. */
73 #define	 ISA16			0x80	/* Enable 16 bit access from the ISA bus. */
74 #define	 NIC16			0x40	/* Enable 16 bit access from the 8390. */
75 #define WD_NIC_OFFSET	16		/* Offset to the 8390 from the base_addr. */
76 #define WD_IO_EXTENT	32
77 
78 
79 /*	Probe for the WD8003 and WD8013.  These cards have the station
80 	address PROM at I/O ports <base>+8 to <base>+13, with a checksum
81 	following. A Soundblaster can have the same checksum as an WDethercard,
82 	so we have an extra exclusionary check for it.
83 
84 	The wd_probe1() routine initializes the card and fills the
85 	station address field. */
86 
87 static int __init do_wd_probe(struct net_device *dev)
88 {
89 	int i;
90 	struct resource *r;
91 	int base_addr = dev->base_addr;
92 	int irq = dev->irq;
93 	int mem_start = dev->mem_start;
94 	int mem_end = dev->mem_end;
95 
96 	if (base_addr > 0x1ff) {	/* Check a user specified location. */
97 		r = request_region(base_addr, WD_IO_EXTENT, "wd-probe");
98 		if ( r == NULL)
99 			return -EBUSY;
100 		i = wd_probe1(dev, base_addr);
101 		if (i != 0)
102 			release_region(base_addr, WD_IO_EXTENT);
103 		else
104 			r->name = dev->name;
105 		return i;
106 	}
107 	else if (base_addr != 0)	/* Don't probe at all. */
108 		return -ENXIO;
109 
110 	for (i = 0; wd_portlist[i]; i++) {
111 		int ioaddr = wd_portlist[i];
112 		r = request_region(ioaddr, WD_IO_EXTENT, "wd-probe");
113 		if (r == NULL)
114 			continue;
115 		if (wd_probe1(dev, ioaddr) == 0) {
116 			r->name = dev->name;
117 			return 0;
118 		}
119 		release_region(ioaddr, WD_IO_EXTENT);
120 		dev->irq = irq;
121 		dev->mem_start = mem_start;
122 		dev->mem_end = mem_end;
123 	}
124 
125 	return -ENODEV;
126 }
127 
128 #ifndef MODULE
129 struct net_device * __init wd_probe(int unit)
130 {
131 	struct net_device *dev = alloc_ei_netdev();
132 	int err;
133 
134 	if (!dev)
135 		return ERR_PTR(-ENOMEM);
136 
137 	sprintf(dev->name, "eth%d", unit);
138 	netdev_boot_setup_check(dev);
139 
140 	err = do_wd_probe(dev);
141 	if (err)
142 		goto out;
143 	return dev;
144 out:
145 	free_netdev(dev);
146 	return ERR_PTR(err);
147 }
148 #endif
149 
150 static const struct net_device_ops wd_netdev_ops = {
151 	.ndo_open		= wd_open,
152 	.ndo_stop		= wd_close,
153 	.ndo_start_xmit		= ei_start_xmit,
154 	.ndo_tx_timeout		= ei_tx_timeout,
155 	.ndo_get_stats		= ei_get_stats,
156 	.ndo_set_rx_mode	= ei_set_multicast_list,
157 	.ndo_validate_addr	= eth_validate_addr,
158 	.ndo_set_mac_address 	= eth_mac_addr,
159 #ifdef CONFIG_NET_POLL_CONTROLLER
160 	.ndo_poll_controller 	= ei_poll,
161 #endif
162 };
163 
164 static int __init wd_probe1(struct net_device *dev, int ioaddr)
165 {
166 	int i;
167 	int err;
168 	int checksum = 0;
169 	int ancient = 0;			/* An old card without config registers. */
170 	int word16 = 0;				/* 0 = 8 bit, 1 = 16 bit */
171 	u8 addr[ETH_ALEN];
172 	const char *model_name;
173 	static unsigned version_printed;
174 	struct ei_device *ei_local = netdev_priv(dev);
175 
176 	for (i = 0; i < 8; i++)
177 		checksum += inb(ioaddr + 8 + i);
178 	if (inb(ioaddr + 8) == 0xff 	/* Extra check to avoid soundcard. */
179 		|| inb(ioaddr + 9) == 0xff
180 		|| (checksum & 0xff) != 0xFF)
181 		return -ENODEV;
182 
183 	/* Check for semi-valid mem_start/end values if supplied. */
184 	if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
185 		netdev_warn(dev,
186 			    "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
187 		dev->mem_start = 0;
188 		dev->mem_end = 0;
189 	}
190 
191 	if ((wd_msg_enable & NETIF_MSG_DRV) && (version_printed++ == 0))
192 		netdev_info(dev, version);
193 
194 	for (i = 0; i < 6; i++)
195 		addr[i] = inb(ioaddr + 8 + i);
196 	eth_hw_addr_set(dev, addr);
197 
198 	netdev_info(dev, "WD80x3 at %#3x, %pM", ioaddr, dev->dev_addr);
199 
200 	/* The following PureData probe code was contributed by
201 	   Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
202 	   configuration differently from others so we have to check for them.
203 	   This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
204 	   */
205 	if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') {
206 		unsigned char reg5 = inb(ioaddr+5);
207 
208 		switch (inb(ioaddr+2)) {
209 		case 0x03: word16 = 0; model_name = "PDI8023-8";	break;
210 		case 0x05: word16 = 0; model_name = "PDUC8023";	break;
211 		case 0x0a: word16 = 1; model_name = "PDI8023-16"; break;
212 			/* Either 0x01 (dumb) or they've released a new version. */
213 		default:	 word16 = 0; model_name = "PDI8023";	break;
214 		}
215 		dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12;
216 		dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1;
217 	} else {								/* End of PureData probe */
218 		/* This method of checking for a 16-bit board is borrowed from the
219 		   we.c driver.  A simpler method is just to look in ASIC reg. 0x03.
220 		   I'm comparing the two method in alpha test to make certain they
221 		   return the same result. */
222 		/* Check for the old 8 bit board - it has register 0/8 aliasing.
223 		   Do NOT check i>=6 here -- it hangs the old 8003 boards! */
224 		for (i = 0; i < 6; i++)
225 			if (inb(ioaddr+i) != inb(ioaddr+8+i))
226 				break;
227 		if (i >= 6) {
228 			ancient = 1;
229 			model_name = "WD8003-old";
230 			word16 = 0;
231 		} else {
232 			int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */
233 			outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */
234 			if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */
235 				&& (tmp & 0x01) == 0x01	) {				/* In a 16 slot. */
236 				int asic_reg5 = inb(ioaddr+WD_CMDREG5);
237 				/* Magic to set ASIC to word-wide mode. */
238 				outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5);
239 				outb(tmp, ioaddr+1);
240 				model_name = "WD8013";
241 				word16 = 1;		/* We have a 16bit board here! */
242 			} else {
243 				model_name = "WD8003";
244 				word16 = 0;
245 			}
246 			outb(tmp, ioaddr+1);			/* Restore original reg1 value. */
247 		}
248 #ifndef final_version
249 		if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01))
250 			pr_cont("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
251 				word16 ? 16 : 8,
252 				(inb(ioaddr+1) & 0x01) ? 16 : 8);
253 #endif
254 	}
255 
256 #if defined(WD_SHMEM) && WD_SHMEM > 0x80000
257 	/* Allow a compile-time override.	 */
258 	dev->mem_start = WD_SHMEM;
259 #else
260 	if (dev->mem_start == 0) {
261 		/* Sanity and old 8003 check */
262 		int reg0 = inb(ioaddr);
263 		if (reg0 == 0xff || reg0 == 0) {
264 			/* Future plan: this could check a few likely locations first. */
265 			dev->mem_start = 0xd0000;
266 			pr_cont(" assigning address %#lx", dev->mem_start);
267 		} else {
268 			int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f;
269 			/* Some boards don't have the register 5 -- it returns 0xff. */
270 			if (high_addr_bits == 0x1f || word16 == 0)
271 				high_addr_bits = 0x01;
272 			dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19);
273 		}
274 	}
275 #endif
276 
277 	/* The 8390 isn't at the base address -- the ASIC regs are there! */
278 	dev->base_addr = ioaddr+WD_NIC_OFFSET;
279 
280 	if (dev->irq < 2) {
281 		static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4};
282 		int reg1 = inb(ioaddr+1);
283 		int reg4 = inb(ioaddr+4);
284 		if (ancient || reg1 == 0xff) {	/* Ack!! No way to read the IRQ! */
285 			short nic_addr = ioaddr+WD_NIC_OFFSET;
286 			unsigned long irq_mask;
287 
288 			/* We have an old-style ethercard that doesn't report its IRQ
289 			   line.  Do autoirq to find the IRQ line. Note that this IS NOT
290 			   a reliable way to trigger an interrupt. */
291 			outb_p(E8390_NODMA + E8390_STOP, nic_addr);
292 			outb(0x00, nic_addr+EN0_IMR);	/* Disable all intrs. */
293 
294 			irq_mask = probe_irq_on();
295 			outb_p(0xff, nic_addr + EN0_IMR);	/* Enable all interrupts. */
296 			outb_p(0x00, nic_addr + EN0_RCNTLO);
297 			outb_p(0x00, nic_addr + EN0_RCNTHI);
298 			outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */
299 			mdelay(20);
300 			dev->irq = probe_irq_off(irq_mask);
301 
302 			outb_p(0x00, nic_addr+EN0_IMR);	/* Mask all intrs. again. */
303 
304 			if (wd_msg_enable & NETIF_MSG_PROBE)
305 				pr_cont(" autoirq is %d", dev->irq);
306 			if (dev->irq < 2)
307 				dev->irq = word16 ? 10 : 5;
308 		} else
309 			dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)];
310 	} else if (dev->irq == 2)		/* Fixup bogosity: IRQ2 is really IRQ9 */
311 		dev->irq = 9;
312 
313 	/* Snarf the interrupt now.  There's no point in waiting since we cannot
314 	   share and the board will usually be enabled. */
315 	i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
316 	if (i) {
317 		pr_cont(" unable to get IRQ %d.\n", dev->irq);
318 		return i;
319 	}
320 
321 	/* OK, were are certain this is going to work.  Setup the device. */
322 	ei_status.name = model_name;
323 	ei_status.word16 = word16;
324 	ei_status.tx_start_page = WD_START_PG;
325 	ei_status.rx_start_page = WD_START_PG + TX_PAGES;
326 
327 	/* Don't map in the shared memory until the board is actually opened. */
328 
329 	/* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */
330 	if (dev->mem_end != 0) {
331 		ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
332 		ei_status.priv = dev->mem_end - dev->mem_start;
333 	} else {
334 		ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG;
335 		dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256;
336 		ei_status.priv = (ei_status.stop_page - WD_START_PG)*256;
337 	}
338 
339 	ei_status.mem = ioremap(dev->mem_start, ei_status.priv);
340 	if (!ei_status.mem) {
341 		free_irq(dev->irq, dev);
342 		return -ENOMEM;
343 	}
344 
345 	pr_cont(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
346 		model_name, dev->irq, dev->mem_start, dev->mem_end-1);
347 
348 	ei_status.reset_8390 = wd_reset_8390;
349 	ei_status.block_input = wd_block_input;
350 	ei_status.block_output = wd_block_output;
351 	ei_status.get_8390_hdr = wd_get_8390_hdr;
352 
353 	dev->netdev_ops = &wd_netdev_ops;
354 	NS8390_init(dev, 0);
355 	ei_local->msg_enable = wd_msg_enable;
356 
357 #if 1
358 	/* Enable interrupt generation on softconfig cards -- M.U */
359 	/* .. but possibly potentially unsafe - Donald */
360 	if (inb(ioaddr+14) & 0x20)
361 		outb(inb(ioaddr+4)|0x80, ioaddr+4);
362 #endif
363 
364 	err = register_netdev(dev);
365 	if (err) {
366 		free_irq(dev->irq, dev);
367 		iounmap(ei_status.mem);
368 	}
369 	return err;
370 }
371 
372 static int
373 wd_open(struct net_device *dev)
374 {
375   int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
376 
377   /* Map in the shared memory. Always set register 0 last to remain
378 	 compatible with very old boards. */
379   ei_status.reg0 = ((dev->mem_start>>13) & 0x3f) | WD_MEMENB;
380   ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16;
381 
382   if (ei_status.word16)
383 	  outb(ei_status.reg5, ioaddr+WD_CMDREG5);
384   outb(ei_status.reg0, ioaddr); /* WD_CMDREG */
385 
386   return ei_open(dev);
387 }
388 
389 static void
390 wd_reset_8390(struct net_device *dev)
391 {
392 	int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
393 	struct ei_device *ei_local = netdev_priv(dev);
394 
395 	outb(WD_RESET, wd_cmd_port);
396 	netif_dbg(ei_local, hw, dev, "resetting the WD80x3 t=%lu...\n",
397 		  jiffies);
398 	ei_status.txing = 0;
399 
400 	/* Set up the ASIC registers, just in case something changed them. */
401 	outb((((dev->mem_start>>13) & 0x3f)|WD_MEMENB), wd_cmd_port);
402 	if (ei_status.word16)
403 		outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5);
404 
405 	netif_dbg(ei_local, hw, dev, "reset done\n");
406 }
407 
408 /* Grab the 8390 specific header. Similar to the block_input routine, but
409    we don't need to be concerned with ring wrap as the header will be at
410    the start of a page, so we optimize accordingly. */
411 
412 static void
413 wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
414 {
415 
416 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
417 	void __iomem *hdr_start = ei_status.mem + ((ring_page - WD_START_PG)<<8);
418 
419 	/* We'll always get a 4 byte header read followed by a packet read, so
420 	   we enable 16 bit mode before the header, and disable after the body. */
421 	if (ei_status.word16)
422 		outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
423 
424 #ifdef __BIG_ENDIAN
425 	/* Officially this is what we are doing, but the readl() is faster */
426 	/* unfortunately it isn't endian aware of the struct               */
427 	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
428 	hdr->count = le16_to_cpu(hdr->count);
429 #else
430 	((unsigned int*)hdr)[0] = readl(hdr_start);
431 #endif
432 }
433 
434 /* Block input and output are easy on shared memory ethercards, and trivial
435    on the Western digital card where there is no choice of how to do it.
436    The only complications are that the ring buffer wraps, and need to map
437    switch between 8- and 16-bit modes. */
438 
439 static void
440 wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
441 {
442 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
443 	unsigned long offset = ring_offset - (WD_START_PG<<8);
444 	void __iomem *xfer_start = ei_status.mem + offset;
445 
446 	if (offset + count > ei_status.priv) {
447 		/* We must wrap the input move. */
448 		int semi_count = ei_status.priv - offset;
449 		memcpy_fromio(skb->data, xfer_start, semi_count);
450 		count -= semi_count;
451 		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
452 	} else {
453 		/* Packet is in one chunk -- we can copy + cksum. */
454 		memcpy_fromio(skb->data, xfer_start, count);
455 	}
456 
457 	/* Turn off 16 bit access so that reboot works.	 ISA brain-damage */
458 	if (ei_status.word16)
459 		outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
460 }
461 
462 static void
463 wd_block_output(struct net_device *dev, int count, const unsigned char *buf,
464 				int start_page)
465 {
466 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
467 	void __iomem *shmem = ei_status.mem + ((start_page - WD_START_PG)<<8);
468 
469 
470 	if (ei_status.word16) {
471 		/* Turn on and off 16 bit access so that reboot works. */
472 		outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
473 		memcpy_toio(shmem, buf, count);
474 		outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
475 	} else
476 		memcpy_toio(shmem, buf, count);
477 }
478 
479 
480 static int
481 wd_close(struct net_device *dev)
482 {
483 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
484 	struct ei_device *ei_local = netdev_priv(dev);
485 
486 	netif_dbg(ei_local, ifdown, dev, "Shutting down ethercard.\n");
487 	ei_close(dev);
488 
489 	/* Change from 16-bit to 8-bit shared memory so reboot works. */
490 	if (ei_status.word16)
491 		outb(ei_status.reg5, wd_cmdreg + WD_CMDREG5 );
492 
493 	/* And disable the shared memory. */
494 	outb(ei_status.reg0 & ~WD_MEMENB, wd_cmdreg);
495 
496 	return 0;
497 }
498 
499 
500 #ifdef MODULE
501 #define MAX_WD_CARDS	4	/* Max number of wd cards per module */
502 static struct net_device *dev_wd[MAX_WD_CARDS];
503 static int io[MAX_WD_CARDS];
504 static int irq[MAX_WD_CARDS];
505 static int mem[MAX_WD_CARDS];
506 static int mem_end[MAX_WD_CARDS];	/* for non std. mem size */
507 
508 module_param_hw_array(io, int, ioport, NULL, 0);
509 module_param_hw_array(irq, int, irq, NULL, 0);
510 module_param_hw_array(mem, int, iomem, NULL, 0);
511 module_param_hw_array(mem_end, int, iomem, NULL, 0);
512 module_param_named(msg_enable, wd_msg_enable, uint, 0444);
513 MODULE_PARM_DESC(io, "I/O base address(es)");
514 MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
515 MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
516 MODULE_PARM_DESC(mem_end, "memory end address(es)");
517 MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
518 MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
519 MODULE_LICENSE("GPL");
520 
521 /* This is set up so that only a single autoprobe takes place per call.
522 ISA device autoprobes on a running machine are not recommended. */
523 
524 static int __init wd_init_module(void)
525 {
526 	struct net_device *dev;
527 	int this_dev, found = 0;
528 
529 	for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
530 		if (io[this_dev] == 0)  {
531 			if (this_dev != 0) break; /* only autoprobe 1st one */
532 			printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
533 		}
534 		dev = alloc_ei_netdev();
535 		if (!dev)
536 			break;
537 		dev->irq = irq[this_dev];
538 		dev->base_addr = io[this_dev];
539 		dev->mem_start = mem[this_dev];
540 		dev->mem_end = mem_end[this_dev];
541 		if (do_wd_probe(dev) == 0) {
542 			dev_wd[found++] = dev;
543 			continue;
544 		}
545 		free_netdev(dev);
546 		printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
547 		break;
548 	}
549 	if (found)
550 		return 0;
551 	return -ENXIO;
552 }
553 module_init(wd_init_module);
554 
555 static void cleanup_card(struct net_device *dev)
556 {
557 	free_irq(dev->irq, dev);
558 	release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
559 	iounmap(ei_status.mem);
560 }
561 
562 static void __exit wd_cleanup_module(void)
563 {
564 	int this_dev;
565 
566 	for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
567 		struct net_device *dev = dev_wd[this_dev];
568 		if (dev) {
569 			unregister_netdev(dev);
570 			cleanup_card(dev);
571 			free_netdev(dev);
572 		}
573 	}
574 }
575 module_exit(wd_cleanup_module);
576 #endif /* MODULE */
577