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