* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / isdn / avmb1 / b1pcmcia.c
blobd6acda9d9e08e1b546c714b6036de2a98cd4621d
1 /*
2 * $Id: b1pcmcia.c,v 1.4 1999/08/22 20:26:26 calle Exp $
3 *
4 * Module for AVM B1/M1/M2 PCMCIA-card.
5 *
6 * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
7 *
8 * $Log: b1pcmcia.c,v $
9 * Revision 1.4 1999/08/22 20:26:26 calle
10 * backported changes from kernel 2.3.14:
11 * - several #include "config.h" gone, others come.
12 * - "struct device" changed to "struct net_device" in 2.3.14, added a
13 * define in isdn_compat.h for older kernel versions.
15 * Revision 1.3 1999/07/09 15:05:41 keil
16 * compat.h is now isdn_compat.h
18 * Revision 1.2 1999/07/05 15:09:51 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.1 1999/07/01 15:26:30 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/module.h>
44 #include <linux/kernel.h>
45 #include <linux/skbuff.h>
46 #include <linux/delay.h>
47 #include <linux/mm.h>
48 #include <linux/interrupt.h>
49 #include <linux/ioport.h>
50 #include <asm/io.h>
51 #include <linux/capi.h>
52 #include <linux/b1pcmcia.h>
53 #include <linux/isdn_compat.h>
54 #include "capicmd.h"
55 #include "capiutil.h"
56 #include "capilli.h"
57 #include "avmcard.h"
59 static char *revision = "$Revision: 1.4 $";
61 /* ------------------------------------------------------------- */
63 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
65 /* ------------------------------------------------------------- */
67 static struct capi_driver_interface *di;
69 /* ------------------------------------------------------------- */
71 static void b1pcmcia_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
73 avmcard *card;
75 card = (avmcard *) devptr;
77 if (!card) {
78 printk(KERN_WARNING "b1_interrupt: wrong device\n");
79 return;
81 if (card->interrupt) {
82 printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name);
83 return;
86 card->interrupt = 1;
88 b1_handle_interrupt(card);
90 card->interrupt = 0;
92 /* ------------------------------------------------------------- */
94 static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
96 avmcard *card = (avmcard *)(ctrl->driverdata);
97 unsigned int port = card->port;
99 b1_reset(port);
100 b1_reset(port);
102 di->detach_ctr(ctrl);
103 free_irq(card->irq, card);
104 /* io addrsses managent by CardServices
105 * release_region(card->port, AVMB1_PORTLEN);
107 kfree(card);
109 MOD_DEC_USE_COUNT;
112 /* ------------------------------------------------------------- */
114 static int b1pcmcia_add_card(struct capi_driver *driver,
115 unsigned int port,
116 unsigned irq,
117 enum avmcardtype cardtype)
119 avmcard *card;
120 int retval;
122 card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
124 if (!card) {
125 printk(KERN_WARNING "b1pcmcia: no memory.\n");
126 return -ENOMEM;
128 memset(card, 0, sizeof(avmcard));
129 switch (cardtype) {
130 case avm_m1: sprintf(card->name, "m1-%x", port); break;
131 case avm_m2: sprintf(card->name, "m2-%x", port); break;
132 default: sprintf(card->name, "b1pcmcia-%x", port); break;
134 card->port = port;
135 card->irq = irq;
136 card->cardtype = cardtype;
138 b1_reset(card->port);
139 if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
140 printk(KERN_NOTICE "b1pcmcia: NO card at 0x%x (%d)\n",
141 card->port, retval);
142 kfree(card);
143 return -EIO;
145 b1_reset(card->port);
147 retval = request_irq(card->irq, b1pcmcia_interrupt, 0, card->name, card);
148 if (retval) {
149 printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", card->irq);
150 kfree(card);
151 return -EBUSY;
154 card->ctrl = di->attach_ctr(driver, card->name, card);
155 if (!card->ctrl) {
156 printk(KERN_ERR "b1pcmcia: attach controller failed.\n");
157 free_irq(card->irq, card);
158 kfree(card);
159 return -EBUSY;
162 MOD_INC_USE_COUNT;
163 return card->ctrl->cnr;
166 /* ------------------------------------------------------------- */
168 static char *b1pcmcia_procinfo(struct capi_ctr *ctrl)
170 avmcard *card = (avmcard *)(ctrl->driverdata);
171 if (!card)
172 return "";
173 sprintf(card->infobuf, "%s %s 0x%x %d",
174 card->cardname[0] ? card->cardname : "-",
175 card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-",
176 card->port, card->irq
178 return card->infobuf;
181 /* ------------------------------------------------------------- */
183 static struct capi_driver b1pcmcia_driver = {
184 "b1pcmcia",
185 "0.0",
186 b1_load_firmware,
187 b1_reset_ctr,
188 b1pcmcia_remove_ctr,
189 b1_register_appl,
190 b1_release_appl,
191 b1_send_message,
193 b1pcmcia_procinfo,
194 b1ctl_read_proc,
195 0, /* use standard driver_read_proc */
200 /* ------------------------------------------------------------- */
202 int b1pcmcia_addcard_b1(unsigned int port, unsigned irq)
204 return b1pcmcia_add_card(&b1pcmcia_driver, port, irq, avm_b1pcmcia);
207 int b1pcmcia_addcard_m1(unsigned int port, unsigned irq)
209 return b1pcmcia_add_card(&b1pcmcia_driver, port, irq, avm_m1);
212 int b1pcmcia_addcard_m2(unsigned int port, unsigned irq)
214 return b1pcmcia_add_card(&b1pcmcia_driver, port, irq, avm_m2);
217 int b1pcmcia_delcard(unsigned int port, unsigned irq)
219 struct capi_ctr *ctrl;
220 avmcard *card;
222 for (ctrl = b1pcmcia_driver.controller; ctrl; ctrl = ctrl->next) {
223 card = (avmcard *)(ctrl->driverdata);
224 if (card->port == port && card->irq == irq) {
225 b1pcmcia_remove_ctr(ctrl);
226 return 0;
229 return -ESRCH;
232 EXPORT_SYMBOL(b1pcmcia_addcard_b1);
233 EXPORT_SYMBOL(b1pcmcia_addcard_m1);
234 EXPORT_SYMBOL(b1pcmcia_addcard_m2);
235 EXPORT_SYMBOL(b1pcmcia_delcard);
237 /* ------------------------------------------------------------- */
239 #ifdef MODULE
240 #define b1pcmcia_init init_module
241 void cleanup_module(void);
242 #endif
244 int b1pcmcia_init(void)
246 struct capi_driver *driver = &b1pcmcia_driver;
247 char *p;
249 if ((p = strchr(revision, ':'))) {
250 strncpy(driver->revision, p + 1, sizeof(driver->revision));
251 p = strchr(driver->revision, '$');
252 *p = 0;
255 printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision);
257 di = attach_capi_driver(driver);
259 if (!di) {
260 printk(KERN_ERR "%s: failed to attach capi_driver\n",
261 driver->name);
262 return -EIO;
264 return 0;
267 #ifdef MODULE
268 void cleanup_module(void)
270 detach_capi_driver(&b1pcmcia_driver);
272 #endif