arc-rimi.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:10k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Linux ARCnet driver - "RIM I" (entirely mem-mapped) cards
  3.  * 
  4.  * Written 1994-1999 by Avery Pennarun.
  5.  * Written 1999-2000 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/kernel.h>
  28. #include <linux/module.h>
  29. #include <linux/ioport.h>
  30. #include <linux/slab.h>
  31. #include <linux/delay.h>
  32. #include <linux/netdevice.h>
  33. #include <linux/bootmem.h>
  34. #include <linux/init.h>
  35. #include <asm/io.h>
  36. #include <linux/arcdevice.h>
  37. #define VERSION "arcnet: RIM I (entirely mem-mapped) supportn"
  38. /* Internal function declarations */
  39. static int arcrimi_probe(struct net_device *dev);
  40. static int arcrimi_found(struct net_device *dev);
  41. static void arcrimi_command(struct net_device *dev, int command);
  42. static int arcrimi_status(struct net_device *dev);
  43. static void arcrimi_setmask(struct net_device *dev, int mask);
  44. static int arcrimi_reset(struct net_device *dev, int really_reset);
  45. static void arcrimi_openclose(struct net_device *dev, bool open);
  46. static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
  47.  void *buf, int count);
  48. static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
  49.    void *buf, int count);
  50. /* Handy defines for ARCnet specific stuff */
  51. /* Amount of I/O memory used by the card */
  52. #define BUFFER_SIZE (512)
  53. #define MIRROR_SIZE (BUFFER_SIZE*4)
  54. /* COM 9026 controller chip --> ARCnet register addresses */
  55. #define _INTMASK (ioaddr+0) /* writable */
  56. #define _STATUS  (ioaddr+0) /* readable */
  57. #define _COMMAND (ioaddr+1) /* writable, returns random vals on read (?) */
  58. #define _RESET  (ioaddr+8) /* software reset (on read) */
  59. #define _MEMDATA  (ioaddr+12) /* Data port for IO-mapped memory */
  60. #define _ADDR_HI  (ioaddr+15) /* Control registers for said */
  61. #define _ADDR_LO  (ioaddr+14)
  62. #define _CONFIG  (ioaddr+2) /* Configuration register */
  63. #undef ASTATUS
  64. #undef ACOMMAND
  65. #undef AINTMASK
  66. #define ASTATUS() readb(_STATUS)
  67. #define ACOMMAND(cmd) writeb((cmd),_COMMAND)
  68. #define AINTMASK(msk) writeb((msk),_INTMASK)
  69. #define SETCONF() writeb(lp->config,_CONFIG)
  70. /*
  71.  * We cannot probe for a RIM I card; one reason is I don't know how to reset
  72.  * them.  In fact, we can't even get their node ID automatically.  So, we
  73.  * need to be passed a specific shmem address, IRQ, and node ID.
  74.  */
  75. static int __init arcrimi_probe(struct net_device *dev)
  76. {
  77. BUGLVL(D_NORMAL) printk(VERSION);
  78. BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!n");
  79. BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %dn",
  80.        dev->dev_addr[0], dev->mem_start, dev->irq);
  81. if (dev->mem_start <= 0 || dev->irq <= 0) {
  82. BUGMSG(D_NORMAL, "No autoprobe for RIM I; you "
  83.        "must specify the shmem and irq!n");
  84. return -ENODEV;
  85. }
  86. if (check_mem_region(dev->mem_start, BUFFER_SIZE)) {
  87. BUGMSG(D_NORMAL, "Card memory already allocatedn");
  88. return -ENODEV;
  89. }
  90. if (dev->dev_addr[0] == 0) {
  91. BUGMSG(D_NORMAL, "You need to specify your card's station "
  92.        "ID!n");
  93. return -ENODEV;
  94. }
  95. return arcrimi_found(dev);
  96. }
  97. /*
  98.  * Set up the struct net_device associated with this card.  Called after
  99.  * probing succeeds.
  100.  */
  101. static int __init arcrimi_found(struct net_device *dev)
  102. {
  103. struct arcnet_local *lp;
  104. u_long first_mirror, last_mirror, shmem;
  105. int mirror_size;
  106. /* reserve the irq */  {
  107. if (request_irq(dev->irq, &arcnet_interrupt, 0, "arcnet (RIM I)", dev))
  108. BUGMSG(D_NORMAL, "Can't get IRQ %d!n", dev->irq);
  109. return -ENODEV;
  110. }
  111. shmem = dev->mem_start;
  112. isa_writeb(TESTvalue, shmem);
  113. isa_writeb(dev->dev_addr[0], shmem + 1); /* actually the node ID */
  114. /* find the real shared memory start/end points, including mirrors */
  115. /* guess the actual size of one "memory mirror" - the number of
  116.  * bytes between copies of the shared memory.  On most cards, it's
  117.  * 2k (or there are no mirrors at all) but on some, it's 4k.
  118.  */
  119. mirror_size = MIRROR_SIZE;
  120. if (isa_readb(shmem) == TESTvalue
  121.     && isa_readb(shmem - mirror_size) != TESTvalue
  122.     && isa_readb(shmem - 2 * mirror_size) == TESTvalue)
  123. mirror_size *= 2;
  124. first_mirror = last_mirror = shmem;
  125. while (isa_readb(first_mirror) == TESTvalue)
  126. first_mirror -= mirror_size;
  127. first_mirror += mirror_size;
  128. while (isa_readb(last_mirror) == TESTvalue)
  129. last_mirror += mirror_size;
  130. last_mirror -= mirror_size;
  131. dev->mem_start = first_mirror;
  132. dev->mem_end = last_mirror + MIRROR_SIZE - 1;
  133. dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;
  134. dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;
  135. /* initialize the rest of the device structure. */
  136. lp = dev->priv = kmalloc(sizeof(struct arcnet_local), GFP_KERNEL);
  137. if (!lp) {
  138. BUGMSG(D_NORMAL, "Can't allocate device data!n");
  139. goto err_free_irq;
  140. }
  141. lp->card_name = "RIM I";
  142. lp->hw.command = arcrimi_command;
  143. lp->hw.status = arcrimi_status;
  144. lp->hw.intmask = arcrimi_setmask;
  145. lp->hw.reset = arcrimi_reset;
  146. lp->hw.open_close = arcrimi_openclose;
  147. lp->hw.copy_to_card = arcrimi_copy_to_card;
  148. lp->hw.copy_from_card = arcrimi_copy_from_card;
  149. lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
  150. if (!lp->mem_start) {
  151. BUGMSG(D_NORMAL, "Can't remap device memory!n");
  152. goto err_free_dev_priv;
  153. }
  154. /* Fill in the fields of the device structure with generic
  155.  * values.
  156.  */
  157. arcdev_setup(dev);
  158. /* get and check the station ID from offset 1 in shmem */
  159. dev->dev_addr[0] = readb(lp->mem_start + 1);
  160. /* reserve the memory region - guaranteed to work by check_region */
  161. request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)");
  162. BUGMSG(D_NORMAL, "ARCnet RIM I: station %02Xh found at IRQ %d, "
  163.        "ShMem %lXh (%ld*%d bytes).n",
  164.        dev->dev_addr[0],
  165.        dev->irq, dev->mem_start,
  166.  (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);
  167. return 0;
  168.       err_free_dev_priv:
  169. kfree(dev->priv);
  170.       err_free_irq:
  171. free_irq(dev->irq, dev);
  172. return -EIO;
  173. }
  174. /*
  175.  * Do a hardware reset on the card, and set up necessary registers.
  176.  *
  177.  * This should be called as little as possible, because it disrupts the
  178.  * token on the network (causes a RECON) and requires a significant delay.
  179.  *
  180.  * However, it does make sure the card is in a defined state.
  181.  */
  182. static int arcrimi_reset(struct net_device *dev, int really_reset)
  183. {
  184. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  185. void *ioaddr = lp->mem_start + 0x800;
  186. BUGMSG(D_INIT, "Resetting %s (status=%02Xh)n", dev->name, ASTATUS());
  187. if (really_reset) {
  188. writeb(TESTvalue, ioaddr - 0x800); /* fake reset */
  189. return 0;
  190. }
  191. ACOMMAND(CFLAGScmd | RESETclear); /* clear flags & end reset */
  192. ACOMMAND(CFLAGScmd | CONFIGclear);
  193. /* enable extended (512-byte) packets */
  194. ACOMMAND(CONFIGcmd | EXTconf);
  195. /* done!  return success. */
  196. return 0;
  197. }
  198. static void arcrimi_openclose(struct net_device *dev, int open)
  199. {
  200. if (open)
  201. MOD_INC_USE_COUNT;
  202. else
  203. MOD_DEC_USE_COUNT;
  204. }
  205. static void arcrimi_setmask(struct net_device *dev, int mask)
  206. {
  207. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  208. void *ioaddr = lp->mem_start + 0x800;
  209. AINTMASK(mask);
  210. }
  211. static int arcrimi_status(struct net_device *dev)
  212. {
  213. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  214. void *ioaddr = lp->mem_start + 0x800;
  215. return ASTATUS();
  216. }
  217. static void arcrimi_command(struct net_device *dev, int cmd)
  218. {
  219. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  220. void *ioaddr = lp->mem_start + 0x800;
  221. ACOMMAND(cmd);
  222. }
  223. static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
  224.  void *buf, int count)
  225. {
  226. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  227. void *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
  228. TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
  229. }
  230. static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
  231.    void *buf, int count)
  232. {
  233. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  234. void *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
  235. TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
  236. }
  237. #ifdef MODULE
  238. static struct net_device *my_dev;
  239. /* Module parameters */
  240. static int node = 0;
  241. static int io = 0x0; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
  242. static int irq = 0; /* or use the insmod io= irq= shmem= options */
  243. static char *device; /* use eg. device="arc1" to change name */
  244. MODULE_PARM(node, "i");
  245. MODULE_PARM(io, "i");
  246. MODULE_PARM(irq, "i");
  247. MODULE_PARM(device, "s");
  248. MODULE_LICENSE("GPL");
  249. int init_module(void)
  250. {
  251. struct net_device *dev;
  252. int err;
  253. dev = dev_alloc(device ? : "arc%d", &err);
  254. if (!dev)
  255. return err;
  256. if (node && node != 0xff)
  257. dev->dev_addr[0] = node;
  258. dev->base_addr = io;
  259. dev->irq = irq;
  260. if (dev->irq == 2)
  261. dev->irq = 9;
  262. if (arcrimi_probe(dev))
  263. return -EIO;
  264. my_dev = dev;
  265. return 0;
  266. }
  267. void cleanup_module(void)
  268. {
  269. struct net_device *dev = my_dev;
  270. struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
  271. unregister_netdev(dev);
  272. free_irq(dev->irq, dev);
  273. iounmap(lp->mem_start);
  274. release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
  275. kfree(dev->priv);
  276. kfree(dev);
  277. }
  278. #else
  279. static int __init arcrimi_setup(char *s)
  280. {
  281. struct net_device *dev;
  282. int ints[8];
  283. s = get_options(s, 8, ints);
  284. if (!ints[0])
  285. return 1;
  286. dev = alloc_bootmem(sizeof(struct net_device));
  287. memset(dev, 0, sizeof(struct net_device));
  288. dev->init = arcrimi_probe;
  289. switch (ints[0]) {
  290. default: /* ERROR */
  291. printk("arcrimi: Too many arguments.n");
  292. case 3: /* Node ID */
  293. dev->dev_addr[0] = ints[3];
  294. case 2: /* IRQ */
  295. dev->irq = ints[2];
  296. case 1: /* IO address */
  297. dev->mem_start = ints[1];
  298. }
  299. if (*s)
  300. strncpy(dev->name, s, 9);
  301. else
  302. strcpy(dev->name, "arc%d");
  303. if (register_netdev(dev))
  304. printk(KERN_ERR "arc-rimi: Cannot register arcnet devicen");
  305. return 1;
  306. }
  307. __setup("arcrimi=", arcrimi_setup);
  308. #endif /* MODULE */