arcnet: Expand odd BUGLVL macro with if and uses
[cascardo/linux.git] / drivers / net / arcnet / com90xx.c
1 /*
2  * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
3  *
4  * Written 1994-1999 by Avery Pennarun.
5  * Written 1999 by Martin Mares <mj@ucw.cz>.
6  * Derived from skeleton.c by Donald Becker.
7  *
8  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
9  *  for sponsoring the further development of this driver.
10  *
11  * **********************
12  *
13  * The original copyright of skeleton.c was as follows:
14  *
15  * skeleton.c Written 1993 by Donald Becker.
16  * Copyright 1993 United States Government as represented by the
17  * Director, National Security Agency.  This software may only be used
18  * and distributed according to the terms of the GNU General Public License as
19  * modified by SRC, incorporated herein by reference.
20  *
21  * **********************
22  *
23  * For more details, see drivers/net/arcnet.c
24  *
25  * **********************
26  */
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
29 #include <linux/init.h>
30 #include <linux/interrupt.h>
31 #include <linux/ioport.h>
32 #include <linux/delay.h>
33 #include <linux/netdevice.h>
34 #include <linux/slab.h>
35 #include <linux/io.h>
36 #include <linux/arcdevice.h>
37
38 #define VERSION "arcnet: COM90xx chipset support\n"
39
40 /* Define this to speed up the autoprobe by assuming if only one io port and
41  * shmem are left in the list at Stage 5, they must correspond to each
42  * other.
43  *
44  * This is undefined by default because it might not always be true, and the
45  * extra check makes the autoprobe even more careful.  Speed demons can turn
46  * it on - I think it should be fine if you only have one ARCnet card
47  * installed.
48  *
49  * If no ARCnet cards are installed, this delay never happens anyway and thus
50  * the option has no effect.
51  */
52 #undef FAST_PROBE
53
54 /* Internal function declarations */
55 static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *);
56 static void com90xx_command(struct net_device *dev, int command);
57 static int com90xx_status(struct net_device *dev);
58 static void com90xx_setmask(struct net_device *dev, int mask);
59 static int com90xx_reset(struct net_device *dev, int really_reset);
60 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
61                                  void *buf, int count);
62 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
63                                    void *buf, int count);
64
65 /* Known ARCnet cards */
66
67 static struct net_device *cards[16];
68 static int numcards;
69
70 /* Handy defines for ARCnet specific stuff */
71
72 /* The number of low I/O ports used by the card */
73 #define ARCNET_TOTAL_SIZE       16
74
75 /* Amount of I/O memory used by the card */
76 #define BUFFER_SIZE (512)
77 #define MIRROR_SIZE (BUFFER_SIZE * 4)
78
79 /* COM 9026 controller chip --> ARCnet register addresses */
80 #define _INTMASK        (ioaddr + 0)    /* writable */
81 #define _STATUS         (ioaddr + 0)    /* readable */
82 #define _COMMAND        (ioaddr + 1)    /* writable, returns random vals on read (?) */
83 #define _CONFIG         (ioaddr + 2)    /* Configuration register */
84 #define _RESET          (ioaddr + 8)    /* software reset (on read) */
85 #define _MEMDATA        (ioaddr + 12)   /* Data port for IO-mapped memory */
86 #define _ADDR_HI        (ioaddr + 15)   /* Control registers for said */
87 #define _ADDR_LO        (ioaddr + 14)
88
89 #undef ASTATUS
90 #undef ACOMMAND
91 #undef AINTMASK
92
93 #define ASTATUS()       inb(_STATUS)
94 #define ACOMMAND(cmd)   outb((cmd), _COMMAND)
95 #define AINTMASK(msk)   outb((msk), _INTMASK)
96
97 static int com90xx_skip_probe __initdata = 0;
98
99 /* Module parameters */
100
101 static int io;                  /* use the insmod io= irq= shmem= options */
102 static int irq;
103 static int shmem;
104 static char device[9];          /* use eg. device=arc1 to change name */
105
106 module_param(io, int, 0);
107 module_param(irq, int, 0);
108 module_param(shmem, int, 0);
109 module_param_string(device, device, sizeof(device), 0);
110
111 static void __init com90xx_probe(void)
112 {
113         int count, status, ioaddr, numprint, airq, openparen = 0;
114         unsigned long airqmask;
115         int ports[(0x3f0 - 0x200) / 16 + 1] = { 0 };
116         unsigned long *shmems;
117         void __iomem **iomem;
118         int numports, numshmems, *port;
119         u_long *p;
120         int index;
121
122         if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
123                 return;
124
125         shmems = kzalloc(((0x100000 - 0xa0000) / 0x800) * sizeof(unsigned long),
126                          GFP_KERNEL);
127         if (!shmems)
128                 return;
129         iomem = kzalloc(((0x100000 - 0xa0000) / 0x800) * sizeof(void __iomem *),
130                         GFP_KERNEL);
131         if (!iomem) {
132                 kfree(shmems);
133                 return;
134         }
135
136         if (BUGLVL(D_NORMAL))
137                 printk(VERSION);
138
139         /* set up the arrays where we'll store the possible probe addresses */
140         numports = numshmems = 0;
141         if (io)
142                 ports[numports++] = io;
143         else
144                 for (count = 0x200; count <= 0x3f0; count += 16)
145                         ports[numports++] = count;
146         if (shmem)
147                 shmems[numshmems++] = shmem;
148         else
149                 for (count = 0xA0000; count <= 0xFF800; count += 2048)
150                         shmems[numshmems++] = count;
151
152         /* Stage 1: abandon any reserved ports, or ones with status==0xFF
153          * (empty), and reset any others by reading the reset port.
154          */
155         numprint = -1;
156         for (port = &ports[0]; port - ports < numports; port++) {
157                 numprint++;
158                 numprint %= 8;
159                 if (!numprint) {
160                         BUGMSG2(D_INIT, "\n");
161                         BUGMSG2(D_INIT, "S1: ");
162                 }
163                 BUGMSG2(D_INIT, "%Xh ", *port);
164
165                 ioaddr = *port;
166
167                 if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
168                         BUGMSG2(D_INIT_REASONS, "(request_region)\n");
169                         BUGMSG2(D_INIT_REASONS, "S1: ");
170                         if (BUGLVL(D_INIT_REASONS))
171                                 numprint = 0;
172                         *port-- = ports[--numports];
173                         continue;
174                 }
175                 if (ASTATUS() == 0xFF) {
176                         BUGMSG2(D_INIT_REASONS, "(empty)\n");
177                         BUGMSG2(D_INIT_REASONS, "S1: ");
178                         if (BUGLVL(D_INIT_REASONS))
179                                 numprint = 0;
180                         release_region(*port, ARCNET_TOTAL_SIZE);
181                         *port-- = ports[--numports];
182                         continue;
183                 }
184                 inb(_RESET);    /* begin resetting card */
185
186                 BUGMSG2(D_INIT_REASONS, "\n");
187                 BUGMSG2(D_INIT_REASONS, "S1: ");
188                 if (BUGLVL(D_INIT_REASONS))
189                         numprint = 0;
190         }
191         BUGMSG2(D_INIT, "\n");
192
193         if (!numports) {
194                 BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
195                 kfree(shmems);
196                 kfree(iomem);
197                 return;
198         }
199         /* Stage 2: we have now reset any possible ARCnet cards, so we can't
200          * do anything until they finish.  If D_INIT, print the list of
201          * cards that are left.
202          */
203         numprint = -1;
204         for (port = &ports[0]; port < ports + numports; port++) {
205                 numprint++;
206                 numprint %= 8;
207                 if (!numprint) {
208                         BUGMSG2(D_INIT, "\n");
209                         BUGMSG2(D_INIT, "S2: ");
210                 }
211                 BUGMSG2(D_INIT, "%Xh ", *port);
212         }
213         BUGMSG2(D_INIT, "\n");
214         mdelay(RESETtime);
215
216         /* Stage 3: abandon any shmem addresses that don't have the signature
217          * 0xD1 byte in the right place, or are read-only.
218          */
219         numprint = -1;
220         for (index = 0, p = &shmems[0]; index < numshmems; p++, index++) {
221                 void __iomem *base;
222
223                 numprint++;
224                 numprint %= 8;
225                 if (!numprint) {
226                         BUGMSG2(D_INIT, "\n");
227                         BUGMSG2(D_INIT, "S3: ");
228                 }
229                 BUGMSG2(D_INIT, "%lXh ", *p);
230
231                 if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) {
232                         BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n");
233                         BUGMSG2(D_INIT_REASONS, "Stage 3: ");
234                         if (BUGLVL(D_INIT_REASONS))
235                                 numprint = 0;
236                         goto out;
237                 }
238                 base = ioremap(*p, MIRROR_SIZE);
239                 if (!base) {
240                         BUGMSG2(D_INIT_REASONS, "(ioremap)\n");
241                         BUGMSG2(D_INIT_REASONS, "Stage 3: ");
242                         if (BUGLVL(D_INIT_REASONS))
243                                 numprint = 0;
244                         goto out1;
245                 }
246                 if (readb(base) != TESTvalue) {
247                         BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
248                                 readb(base), TESTvalue);
249                         BUGMSG2(D_INIT_REASONS, "S3: ");
250                         if (BUGLVL(D_INIT_REASONS))
251                                 numprint = 0;
252                         goto out2;
253                 }
254                 /* By writing 0x42 to the TESTvalue location, we also make
255                  * sure no "mirror" shmem areas show up - if they occur
256                  * in another pass through this loop, they will be discarded
257                  * because *cptr != TESTvalue.
258                  */
259                 writeb(0x42, base);
260                 if (readb(base) != 0x42) {
261                         BUGMSG2(D_INIT_REASONS, "(read only)\n");
262                         BUGMSG2(D_INIT_REASONS, "S3: ");
263                         goto out2;
264                 }
265                 BUGMSG2(D_INIT_REASONS, "\n");
266                 BUGMSG2(D_INIT_REASONS, "S3: ");
267                 if (BUGLVL(D_INIT_REASONS))
268                         numprint = 0;
269                 iomem[index] = base;
270                 continue;
271         out2:
272                 iounmap(base);
273         out1:
274                 release_mem_region(*p, MIRROR_SIZE);
275         out:
276                 *p-- = shmems[--numshmems];
277                 index--;
278         }
279         BUGMSG2(D_INIT, "\n");
280
281         if (!numshmems) {
282                 BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
283                 for (port = &ports[0]; port < ports + numports; port++)
284                         release_region(*port, ARCNET_TOTAL_SIZE);
285                 kfree(shmems);
286                 kfree(iomem);
287                 return;
288         }
289         /* Stage 4: something of a dummy, to report the shmems that are
290          * still possible after stage 3.
291          */
292         numprint = -1;
293         for (p = &shmems[0]; p < shmems + numshmems; p++) {
294                 numprint++;
295                 numprint %= 8;
296                 if (!numprint) {
297                         BUGMSG2(D_INIT, "\n");
298                         BUGMSG2(D_INIT, "S4: ");
299                 }
300                 BUGMSG2(D_INIT, "%lXh ", *p);
301         }
302         BUGMSG2(D_INIT, "\n");
303
304         /* Stage 5: for any ports that have the correct status, can disable
305          * the RESET flag, and (if no irq is given) generate an autoirq,
306          * register an ARCnet device.
307          *
308          * Currently, we can only register one device per probe, so quit
309          * after the first one is found.
310          */
311         numprint = -1;
312         for (port = &ports[0]; port < ports + numports; port++) {
313                 int found = 0;
314
315                 numprint++;
316                 numprint %= 8;
317                 if (!numprint) {
318                         BUGMSG2(D_INIT, "\n");
319                         BUGMSG2(D_INIT, "S5: ");
320                 }
321                 BUGMSG2(D_INIT, "%Xh ", *port);
322
323                 ioaddr = *port;
324                 status = ASTATUS();
325
326                 if ((status & 0x9D)
327                     != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
328                         BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
329                         BUGMSG2(D_INIT_REASONS, "S5: ");
330                         if (BUGLVL(D_INIT_REASONS))
331                                 numprint = 0;
332                         release_region(*port, ARCNET_TOTAL_SIZE);
333                         *port-- = ports[--numports];
334                         continue;
335                 }
336                 ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
337                 status = ASTATUS();
338                 if (status & RESETflag) {
339                         BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
340                                 status);
341                         BUGMSG2(D_INIT_REASONS, "S5: ");
342                         if (BUGLVL(D_INIT_REASONS))
343                                 numprint = 0;
344                         release_region(*port, ARCNET_TOTAL_SIZE);
345                         *port-- = ports[--numports];
346                         continue;
347                 }
348                 /* skip this completely if an IRQ was given, because maybe
349                  * we're on a machine that locks during autoirq!
350                  */
351                 if (!irq) {
352                         /* if we do this, we're sure to get an IRQ since the
353                          * card has just reset and the NORXflag is on until
354                          * we tell it to start receiving.
355                          */
356                         airqmask = probe_irq_on();
357                         AINTMASK(NORXflag);
358                         udelay(1);
359                         AINTMASK(0);
360                         airq = probe_irq_off(airqmask);
361
362                         if (airq <= 0) {
363                                 BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
364                                 BUGMSG2(D_INIT_REASONS, "S5: ");
365                                 if (BUGLVL(D_INIT_REASONS))
366                                         numprint = 0;
367                                 release_region(*port, ARCNET_TOTAL_SIZE);
368                                 *port-- = ports[--numports];
369                                 continue;
370                         }
371                 } else {
372                         airq = irq;
373                 }
374
375                 BUGMSG2(D_INIT, "(%d,", airq);
376                 openparen = 1;
377
378                 /* Everything seems okay.  But which shmem, if any, puts
379                  * back its signature byte when the card is reset?
380                  *
381                  * If there are multiple cards installed, there might be
382                  * multiple shmems still in the list.
383                  */
384 #ifdef FAST_PROBE
385                 if (numports > 1 || numshmems > 1) {
386                         inb(_RESET);
387                         mdelay(RESETtime);
388                 } else {
389                         /* just one shmem and port, assume they match */
390                         writeb(TESTvalue, iomem[0]);
391                 }
392 #else
393                 inb(_RESET);
394                 mdelay(RESETtime);
395 #endif
396
397                 for (index = 0; index < numshmems; index++) {
398                         u_long ptr = shmems[index];
399                         void __iomem *base = iomem[index];
400
401                         if (readb(base) == TESTvalue) { /* found one */
402                                 BUGMSG2(D_INIT, "%lXh)\n", *p);
403                                 openparen = 0;
404
405                                 /* register the card */
406                                 if (com90xx_found(*port, airq, ptr, base) == 0)
407                                         found = 1;
408                                 numprint = -1;
409
410                                 /* remove shmem from the list */
411                                 shmems[index] = shmems[--numshmems];
412                                 iomem[index] = iomem[numshmems];
413                                 break;  /* go to the next I/O port */
414                         } else {
415                                 BUGMSG2(D_INIT_REASONS, "%Xh-", readb(base));
416                         }
417                 }
418
419                 if (openparen) {
420                         if (BUGLVL(D_INIT))
421                                 printk("no matching shmem)\n");
422                         if (BUGLVL(D_INIT_REASONS)) {
423                                 printk("S5: ");
424                                 numprint = 0;
425                         }
426                 }
427                 if (!found)
428                         release_region(*port, ARCNET_TOTAL_SIZE);
429                 *port-- = ports[--numports];
430         }
431
432         if (BUGLVL(D_INIT_REASONS))
433                 printk("\n");
434
435         /* Now put back TESTvalue on all leftover shmems. */
436         for (index = 0; index < numshmems; index++) {
437                 writeb(TESTvalue, iomem[index]);
438                 iounmap(iomem[index]);
439                 release_mem_region(shmems[index], MIRROR_SIZE);
440         }
441         kfree(shmems);
442         kfree(iomem);
443 }
444
445 static int check_mirror(unsigned long addr, size_t size)
446 {
447         void __iomem *p;
448         int res = -1;
449
450         if (!request_mem_region(addr, size, "arcnet (90xx)"))
451                 return -1;
452
453         p = ioremap(addr, size);
454         if (p) {
455                 if (readb(p) == TESTvalue)
456                         res = 1;
457                 else
458                         res = 0;
459                 iounmap(p);
460         }
461
462         release_mem_region(addr, size);
463         return res;
464 }
465
466 /* Set up the struct net_device associated with this card.  Called after
467  * probing succeeds.
468  */
469 static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *p)
470 {
471         struct net_device *dev = NULL;
472         struct arcnet_local *lp;
473         u_long first_mirror, last_mirror;
474         int mirror_size;
475
476         /* allocate struct net_device */
477         dev = alloc_arcdev(device);
478         if (!dev) {
479                 BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
480                 iounmap(p);
481                 release_mem_region(shmem, MIRROR_SIZE);
482                 return -ENOMEM;
483         }
484         lp = netdev_priv(dev);
485         /* find the real shared memory start/end points, including mirrors */
486
487         /* guess the actual size of one "memory mirror" - the number of
488          * bytes between copies of the shared memory.  On most cards, it's
489          * 2k (or there are no mirrors at all) but on some, it's 4k.
490          */
491         mirror_size = MIRROR_SIZE;
492         if (readb(p) == TESTvalue &&
493             check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
494             check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
495                 mirror_size = 2 * MIRROR_SIZE;
496
497         first_mirror = shmem - mirror_size;
498         while (check_mirror(first_mirror, mirror_size) == 1)
499                 first_mirror -= mirror_size;
500         first_mirror += mirror_size;
501
502         last_mirror = shmem + mirror_size;
503         while (check_mirror(last_mirror, mirror_size) == 1)
504                 last_mirror += mirror_size;
505         last_mirror -= mirror_size;
506
507         dev->mem_start = first_mirror;
508         dev->mem_end = last_mirror + MIRROR_SIZE - 1;
509
510         iounmap(p);
511         release_mem_region(shmem, MIRROR_SIZE);
512
513         if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
514                 goto err_free_dev;
515
516         /* reserve the irq */
517         if (request_irq(airq, arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
518                 BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
519                 goto err_release_mem;
520         }
521         dev->irq = airq;
522
523         /* Initialize the rest of the device structure. */
524         lp->card_name = "COM90xx";
525         lp->hw.command = com90xx_command;
526         lp->hw.status = com90xx_status;
527         lp->hw.intmask = com90xx_setmask;
528         lp->hw.reset = com90xx_reset;
529         lp->hw.owner = THIS_MODULE;
530         lp->hw.copy_to_card = com90xx_copy_to_card;
531         lp->hw.copy_from_card = com90xx_copy_from_card;
532         lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
533         if (!lp->mem_start) {
534                 BUGMSG(D_NORMAL, "Can't remap device memory!\n");
535                 goto err_free_irq;
536         }
537
538         /* get and check the station ID from offset 1 in shmem */
539         dev->dev_addr[0] = readb(lp->mem_start + 1);
540
541         dev->base_addr = ioaddr;
542
543         BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, ShMem %lXh (%ld*%xh).\n",
544                dev->dev_addr[0],
545                dev->base_addr, dev->irq, dev->mem_start,
546          (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
547
548         if (register_netdev(dev))
549                 goto err_unmap;
550
551         cards[numcards++] = dev;
552         return 0;
553
554 err_unmap:
555         iounmap(lp->mem_start);
556 err_free_irq:
557         free_irq(dev->irq, dev);
558 err_release_mem:
559         release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
560 err_free_dev:
561         free_netdev(dev);
562         return -EIO;
563 }
564
565 static void com90xx_command(struct net_device *dev, int cmd)
566 {
567         short ioaddr = dev->base_addr;
568
569         ACOMMAND(cmd);
570 }
571
572 static int com90xx_status(struct net_device *dev)
573 {
574         short ioaddr = dev->base_addr;
575
576         return ASTATUS();
577 }
578
579 static void com90xx_setmask(struct net_device *dev, int mask)
580 {
581         short ioaddr = dev->base_addr;
582
583         AINTMASK(mask);
584 }
585
586 /* Do a hardware reset on the card, and set up necessary registers.
587  *
588  * This should be called as little as possible, because it disrupts the
589  * token on the network (causes a RECON) and requires a significant delay.
590  *
591  * However, it does make sure the card is in a defined state.
592  */
593 static int com90xx_reset(struct net_device *dev, int really_reset)
594 {
595         struct arcnet_local *lp = netdev_priv(dev);
596         short ioaddr = dev->base_addr;
597
598         BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
599
600         if (really_reset) {
601                 /* reset the card */
602                 inb(_RESET);
603                 mdelay(RESETtime);
604         }
605         ACOMMAND(CFLAGScmd | RESETclear);       /* clear flags & end reset */
606         ACOMMAND(CFLAGScmd | CONFIGclear);
607
608         /* don't do this until we verify that it doesn't hurt older cards! */
609         /* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */
610
611         /* verify that the ARCnet signature byte is present */
612         if (readb(lp->mem_start) != TESTvalue) {
613                 if (really_reset)
614                         BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
615                 return 1;
616         }
617         /* enable extended (512-byte) packets */
618         ACOMMAND(CONFIGcmd | EXTconf);
619
620         /* clean out all the memory to make debugging make more sense :) */
621         if (BUGLVL(D_DURING))
622                 memset_io(lp->mem_start, 0x42, 2048);
623
624         /* done!  return success. */
625         return 0;
626 }
627
628 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
629                                  void *buf, int count)
630 {
631         struct arcnet_local *lp = netdev_priv(dev);
632         void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
633
634         TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
635 }
636
637 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
638                                    void *buf, int count)
639 {
640         struct arcnet_local *lp = netdev_priv(dev);
641         void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
642
643         TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
644 }
645
646 MODULE_LICENSE("GPL");
647
648 static int __init com90xx_init(void)
649 {
650         if (irq == 2)
651                 irq = 9;
652         com90xx_probe();
653         if (!numcards)
654                 return -EIO;
655         return 0;
656 }
657
658 static void __exit com90xx_exit(void)
659 {
660         struct net_device *dev;
661         struct arcnet_local *lp;
662         int count;
663
664         for (count = 0; count < numcards; count++) {
665                 dev = cards[count];
666                 lp = netdev_priv(dev);
667
668                 unregister_netdev(dev);
669                 free_irq(dev->irq, dev);
670                 iounmap(lp->mem_start);
671                 release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
672                 release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
673                 free_netdev(dev);
674         }
675 }
676
677 module_init(com90xx_init);
678 module_exit(com90xx_exit);
679
680 #ifndef MODULE
681 static int __init com90xx_setup(char *s)
682 {
683         int ints[8];
684
685         s = get_options(s, 8, ints);
686         if (!ints[0] && !*s) {
687                 printk("com90xx: Disabled.\n");
688                 return 1;
689         }
690
691         switch (ints[0]) {
692         default:                /* ERROR */
693                 printk("com90xx: Too many arguments.\n");
694         case 3:         /* Mem address */
695                 shmem = ints[3];
696         case 2:         /* IRQ */
697                 irq = ints[2];
698         case 1:         /* IO address */
699                 io = ints[1];
700         }
701
702         if (*s)
703                 snprintf(device, sizeof(device), "%s", s);
704
705         return 1;
706 }
707
708 __setup("com90xx=", com90xx_setup);
709 #endif