b1isa.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $
  2. *
  3. * Module for AVM B1 ISA-card.
  4. *
  5. * Copyright 1999 by Carsten Paeth <calle@calle.de>
  6. *
  7. * This software may be used and distributed according to the terms
  8. * of the GNU General Public License, incorporated herein by reference.
  9. *
  10. */
  11. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/skbuff.h>
  14. #include <linux/delay.h>
  15. #include <linux/mm.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/ioport.h>
  18. #include <linux/capi.h>
  19. #include <linux/init.h>
  20. #include <linux/pci.h>
  21. #include <asm/io.h>
  22. #include <linux/isdn/capicmd.h>
  23. #include <linux/isdn/capiutil.h>
  24. #include <linux/isdn/capilli.h>
  25. #include "avmcard.h"
  26. /* ------------------------------------------------------------- */
  27. static char *revision = "$Revision: 1.1.2.3 $";
  28. /* ------------------------------------------------------------- */
  29. MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card");
  30. MODULE_AUTHOR("Carsten Paeth");
  31. MODULE_LICENSE("GPL");
  32. /* ------------------------------------------------------------- */
  33. static void b1isa_remove(struct pci_dev *pdev)
  34. {
  35. avmctrl_info *cinfo = pci_get_drvdata(pdev);
  36. avmcard *card;
  37. if (!cinfo)
  38. return;
  39. card = cinfo->card;
  40. b1_reset(card->port);
  41. b1_reset(card->port);
  42. detach_capi_ctr(&cinfo->capi_ctrl);
  43. free_irq(card->irq, card);
  44. release_region(card->port, AVMB1_PORTLEN);
  45. b1_free_card(card);
  46. }
  47. /* ------------------------------------------------------------- */
  48. static char *b1isa_procinfo(struct capi_ctr *ctrl);
  49. static int b1isa_probe(struct pci_dev *pdev)
  50. {
  51. avmctrl_info *cinfo;
  52. avmcard *card;
  53. int retval;
  54. card = b1_alloc_card(1);
  55. if (!card) {
  56. printk(KERN_WARNING "b1isa: no memory.\n");
  57. retval = -ENOMEM;
  58. goto err;
  59. }
  60. cinfo = card->ctrlinfo;
  61. card->port = pci_resource_start(pdev, 0);
  62. card->irq = pdev->irq;
  63. card->cardtype = avm_b1isa;
  64. sprintf(card->name, "b1isa-%x", card->port);
  65. if (card->port != 0x150 && card->port != 0x250
  66. && card->port != 0x300 && card->port != 0x340) {
  67. printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port);
  68. retval = -EINVAL;
  69. goto err_free;
  70. }
  71. if (b1_irq_table[card->irq & 0xf] == 0) {
  72. printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq);
  73. retval = -EINVAL;
  74. goto err_free;
  75. }
  76. if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
  77. printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n",
  78. card->port, card->port + AVMB1_PORTLEN);
  79. retval = -EBUSY;
  80. goto err_free;
  81. }
  82. retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
  83. if (retval) {
  84. printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq);
  85. goto err_release_region;
  86. }
  87. b1_reset(card->port);
  88. if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
  89. printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n",
  90. card->port, retval);
  91. retval = -ENODEV;
  92. goto err_free_irq;
  93. }
  94. b1_reset(card->port);
  95. b1_getrevision(card);
  96. cinfo->capi_ctrl.owner = THIS_MODULE;
  97. cinfo->capi_ctrl.driver_name = "b1isa";
  98. cinfo->capi_ctrl.driverdata = cinfo;
  99. cinfo->capi_ctrl.register_appl = b1_register_appl;
  100. cinfo->capi_ctrl.release_appl = b1_release_appl;
  101. cinfo->capi_ctrl.send_message = b1_send_message;
  102. cinfo->capi_ctrl.load_firmware = b1_load_firmware;
  103. cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
  104. cinfo->capi_ctrl.procinfo = b1isa_procinfo;
  105. cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
  106. strcpy(cinfo->capi_ctrl.name, card->name);
  107. retval = attach_capi_ctr(&cinfo->capi_ctrl);
  108. if (retval) {
  109. printk(KERN_ERR "b1isa: attach controller failed.\n");
  110. goto err_free_irq;
  111. }
  112. printk(KERN_INFO "b1isa: AVM B1 ISA at i/o %#x, irq %d, revision %d\n",
  113. card->port, card->irq, card->revision);
  114. pci_set_drvdata(pdev, cinfo);
  115. return 0;
  116. err_free_irq:
  117. free_irq(card->irq, card);
  118. err_release_region:
  119. release_region(card->port, AVMB1_PORTLEN);
  120. err_free:
  121. b1_free_card(card);
  122. err:
  123. return retval;
  124. }
  125. static char *b1isa_procinfo(struct capi_ctr *ctrl)
  126. {
  127. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  128. if (!cinfo)
  129. return "";
  130. sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
  131. cinfo->cardname[0] ? cinfo->cardname : "-",
  132. cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
  133. cinfo->card ? cinfo->card->port : 0x0,
  134. cinfo->card ? cinfo->card->irq : 0,
  135. cinfo->card ? cinfo->card->revision : 0
  136. );
  137. return cinfo->infobuf;
  138. }
  139. /* ------------------------------------------------------------- */
  140. #define MAX_CARDS 4
  141. static struct pci_dev isa_dev[MAX_CARDS];
  142. static int io[MAX_CARDS];
  143. static int irq[MAX_CARDS];
  144. module_param_hw_array(io, int, ioport, NULL, 0);
  145. module_param_hw_array(irq, int, irq, NULL, 0);
  146. MODULE_PARM_DESC(io, "I/O base address(es)");
  147. MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
  148. static int b1isa_add_card(struct capi_driver *driver, capicardparams *data)
  149. {
  150. int i;
  151. for (i = 0; i < MAX_CARDS; i++) {
  152. if (isa_dev[i].resource[0].start)
  153. continue;
  154. isa_dev[i].resource[0].start = data->port;
  155. isa_dev[i].irq = data->irq;
  156. if (b1isa_probe(&isa_dev[i]) == 0)
  157. return 0;
  158. }
  159. return -ENODEV;
  160. }
  161. static struct capi_driver capi_driver_b1isa = {
  162. .name = "b1isa",
  163. .revision = "1.0",
  164. .add_card = b1isa_add_card,
  165. };
  166. static int __init b1isa_init(void)
  167. {
  168. char *p;
  169. char rev[32];
  170. int i;
  171. if ((p = strchr(revision, ':')) != NULL && p[1]) {
  172. strlcpy(rev, p + 2, 32);
  173. if ((p = strchr(rev, '$')) != NULL && p > rev)
  174. *(p - 1) = 0;
  175. } else
  176. strcpy(rev, "1.0");
  177. for (i = 0; i < MAX_CARDS; i++) {
  178. if (!io[i])
  179. break;
  180. isa_dev[i].resource[0].start = io[i];
  181. isa_dev[i].irq = irq[i];
  182. if (b1isa_probe(&isa_dev[i]) != 0)
  183. return -ENODEV;
  184. }
  185. strlcpy(capi_driver_b1isa.revision, rev, 32);
  186. register_capi_driver(&capi_driver_b1isa);
  187. printk(KERN_INFO "b1isa: revision %s\n", rev);
  188. return 0;
  189. }
  190. static void __exit b1isa_exit(void)
  191. {
  192. int i;
  193. for (i = 0; i < MAX_CARDS; i++) {
  194. if (isa_dev[i].resource[0].start)
  195. b1isa_remove(&isa_dev[i]);
  196. }
  197. unregister_capi_driver(&capi_driver_b1isa);
  198. }
  199. module_init(b1isa_init);
  200. module_exit(b1isa_exit);