* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / isdn / avmb1 / b1pci.c
blob8c0006a78bf59f7eb23750cc9db657f2871487d9
1 /*
2 * $Id: b1pci.c,v 1.16 1999/08/11 21:01:07 keil Exp $
3 *
4 * Module for AVM B1 PCI-card.
5 *
6 * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
7 *
8 * $Log: b1pci.c,v $
9 * Revision 1.16 1999/08/11 21:01:07 keil
10 * new PCI codefix
12 * Revision 1.15 1999/08/10 16:02:27 calle
13 * struct pci_dev changed in 2.3.13. Made the necessary changes.
15 * Revision 1.14 1999/07/09 15:05:41 keil
16 * compat.h is now isdn_compat.h
18 * Revision 1.13 1999/07/05 15:09:50 calle
19 * - renamed "appl_release" to "appl_released".
20 * - version und profile data now cleared on controller reset
21 * - extended /proc interface, to allow driver and controller specific
22 * informations to include by driver hackers.
24 * Revision 1.12 1999/07/01 15:26:29 calle
25 * complete new version (I love it):
26 * + new hardware independed "capi_driver" interface that will make it easy to:
27 * - support other controllers with CAPI-2.0 (i.e. USB Controller)
28 * - write a CAPI-2.0 for the passive cards
29 * - support serial link CAPI-2.0 boxes.
30 * + wrote "capi_driver" for all supported cards.
31 * + "capi_driver" (supported cards) now have to be configured with
32 * make menuconfig, in the past all supported cards where included
33 * at once.
34 * + new and better informations in /proc/capi/
35 * + new ioctl to switch trace of capi messages per controller
36 * using "avmcapictrl trace [contr] on|off|...."
37 * + complete testcircle with all supported cards and also the
38 * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
43 #include <linux/config.h>
44 #include <linux/module.h>
45 #include <linux/kernel.h>
46 #include <linux/skbuff.h>
47 #include <linux/delay.h>
48 #include <linux/mm.h>
49 #include <linux/interrupt.h>
50 #include <linux/ioport.h>
51 #include <linux/pci.h>
52 #include <linux/capi.h>
53 #include <asm/io.h>
54 #include <linux/isdn_compat.h>
55 #include "capicmd.h"
56 #include "capiutil.h"
57 #include "capilli.h"
58 #include "avmcard.h"
60 static char *revision = "$Revision: 1.16 $";
62 /* ------------------------------------------------------------- */
64 #ifndef PCI_VENDOR_ID_AVM
65 #define PCI_VENDOR_ID_AVM 0x1244
66 #endif
68 #ifndef PCI_DEVICE_ID_AVM_B1
69 #define PCI_DEVICE_ID_AVM_B1 0x700
70 #endif
72 /* ------------------------------------------------------------- */
74 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
76 /* ------------------------------------------------------------- */
78 static struct capi_driver_interface *di;
80 /* ------------------------------------------------------------- */
82 static void b1pci_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
84 avmcard *card;
86 card = (avmcard *) devptr;
88 if (!card) {
89 printk(KERN_WARNING "b1_interrupt: wrong device\n");
90 return;
92 if (card->interrupt) {
93 printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name);
94 return;
97 card->interrupt = 1;
99 b1_handle_interrupt(card);
101 card->interrupt = 0;
103 /* ------------------------------------------------------------- */
105 static void b1pci_remove_ctr(struct capi_ctr *ctrl)
107 avmcard *card = (avmcard *)(ctrl->driverdata);
108 unsigned int port = card->port;
110 b1_reset(port);
111 b1_reset(port);
113 di->detach_ctr(ctrl);
114 free_irq(card->irq, card);
115 release_region(card->port, AVMB1_PORTLEN);
116 ctrl->driverdata = 0;
117 kfree(card);
119 MOD_DEC_USE_COUNT;
122 /* ------------------------------------------------------------- */
124 static char *b1pci_procinfo(struct capi_ctr *ctrl)
126 avmcard *card = (avmcard *)(ctrl->driverdata);
127 if (!card)
128 return "";
129 sprintf(card->infobuf, "%s %s 0x%x %d",
130 card->cardname[0] ? card->cardname : "-",
131 card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-",
132 card->port, card->irq
134 return card->infobuf;
137 /* ------------------------------------------------------------- */
139 static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
141 avmcard *card;
142 int retval;
144 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
146 if (!card) {
147 printk(KERN_WARNING "b1pci: no memory.\n");
148 return -ENOMEM;
150 memset(card, 0, sizeof(avmcard));
151 sprintf(card->name, "b1pci-%x", p->port);
152 card->port = p->port;
153 card->irq = p->irq;
154 card->cardtype = avm_b1pci;
156 if (check_region(card->port, AVMB1_PORTLEN)) {
157 printk(KERN_WARNING
158 "b1pci: ports 0x%03x-0x%03x in use.\n",
159 card->port, card->port + AVMB1_PORTLEN);
160 kfree(card);
161 return -EBUSY;
163 b1_reset(card->port);
164 if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
165 printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n",
166 card->port, retval);
167 kfree(card);
168 return -EIO;
170 b1_reset(card->port);
172 request_region(p->port, AVMB1_PORTLEN, card->name);
174 retval = request_irq(card->irq, b1pci_interrupt, 0, card->name, card);
175 if (retval) {
176 printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq);
177 release_region(card->port, AVMB1_PORTLEN);
178 kfree(card);
179 return -EBUSY;
182 card->ctrl = di->attach_ctr(driver, card->name, card);
183 if (!card->ctrl) {
184 printk(KERN_ERR "b1pci: attach controller failed.\n");
185 free_irq(card->irq, card);
186 release_region(card->port, AVMB1_PORTLEN);
187 kfree(card);
188 return -EBUSY;
191 MOD_INC_USE_COUNT;
193 return 0;
196 /* ------------------------------------------------------------- */
198 static struct capi_driver b1pci_driver = {
199 "b1pci",
200 "0.0",
201 b1_load_firmware,
202 b1_reset_ctr,
203 b1pci_remove_ctr,
204 b1_register_appl,
205 b1_release_appl,
206 b1_send_message,
208 b1pci_procinfo,
209 b1ctl_read_proc,
210 0, /* use standard driver_read_proc */
212 0, /* no add_card function */
215 #ifdef MODULE
216 #define b1pci_init init_module
217 void cleanup_module(void);
218 #endif
220 static int ncards = 0;
222 int b1pci_init(void)
224 struct capi_driver *driver = &b1pci_driver;
225 struct pci_dev *dev = NULL;
226 char *p;
227 int retval;
229 if ((p = strchr(revision, ':'))) {
230 strncpy(driver->revision, p + 1, sizeof(driver->revision));
231 p = strchr(driver->revision, '$');
232 *p = 0;
235 printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
237 di = attach_capi_driver(driver);
239 if (!di) {
240 printk(KERN_ERR "%s: failed to attach capi_driver\n",
241 driver->name);
242 return -EIO;
245 #ifdef CONFIG_PCI
246 if (!pci_present()) {
247 printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
248 detach_capi_driver(driver);
249 return -EIO;
252 while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) {
253 struct capicardparams param;
255 param.port = get_pcibase(dev, 1) & PCI_BASE_ADDRESS_IO_MASK;
256 param.irq = dev->irq;
257 printk(KERN_INFO
258 "%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
259 driver->name, param.port, param.irq);
260 retval = b1pci_add_card(driver, &param);
261 if (retval != 0) {
262 printk(KERN_ERR
263 "%s: no AVM-B1 at i/o %#x, irq %d detected\n",
264 driver->name, param.port, param.irq);
265 #ifdef MODULE
266 cleanup_module();
267 #endif
268 return retval;
270 ncards++;
272 if (ncards) {
273 printk(KERN_INFO "%s: %d B1-PCI card(s) detected\n",
274 driver->name, ncards);
275 return 0;
277 printk(KERN_ERR "%s: NO B1-PCI card detected\n", driver->name);
278 return -ESRCH;
279 #else
280 printk(KERN_ERR "b1pci: kernel not compiled with PCI.\n");
281 return -EIO;
282 #endif
285 #ifdef MODULE
286 void cleanup_module(void)
288 detach_capi_driver(&b1pci_driver);
290 #endif