b1pci.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /* $Id: b1pci.c,v 1.1.2.2 2004/01/16 21:09:27 keil Exp $
  2. *
  3. * Module for AVM B1 PCI-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/config.h>
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/skbuff.h>
  15. #include <linux/delay.h>
  16. #include <linux/mm.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/ioport.h>
  19. #include <linux/pci.h>
  20. #include <linux/capi.h>
  21. #include <asm/io.h>
  22. #include <linux/init.h>
  23. #include <linux/isdn/capicmd.h>
  24. #include <linux/isdn/capiutil.h>
  25. #include <linux/isdn/capilli.h>
  26. #include "avmcard.h"
  27. /* ------------------------------------------------------------- */
  28. static char *revision = "$Revision: 1.1.2.2 $";
  29. /* ------------------------------------------------------------- */
  30. static struct pci_device_id b1pci_pci_tbl[] = {
  31. { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, PCI_ANY_ID, PCI_ANY_ID },
  32. { } /* Terminating entry */
  33. };
  34. MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl);
  35. MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card");
  36. MODULE_AUTHOR("Carsten Paeth");
  37. MODULE_LICENSE("GPL");
  38. /* ------------------------------------------------------------- */
  39. static char *b1pci_procinfo(struct capi_ctr *ctrl)
  40. {
  41. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  42. if (!cinfo)
  43. return "";
  44. sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
  45. cinfo->cardname[0] ? cinfo->cardname : "-",
  46. cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
  47. cinfo->card ? cinfo->card->port : 0x0,
  48. cinfo->card ? cinfo->card->irq : 0,
  49. cinfo->card ? cinfo->card->revision : 0
  50. );
  51. return cinfo->infobuf;
  52. }
  53. /* ------------------------------------------------------------- */
  54. static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
  55. {
  56. avmcard *card;
  57. avmctrl_info *cinfo;
  58. int retval;
  59. card = b1_alloc_card(1);
  60. if (!card) {
  61. printk(KERN_WARNING "b1pci: no memory.\n");
  62. retval = -ENOMEM;
  63. goto err;
  64. }
  65. cinfo = card->ctrlinfo;
  66. sprintf(card->name, "b1pci-%x", p->port);
  67. card->port = p->port;
  68. card->irq = p->irq;
  69. card->cardtype = avm_b1pci;
  70. if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
  71. printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
  72. card->port, card->port + AVMB1_PORTLEN);
  73. retval = -EBUSY;
  74. goto err_free;
  75. }
  76. b1_reset(card->port);
  77. retval = b1_detect(card->port, card->cardtype);
  78. if (retval) {
  79. printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
  80. card->port, retval);
  81. retval = -ENODEV;
  82. goto err_release_region;
  83. }
  84. b1_reset(card->port);
  85. b1_getrevision(card);
  86. retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card);
  87. if (retval) {
  88. printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq);
  89. retval = -EBUSY;
  90. goto err_release_region;
  91. }
  92. cinfo->capi_ctrl.driver_name = "b1pci";
  93. cinfo->capi_ctrl.driverdata = cinfo;
  94. cinfo->capi_ctrl.register_appl = b1_register_appl;
  95. cinfo->capi_ctrl.release_appl = b1_release_appl;
  96. cinfo->capi_ctrl.send_message = b1_send_message;
  97. cinfo->capi_ctrl.load_firmware = b1_load_firmware;
  98. cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
  99. cinfo->capi_ctrl.procinfo = b1pci_procinfo;
  100. cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
  101. strcpy(cinfo->capi_ctrl.name, card->name);
  102. cinfo->capi_ctrl.owner = THIS_MODULE;
  103. retval = attach_capi_ctr(&cinfo->capi_ctrl);
  104. if (retval) {
  105. printk(KERN_ERR "b1pci: attach controller failed.\n");
  106. goto err_free_irq;
  107. }
  108. if (card->revision >= 4) {
  109. printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, revision %d (no dma)\n",
  110. card->port, card->irq, card->revision);
  111. } else {
  112. printk(KERN_INFO "b1pci: AVM B1 PCI at i/o %#x, irq %d, revision %d\n",
  113. card->port, card->irq, card->revision);
  114. }
  115. pci_set_drvdata(pdev, card);
  116. return 0;
  117. err_free_irq:
  118. free_irq(card->irq, card);
  119. err_release_region:
  120. release_region(card->port, AVMB1_PORTLEN);
  121. err_free:
  122. b1_free_card(card);
  123. err:
  124. return retval;
  125. }
  126. static void b1pci_remove(struct pci_dev *pdev)
  127. {
  128. avmcard *card = pci_get_drvdata(pdev);
  129. avmctrl_info *cinfo = card->ctrlinfo;
  130. unsigned int port = card->port;
  131. b1_reset(port);
  132. b1_reset(port);
  133. detach_capi_ctr(&cinfo->capi_ctrl);
  134. free_irq(card->irq, card);
  135. release_region(card->port, AVMB1_PORTLEN);
  136. b1_free_card(card);
  137. }
  138. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  139. /* ------------------------------------------------------------- */
  140. static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
  141. {
  142. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  143. if (!cinfo)
  144. return "";
  145. sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx r%d",
  146. cinfo->cardname[0] ? cinfo->cardname : "-",
  147. cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
  148. cinfo->card ? cinfo->card->port : 0x0,
  149. cinfo->card ? cinfo->card->irq : 0,
  150. cinfo->card ? cinfo->card->membase : 0,
  151. cinfo->card ? cinfo->card->revision : 0
  152. );
  153. return cinfo->infobuf;
  154. }
  155. /* ------------------------------------------------------------- */
  156. static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
  157. {
  158. avmcard *card;
  159. avmctrl_info *cinfo;
  160. int retval;
  161. card = b1_alloc_card(1);
  162. if (!card) {
  163. printk(KERN_WARNING "b1pci: no memory.\n");
  164. retval = -ENOMEM;
  165. goto err;
  166. }
  167. card->dma = avmcard_dma_alloc("b1pci", pdev, 2048+128, 2048+128);
  168. if (!card->dma) {
  169. printk(KERN_WARNING "b1pci: dma alloc.\n");
  170. retval = -ENOMEM;
  171. goto err_free;
  172. }
  173. cinfo = card->ctrlinfo;
  174. sprintf(card->name, "b1pciv4-%x", p->port);
  175. card->port = p->port;
  176. card->irq = p->irq;
  177. card->membase = p->membase;
  178. card->cardtype = avm_b1pci;
  179. if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
  180. printk(KERN_WARNING "b1pci: ports 0x%03x-0x%03x in use.\n",
  181. card->port, card->port + AVMB1_PORTLEN);
  182. retval = -EBUSY;
  183. goto err_free_dma;
  184. }
  185. card->mbase = ioremap(card->membase, 64);
  186. if (!card->mbase) {
  187. printk(KERN_NOTICE "b1pci: can't remap memory at 0x%lx\n",
  188. card->membase);
  189. retval = -ENOMEM;
  190. goto err_release_region;
  191. }
  192. b1dma_reset(card);
  193. retval = b1pciv4_detect(card);
  194. if (retval) {
  195. printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
  196. card->port, retval);
  197. retval = -ENODEV;
  198. goto err_unmap;
  199. }
  200. b1dma_reset(card);
  201. b1_getrevision(card);
  202. retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
  203. if (retval) {
  204. printk(KERN_ERR "b1pci: unable to get IRQ %d.\n",
  205. card->irq);
  206. retval = -EBUSY;
  207. goto err_unmap;
  208. }
  209. cinfo->capi_ctrl.owner = THIS_MODULE;
  210. cinfo->capi_ctrl.driver_name = "b1pciv4";
  211. cinfo->capi_ctrl.driverdata = cinfo;
  212. cinfo->capi_ctrl.register_appl = b1dma_register_appl;
  213. cinfo->capi_ctrl.release_appl = b1dma_release_appl;
  214. cinfo->capi_ctrl.send_message = b1dma_send_message;
  215. cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
  216. cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
  217. cinfo->capi_ctrl.procinfo = b1pciv4_procinfo;
  218. cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
  219. strcpy(cinfo->capi_ctrl.name, card->name);
  220. retval = attach_capi_ctr(&cinfo->capi_ctrl);
  221. if (retval) {
  222. printk(KERN_ERR "b1pci: attach controller failed.\n");
  223. goto err_free_irq;
  224. }
  225. card->cardnr = cinfo->capi_ctrl.cnr;
  226. printk(KERN_INFO "b1pci: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n",
  227. card->port, card->irq, card->membase, card->revision);
  228. pci_set_drvdata(pdev, card);
  229. return 0;
  230. err_free_irq:
  231. free_irq(card->irq, card);
  232. err_unmap:
  233. iounmap(card->mbase);
  234. err_release_region:
  235. release_region(card->port, AVMB1_PORTLEN);
  236. err_free_dma:
  237. avmcard_dma_free(card->dma);
  238. err_free:
  239. b1_free_card(card);
  240. err:
  241. return retval;
  242. }
  243. static void b1pciv4_remove(struct pci_dev *pdev)
  244. {
  245. avmcard *card = pci_get_drvdata(pdev);
  246. avmctrl_info *cinfo = card->ctrlinfo;
  247. b1dma_reset(card);
  248. detach_capi_ctr(&cinfo->capi_ctrl);
  249. free_irq(card->irq, card);
  250. iounmap(card->mbase);
  251. release_region(card->port, AVMB1_PORTLEN);
  252. avmcard_dma_free(card->dma);
  253. b1_free_card(card);
  254. }
  255. #endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
  256. static int __devinit b1pci_pci_probe(struct pci_dev *pdev,
  257. const struct pci_device_id *ent)
  258. {
  259. struct capicardparams param;
  260. int retval;
  261. if (pci_enable_device(pdev) < 0) {
  262. printk(KERN_ERR "b1pci: failed to enable AVM-B1\n");
  263. return -ENODEV;
  264. }
  265. param.irq = pdev->irq;
  266. if (pci_resource_start(pdev, 2)) { /* B1 PCI V4 */
  267. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  268. pci_set_master(pdev);
  269. #endif
  270. param.membase = pci_resource_start(pdev, 0);
  271. param.port = pci_resource_start(pdev, 2);
  272. printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
  273. param.port, param.irq, param.membase);
  274. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  275. retval = b1pciv4_probe(&param, pdev);
  276. #else
  277. retval = b1pci_probe(&param, pdev);
  278. #endif
  279. if (retval != 0) {
  280. printk(KERN_ERR "b1pci: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
  281. param.port, param.irq, param.membase);
  282. }
  283. } else {
  284. param.membase = 0;
  285. param.port = pci_resource_start(pdev, 1);
  286. printk(KERN_INFO "b1pci: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
  287. param.port, param.irq);
  288. retval = b1pci_probe(&param, pdev);
  289. if (retval != 0) {
  290. printk(KERN_ERR "b1pci: no AVM-B1 at i/o %#x, irq %d detected\n",
  291. param.port, param.irq);
  292. }
  293. }
  294. return retval;
  295. }
  296. static void __devexit b1pci_pci_remove(struct pci_dev *pdev)
  297. {
  298. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  299. avmcard *card = pci_get_drvdata(pdev);
  300. if (card->dma)
  301. b1pciv4_remove(pdev);
  302. else
  303. b1pci_remove(pdev);
  304. #else
  305. b1pci_remove(pdev);
  306. #endif
  307. }
  308. static struct pci_driver b1pci_pci_driver = {
  309. .name = "b1pci",
  310. .id_table = b1pci_pci_tbl,
  311. .probe = b1pci_pci_probe,
  312. .remove = __devexit_p(b1pci_pci_remove),
  313. };
  314. static struct capi_driver capi_driver_b1pci = {
  315. .name = "b1pci",
  316. .revision = "1.0",
  317. };
  318. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  319. static struct capi_driver capi_driver_b1pciv4 = {
  320. .name = "b1pciv4",
  321. .revision = "1.0",
  322. };
  323. #endif
  324. static int __init b1pci_init(void)
  325. {
  326. char *p;
  327. char rev[32];
  328. int err;
  329. if ((p = strchr(revision, ':')) != 0 && p[1]) {
  330. strlcpy(rev, p + 2, 32);
  331. if ((p = strchr(rev, '$')) != 0 && p > rev)
  332. *(p-1) = 0;
  333. } else
  334. strcpy(rev, "1.0");
  335. err = pci_register_driver(&b1pci_pci_driver);
  336. if (!err) {
  337. strlcpy(capi_driver_b1pci.revision, rev, 32);
  338. register_capi_driver(&capi_driver_b1pci);
  339. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  340. strlcpy(capi_driver_b1pciv4.revision, rev, 32);
  341. register_capi_driver(&capi_driver_b1pciv4);
  342. #endif
  343. printk(KERN_INFO "b1pci: revision %s\n", rev);
  344. }
  345. return err;
  346. }
  347. static void __exit b1pci_exit(void)
  348. {
  349. unregister_capi_driver(&capi_driver_b1pci);
  350. #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
  351. unregister_capi_driver(&capi_driver_b1pciv4);
  352. #endif
  353. pci_unregister_driver(&b1pci_pci_driver);
  354. }
  355. module_init(b1pci_init);
  356. module_exit(b1pci_exit);