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