]> Pileus Git - ~andy/linux/blob - drivers/net/smc-ultra.c
[NET]: Nuke SET_MODULE_OWNER macro.
[~andy/linux] / drivers / net / smc-ultra.c
1 /* smc-ultra.c: A SMC Ultra ethernet driver for linux. */
2 /*
3         This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards.
4
5         Written 1993-1998 by Donald Becker.
6
7         Copyright 1993 United States Government as represented by the
8         Director, National Security Agency.
9
10         This software may be used and distributed according to the terms
11         of the GNU General Public License, incorporated herein by reference.
12
13         The author may be reached as becker@scyld.com, or C/O
14         Scyld Computing Corporation
15         410 Severn Ave., Suite 210
16         Annapolis MD 21403
17
18         This driver uses the cards in the 8390-compatible mode.
19         Most of the run-time complexity is handled by the generic code in
20         8390.c.  The code in this file is responsible for
21
22                 ultra_probe()           Detecting and initializing the card.
23                 ultra_probe1()
24                 ultra_probe_isapnp()
25
26                 ultra_open()            The card-specific details of starting, stopping
27                 ultra_reset_8390()      and resetting the 8390 NIC core.
28                 ultra_close()
29
30                 ultra_block_input()             Routines for reading and writing blocks of
31                 ultra_block_output()    packet buffer memory.
32                 ultra_pio_input()
33                 ultra_pio_output()
34
35         This driver enables the shared memory only when doing the actual data
36         transfers to avoid a bug in early version of the card that corrupted
37         data transferred by a AHA1542.
38
39         This driver now supports the programmed-I/O (PIO) data transfer mode of
40         the EtherEZ. It does not use the non-8390-compatible "Altego" mode.
41         That support (if available) is in smc-ez.c.
42
43         Changelog:
44
45         Paul Gortmaker  : multiple card support for module users.
46         Donald Becker   : 4/17/96 PIO support, minor potential problems avoided.
47         Donald Becker   : 6/6/96 correctly set auto-wrap bit.
48         Alexander Sotirov : 1/20/01 Added support for ISAPnP cards
49
50         Note about the ISA PnP support:
51
52         This driver can not autoprobe for more than one SMC EtherEZ PnP card.
53         You have to configure the second card manually through the /proc/isapnp
54         interface and then load the module with an explicit io=0x___ option.
55 */
56
57 static const char version[] =
58         "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
59
60 #include <linux/module.h>
61 #include <linux/kernel.h>
62 #include <linux/errno.h>
63 #include <linux/string.h>
64 #include <linux/init.h>
65 #include <linux/isapnp.h>
66 #include <linux/netdevice.h>
67 #include <linux/etherdevice.h>
68
69 #include <asm/io.h>
70 #include <asm/irq.h>
71 #include <asm/system.h>
72
73 #include "8390.h"
74
75 #define DRV_NAME "smc-ultra"
76
77 /* A zero-terminated list of I/O addresses to be probed. */
78 static unsigned int ultra_portlist[] __initdata =
79 {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
80
81 static int ultra_probe1(struct net_device *dev, int ioaddr);
82
83 #ifdef __ISAPNP__
84 static int ultra_probe_isapnp(struct net_device *dev);
85 #endif
86
87 static int ultra_open(struct net_device *dev);
88 static void ultra_reset_8390(struct net_device *dev);
89 static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
90                                                 int ring_page);
91 static void ultra_block_input(struct net_device *dev, int count,
92                                                   struct sk_buff *skb, int ring_offset);
93 static void ultra_block_output(struct net_device *dev, int count,
94                                                         const unsigned char *buf, const int start_page);
95 static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
96                                                 int ring_page);
97 static void ultra_pio_input(struct net_device *dev, int count,
98                                                   struct sk_buff *skb, int ring_offset);
99 static void ultra_pio_output(struct net_device *dev, int count,
100                                                          const unsigned char *buf, const int start_page);
101 static int ultra_close_card(struct net_device *dev);
102
103 #ifdef __ISAPNP__
104 static struct isapnp_device_id ultra_device_ids[] __initdata = {
105         {       ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
106                 ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416),
107                 (long) "SMC EtherEZ (8416)" },
108         { }     /* terminate list */
109 };
110
111 MODULE_DEVICE_TABLE(isapnp, ultra_device_ids);
112 #endif
113
114
115 #define START_PG                0x00    /* First page of TX buffer */
116
117 #define ULTRA_CMDREG    0               /* Offset to ASIC command register. */
118 #define  ULTRA_RESET    0x80    /* Board reset, in ULTRA_CMDREG. */
119 #define  ULTRA_MEMENB   0x40    /* Enable the shared memory. */
120 #define IOPD    0x02                    /* I/O Pipe Data (16 bits), PIO operation. */
121 #define IOPA    0x07                    /* I/O Pipe Address for PIO operation. */
122 #define ULTRA_NIC_OFFSET  16    /* NIC register offset from the base_addr. */
123 #define ULTRA_IO_EXTENT 32
124 #define EN0_ERWCNT              0x08    /* Early receive warning count. */
125
126 #ifdef CONFIG_NET_POLL_CONTROLLER
127 static void ultra_poll(struct net_device *dev)
128 {
129         disable_irq(dev->irq);
130         ei_interrupt(dev->irq, dev);
131         enable_irq(dev->irq);
132 }
133 #endif
134 /*      Probe for the Ultra.  This looks like a 8013 with the station
135         address PROM at I/O ports <base>+8 to <base>+13, with a checksum
136         following.
137 */
138
139 static int __init do_ultra_probe(struct net_device *dev)
140 {
141         int i;
142         int base_addr = dev->base_addr;
143         int irq = dev->irq;
144
145 #ifdef CONFIG_NET_POLL_CONTROLLER
146         dev->poll_controller = &ultra_poll;
147 #endif
148         if (base_addr > 0x1ff)          /* Check a single specified location. */
149                 return ultra_probe1(dev, base_addr);
150         else if (base_addr != 0)        /* Don't probe at all. */
151                 return -ENXIO;
152
153 #ifdef __ISAPNP__
154         /* Look for any installed ISAPnP cards */
155         if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
156                 return 0;
157 #endif
158
159         for (i = 0; ultra_portlist[i]; i++) {
160                 dev->irq = irq;
161                 if (ultra_probe1(dev, ultra_portlist[i]) == 0)
162                         return 0;
163         }
164
165         return -ENODEV;
166 }
167
168 #ifndef MODULE
169 struct net_device * __init ultra_probe(int unit)
170 {
171         struct net_device *dev = alloc_ei_netdev();
172         int err;
173
174         if (!dev)
175                 return ERR_PTR(-ENOMEM);
176
177         sprintf(dev->name, "eth%d", unit);
178         netdev_boot_setup_check(dev);
179
180         err = do_ultra_probe(dev);
181         if (err)
182                 goto out;
183         return dev;
184 out:
185         free_netdev(dev);
186         return ERR_PTR(err);
187 }
188 #endif
189
190 static int __init ultra_probe1(struct net_device *dev, int ioaddr)
191 {
192         int i, retval;
193         int checksum = 0;
194         const char *model_name;
195         unsigned char eeprom_irq = 0;
196         static unsigned version_printed;
197         /* Values from various config regs. */
198         unsigned char num_pages, irqreg, addr, piomode;
199         unsigned char idreg = inb(ioaddr + 7);
200         unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
201
202         if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME))
203                 return -EBUSY;
204
205         /* Check the ID nibble. */
206         if ((idreg & 0xF0) != 0x20                      /* SMC Ultra */
207                 && (idreg & 0xF0) != 0x40) {            /* SMC EtherEZ */
208                 retval = -ENODEV;
209                 goto out;
210         }
211
212         /* Select the station address register set. */
213         outb(reg4, ioaddr + 4);
214
215         for (i = 0; i < 8; i++)
216                 checksum += inb(ioaddr + 8 + i);
217         if ((checksum & 0xff) != 0xFF) {
218                 retval = -ENODEV;
219                 goto out;
220         }
221
222         if (ei_debug  &&  version_printed++ == 0)
223                 printk(version);
224
225         model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ";
226
227         printk("%s: %s at %#3x,", dev->name, model_name, ioaddr);
228
229         for (i = 0; i < 6; i++)
230                 printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
231
232         /* Switch from the station address to the alternate register set and
233            read the useful registers there. */
234         outb(0x80 | reg4, ioaddr + 4);
235
236         /* Enabled FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */
237         outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
238         piomode = inb(ioaddr + 0x8);
239         addr = inb(ioaddr + 0xb);
240         irqreg = inb(ioaddr + 0xd);
241
242         /* Switch back to the station address register set so that the MS-DOS driver
243            can find the card after a warm boot. */
244         outb(reg4, ioaddr + 4);
245
246         if (dev->irq < 2) {
247                 unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15};
248                 int irq;
249
250                 /* The IRQ bits are split. */
251                 irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)];
252
253                 if (irq == 0) {
254                         printk(", failed to detect IRQ line.\n");
255                         retval =  -EAGAIN;
256                         goto out;
257                 }
258                 dev->irq = irq;
259                 eeprom_irq = 1;
260         }
261
262         /* The 8390 isn't at the base address, so fake the offset */
263         dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
264
265         {
266                 int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000};
267                 short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff};
268
269                 dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ;
270                 num_pages = num_pages_tbl[(addr >> 4) & 3];
271         }
272
273         ei_status.name = model_name;
274         ei_status.word16 = 1;
275         ei_status.tx_start_page = START_PG;
276         ei_status.rx_start_page = START_PG + TX_PAGES;
277         ei_status.stop_page = num_pages;
278
279         ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG)*256);
280         if (!ei_status.mem) {
281                 printk(", failed to ioremap.\n");
282                 retval =  -ENOMEM;
283                 goto out;
284         }
285
286         dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG)*256;
287
288         if (piomode) {
289                 printk(",%s IRQ %d programmed-I/O mode.\n",
290                            eeprom_irq ? "EEPROM" : "assigned ", dev->irq);
291                 ei_status.block_input = &ultra_pio_input;
292                 ei_status.block_output = &ultra_pio_output;
293                 ei_status.get_8390_hdr = &ultra_pio_get_hdr;
294         } else {
295                 printk(",%s IRQ %d memory %#lx-%#lx.\n", eeprom_irq ? "" : "assigned ",
296                            dev->irq, dev->mem_start, dev->mem_end-1);
297                 ei_status.block_input = &ultra_block_input;
298                 ei_status.block_output = &ultra_block_output;
299                 ei_status.get_8390_hdr = &ultra_get_8390_hdr;
300         }
301         ei_status.reset_8390 = &ultra_reset_8390;
302         dev->open = &ultra_open;
303         dev->stop = &ultra_close_card;
304 #ifdef CONFIG_NET_POLL_CONTROLLER
305         dev->poll_controller = ei_poll;
306 #endif
307         NS8390_init(dev, 0);
308
309         retval = register_netdev(dev);
310         if (retval)
311                 goto out;
312         return 0;
313 out:
314         release_region(ioaddr, ULTRA_IO_EXTENT);
315         return retval;
316 }
317
318 #ifdef __ISAPNP__
319 static int __init ultra_probe_isapnp(struct net_device *dev)
320 {
321         int i;
322
323         for (i = 0; ultra_device_ids[i].vendor != 0; i++) {
324                 struct pnp_dev *idev = NULL;
325
326                 while ((idev = pnp_find_dev(NULL,
327                                             ultra_device_ids[i].vendor,
328                                             ultra_device_ids[i].function,
329                                             idev))) {
330                         /* Avoid already found cards from previous calls */
331                         if (pnp_device_attach(idev) < 0)
332                                 continue;
333                         if (pnp_activate_dev(idev) < 0) {
334                               __again:
335                                 pnp_device_detach(idev);
336                                 continue;
337                         }
338                         /* if no io and irq, search for next */
339                         if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0))
340                                 goto __again;
341                         /* found it */
342                         dev->base_addr = pnp_port_start(idev, 0);
343                         dev->irq = pnp_irq(idev, 0);
344                         printk(KERN_INFO "smc-ultra.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
345                                 (char *) ultra_device_ids[i].driver_data,
346                                 dev->base_addr, dev->irq);
347                         if (ultra_probe1(dev, dev->base_addr) != 0) {      /* Shouldn't happen. */
348                                 printk(KERN_ERR "smc-ultra.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr);
349                                 pnp_device_detach(idev);
350                                 return -ENXIO;
351                         }
352                         ei_status.priv = (unsigned long)idev;
353                         break;
354                 }
355                 if (!idev)
356                         continue;
357                 return 0;
358         }
359
360         return -ENODEV;
361 }
362 #endif
363
364 static int
365 ultra_open(struct net_device *dev)
366 {
367         int retval;
368         int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
369         unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40,
370                                    0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, };
371
372         retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
373         if (retval)
374                 return retval;
375
376         outb(0x00, ioaddr);     /* Disable shared memory for safety. */
377         outb(0x80, ioaddr + 5);
378         /* Set the IRQ line. */
379         outb(inb(ioaddr + 4) | 0x80, ioaddr + 4);
380         outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13);
381         outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4);
382
383         if (ei_status.block_input == &ultra_pio_input) {
384                 outb(0x11, ioaddr + 6);         /* Enable interrupts and PIO. */
385                 outb(0x01, ioaddr + 0x19);      /* Enable ring read auto-wrap. */
386         } else
387                 outb(0x01, ioaddr + 6);         /* Enable interrupts and memory. */
388         /* Set the early receive warning level in window 0 high enough not
389            to receive ERW interrupts. */
390         outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr);
391         outb(0xff, dev->base_addr + EN0_ERWCNT);
392         ei_open(dev);
393         return 0;
394 }
395
396 static void
397 ultra_reset_8390(struct net_device *dev)
398 {
399         int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */
400
401         outb(ULTRA_RESET, cmd_port);
402         if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies);
403         ei_status.txing = 0;
404
405         outb(0x00, cmd_port);   /* Disable shared memory for safety. */
406         outb(0x80, cmd_port + 5);
407         if (ei_status.block_input == &ultra_pio_input)
408                 outb(0x11, cmd_port + 6);               /* Enable interrupts and PIO. */
409         else
410                 outb(0x01, cmd_port + 6);               /* Enable interrupts and memory. */
411
412         if (ei_debug > 1) printk("reset done\n");
413         return;
414 }
415
416 /* Grab the 8390 specific header. Similar to the block_input routine, but
417    we don't need to be concerned with ring wrap as the header will be at
418    the start of a page, so we optimize accordingly. */
419
420 static void
421 ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
422 {
423         void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG)<<8);
424
425         outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);  /* shmem on */
426 #ifdef __BIG_ENDIAN
427         /* Officially this is what we are doing, but the readl() is faster */
428         /* unfortunately it isn't endian aware of the struct               */
429         memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
430         hdr->count = le16_to_cpu(hdr->count);
431 #else
432         ((unsigned int*)hdr)[0] = readl(hdr_start);
433 #endif
434         outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
435 }
436
437 /* Block input and output are easy on shared memory ethercards, the only
438    complication is when the ring buffer wraps. */
439
440 static void
441 ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
442 {
443         void __iomem *xfer_start = ei_status.mem + ring_offset - (START_PG<<8);
444
445         /* Enable shared memory. */
446         outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
447
448         if (ring_offset + count > ei_status.stop_page*256) {
449                 /* We must wrap the input move. */
450                 int semi_count = ei_status.stop_page*256 - ring_offset;
451                 memcpy_fromio(skb->data, xfer_start, semi_count);
452                 count -= semi_count;
453                 memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
454         } else {
455                 memcpy_fromio(skb->data, xfer_start, count);
456         }
457
458         outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET);  /* Disable memory. */
459 }
460
461 static void
462 ultra_block_output(struct net_device *dev, int count, const unsigned char *buf,
463                                 int start_page)
464 {
465         void __iomem *shmem = ei_status.mem + ((start_page - START_PG)<<8);
466
467         /* Enable shared memory. */
468         outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
469
470         memcpy_toio(shmem, buf, count);
471
472         outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */
473 }
474
475 /* The identical operations for programmed I/O cards.
476    The PIO model is trivial to use: the 16 bit start address is written
477    byte-sequentially to IOPA, with no intervening I/O operations, and the
478    data is read or written to the IOPD data port.
479    The only potential complication is that the address register is shared
480    and must be always be rewritten between each read/write direction change.
481    This is no problem for us, as the 8390 code ensures that we are single
482    threaded. */
483 static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
484                                                 int ring_page)
485 {
486         int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
487         outb(0x00, ioaddr + IOPA);      /* Set the address, LSB first. */
488         outb(ring_page, ioaddr + IOPA);
489         insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1);
490 }
491
492 static void ultra_pio_input(struct net_device *dev, int count,
493                                                   struct sk_buff *skb, int ring_offset)
494 {
495         int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
496     char *buf = skb->data;
497
498         /* For now set the address again, although it should already be correct. */
499         outb(ring_offset, ioaddr + IOPA);       /* Set the address, LSB first. */
500         outb(ring_offset >> 8, ioaddr + IOPA);
501         /* We know skbuffs are padded to at least word alignment. */
502         insw(ioaddr + IOPD, buf, (count+1)>>1);
503 }
504
505 static void ultra_pio_output(struct net_device *dev, int count,
506                                                         const unsigned char *buf, const int start_page)
507 {
508         int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
509         outb(0x00, ioaddr + IOPA);      /* Set the address, LSB first. */
510         outb(start_page, ioaddr + IOPA);
511         /* An extra odd byte is OK here as well. */
512         outsw(ioaddr + IOPD, buf, (count+1)>>1);
513 }
514
515 static int
516 ultra_close_card(struct net_device *dev)
517 {
518         int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */
519
520         netif_stop_queue(dev);
521
522         if (ei_debug > 1)
523                 printk("%s: Shutting down ethercard.\n", dev->name);
524
525         outb(0x00, ioaddr + 6);         /* Disable interrupts. */
526         free_irq(dev->irq, dev);
527
528         NS8390_init(dev, 0);
529
530         /* We should someday disable shared memory and change to 8-bit mode
531            "just in case"... */
532
533         return 0;
534 }
535
536
537 #ifdef MODULE
538 #define MAX_ULTRA_CARDS 4       /* Max number of Ultra cards per module */
539 static struct net_device *dev_ultra[MAX_ULTRA_CARDS];
540 static int io[MAX_ULTRA_CARDS];
541 static int irq[MAX_ULTRA_CARDS];
542
543 module_param_array(io, int, NULL, 0);
544 module_param_array(irq, int, NULL, 0);
545 MODULE_PARM_DESC(io, "I/O base address(es)");
546 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
547 MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver");
548 MODULE_LICENSE("GPL");
549
550 /* This is set up so that only a single autoprobe takes place per call.
551 ISA device autoprobes on a running machine are not recommended. */
552 int __init
553 init_module(void)
554 {
555         struct net_device *dev;
556         int this_dev, found = 0;
557
558         for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
559                 if (io[this_dev] == 0)  {
560                         if (this_dev != 0) break; /* only autoprobe 1st one */
561                         printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n");
562                 }
563                 dev = alloc_ei_netdev();
564                 if (!dev)
565                         break;
566                 dev->irq = irq[this_dev];
567                 dev->base_addr = io[this_dev];
568                 if (do_ultra_probe(dev) == 0) {
569                         dev_ultra[found++] = dev;
570                         continue;
571                 }
572                 free_netdev(dev);
573                 printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
574                 break;
575         }
576         if (found)
577                 return 0;
578         return -ENXIO;
579 }
580
581 static void cleanup_card(struct net_device *dev)
582 {
583         /* NB: ultra_close_card() does free_irq */
584 #ifdef __ISAPNP__
585         struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
586         if (idev)
587                 pnp_device_detach(idev);
588 #endif
589         release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
590         iounmap(ei_status.mem);
591 }
592
593 void __exit
594 cleanup_module(void)
595 {
596         int this_dev;
597
598         for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
599                 struct net_device *dev = dev_ultra[this_dev];
600                 if (dev) {
601                         unregister_netdev(dev);
602                         cleanup_card(dev);
603                         free_netdev(dev);
604                 }
605         }
606 }
607 #endif /* MODULE */