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