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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/acorn/char/serial-card.c
  3.  *
  4.  *  Copyright (C) 1996-1999 Russell King.
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  *
  10.  * A generic handler of serial expansion cards that use 16550s or
  11.  * the like.
  12.  *
  13.  * Definitions:
  14.  *  MY_PRODS Product numbers to identify this card by
  15.  *  MY_MANUS Manufacturer numbers to identify this card by
  16.  *  MY_NUMPORTS Number of ports per card
  17.  *  MY_BAUD_BASE Baud base for the card
  18.  *  MY_INIT Initialisation routine name
  19.  *  MY_BASE_ADDRESS(ec) Return base address for ports
  20.  *  MY_PORT_ADDRESS
  21.  * (port,cardaddr) Return address for port using base address
  22.  * from above.
  23.  *
  24.  * Changelog:
  25.  *  30-07-1996 RMK Created
  26.  *  22-04-1998 RMK Removed old register_pre_init_serial
  27.  */
  28. #include <linux/module.h>
  29. #include <linux/types.h>
  30. #include <linux/serial.h>
  31. #include <linux/errno.h>
  32. #include <linux/init.h>
  33. #include <asm/ecard.h>
  34. #include <asm/string.h>
  35. #ifndef NUM_SERIALS
  36. #define NUM_SERIALS MY_NUMPORTS * MAX_ECARDS
  37. #endif
  38. #ifdef MODULE
  39. static int __serial_ports[NUM_SERIALS];
  40. static int __serial_pcount;
  41. static int __serial_addr[NUM_SERIALS];
  42. static struct expansion_card *expcard[MAX_ECARDS];
  43. #define ADD_ECARD(ec,card) expcard[(card)] = (ec)
  44. #define ADD_PORT(port,addr)
  45. do {
  46. __serial_ports[__serial_pcount] = (port);
  47. __serial_addr[__serial_pcount] = (addr);
  48. __serial_pcount += 1;
  49. } while (0)
  50. #else
  51. #define ADD_ECARD(ec,card)
  52. #define ADD_PORT(port,addr)
  53. #endif
  54. static const card_ids serial_cids[] = { MY_CARD_LIST, { 0xffff, 0xffff } };
  55. static inline int serial_register_onedev (unsigned long port, int irq)
  56. {
  57.     struct serial_struct req;
  58.     memset(&req, 0, sizeof(req));
  59.     req.baud_base = MY_BAUD_BASE;
  60.     req.irq = irq;
  61.     req.port = port;
  62.     req.flags = 0;
  63.     return register_serial(&req);
  64. }
  65. static int __init INIT (void)
  66. {
  67.     int card = 0;
  68.     ecard_startfind ();
  69.     do {
  70. struct expansion_card *ec;
  71. unsigned long cardaddr;
  72. int port;
  73. ec = ecard_find (0, serial_cids);
  74. if (!ec)
  75.     break;
  76. cardaddr = MY_BASE_ADDRESS(ec);
  77. for (port = 0; port < MY_NUMPORTS; port ++) {
  78.     unsigned long address;
  79.     int line;
  80.     address = MY_PORT_ADDRESS(port, cardaddr);
  81.     line = serial_register_onedev (address, ec->irq);
  82.     if (line < 0)
  83. break;
  84.     ADD_PORT(line, address);
  85. }
  86. if (port) {
  87.     ecard_claim (ec);
  88.     ADD_ECARD(ec, card);
  89. } else
  90.     break;
  91.     } while (++card < MAX_ECARDS);
  92.     return card ? 0 : -ENODEV;
  93. }
  94. static void __exit EXIT (void)
  95. {
  96. #ifdef MODULE
  97.     int i;
  98.     for (i = 0; i < __serial_pcount; i++) {
  99. unregister_serial(__serial_ports[i]);
  100. release_region(__serial_addr[i], 8);
  101.     }
  102.     for (i = 0; i < MAX_ECARDS; i++)
  103. if (expcard[i])
  104.     ecard_release (expcard[i]);
  105. #endif
  106. }
  107. EXPORT_NO_SYMBOLS;
  108. MODULE_LICENSE("GPL");
  109. module_init(INIT);
  110. module_exit(EXIT);