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