File: /usr/src/linux/drivers/isdn/avmb1/t1pci.c

1     /*
2      * $Id: t1pci.c,v 1.13.6.5 2001/05/17 20:41:51 kai Exp $
3      * 
4      * Module for AVM T1 PCI-card.
5      * 
6      * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
7      * 
8      */
9     
10     #include <linux/config.h>
11     #include <linux/module.h>
12     #include <linux/kernel.h>
13     #include <linux/skbuff.h>
14     #include <linux/delay.h>
15     #include <linux/mm.h>
16     #include <linux/interrupt.h>
17     #include <linux/ioport.h>
18     #include <linux/pci.h>
19     #include <linux/capi.h>
20     #include <linux/init.h>
21     #include <asm/io.h>
22     #include "capicmd.h"
23     #include "capiutil.h"
24     #include "capilli.h"
25     #include "avmcard.h"
26     
27     static char *revision = "$Revision: 1.13.6.5 $";
28     
29     #undef CONFIG_T1PCI_DEBUG
30     #undef CONFIG_T1PCI_POLLDEBUG
31     
32     /* ------------------------------------------------------------- */
33     
34     static struct pci_device_id t1pci_pci_tbl[] __initdata = {
35     	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, PCI_ANY_ID, PCI_ANY_ID },
36     	{ }				/* Terminating entry */
37     };
38     
39     MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl);
40     MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
41     
42     /* ------------------------------------------------------------- */
43     
44     static struct capi_driver_interface *di;
45     
46     /* ------------------------------------------------------------- */
47     
48     static void t1pci_remove_ctr(struct capi_ctr *ctrl)
49     {
50     	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
51     	avmcard *card = cinfo->card;
52     
53      	b1dma_reset(card);
54     
55     	di->detach_ctr(ctrl);
56     	free_irq(card->irq, card);
57     	iounmap(card->mbase);
58     	release_region(card->port, AVMB1_PORTLEN);
59     	ctrl->driverdata = 0;
60     	kfree(card->ctrlinfo);
61     	kfree(card->dma);
62     	kfree(card);
63     
64     	MOD_DEC_USE_COUNT;
65     }
66     
67     /* ------------------------------------------------------------- */
68     
69     static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
70     {
71     	avmcard *card;
72     	avmctrl_info *cinfo;
73     	int retval;
74     
75     	MOD_INC_USE_COUNT;
76     
77     	card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
78     
79     	if (!card) {
80     		printk(KERN_WARNING "%s: no memory.\n", driver->name);
81     	        MOD_DEC_USE_COUNT;
82     		return -ENOMEM;
83     	}
84     	memset(card, 0, sizeof(avmcard));
85     	card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC);
86     	if (!card->dma) {
87     		printk(KERN_WARNING "%s: no memory.\n", driver->name);
88     		kfree(card);
89     	        MOD_DEC_USE_COUNT;
90     		return -ENOMEM;
91     	}
92     	memset(card->dma, 0, sizeof(avmcard_dmainfo));
93             cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
94     	if (!cinfo) {
95     		printk(KERN_WARNING "%s: no memory.\n", driver->name);
96     		kfree(card->dma);
97     		kfree(card);
98     	        MOD_DEC_USE_COUNT;
99     		return -ENOMEM;
100     	}
101     	memset(cinfo, 0, sizeof(avmctrl_info));
102     	card->ctrlinfo = cinfo;
103     	cinfo->card = card;
104     	sprintf(card->name, "t1pci-%x", p->port);
105     	card->port = p->port;
106     	card->irq = p->irq;
107     	card->membase = p->membase;
108     	card->cardtype = avm_t1pci;
109     
110     	if (check_region(card->port, AVMB1_PORTLEN)) {
111     		printk(KERN_WARNING
112     		       "%s: ports 0x%03x-0x%03x in use.\n",
113     		       driver->name, card->port, card->port + AVMB1_PORTLEN);
114     	        kfree(card->ctrlinfo);
115     		kfree(card->dma);
116     		kfree(card);
117     	        MOD_DEC_USE_COUNT;
118     		return -EBUSY;
119     	}
120     
121     	card->mbase = ioremap_nocache(card->membase, 64);
122     	if (!card->mbase) {
123     		printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
124     					driver->name, card->membase);
125     	        kfree(card->ctrlinfo);
126     		kfree(card->dma);
127     		kfree(card);
128     	        MOD_DEC_USE_COUNT;
129     		return -EIO;
130     	}
131     
132     	b1dma_reset(card);
133     
134     	if ((retval = t1pci_detect(card)) != 0) {
135     		if (retval < 6)
136     			printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
137     					driver->name, card->port, retval);
138     		else
139     			printk(KERN_NOTICE "%s: card at 0x%x, but cabel not connected or T1 has no power (%d)\n",
140     					driver->name, card->port, retval);
141                     iounmap(card->mbase);
142     	        kfree(card->ctrlinfo);
143     		kfree(card->dma);
144     		kfree(card);
145     	        MOD_DEC_USE_COUNT;
146     		return -EIO;
147     	}
148     	b1dma_reset(card);
149     
150     	request_region(p->port, AVMB1_PORTLEN, card->name);
151     
152     	retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
153     	if (retval) {
154     		printk(KERN_ERR "%s: unable to get IRQ %d.\n",
155     				driver->name, card->irq);
156                     iounmap(card->mbase);
157     		release_region(card->port, AVMB1_PORTLEN);
158     	        kfree(card->ctrlinfo);
159     		kfree(card->dma);
160     		kfree(card);
161     	        MOD_DEC_USE_COUNT;
162     		return -EBUSY;
163     	}
164     
165     	cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
166     	if (!cinfo->capi_ctrl) {
167     		printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
168                     iounmap(card->mbase);
169     		free_irq(card->irq, card);
170     		release_region(card->port, AVMB1_PORTLEN);
171     	        kfree(card->ctrlinfo);
172     		kfree(card->dma);
173     		kfree(card);
174     	        MOD_DEC_USE_COUNT;
175     		return -EBUSY;
176     	}
177     	card->cardnr = cinfo->capi_ctrl->cnr;
178     
179     	skb_queue_head_init(&card->dma->send_queue);
180     
181     	printk(KERN_INFO
182     		"%s: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n",
183     		driver->name, card->port, card->irq, card->membase);
184     
185     	return 0;
186     }
187     
188     /* ------------------------------------------------------------- */
189     
190     static char *t1pci_procinfo(struct capi_ctr *ctrl)
191     {
192     	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
193     
194     	if (!cinfo)
195     		return "";
196     	sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
197     		cinfo->cardname[0] ? cinfo->cardname : "-",
198     		cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
199     		cinfo->card ? cinfo->card->port : 0x0,
200     		cinfo->card ? cinfo->card->irq : 0,
201     		cinfo->card ? cinfo->card->membase : 0
202     		);
203     	return cinfo->infobuf;
204     }
205     
206     /* ------------------------------------------------------------- */
207     
208     static struct capi_driver t1pci_driver = {
209         name: "t1pci",
210         revision: "0.0",
211         load_firmware: b1dma_load_firmware,
212         reset_ctr: b1dma_reset_ctr,
213         remove_ctr: t1pci_remove_ctr,
214         register_appl: b1dma_register_appl,
215         release_appl: b1dma_release_appl,
216         send_message: b1dma_send_message,
217     
218         procinfo: t1pci_procinfo,
219         ctr_read_proc: b1dmactl_read_proc,
220         driver_read_proc: 0,	/* use standard driver_read_proc */
221     
222         add_card: 0, /* no add_card function */
223     };
224     
225     static int ncards = 0;
226     
227     static int __init t1pci_init(void)
228     {
229     	struct capi_driver *driver = &t1pci_driver;
230     	struct pci_dev *dev = NULL;
231     	char *p;
232     	int retval;
233     
234     	MOD_INC_USE_COUNT;
235     
236     	if ((p = strchr(revision, ':')) != 0 && p[1]) {
237     		strncpy(driver->revision, p + 2, sizeof(driver->revision));
238     		driver->revision[sizeof(driver->revision)-1] = 0;
239     		if ((p = strchr(driver->revision, '$')) != 0 && p > driver->revision)
240     			*(p-1) = 0;
241     	}
242     
243     	printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
244     
245             di = attach_capi_driver(driver);
246     	if (!di) {
247     		printk(KERN_ERR "%s: failed to attach capi_driver\n",
248     				driver->name);
249     		MOD_DEC_USE_COUNT;
250     		return -EIO;
251     	}
252     
253     	while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) {
254     		struct capicardparams param;
255     
256     		if (pci_enable_device(dev) < 0) {
257     		        printk(KERN_ERR	"%s: failed to enable AVM-T1-PCI\n",
258     			       driver->name);
259     			continue;
260     		}
261     		pci_set_master(dev);
262     
263     		param.port = pci_resource_start(dev, 1);
264      		param.irq = dev->irq;
265     		param.membase = pci_resource_start(dev, 0);
266     
267     		printk(KERN_INFO
268     			"%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
269     			driver->name, param.port, param.irq, param.membase);
270     		retval = t1pci_add_card(driver, &param);
271     		if (retval != 0) {
272     		        printk(KERN_ERR
273     			"%s: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n",
274     			driver->name, param.port, param.irq, param.membase);
275     			continue;
276     		}
277     		ncards++;
278     	}
279     	if (ncards) {
280     		printk(KERN_INFO "%s: %d T1-PCI card(s) detected\n",
281     				driver->name, ncards);
282     		MOD_DEC_USE_COUNT;
283     		return 0;
284     	}
285     	printk(KERN_ERR "%s: NO T1-PCI card detected\n", driver->name);
286     	detach_capi_driver(&t1pci_driver);
287     	MOD_DEC_USE_COUNT;
288     	return -ENODEV;
289     }
290     
291     static void __exit t1pci_exit(void)
292     {
293         detach_capi_driver(&t1pci_driver);
294     }
295     
296     module_init(t1pci_init);
297     module_exit(t1pci_exit);
298