com20020-isa.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Linux ARCnet driver - COM20020 chipset support
  3. *
  4. * Written 1997 by David Woodhouse.
  5. * Written 1994-1999 by Avery Pennarun.
  6. * Written 1999-2000 by Martin Mares <mj@ucw.cz>.
  7. * Derived from skeleton.c by Donald Becker.
  8. *
  9. * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
  10. * for sponsoring the further development of this driver.
  11. *
  12. * **********************
  13. *
  14. * The original copyright of skeleton.c was as follows:
  15. *
  16. * skeleton.c Written 1993 by Donald Becker.
  17. * Copyright 1993 United States Government as represented by the
  18. * Director, National Security Agency. This software may only be used
  19. * and distributed according to the terms of the GNU General Public License as
  20. * modified by SRC, incorporated herein by reference.
  21. *
  22. * **********************
  23. *
  24. * For more details, see drivers/net/arcnet.c
  25. *
  26. * **********************
  27. */
  28. #include <linux/module.h>
  29. #include <linux/moduleparam.h>
  30. #include <linux/kernel.h>
  31. #include <linux/types.h>
  32. #include <linux/ioport.h>
  33. #include <linux/errno.h>
  34. #include <linux/delay.h>
  35. #include <linux/netdevice.h>
  36. #include <linux/init.h>
  37. #include <linux/interrupt.h>
  38. #include <linux/bootmem.h>
  39. #include <linux/arcdevice.h>
  40. #include <linux/com20020.h>
  41. #include <asm/io.h>
  42. #define VERSION "arcnet: COM20020 ISA support (by David Woodhouse et al.)\n"
  43. /*
  44. * We cannot (yet) probe for an IO mapped card, although we can check that
  45. * it's where we were told it was, and even do autoirq.
  46. */
  47. static int __init com20020isa_probe(struct net_device *dev)
  48. {
  49. int ioaddr;
  50. unsigned long airqmask;
  51. struct arcnet_local *lp = netdev_priv(dev);
  52. int err;
  53. BUGLVL(D_NORMAL) printk(VERSION);
  54. ioaddr = dev->base_addr;
  55. if (!ioaddr) {
  56. BUGMSG(D_NORMAL, "No autoprobe (yet) for IO mapped cards; you "
  57. "must specify the base address!\n");
  58. return -ENODEV;
  59. }
  60. if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
  61. BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
  62. ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
  63. return -ENXIO;
  64. }
  65. if (ASTATUS() == 0xFF) {
  66. BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
  67. err = -ENODEV;
  68. goto out;
  69. }
  70. if (com20020_check(dev)) {
  71. err = -ENODEV;
  72. goto out;
  73. }
  74. if (!dev->irq) {
  75. /* if we do this, we're sure to get an IRQ since the
  76. * card has just reset and the NORXflag is on until
  77. * we tell it to start receiving.
  78. */
  79. BUGMSG(D_INIT_REASONS, "intmask was %02Xh\n", inb(_INTMASK));
  80. outb(0, _INTMASK);
  81. airqmask = probe_irq_on();
  82. outb(NORXflag, _INTMASK);
  83. udelay(1);
  84. outb(0, _INTMASK);
  85. dev->irq = probe_irq_off(airqmask);
  86. if ((int)dev->irq <= 0) {
  87. BUGMSG(D_INIT_REASONS, "Autoprobe IRQ failed first time\n");
  88. airqmask = probe_irq_on();
  89. outb(NORXflag, _INTMASK);
  90. udelay(5);
  91. outb(0, _INTMASK);
  92. dev->irq = probe_irq_off(airqmask);
  93. if ((int)dev->irq <= 0) {
  94. BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
  95. err = -ENODEV;
  96. goto out;
  97. }
  98. }
  99. }
  100. lp->card_name = "ISA COM20020";
  101. if ((err = com20020_found(dev, 0)) != 0)
  102. goto out;
  103. return 0;
  104. out:
  105. release_region(ioaddr, ARCNET_TOTAL_SIZE);
  106. return err;
  107. }
  108. static int node = 0;
  109. static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
  110. static int irq = 0; /* or use the insmod io= irq= shmem= options */
  111. static char device[9]; /* use eg. device="arc1" to change name */
  112. static int timeout = 3;
  113. static int backplane = 0;
  114. static int clockp = 0;
  115. static int clockm = 0;
  116. module_param(node, int, 0);
  117. module_param(io, int, 0);
  118. module_param(irq, int, 0);
  119. module_param_string(device, device, sizeof(device), 0);
  120. module_param(timeout, int, 0);
  121. module_param(backplane, int, 0);
  122. module_param(clockp, int, 0);
  123. module_param(clockm, int, 0);
  124. MODULE_LICENSE("GPL");
  125. static struct net_device *my_dev;
  126. static int __init com20020_init(void)
  127. {
  128. struct net_device *dev;
  129. struct arcnet_local *lp;
  130. dev = alloc_arcdev(device);
  131. if (!dev)
  132. return -ENOMEM;
  133. if (node && node != 0xff)
  134. dev->dev_addr[0] = node;
  135. dev->netdev_ops = &com20020_netdev_ops;
  136. lp = netdev_priv(dev);
  137. lp->backplane = backplane;
  138. lp->clockp = clockp & 7;
  139. lp->clockm = clockm & 3;
  140. lp->timeout = timeout & 3;
  141. lp->hw.owner = THIS_MODULE;
  142. dev->base_addr = io;
  143. dev->irq = irq;
  144. if (dev->irq == 2)
  145. dev->irq = 9;
  146. if (com20020isa_probe(dev)) {
  147. free_netdev(dev);
  148. return -EIO;
  149. }
  150. my_dev = dev;
  151. return 0;
  152. }
  153. static void __exit com20020_exit(void)
  154. {
  155. unregister_netdev(my_dev);
  156. free_irq(my_dev->irq, my_dev);
  157. release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
  158. free_netdev(my_dev);
  159. }
  160. #ifndef MODULE
  161. static int __init com20020isa_setup(char *s)
  162. {
  163. int ints[8];
  164. s = get_options(s, 8, ints);
  165. if (!ints[0])
  166. return 1;
  167. switch (ints[0]) {
  168. default: /* ERROR */
  169. printk("com90xx: Too many arguments.\n");
  170. case 6: /* Timeout */
  171. timeout = ints[6];
  172. case 5: /* CKP value */
  173. clockp = ints[5];
  174. case 4: /* Backplane flag */
  175. backplane = ints[4];
  176. case 3: /* Node ID */
  177. node = ints[3];
  178. case 2: /* IRQ */
  179. irq = ints[2];
  180. case 1: /* IO address */
  181. io = ints[1];
  182. }
  183. if (*s)
  184. snprintf(device, sizeof(device), "%s", s);
  185. return 1;
  186. }
  187. __setup("com20020=", com20020isa_setup);
  188. #endif /* MODULE */
  189. module_init(com20020_init)
  190. module_exit(com20020_exit)