com20020-isa.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. #define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt
  29. #include <linux/module.h>
  30. #include <linux/moduleparam.h>
  31. #include <linux/kernel.h>
  32. #include <linux/types.h>
  33. #include <linux/ioport.h>
  34. #include <linux/errno.h>
  35. #include <linux/delay.h>
  36. #include <linux/netdevice.h>
  37. #include <linux/init.h>
  38. #include <linux/interrupt.h>
  39. #include <linux/bootmem.h>
  40. #include <linux/io.h>
  41. #include "arcdevice.h"
  42. #include "com20020.h"
  43. /* We cannot (yet) probe for an IO mapped card, although we can check that
  44. * it's where we were told it was, and even do autoirq.
  45. */
  46. static int __init com20020isa_probe(struct net_device *dev)
  47. {
  48. int ioaddr;
  49. unsigned long airqmask;
  50. struct arcnet_local *lp = netdev_priv(dev);
  51. int err;
  52. if (BUGLVL(D_NORMAL))
  53. pr_info("%s\n", "COM20020 ISA support (by David Woodhouse et al.)");
  54. ioaddr = dev->base_addr;
  55. if (!ioaddr) {
  56. arc_printk(D_NORMAL, dev, "No autoprobe (yet) for IO mapped cards; you must specify the base address!\n");
  57. return -ENODEV;
  58. }
  59. if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
  60. arc_printk(D_NORMAL, dev, "IO region %xh-%xh already allocated.\n",
  61. ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
  62. return -ENXIO;
  63. }
  64. if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
  65. arc_printk(D_NORMAL, dev, "IO address %x empty\n", ioaddr);
  66. err = -ENODEV;
  67. goto out;
  68. }
  69. if (com20020_check(dev)) {
  70. err = -ENODEV;
  71. goto out;
  72. }
  73. if (!dev->irq) {
  74. /* if we do this, we're sure to get an IRQ since the
  75. * card has just reset and the NORXflag is on until
  76. * we tell it to start receiving.
  77. */
  78. arc_printk(D_INIT_REASONS, dev, "intmask was %02Xh\n",
  79. arcnet_inb(ioaddr, COM20020_REG_R_STATUS));
  80. arcnet_outb(0, ioaddr, COM20020_REG_W_INTMASK);
  81. airqmask = probe_irq_on();
  82. arcnet_outb(NORXflag, ioaddr, COM20020_REG_W_INTMASK);
  83. udelay(1);
  84. arcnet_outb(0, ioaddr, COM20020_REG_W_INTMASK);
  85. dev->irq = probe_irq_off(airqmask);
  86. if ((int)dev->irq <= 0) {
  87. arc_printk(D_INIT_REASONS, dev, "Autoprobe IRQ failed first time\n");
  88. airqmask = probe_irq_on();
  89. arcnet_outb(NORXflag, ioaddr, COM20020_REG_W_INTMASK);
  90. udelay(5);
  91. arcnet_outb(0, ioaddr, COM20020_REG_W_INTMASK);
  92. dev->irq = probe_irq_off(airqmask);
  93. if ((int)dev->irq <= 0) {
  94. arc_printk(D_NORMAL, dev, "Autoprobe IRQ failed.\n");
  95. err = -ENODEV;
  96. goto out;
  97. }
  98. }
  99. }
  100. lp->card_name = "ISA COM20020";
  101. err = com20020_found(dev, 0);
  102. if (err != 0)
  103. goto out;
  104. return 0;
  105. out:
  106. release_region(ioaddr, ARCNET_TOTAL_SIZE);
  107. return err;
  108. }
  109. static int node = 0;
  110. static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
  111. static int irq = 0; /* or use the insmod io= irq= shmem= options */
  112. static char device[9]; /* use eg. device="arc1" to change name */
  113. static int timeout = 3;
  114. static int backplane = 0;
  115. static int clockp = 0;
  116. static int clockm = 0;
  117. module_param(node, int, 0);
  118. module_param_hw(io, int, ioport, 0);
  119. module_param_hw(irq, int, irq, 0);
  120. module_param_string(device, device, sizeof(device), 0);
  121. module_param(timeout, int, 0);
  122. module_param(backplane, int, 0);
  123. module_param(clockp, int, 0);
  124. module_param(clockm, int, 0);
  125. MODULE_LICENSE("GPL");
  126. static struct net_device *my_dev;
  127. static int __init com20020_init(void)
  128. {
  129. struct net_device *dev;
  130. struct arcnet_local *lp;
  131. dev = alloc_arcdev(device);
  132. if (!dev)
  133. return -ENOMEM;
  134. if (node && node != 0xff)
  135. dev->dev_addr[0] = node;
  136. dev->netdev_ops = &com20020_netdev_ops;
  137. lp = netdev_priv(dev);
  138. lp->backplane = backplane;
  139. lp->clockp = clockp & 7;
  140. lp->clockm = clockm & 3;
  141. lp->timeout = timeout & 3;
  142. lp->hw.owner = THIS_MODULE;
  143. dev->base_addr = io;
  144. dev->irq = irq;
  145. if (dev->irq == 2)
  146. dev->irq = 9;
  147. if (com20020isa_probe(dev)) {
  148. free_netdev(dev);
  149. return -EIO;
  150. }
  151. my_dev = dev;
  152. return 0;
  153. }
  154. static void __exit com20020_exit(void)
  155. {
  156. unregister_netdev(my_dev);
  157. free_irq(my_dev->irq, my_dev);
  158. release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
  159. free_netdev(my_dev);
  160. }
  161. #ifndef MODULE
  162. static int __init com20020isa_setup(char *s)
  163. {
  164. int ints[8];
  165. s = get_options(s, 8, ints);
  166. if (!ints[0])
  167. return 1;
  168. switch (ints[0]) {
  169. default: /* ERROR */
  170. pr_info("Too many arguments\n");
  171. case 6: /* Timeout */
  172. timeout = ints[6];
  173. case 5: /* CKP value */
  174. clockp = ints[5];
  175. case 4: /* Backplane flag */
  176. backplane = ints[4];
  177. case 3: /* Node ID */
  178. node = ints[3];
  179. case 2: /* IRQ */
  180. irq = ints[2];
  181. case 1: /* IO address */
  182. io = ints[1];
  183. }
  184. if (*s)
  185. snprintf(device, sizeof(device), "%s", s);
  186. return 1;
  187. }
  188. __setup("com20020=", com20020isa_setup);
  189. #endif /* MODULE */
  190. module_init(com20020_init)
  191. module_exit(com20020_exit)