2 * $Id: b1pcmcia.c,v 1.4 1999/08/22 20:26:26 calle Exp $
4 * Module for AVM B1/M1/M2 PCMCIA-card.
6 * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
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
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>
48 #include <linux/interrupt.h>
49 #include <linux/ioport.h>
51 #include <linux/capi.h>
52 #include <linux/b1pcmcia.h>
53 #include <linux/isdn_compat.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
)
75 card
= (avmcard
*) devptr
;
78 printk(KERN_WARNING
"b1_interrupt: wrong device\n");
81 if (card
->interrupt
) {
82 printk(KERN_ERR
"b1_interrupt: reentering interrupt hander (%s)\n", card
->name
);
88 b1_handle_interrupt(card
);
92 /* ------------------------------------------------------------- */
94 static void b1pcmcia_remove_ctr(struct capi_ctr
*ctrl
)
96 avmcard
*card
= (avmcard
*)(ctrl
->driverdata
);
97 unsigned int port
= card
->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);
112 /* ------------------------------------------------------------- */
114 static int b1pcmcia_add_card(struct capi_driver
*driver
,
117 enum avmcardtype cardtype
)
122 card
= (avmcard
*) kmalloc(sizeof(avmcard
), GFP_ATOMIC
);
125 printk(KERN_WARNING
"b1pcmcia: no memory.\n");
128 memset(card
, 0, sizeof(avmcard
));
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;
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",
145 b1_reset(card
->port
);
147 retval
= request_irq(card
->irq
, b1pcmcia_interrupt
, 0, card
->name
, card
);
149 printk(KERN_ERR
"b1pcmcia: unable to get IRQ %d.\n", card
->irq
);
154 card
->ctrl
= di
->attach_ctr(driver
, card
->name
, card
);
156 printk(KERN_ERR
"b1pcmcia: attach controller failed.\n");
157 free_irq(card
->irq
, card
);
163 return card
->ctrl
->cnr
;
166 /* ------------------------------------------------------------- */
168 static char *b1pcmcia_procinfo(struct capi_ctr
*ctrl
)
170 avmcard
*card
= (avmcard
*)(ctrl
->driverdata
);
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
= {
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
;
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
);
232 EXPORT_SYMBOL(b1pcmcia_addcard_b1
);
233 EXPORT_SYMBOL(b1pcmcia_addcard_m1
);
234 EXPORT_SYMBOL(b1pcmcia_addcard_m2
);
235 EXPORT_SYMBOL(b1pcmcia_delcard
);
237 /* ------------------------------------------------------------- */
240 #define b1pcmcia_init init_module
241 void cleanup_module(void);
244 int b1pcmcia_init(void)
246 struct capi_driver
*driver
= &b1pcmcia_driver
;
249 if ((p
= strchr(revision
, ':'))) {
250 strncpy(driver
->revision
, p
+ 1, sizeof(driver
->revision
));
251 p
= strchr(driver
->revision
, '$');
255 printk(KERN_INFO
"%s: revision %s\n", driver
->name
, driver
->revision
);
257 di
= attach_capi_driver(driver
);
260 printk(KERN_ERR
"%s: failed to attach capi_driver\n",
268 void cleanup_module(void)
270 detach_capi_driver(&b1pcmcia_driver
);