Merge with Linux 2.4.0-test3-pre2.
[linux-2.6/linux-mips.git] / drivers / isdn / avmb1 / t1pci.c
blob07625bd0da9443dec28e97a3849685afdecc3668
1 /*
2 * $Id: t1pci.c,v 1.9 2000/05/19 15:43:22 calle Exp $
3 *
4 * Module for AVM T1 PCI-card.
5 *
6 * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
7 *
8 * $Log: t1pci.c,v $
9 * Revision 1.9 2000/05/19 15:43:22 calle
10 * added calls to pci_device_start().
12 * Revision 1.8 2000/05/06 00:52:36 kai
13 * merged changes from kernel tree
14 * fixed timer and net_device->name breakage
16 * Revision 1.7 2000/04/07 15:26:55 calle
17 * better error message if cabel not connected or T1 has no power.
19 * Revision 1.6 2000/04/03 13:29:25 calle
20 * make Tim Waugh happy (module unload races in 2.3.99-pre3).
21 * no real problem there, but now it is much cleaner ...
23 * Revision 1.5 2000/02/02 18:36:04 calle
24 * - Modules are now locked while init_module is running
25 * - fixed problem with memory mapping if address is not aligned
27 * Revision 1.4 2000/01/25 14:33:38 calle
28 * - Added Support AVM B1 PCI V4.0 (tested with prototype)
29 * - splitted up t1pci.c into b1dma.c for common function with b1pciv4
30 * - support for revision register
32 * Revision 1.3 1999/11/13 21:27:16 keil
33 * remove KERNELVERSION
35 * Revision 1.2 1999/11/05 16:38:02 calle
36 * Cleanups before kernel 2.4:
37 * - Changed all messages to use card->name or driver->name instead of
38 * constant string.
39 * - Moved some data from struct avmcard into new struct avmctrl_info.
40 * Changed all lowlevel capi driver to match the new structur.
42 * Revision 1.1 1999/10/26 15:31:42 calle
43 * Added driver for T1-PCI card.
48 #include <linux/config.h>
49 #include <linux/module.h>
50 #include <linux/kernel.h>
51 #include <linux/skbuff.h>
52 #include <linux/delay.h>
53 #include <linux/mm.h>
54 #include <linux/interrupt.h>
55 #include <linux/ioport.h>
56 #include <linux/pci.h>
57 #include <linux/capi.h>
58 #include <asm/io.h>
59 #include <linux/isdn.h>
60 #include "capicmd.h"
61 #include "capiutil.h"
62 #include "capilli.h"
63 #include "avmcard.h"
65 static char *revision = "$Revision: 1.9 $";
67 #undef CONFIG_T1PCI_DEBUG
68 #undef CONFIG_T1PCI_POLLDEBUG
70 /* ------------------------------------------------------------- */
72 #ifndef PCI_VENDOR_ID_AVM
73 #define PCI_VENDOR_ID_AVM 0x1244
74 #endif
76 #ifndef PCI_DEVICE_ID_AVM_T1
77 #define PCI_DEVICE_ID_AVM_T1 0x1200
78 #endif
80 /* ------------------------------------------------------------- */
82 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
84 /* ------------------------------------------------------------- */
86 static struct capi_driver_interface *di;
88 /* ------------------------------------------------------------- */
90 static void t1pci_remove_ctr(struct capi_ctr *ctrl)
92 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
93 avmcard *card = cinfo->card;
95 b1dma_reset(card);
97 di->detach_ctr(ctrl);
98 free_irq(card->irq, card);
99 iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
100 release_region(card->port, AVMB1_PORTLEN);
101 ctrl->driverdata = 0;
102 kfree(card->ctrlinfo);
103 kfree(card->dma);
104 kfree(card);
106 MOD_DEC_USE_COUNT;
109 /* ------------------------------------------------------------- */
111 static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
113 unsigned long base, page_offset;
114 avmcard *card;
115 avmctrl_info *cinfo;
116 int retval;
118 MOD_INC_USE_COUNT;
120 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
122 if (!card) {
123 printk(KERN_WARNING "%s: no memory.\n", driver->name);
124 MOD_DEC_USE_COUNT;
125 return -ENOMEM;
127 memset(card, 0, sizeof(avmcard));
128 card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC);
129 if (!card->dma) {
130 printk(KERN_WARNING "%s: no memory.\n", driver->name);
131 kfree(card);
132 MOD_DEC_USE_COUNT;
133 return -ENOMEM;
135 memset(card->dma, 0, sizeof(avmcard_dmainfo));
136 cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
137 if (!cinfo) {
138 printk(KERN_WARNING "%s: no memory.\n", driver->name);
139 kfree(card->dma);
140 kfree(card);
141 MOD_DEC_USE_COUNT;
142 return -ENOMEM;
144 memset(cinfo, 0, sizeof(avmctrl_info));
145 card->ctrlinfo = cinfo;
146 cinfo->card = card;
147 sprintf(card->name, "t1pci-%x", p->port);
148 card->port = p->port;
149 card->irq = p->irq;
150 card->membase = p->membase;
151 card->cardtype = avm_t1pci;
153 if (check_region(card->port, AVMB1_PORTLEN)) {
154 printk(KERN_WARNING
155 "%s: ports 0x%03x-0x%03x in use.\n",
156 driver->name, card->port, card->port + AVMB1_PORTLEN);
157 kfree(card->ctrlinfo);
158 kfree(card->dma);
159 kfree(card);
160 MOD_DEC_USE_COUNT;
161 return -EBUSY;
164 base = card->membase & PAGE_MASK;
165 page_offset = card->membase - base;
166 card->mbase = ioremap_nocache(base, page_offset + 64);
167 if (card->mbase) {
168 card->mbase += page_offset;
169 } else {
170 printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
171 driver->name, card->membase);
172 kfree(card->ctrlinfo);
173 kfree(card->dma);
174 kfree(card);
175 MOD_DEC_USE_COUNT;
176 return -EIO;
179 b1dma_reset(card);
181 if ((retval = t1pci_detect(card)) != 0) {
182 if (retval < 6)
183 printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
184 driver->name, card->port, retval);
185 else
186 printk(KERN_NOTICE "%s: card at 0x%x, but cabel not connected or T1 has no power (%d)\n",
187 driver->name, card->port, retval);
188 iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
189 kfree(card->ctrlinfo);
190 kfree(card->dma);
191 kfree(card);
192 MOD_DEC_USE_COUNT;
193 return -EIO;
195 b1dma_reset(card);
197 request_region(p->port, AVMB1_PORTLEN, card->name);
199 retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
200 if (retval) {
201 printk(KERN_ERR "%s: unable to get IRQ %d.\n",
202 driver->name, card->irq);
203 iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
204 release_region(card->port, AVMB1_PORTLEN);
205 kfree(card->ctrlinfo);
206 kfree(card->dma);
207 kfree(card);
208 MOD_DEC_USE_COUNT;
209 return -EBUSY;
212 cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
213 if (!cinfo->capi_ctrl) {
214 printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
215 iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
216 free_irq(card->irq, card);
217 release_region(card->port, AVMB1_PORTLEN);
218 kfree(card->ctrlinfo);
219 kfree(card->dma);
220 kfree(card);
221 MOD_DEC_USE_COUNT;
222 return -EBUSY;
224 card->cardnr = cinfo->capi_ctrl->cnr;
226 skb_queue_head_init(&card->dma->send_queue);
228 printk(KERN_INFO
229 "%s: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n",
230 driver->name, card->port, card->irq, card->membase);
232 return 0;
235 /* ------------------------------------------------------------- */
237 static char *t1pci_procinfo(struct capi_ctr *ctrl)
239 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
241 if (!cinfo)
242 return "";
243 sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
244 cinfo->cardname[0] ? cinfo->cardname : "-",
245 cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
246 cinfo->card ? cinfo->card->port : 0x0,
247 cinfo->card ? cinfo->card->irq : 0,
248 cinfo->card ? cinfo->card->membase : 0
250 return cinfo->infobuf;
253 /* ------------------------------------------------------------- */
255 static struct capi_driver t1pci_driver = {
256 "t1pci",
257 "0.0",
258 b1dma_load_firmware,
259 b1dma_reset_ctr,
260 t1pci_remove_ctr,
261 b1dma_register_appl,
262 b1dma_release_appl,
263 b1dma_send_message,
265 t1pci_procinfo,
266 b1dmactl_read_proc,
267 0, /* use standard driver_read_proc */
269 0, /* no add_card function */
272 #ifdef MODULE
273 #define t1pci_init init_module
274 void cleanup_module(void);
275 #endif
277 static int ncards = 0;
279 int t1pci_init(void)
281 struct capi_driver *driver = &t1pci_driver;
282 struct pci_dev *dev = NULL;
283 char *p;
284 int retval;
286 MOD_INC_USE_COUNT;
288 if ((p = strchr(revision, ':'))) {
289 strncpy(driver->revision, p + 1, sizeof(driver->revision));
290 p = strchr(driver->revision, '$');
291 *p = 0;
294 printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
296 di = attach_capi_driver(driver);
298 if (!di) {
299 printk(KERN_ERR "%s: failed to attach capi_driver\n",
300 driver->name);
301 MOD_DEC_USE_COUNT;
302 return -EIO;
305 #ifdef CONFIG_PCI
306 if (!pci_present()) {
307 printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
308 detach_capi_driver(driver);
309 MOD_DEC_USE_COUNT;
310 return -EIO;
313 while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) {
314 struct capicardparams param;
316 param.port = pci_resource_start(dev, 1);
317 param.irq = dev->irq;
318 param.membase = pci_resource_start(dev, 0);
320 retval = pci_enable_device (dev);
321 if (retval != 0) {
322 printk(KERN_ERR
323 "%s: failed to enable AVM-T1-PCI at i/o %#x, irq %d, mem %#x err=%d\n",
324 driver->name, param.port, param.irq, param.membase, retval);
325 #ifdef MODULE
326 cleanup_module();
327 #endif
328 MOD_DEC_USE_COUNT;
329 return -EIO;
332 printk(KERN_INFO
333 "%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
334 driver->name, param.port, param.irq, param.membase);
335 retval = t1pci_add_card(driver, &param);
336 if (retval != 0) {
337 printk(KERN_ERR
338 "%s: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n",
339 driver->name, param.port, param.irq, param.membase);
340 #ifdef MODULE
341 cleanup_module();
342 #endif
343 MOD_DEC_USE_COUNT;
344 return retval;
346 ncards++;
348 if (ncards) {
349 printk(KERN_INFO "%s: %d T1-PCI card(s) detected\n",
350 driver->name, ncards);
351 MOD_DEC_USE_COUNT;
352 return 0;
354 printk(KERN_ERR "%s: NO T1-PCI card detected\n", driver->name);
355 MOD_DEC_USE_COUNT;
356 return -ESRCH;
357 #else
358 printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name);
359 MOD_DEC_USE_COUNT;
360 return -EIO;
361 #endif
364 #ifdef MODULE
365 void cleanup_module(void)
367 detach_capi_driver(&t1pci_driver);
369 #endif