1 /* $Id: b1pci.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
3 * Module for AVM B1 PCI-card.
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
12 #include <linux/config.h>
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/skbuff.h>
16 #include <linux/delay.h>
18 #include <linux/interrupt.h>
19 #include <linux/ioport.h>
20 #include <linux/pci.h>
21 #include <linux/capi.h>
23 #include <linux/init.h>
29 static char *revision = "$Revision: 1.1.4.1 $";
31 /* ------------------------------------------------------------- */
33 static struct pci_device_id b1pci_pci_tbl[] __initdata = {
34 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, PCI_ANY_ID, PCI_ANY_ID },
35 { } /* Terminating entry */
38 MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl);
39 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card");
40 MODULE_AUTHOR("Carsten Paeth");
41 MODULE_LICENSE("GPL");
43 /* ------------------------------------------------------------- */
45 static struct capi_driver_interface *di;
47 /* ------------------------------------------------------------- */
49 static void b1pci_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
53 card = (avmcard *) devptr;
56 printk(KERN_WARNING "b1pci: interrupt: wrong device\n");
59 if (card->interrupt) {
60 printk(KERN_ERR "%s: reentering interrupt hander.\n", card->name);
66 b1_handle_interrupt(card);
70 /* ------------------------------------------------------------- */
72 static void b1pci_remove_ctr(struct capi_ctr *ctrl)
74 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
75 avmcard *card = cinfo->card;
76 unsigned int port = card->port;
82 free_irq(card->irq, card);
83 release_region(card->port, AVMB1_PORTLEN);
85 kfree(card->ctrlinfo);
91 /* ------------------------------------------------------------- */
93 static char *b1pci_procinfo(struct capi_ctr *ctrl)
95 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
99 sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
100 cinfo->cardname[0] ? cinfo->cardname : "-",
101 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
102 cinfo->card ? cinfo->card->port : 0x0,
103 cinfo->card ? cinfo->card->irq : 0,
104 cinfo->card ? cinfo->card->revision : 0
106 return cinfo->infobuf;
109 /* ------------------------------------------------------------- */
111 static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
119 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
122 printk(KERN_WARNING "%s: no memory.\n", driver->name);
126 memset(card, 0, sizeof(avmcard));
127 cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
129 printk(KERN_WARNING "%s: no memory.\n", driver->name);
134 memset(cinfo, 0, sizeof(avmctrl_info));
135 card->ctrlinfo = cinfo;
137 sprintf(card->name, "b1pci-%x", p->port);
138 card->port = p->port;
140 card->cardtype = avm_b1pci;
142 if (check_region(card->port, AVMB1_PORTLEN)) {
144 "%s: ports 0x%03x-0x%03x in use.\n",
145 driver->name, card->port, card->port + AVMB1_PORTLEN);
146 kfree(card->ctrlinfo);
151 b1_reset(card->port);
152 if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
153 printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
154 driver->name, card->port, retval);
155 kfree(card->ctrlinfo);
160 b1_reset(card->port);
161 b1_getrevision(card);
163 request_region(p->port, AVMB1_PORTLEN, card->name);
165 retval = request_irq(card->irq, b1pci_interrupt, SA_SHIRQ, card->name, card);
167 printk(KERN_ERR "%s: unable to get IRQ %d.\n",
168 driver->name, card->irq);
169 release_region(card->port, AVMB1_PORTLEN);
170 kfree(card->ctrlinfo);
176 cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
177 if (!cinfo->capi_ctrl) {
178 printk(KERN_ERR "%s: attach controller failed.\n",
180 free_irq(card->irq, card);
181 release_region(card->port, AVMB1_PORTLEN);
182 kfree(card->ctrlinfo);
188 if (card->revision >= 4) {
190 "%s: AVM B1 PCI V4 at i/o %#x, irq %d, revision %d (no dma)\n",
191 driver->name, card->port, card->irq, card->revision);
194 "%s: AVM B1 PCI at i/o %#x, irq %d, revision %d\n",
195 driver->name, card->port, card->irq, card->revision);
201 /* ------------------------------------------------------------- */
203 static struct capi_driver b1pci_driver = {
206 load_firmware: b1_load_firmware,
207 reset_ctr: b1_reset_ctr,
208 remove_ctr: b1pci_remove_ctr,
209 register_appl: b1_register_appl,
210 release_appl: b1_release_appl,
211 send_message: b1_send_message,
213 procinfo: b1pci_procinfo,
214 ctr_read_proc: b1ctl_read_proc,
215 driver_read_proc: 0, /* use standard driver_read_proc */
217 add_card: 0, /* no add_card function */
220 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
221 /* ------------------------------------------------------------- */
223 static struct capi_driver_interface *div4;
225 /* ------------------------------------------------------------- */
227 static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
229 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
230 avmcard *card = cinfo->card;
234 div4->detach_ctr(ctrl);
235 free_irq(card->irq, card);
236 iounmap(card->mbase);
237 release_region(card->port, AVMB1_PORTLEN);
238 ctrl->driverdata = 0;
239 kfree(card->ctrlinfo);
246 static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
248 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
252 sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx r%d",
253 cinfo->cardname[0] ? cinfo->cardname : "-",
254 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
255 cinfo->card ? cinfo->card->port : 0x0,
256 cinfo->card ? cinfo->card->irq : 0,
257 cinfo->card ? cinfo->card->membase : 0,
258 cinfo->card ? cinfo->card->revision : 0
260 return cinfo->infobuf;
263 /* ------------------------------------------------------------- */
265 static int b1pciv4_add_card(struct capi_driver *driver, struct capicardparams *p)
273 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
276 printk(KERN_WARNING "%s: no memory.\n", driver->name);
280 memset(card, 0, sizeof(avmcard));
281 card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC);
283 printk(KERN_WARNING "%s: no memory.\n", driver->name);
288 memset(card->dma, 0, sizeof(avmcard_dmainfo));
289 cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
291 printk(KERN_WARNING "%s: no memory.\n", driver->name);
297 memset(cinfo, 0, sizeof(avmctrl_info));
298 card->ctrlinfo = cinfo;
300 sprintf(card->name, "b1pciv4-%x", p->port);
301 card->port = p->port;
303 card->membase = p->membase;
304 card->cardtype = avm_b1pci;
306 if (check_region(card->port, AVMB1_PORTLEN)) {
308 "%s: ports 0x%03x-0x%03x in use.\n",
309 driver->name, card->port, card->port + AVMB1_PORTLEN);
310 kfree(card->ctrlinfo);
317 card->mbase = ioremap_nocache(card->membase, 64);
319 printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
320 driver->name, card->membase);
321 kfree(card->ctrlinfo);
330 if ((retval = b1pciv4_detect(card)) != 0) {
331 printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
332 driver->name, card->port, retval);
333 iounmap(card->mbase);
334 kfree(card->ctrlinfo);
341 b1_getrevision(card);
343 request_region(p->port, AVMB1_PORTLEN, card->name);
345 retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
347 printk(KERN_ERR "%s: unable to get IRQ %d.\n",
348 driver->name, card->irq);
349 iounmap(card->mbase);
350 release_region(card->port, AVMB1_PORTLEN);
351 kfree(card->ctrlinfo);
358 cinfo->capi_ctrl = div4->attach_ctr(driver, card->name, cinfo);
359 if (!cinfo->capi_ctrl) {
360 printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
361 iounmap(card->mbase);
362 free_irq(card->irq, card);
363 release_region(card->port, AVMB1_PORTLEN);
364 kfree(card->ctrlinfo);
370 card->cardnr = cinfo->capi_ctrl->cnr;
372 skb_queue_head_init(&card->dma->send_queue);
375 "%s: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n",
376 driver->name, card->port, card->irq,
377 card->membase, card->revision);
382 /* ------------------------------------------------------------- */
385 static struct capi_driver b1pciv4_driver = {
388 load_firmware: b1dma_load_firmware,
389 reset_ctr: b1dma_reset_ctr,
390 remove_ctr: b1pciv4_remove_ctr,
391 register_appl: b1dma_register_appl,
392 release_appl: b1dma_release_appl,
393 send_message: b1dma_send_message,
395 procinfo: b1pciv4_procinfo,
396 ctr_read_proc: b1dmactl_read_proc,
397 driver_read_proc: 0, /* use standard driver_read_proc */
399 add_card: 0, /* no add_card function */
402 #endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
404 static int ncards = 0;
406 static int add_card(struct pci_dev *dev)
408 struct capi_driver *driver = &b1pci_driver;
409 struct capicardparams param;
412 if (pci_enable_device(dev) < 0) {
413 printk(KERN_ERR "%s: failed to enable AVM-B1\n",
417 param.irq = dev->irq;
419 if (pci_resource_start(dev, 2)) { /* B1 PCI V4 */
420 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
421 driver = &b1pciv4_driver;
425 param.membase = pci_resource_start(dev, 0);
426 param.port = pci_resource_start(dev, 2);
429 "%s: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
430 driver->name, param.port, param.irq, param.membase);
431 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
432 retval = b1pciv4_add_card(driver, ¶m);
434 retval = b1pci_add_card(driver, ¶m);
438 "%s: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
439 driver->name, param.port, param.irq, param.membase);
443 param.port = pci_resource_start(dev, 1);
446 "%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
447 driver->name, param.port, param.irq);
448 retval = b1pci_add_card(driver, ¶m);
451 "%s: no AVM-B1 at i/o %#x, irq %d detected\n",
452 driver->name, param.port, param.irq);
458 static int __init b1pci_init(void)
460 struct capi_driver *driver = &b1pci_driver;
461 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
462 struct capi_driver *driverv4 = &b1pciv4_driver;
464 struct pci_dev *dev = NULL;
469 if ((p = strchr(revision, ':')) != 0 && p[1]) {
470 strncpy(driver->revision, p + 2, sizeof(driver->revision));
471 driver->revision[sizeof(driver->revision)-1] = 0;
472 if ((p = strchr(driver->revision, '$')) != 0 && p > driver->revision)
475 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
476 if ((p = strchr(revision, ':')) != 0 && p[1]) {
477 strncpy(driverv4->revision, p + 2, sizeof(driverv4->revision));
478 driverv4->revision[sizeof(driverv4->revision)-1] = 0;
479 if ((p = strchr(driverv4->revision, '$')) != 0 && p > driverv4->revision)
484 printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
486 di = attach_capi_driver(driver);
488 printk(KERN_ERR "%s: failed to attach capi_driver\n",
494 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
495 printk(KERN_INFO "%s: revision %s\n", driverv4->name, driverv4->revision);
497 div4 = attach_capi_driver(driverv4);
499 detach_capi_driver(driver);
500 printk(KERN_ERR "%s: failed to attach capi_driver\n",
507 while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) {
508 if (add_card(dev) == 0)
512 printk(KERN_INFO "%s: %d B1-PCI card(s) detected\n",
513 driver->name, ncards);
517 printk(KERN_ERR "%s: NO B1-PCI card detected\n", driver->name);
518 detach_capi_driver(driver);
519 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
520 detach_capi_driver(driverv4);
526 static void __exit b1pci_exit(void)
528 detach_capi_driver(&b1pci_driver);
529 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
530 detach_capi_driver(&b1pciv4_driver);
534 module_init(b1pci_init);
535 module_exit(b1pci_exit);