linux/drivers/net/ethernet/8390/wd.c
<<
>>
Prefs
   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
  28static 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. */
  48static unsigned int wd_portlist[] __initdata =
  49{0x300, 0x280, 0x380, 0x240, 0};
  50
  51static int wd_probe1(struct net_device *dev, int ioaddr);
  52
  53static int wd_open(struct net_device *dev);
  54static void wd_reset_8390(struct net_device *dev);
  55static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
  56                                                int ring_page);
  57static void wd_block_input(struct net_device *dev, int count,
  58                                                  struct sk_buff *skb, int ring_offset);
  59static void wd_block_output(struct net_device *dev, int count,
  60                                                        const unsigned char *buf, int start_page);
  61static int wd_close(struct net_device *dev);
  62
  63static 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
  87static 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
 129struct 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;
 144out:
 145        free_netdev(dev);
 146        return ERR_PTR(err);
 147}
 148#endif
 149
 150static 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
 164static 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
 372static int
 373wd_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
 389static void
 390wd_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
 412static void
 413wd_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
 439static void
 440wd_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
 462static void
 463wd_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
 480static int
 481wd_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 */
 502static struct net_device *dev_wd[MAX_WD_CARDS];
 503static int io[MAX_WD_CARDS];
 504static int irq[MAX_WD_CARDS];
 505static int mem[MAX_WD_CARDS];
 506static int mem_end[MAX_WD_CARDS];       /* for non std. mem size */
 507
 508module_param_hw_array(io, int, ioport, NULL, 0);
 509module_param_hw_array(irq, int, irq, NULL, 0);
 510module_param_hw_array(mem, int, iomem, NULL, 0);
 511module_param_hw_array(mem_end, int, iomem, NULL, 0);
 512module_param_named(msg_enable, wd_msg_enable, uint, 0444);
 513MODULE_PARM_DESC(io, "I/O base address(es)");
 514MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
 515MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
 516MODULE_PARM_DESC(mem_end, "memory end address(es)");
 517MODULE_PARM_DESC(msg_enable, "Debug message level (see linux/netdevice.h for bitmap)");
 518MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
 519MODULE_LICENSE("GPL");
 520
 521/* This is set up so that only a single autoprobe takes place per call.
 522ISA device autoprobes on a running machine are not recommended. */
 523
 524static 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}
 553module_init(wd_init_module);
 554
 555static 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
 562static 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}
 575module_exit(wd_cleanup_module);
 576#endif /* MODULE */
 577