- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / isdn / avmb1 / kcapi.c
blob6f7bd4fd0609f13e4d9d5b05d823c7e36e42505c
1 /*
2 * $Id: kcapi.c,v 1.21.6.1 2000/12/10 23:39:19 kai Exp $
3 *
4 * Kernel CAPI 2.0 Module
5 *
6 * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
7 *
8 * $Log: kcapi.c,v $
9 * Revision 1.21.6.1 2000/12/10 23:39:19 kai
10 * in 2.4 we don't have tq_scheduler anymore.
11 * also add one supported card to hfc_pci.c
12 * (from main branch)
14 * Revision 1.21 2000/11/23 20:45:14 kai
15 * fixed module_init/exit stuff
16 * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
18 * Revision 1.20 2000/11/19 17:01:53 kai
19 * compatibility cleanup - part 2
21 * Revision 1.19 2000/11/01 14:05:02 calle
22 * - use module_init/module_exit from linux/init.h.
23 * - all static struct variables are initialized with "membername:" now.
24 * - avm_cs.c, let it work with newer pcmcia-cs.
26 * Revision 1.18 2000/07/20 10:22:27 calle
27 * - Made procfs function cleaner and removed variable "begin".
29 * Revision 1.17 2000/04/21 13:00:56 calle
30 * Bugfix: driver_proc_info was also wrong.
32 * Revision 1.16 2000/04/21 12:38:42 calle
33 * Bugfix: error in proc_ functions, begin-off => off-begin
35 * Revision 1.15 2000/04/06 15:01:25 calle
36 * Bugfix: crash in capidrv.c when reseting a capi controller.
37 * - changed code order on remove of controller.
38 * - using tq_schedule for notifier in kcapi.c.
39 * - now using spin_lock_irqsave() and spin_unlock_irqrestore().
40 * strange: sometimes even MP hang on unload of isdn.o ...
42 * Revision 1.14 2000/04/03 13:29:25 calle
43 * make Tim Waugh happy (module unload races in 2.3.99-pre3).
44 * no real problem there, but now it is much cleaner ...
46 * Revision 1.13 2000/03/03 15:50:42 calle
47 * - kernel CAPI:
48 * - Changed parameter "param" in capi_signal from __u32 to void *.
49 * - rewrote notifier handling in kcapi.c
50 * - new notifier NCCI_UP and NCCI_DOWN
51 * - User CAPI:
52 * - /dev/capi20 is now a cloning device.
53 * - middleware extentions prepared.
54 * - capidrv.c
55 * - locking of list operations and module count updates.
57 * Revision 1.12 2000/01/28 16:45:39 calle
58 * new manufacturer command KCAPI_CMD_ADDCARD (generic addcard),
59 * will search named driver and call the add_card function if one exist.
61 * Revision 1.11 1999/11/23 13:29:29 calle
62 * Bugfix: incoming capi message were never traced.
64 * Revision 1.10 1999/10/26 15:30:32 calle
65 * Generate error message if user want to add card, but driver module is
66 * not loaded.
68 * Revision 1.9 1999/10/11 22:04:12 keil
69 * COMPAT_NEED_UACCESS (no include in isdn_compat.h)
71 * Revision 1.8 1999/09/10 17:24:18 calle
72 * Changes for proposed standard for CAPI2.0:
73 * - AK148 "Linux Exention"
75 * Revision 1.7 1999/09/04 06:20:05 keil
76 * Changes from kernel set_current_state()
78 * Revision 1.6 1999/07/20 06:41:49 calle
79 * Bugfix: After the redesign of the AVM B1 driver, the driver didn't even
80 * compile, if not selected as modules.
82 * Revision 1.5 1999/07/09 15:05:48 keil
83 * compat.h is now isdn_compat.h
85 * Revision 1.4 1999/07/08 14:15:17 calle
86 * Forgot to count down ncards in drivercb_detach_ctr.
88 * Revision 1.3 1999/07/06 07:42:02 calle
89 * - changes in /proc interface
90 * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
92 * Revision 1.2 1999/07/05 15:09:52 calle
93 * - renamed "appl_release" to "appl_released".
94 * - version und profile data now cleared on controller reset
95 * - extended /proc interface, to allow driver and controller specific
96 * informations to include by driver hackers.
98 * Revision 1.1 1999/07/01 15:26:42 calle
99 * complete new version (I love it):
100 * + new hardware independed "capi_driver" interface that will make it easy to:
101 * - support other controllers with CAPI-2.0 (i.e. USB Controller)
102 * - write a CAPI-2.0 for the passive cards
103 * - support serial link CAPI-2.0 boxes.
104 * + wrote "capi_driver" for all supported cards.
105 * + "capi_driver" (supported cards) now have to be configured with
106 * make menuconfig, in the past all supported cards where included
107 * at once.
108 * + new and better informations in /proc/capi/
109 * + new ioctl to switch trace of capi messages per controller
110 * using "avmcapictrl trace [contr] on|off|...."
111 * + complete testcircle with all supported cards and also the
112 * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
115 #define CONFIG_AVMB1_COMPAT
117 #include <linux/config.h>
118 #include <linux/module.h>
119 #include <linux/kernel.h>
120 #include <linux/mm.h>
121 #include <linux/interrupt.h>
122 #include <linux/ioport.h>
123 #include <asm/segment.h>
124 #include <linux/proc_fs.h>
125 #include <linux/skbuff.h>
126 #include <linux/tqueue.h>
127 #include <linux/capi.h>
128 #include <linux/kernelcapi.h>
129 #include <linux/locks.h>
130 #include <linux/init.h>
131 #include <asm/uaccess.h>
132 #include "capicmd.h"
133 #include "capiutil.h"
134 #include "capilli.h"
135 #ifdef CONFIG_AVMB1_COMPAT
136 #include <linux/b1lli.h>
137 #endif
139 static char *revision = "$Revision: 1.21.6.1 $";
141 /* ------------------------------------------------------------- */
143 #define CARD_FREE 0
144 #define CARD_DETECTED 1
145 #define CARD_LOADING 2
146 #define CARD_RUNNING 3
148 /* ------------------------------------------------------------- */
150 int showcapimsgs = 0;
152 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
153 MODULE_PARM(showcapimsgs, "0-4i");
155 /* ------------------------------------------------------------- */
157 struct msgidqueue {
158 struct msgidqueue *next;
159 __u16 msgid;
162 struct capi_ncci {
163 struct capi_ncci *next;
164 __u16 applid;
165 __u32 ncci;
166 __u32 winsize;
167 int nmsg;
168 struct msgidqueue *msgidqueue;
169 struct msgidqueue *msgidlast;
170 struct msgidqueue *msgidfree;
171 struct msgidqueue msgidpool[CAPI_MAXDATAWINDOW];
174 struct capi_appl {
175 __u16 applid;
176 capi_register_params rparam;
177 int releasing;
178 void *param;
179 void (*signal) (__u16 applid, void *param);
180 struct sk_buff_head recv_queue;
181 int nncci;
182 struct capi_ncci *nccilist;
184 unsigned long nrecvctlpkt;
185 unsigned long nrecvdatapkt;
186 unsigned long nsentctlpkt;
187 unsigned long nsentdatapkt;
190 struct capi_notifier {
191 struct capi_notifier *next;
192 unsigned int cmd;
193 __u32 controller;
194 __u16 applid;
195 __u32 ncci;
198 /* ------------------------------------------------------------- */
200 static struct capi_version driver_version = {2, 0, 1, 1<<4};
201 static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
202 static char capi_manufakturer[64] = "AVM Berlin";
204 #define APPL(a) (&applications[(a)-1])
205 #define VALID_APPLID(a) ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a)
206 #define APPL_IS_FREE(a) (APPL(a)->applid == 0)
207 #define APPL_MARK_FREE(a) do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0);
208 #define APPL_MARK_USED(a) do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0);
210 #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
212 #define VALID_CARD(c) ((c) > 0 && (c) <= CAPI_MAXCONTR)
213 #define CARD(c) (&cards[(c)-1])
214 #define CARDNR(cp) (((cp)-cards)+1)
216 static struct capi_appl applications[CAPI_MAXAPPL];
217 static struct capi_ctr cards[CAPI_MAXCONTR];
218 static int ncards = 0;
219 static struct sk_buff_head recv_queue;
220 static struct capi_interface_user *capi_users = 0;
221 static spinlock_t capi_users_lock = SPIN_LOCK_UNLOCKED;
222 static struct capi_driver *drivers;
223 static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
225 static struct tq_struct tq_state_notify;
226 static struct tq_struct tq_recv_notify;
228 /* -------- util functions ------------------------------------ */
230 static char *cardstate2str(unsigned short cardstate)
232 switch (cardstate) {
233 default:
234 case CARD_FREE: return "free";
235 case CARD_DETECTED: return "detected";
236 case CARD_LOADING: return "loading";
237 case CARD_RUNNING: return "running";
241 static inline int capi_cmd_valid(__u8 cmd)
243 switch (cmd) {
244 case CAPI_ALERT:
245 case CAPI_CONNECT:
246 case CAPI_CONNECT_ACTIVE:
247 case CAPI_CONNECT_B3_ACTIVE:
248 case CAPI_CONNECT_B3:
249 case CAPI_CONNECT_B3_T90_ACTIVE:
250 case CAPI_DATA_B3:
251 case CAPI_DISCONNECT_B3:
252 case CAPI_DISCONNECT:
253 case CAPI_FACILITY:
254 case CAPI_INFO:
255 case CAPI_LISTEN:
256 case CAPI_MANUFACTURER:
257 case CAPI_RESET_B3:
258 case CAPI_SELECT_B_PROTOCOL:
259 return 1;
261 return 0;
264 static inline int capi_subcmd_valid(__u8 subcmd)
266 switch (subcmd) {
267 case CAPI_REQ:
268 case CAPI_CONF:
269 case CAPI_IND:
270 case CAPI_RESP:
271 return 1;
273 return 0;
276 /* -------- /proc functions ----------------------------------- */
278 * /proc/capi/applications:
279 * applid l3cnt dblkcnt dblklen #ncci recvqueuelen
281 static int proc_applications_read_proc(char *page, char **start, off_t off,
282 int count, int *eof, void *data)
284 struct capi_appl *ap;
285 int i;
286 int len = 0;
288 for (i=0; i < CAPI_MAXAPPL; i++) {
289 ap = &applications[i];
290 if (ap->applid == 0) continue;
291 len += sprintf(page+len, "%u %d %d %d %d %d\n",
292 ap->applid,
293 ap->rparam.level3cnt,
294 ap->rparam.datablkcnt,
295 ap->rparam.datablklen,
296 ap->nncci,
297 skb_queue_len(&ap->recv_queue));
298 if (len <= off) {
299 off -= len;
300 len = 0;
301 } else {
302 if (len-off > count)
303 goto endloop;
306 endloop:
307 *start = page+off;
308 if (len < count)
309 *eof = 1;
310 if (len>count) len = count;
311 if (len<0) len = 0;
312 return len;
316 * /proc/capi/ncci:
317 * applid ncci winsize nblk
319 static int proc_ncci_read_proc(char *page, char **start, off_t off,
320 int count, int *eof, void *data)
322 struct capi_appl *ap;
323 struct capi_ncci *np;
324 int i;
325 int len = 0;
327 for (i=0; i < CAPI_MAXAPPL; i++) {
328 ap = &applications[i];
329 if (ap->applid == 0) continue;
330 for (np = ap->nccilist; np; np = np->next) {
331 len += sprintf(page+len, "%d 0x%x %d %d\n",
332 np->applid,
333 np->ncci,
334 np->winsize,
335 np->nmsg);
336 if (len <= off) {
337 off -= len;
338 len = 0;
339 } else {
340 if (len-off > count)
341 goto endloop;
345 endloop:
346 *start = page+off;
347 if (len < count)
348 *eof = 1;
349 if (len>count) len = count;
350 if (len<0) len = 0;
351 return len;
355 * /proc/capi/driver:
356 * driver ncontroller
358 static int proc_driver_read_proc(char *page, char **start, off_t off,
359 int count, int *eof, void *data)
361 struct capi_driver *driver;
362 int len = 0;
364 spin_lock(&drivers_lock);
365 for (driver = drivers; driver; driver = driver->next) {
366 len += sprintf(page+len, "%-32s %d %s\n",
367 driver->name,
368 driver->ncontroller,
369 driver->revision);
370 if (len <= off) {
371 off -= len;
372 len = 0;
373 } else {
374 if (len-off > count)
375 goto endloop;
378 endloop:
379 spin_unlock(&drivers_lock);
380 *start = page+off;
381 if (len < count)
382 *eof = 1;
383 if (len>count) len = count;
384 if (len<0) len = 0;
385 return len;
389 * /proc/capi/users:
390 * name
392 static int proc_users_read_proc(char *page, char **start, off_t off,
393 int count, int *eof, void *data)
395 struct capi_interface_user *cp;
396 int len = 0;
398 spin_lock(&capi_users_lock);
399 for (cp = capi_users; cp ; cp = cp->next) {
400 len += sprintf(page+len, "%s\n", cp->name);
401 if (len <= off) {
402 off -= len;
403 len = 0;
404 } else {
405 if (len-off > count)
406 goto endloop;
409 endloop:
410 spin_unlock(&capi_users_lock);
411 *start = page+off;
412 if (len < count)
413 *eof = 1;
414 if (len>count) len = count;
415 if (len<0) len = 0;
416 return len;
420 * /proc/capi/controller:
421 * cnr driver cardstate name driverinfo
423 static int proc_controller_read_proc(char *page, char **start, off_t off,
424 int count, int *eof, void *data)
426 struct capi_ctr *cp;
427 int i;
428 int len = 0;
430 for (i=0; i < CAPI_MAXCONTR; i++) {
431 cp = &cards[i];
432 if (cp->cardstate == CARD_FREE) continue;
433 len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n",
434 cp->cnr, cp->driver->name,
435 cardstate2str(cp->cardstate),
436 cp->name,
437 cp->driver->procinfo ? cp->driver->procinfo(cp) : ""
439 if (len <= off) {
440 off -= len;
441 len = 0;
442 } else {
443 if (len-off > count)
444 goto endloop;
447 endloop:
448 *start = page+off;
449 if (len < count)
450 *eof = 1;
451 if (len>count) len = count;
452 if (len<0) len = 0;
453 return len;
457 * /proc/capi/applstats:
458 * applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
460 static int proc_applstats_read_proc(char *page, char **start, off_t off,
461 int count, int *eof, void *data)
463 struct capi_appl *ap;
464 int i;
465 int len = 0;
467 for (i=0; i < CAPI_MAXAPPL; i++) {
468 ap = &applications[i];
469 if (ap->applid == 0) continue;
470 len += sprintf(page+len, "%u %lu %lu %lu %lu\n",
471 ap->applid,
472 ap->nrecvctlpkt,
473 ap->nrecvdatapkt,
474 ap->nsentctlpkt,
475 ap->nsentdatapkt);
476 if (len <= off) {
477 off -= len;
478 len = 0;
479 } else {
480 if (len-off > count)
481 goto endloop;
484 endloop:
485 *start = page+off;
486 if (len < count)
487 *eof = 1;
488 if (len>count) len = count;
489 if (len<0) len = 0;
490 return len;
494 * /proc/capi/contrstats:
495 * cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
497 static int proc_contrstats_read_proc(char *page, char **start, off_t off,
498 int count, int *eof, void *data)
500 struct capi_ctr *cp;
501 int i;
502 int len = 0;
504 for (i=0; i < CAPI_MAXCONTR; i++) {
505 cp = &cards[i];
506 if (cp->cardstate == CARD_FREE) continue;
507 len += sprintf(page+len, "%d %lu %lu %lu %lu\n",
508 cp->cnr,
509 cp->nrecvctlpkt,
510 cp->nrecvdatapkt,
511 cp->nsentctlpkt,
512 cp->nsentdatapkt);
513 if (len <= off) {
514 off -= len;
515 len = 0;
516 } else {
517 if (len-off > count)
518 goto endloop;
521 endloop:
522 *start = page+off;
523 if (len < count)
524 *eof = 1;
525 if (len>count) len = count;
526 if (len<0) len = 0;
527 return len;
530 static struct procfsentries {
531 char *name;
532 mode_t mode;
533 int (*read_proc)(char *page, char **start, off_t off,
534 int count, int *eof, void *data);
535 struct proc_dir_entry *procent;
536 } procfsentries[] = {
537 { "capi", S_IFDIR, 0 },
538 { "capi/applications", 0 , proc_applications_read_proc },
539 { "capi/ncci", 0 , proc_ncci_read_proc },
540 { "capi/driver", 0 , proc_driver_read_proc },
541 { "capi/users", 0 , proc_users_read_proc },
542 { "capi/controller", 0 , proc_controller_read_proc },
543 { "capi/applstats", 0 , proc_applstats_read_proc },
544 { "capi/contrstats", 0 , proc_contrstats_read_proc },
545 { "capi/drivers", S_IFDIR, 0 },
546 { "capi/controllers", S_IFDIR, 0 },
549 static void proc_capi_init(void)
551 int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
552 int i;
554 for (i=0; i < nelem; i++) {
555 struct procfsentries *p = procfsentries + i;
556 p->procent = create_proc_entry(p->name, p->mode, 0);
557 if (p->procent) p->procent->read_proc = p->read_proc;
561 static void proc_capi_exit(void)
563 int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
564 int i;
566 for (i=nelem-1; i >= 0; i--) {
567 struct procfsentries *p = procfsentries + i;
568 if (p->procent) {
569 remove_proc_entry(p->name, 0);
570 p->procent = 0;
575 /* -------- Notifier handling --------------------------------- */
577 static struct capi_notifier_list{
578 struct capi_notifier *head;
579 struct capi_notifier *tail;
580 } notifier_list;
582 static spinlock_t notifier_lock = SPIN_LOCK_UNLOCKED;
584 static inline void notify_enqueue(struct capi_notifier *np)
586 struct capi_notifier_list *q = &notifier_list;
587 unsigned long flags;
589 spin_lock_irqsave(&notifier_lock, flags);
590 if (q->tail) {
591 q->tail->next = np;
592 q->tail = np;
593 } else {
594 q->head = q->tail = np;
596 spin_unlock_irqrestore(&notifier_lock, flags);
599 static inline struct capi_notifier *notify_dequeue(void)
601 struct capi_notifier_list *q = &notifier_list;
602 struct capi_notifier *np = 0;
603 unsigned long flags;
605 spin_lock_irqsave(&notifier_lock, flags);
606 if (q->head) {
607 np = q->head;
608 if ((q->head = np->next) == 0)
609 q->tail = 0;
610 np->next = 0;
612 spin_unlock_irqrestore(&notifier_lock, flags);
613 return np;
616 static int notify_push(unsigned int cmd, __u32 controller,
617 __u16 applid, __u32 ncci)
619 struct capi_notifier *np;
621 MOD_INC_USE_COUNT;
622 np = (struct capi_notifier *)kmalloc(sizeof(struct capi_notifier), GFP_ATOMIC);
623 if (!np) {
624 MOD_DEC_USE_COUNT;
625 return -1;
627 memset(np, 0, sizeof(struct capi_notifier));
628 np->cmd = cmd;
629 np->controller = controller;
630 np->applid = applid;
631 np->ncci = ncci;
632 notify_enqueue(np);
634 * The notifier will result in adding/deleteing
635 * of devices. Devices can only removed in
636 * user process, not in bh.
638 MOD_INC_USE_COUNT;
639 if (schedule_task(&tq_state_notify) == 0)
640 MOD_DEC_USE_COUNT;
641 return 0;
644 /* -------- KCI_CONTRUP --------------------------------------- */
646 static void notify_up(__u32 contr)
648 struct capi_interface_user *p;
650 printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
651 spin_lock(&capi_users_lock);
652 for (p = capi_users; p; p = p->next) {
653 if (!p->callback) continue;
654 (*p->callback) (KCI_CONTRUP, contr, &CARD(contr)->profile);
656 spin_unlock(&capi_users_lock);
659 /* -------- KCI_CONTRDOWN ------------------------------------- */
661 static void notify_down(__u32 contr)
663 struct capi_interface_user *p;
664 printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);
665 spin_lock(&capi_users_lock);
666 for (p = capi_users; p; p = p->next) {
667 if (!p->callback) continue;
668 (*p->callback) (KCI_CONTRDOWN, contr, 0);
670 spin_unlock(&capi_users_lock);
673 /* -------- KCI_NCCIUP ---------------------------------------- */
675 static void notify_ncciup(__u32 contr, __u16 applid, __u32 ncci)
677 struct capi_interface_user *p;
678 struct capi_ncciinfo n;
679 n.applid = applid;
680 n.ncci = ncci;
681 /*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/
682 spin_lock(&capi_users_lock);
683 for (p = capi_users; p; p = p->next) {
684 if (!p->callback) continue;
685 (*p->callback) (KCI_NCCIUP, contr, &n);
687 spin_unlock(&capi_users_lock);
690 /* -------- KCI_NCCIDOWN -------------------------------------- */
692 static void notify_nccidown(__u32 contr, __u16 applid, __u32 ncci)
694 struct capi_interface_user *p;
695 struct capi_ncciinfo n;
696 n.applid = applid;
697 n.ncci = ncci;
698 /*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/
699 spin_lock(&capi_users_lock);
700 for (p = capi_users; p; p = p->next) {
701 if (!p->callback) continue;
702 (*p->callback) (KCI_NCCIDOWN, contr, &n);
704 spin_unlock(&capi_users_lock);
707 /* ------------------------------------------------------------ */
709 static void inline notify_doit(struct capi_notifier *np)
711 switch (np->cmd) {
712 case KCI_CONTRUP:
713 notify_up(np->controller);
714 break;
715 case KCI_CONTRDOWN:
716 notify_down(np->controller);
717 break;
718 case KCI_NCCIUP:
719 notify_ncciup(np->controller, np->applid, np->ncci);
720 break;
721 case KCI_NCCIDOWN:
722 notify_nccidown(np->controller, np->applid, np->ncci);
723 break;
727 static void notify_handler(void *dummy)
729 struct capi_notifier *np;
731 while ((np = notify_dequeue()) != 0) {
732 notify_doit(np);
733 kfree(np);
734 MOD_DEC_USE_COUNT;
736 MOD_DEC_USE_COUNT;
739 /* -------- NCCI Handling ------------------------------------- */
741 static inline void mq_init(struct capi_ncci * np)
743 int i;
744 np->msgidqueue = 0;
745 np->msgidlast = 0;
746 np->nmsg = 0;
747 memset(np->msgidpool, 0, sizeof(np->msgidpool));
748 np->msgidfree = &np->msgidpool[0];
749 for (i = 1; i < np->winsize; i++) {
750 np->msgidpool[i].next = np->msgidfree;
751 np->msgidfree = &np->msgidpool[i];
755 static inline int mq_enqueue(struct capi_ncci * np, __u16 msgid)
757 struct msgidqueue *mq;
758 if ((mq = np->msgidfree) == 0)
759 return 0;
760 np->msgidfree = mq->next;
761 mq->msgid = msgid;
762 mq->next = 0;
763 if (np->msgidlast)
764 np->msgidlast->next = mq;
765 np->msgidlast = mq;
766 if (!np->msgidqueue)
767 np->msgidqueue = mq;
768 np->nmsg++;
769 return 1;
772 static inline int mq_dequeue(struct capi_ncci * np, __u16 msgid)
774 struct msgidqueue **pp;
775 for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
776 if ((*pp)->msgid == msgid) {
777 struct msgidqueue *mq = *pp;
778 *pp = mq->next;
779 if (mq == np->msgidlast)
780 np->msgidlast = 0;
781 mq->next = np->msgidfree;
782 np->msgidfree = mq;
783 np->nmsg--;
784 return 1;
787 return 0;
790 static void controllercb_appl_registered(struct capi_ctr * card, __u16 appl)
794 static void controllercb_appl_released(struct capi_ctr * card, __u16 appl)
796 struct capi_ncci **pp, **nextpp;
797 for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
798 if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
799 struct capi_ncci *np = *pp;
800 *pp = np->next;
801 printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", appl, np->ncci);
802 kfree(np);
803 APPL(appl)->nncci--;
804 nextpp = pp;
805 } else {
806 nextpp = &(*pp)->next;
809 APPL(appl)->releasing--;
810 if (APPL(appl)->releasing <= 0) {
811 APPL(appl)->signal = 0;
812 APPL_MARK_FREE(appl);
813 printk(KERN_INFO "kcapi: appl %d down\n", appl);
817 * ncci managment
820 static void controllercb_new_ncci(struct capi_ctr * card,
821 __u16 appl, __u32 ncci, __u32 winsize)
823 struct capi_ncci *np;
824 if (!VALID_APPLID(appl)) {
825 printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl);
826 return;
828 if ((np = (struct capi_ncci *) kmalloc(sizeof(struct capi_ncci), GFP_ATOMIC)) == 0) {
829 printk(KERN_ERR "capi_new_ncci: alloc failed ncci 0x%x\n", ncci);
830 return;
832 if (winsize > CAPI_MAXDATAWINDOW) {
833 printk(KERN_ERR "capi_new_ncci: winsize %d too big, set to %d\n",
834 winsize, CAPI_MAXDATAWINDOW);
835 winsize = CAPI_MAXDATAWINDOW;
837 np->applid = appl;
838 np->ncci = ncci;
839 np->winsize = winsize;
840 mq_init(np);
841 np->next = APPL(appl)->nccilist;
842 APPL(appl)->nccilist = np;
843 APPL(appl)->nncci++;
844 printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci);
846 notify_push(KCI_NCCIUP, CARDNR(card), appl, ncci);
849 static void controllercb_free_ncci(struct capi_ctr * card,
850 __u16 appl, __u32 ncci)
852 struct capi_ncci **pp;
853 if (!VALID_APPLID(appl)) {
854 printk(KERN_ERR "free_ncci: illegal appl %d\n", appl);
855 return;
857 for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) {
858 if ((*pp)->ncci == ncci) {
859 struct capi_ncci *np = *pp;
860 *pp = np->next;
861 kfree(np);
862 APPL(appl)->nncci--;
863 printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci);
864 notify_push(KCI_NCCIDOWN, CARDNR(card), appl, ncci);
865 return;
868 printk(KERN_ERR "free_ncci: ncci 0x%x not found\n", ncci);
872 static struct capi_ncci *find_ncci(struct capi_appl * app, __u32 ncci)
874 struct capi_ncci *np;
875 for (np = app->nccilist; np; np = np->next) {
876 if (np->ncci == ncci)
877 return np;
879 return 0;
882 /* -------- Receiver ------------------------------------------ */
884 static void recv_handler(void *dummy)
886 struct sk_buff *skb;
888 while ((skb = skb_dequeue(&recv_queue)) != 0) {
889 __u16 appl = CAPIMSG_APPID(skb->data);
890 struct capi_ncci *np;
891 if (!VALID_APPLID(appl)) {
892 printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n",
893 appl, capi_message2str(skb->data));
894 kfree_skb(skb);
895 continue;
897 if (APPL(appl)->signal == 0) {
898 printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n",
899 appl);
900 kfree_skb(skb);
901 continue;
903 if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
904 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF
905 && (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0
906 && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) {
907 printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
908 CAPIMSG_MSGID(skb->data), np->ncci);
910 if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
911 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
912 APPL(appl)->nrecvdatapkt++;
913 } else {
914 APPL(appl)->nrecvctlpkt++;
916 skb_queue_tail(&APPL(appl)->recv_queue, skb);
917 (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param);
921 static void controllercb_handle_capimsg(struct capi_ctr * card,
922 __u16 appl, struct sk_buff *skb)
924 int showctl = 0;
925 __u8 cmd, subcmd;
927 if (card->cardstate != CARD_RUNNING) {
928 printk(KERN_INFO "kcapi: controller %d not active, got: %s",
929 card->cnr, capi_message2str(skb->data));
930 goto error;
932 cmd = CAPIMSG_COMMAND(skb->data);
933 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
934 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
935 card->nrecvdatapkt++;
936 if (card->traceflag > 2) showctl |= 2;
937 } else {
938 card->nrecvctlpkt++;
939 if (card->traceflag) showctl |= 2;
941 showctl |= (card->traceflag & 1);
942 if (showctl & 2) {
943 if (showctl & 1) {
944 printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n",
945 (unsigned long) card->cnr,
946 CAPIMSG_APPID(skb->data),
947 capi_cmd2str(cmd, subcmd),
948 CAPIMSG_LEN(skb->data));
949 } else {
950 printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n",
951 (unsigned long) card->cnr,
952 capi_message2str(skb->data));
956 skb_queue_tail(&recv_queue, skb);
957 queue_task(&tq_recv_notify, &tq_immediate);
958 mark_bh(IMMEDIATE_BH);
959 return;
961 error:
962 kfree_skb(skb);
965 static void controllercb_ready(struct capi_ctr * card)
967 __u16 appl;
969 card->cardstate = CARD_RUNNING;
971 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
972 if (!VALID_APPLID(appl)) continue;
973 if (APPL(appl)->releasing) continue;
974 card->driver->register_appl(card, appl, &APPL(appl)->rparam);
977 printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
978 CARDNR(card), card->name);
980 notify_push(KCI_CONTRUP, CARDNR(card), 0, 0);
983 static void controllercb_reseted(struct capi_ctr * card)
985 __u16 appl;
987 if (card->cardstate == CARD_FREE)
988 return;
989 if (card->cardstate == CARD_DETECTED)
990 return;
992 card->cardstate = CARD_DETECTED;
994 memset(card->manu, 0, sizeof(card->manu));
995 memset(&card->version, 0, sizeof(card->version));
996 memset(&card->profile, 0, sizeof(card->profile));
997 memset(card->serial, 0, sizeof(card->serial));
999 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
1000 struct capi_ncci **pp, **nextpp;
1001 for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
1002 if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
1003 struct capi_ncci *np = *pp;
1004 *pp = np->next;
1005 printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci);
1006 notify_push(KCI_NCCIDOWN, CARDNR(card), appl, np->ncci);
1007 kfree(np);
1008 nextpp = pp;
1009 } else {
1010 nextpp = &(*pp)->next;
1015 printk(KERN_NOTICE "kcapi: card %d down.\n", CARDNR(card));
1017 notify_push(KCI_CONTRDOWN, CARDNR(card), 0, 0);
1020 static void controllercb_suspend_output(struct capi_ctr *card)
1022 if (!card->blocked) {
1023 printk(KERN_DEBUG "kcapi: card %d suspend\n", CARDNR(card));
1024 card->blocked = 1;
1028 static void controllercb_resume_output(struct capi_ctr *card)
1030 if (card->blocked) {
1031 printk(KERN_DEBUG "kcapi: card %d resume\n", CARDNR(card));
1032 card->blocked = 0;
1036 /* ------------------------------------------------------------- */
1039 struct capi_ctr *
1040 drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
1042 struct capi_ctr *card, **pp;
1043 int i;
1045 for (i=0; i < CAPI_MAXCONTR && cards[i].cardstate != CARD_FREE; i++) ;
1047 if (i == CAPI_MAXCONTR) {
1048 printk(KERN_ERR "kcapi: out of controller slots\n");
1049 return 0;
1051 card = &cards[i];
1052 memset(card, 0, sizeof(struct capi_ctr));
1053 card->driver = driver;
1054 card->cnr = CARDNR(card);
1055 strncpy(card->name, name, sizeof(card->name));
1056 card->cardstate = CARD_DETECTED;
1057 card->blocked = 0;
1058 card->driverdata = driverdata;
1059 card->traceflag = showcapimsgs;
1061 card->ready = controllercb_ready;
1062 card->reseted = controllercb_reseted;
1063 card->suspend_output = controllercb_suspend_output;
1064 card->resume_output = controllercb_resume_output;
1065 card->handle_capimsg = controllercb_handle_capimsg;
1066 card->appl_registered = controllercb_appl_registered;
1067 card->appl_released = controllercb_appl_released;
1068 card->new_ncci = controllercb_new_ncci;
1069 card->free_ncci = controllercb_free_ncci;
1071 for (pp = &driver->controller; *pp; pp = &(*pp)->next) ;
1072 card->next = 0;
1073 *pp = card;
1074 driver->ncontroller++;
1075 sprintf(card->procfn, "capi/controllers/%d", card->cnr);
1076 card->procent = create_proc_entry(card->procfn, 0, 0);
1077 if (card->procent) {
1078 card->procent->read_proc =
1079 (int (*)(char *,char **,off_t,int,int *,void *))
1080 driver->ctr_read_proc;
1081 card->procent->data = card;
1084 ncards++;
1085 printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n",
1086 card->cnr, card->name);
1087 return card;
1090 static int drivercb_detach_ctr(struct capi_ctr *card)
1092 struct capi_driver *driver = card->driver;
1093 struct capi_ctr **pp;
1095 if (card->cardstate == CARD_FREE)
1096 return 0;
1097 if (card->cardstate != CARD_DETECTED)
1098 controllercb_reseted(card);
1099 for (pp = &driver->controller; *pp ; pp = &(*pp)->next) {
1100 if (*pp == card) {
1101 *pp = card->next;
1102 driver->ncontroller--;
1103 ncards--;
1104 break;
1107 if (card->procent) {
1108 remove_proc_entry(card->procfn, 0);
1109 card->procent = 0;
1111 card->cardstate = CARD_FREE;
1112 printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n",
1113 card->cnr, card->name);
1114 return 0;
1117 /* ------------------------------------------------------------- */
1119 /* fallback if no driver read_proc function defined by driver */
1121 static int driver_read_proc(char *page, char **start, off_t off,
1122 int count, int *eof, void *data)
1124 struct capi_driver *driver = (struct capi_driver *)data;
1125 int len = 0;
1127 len += sprintf(page+len, "%-16s %s\n", "name", driver->name);
1128 len += sprintf(page+len, "%-16s %s\n", "revision", driver->revision);
1130 if (len < off)
1131 return 0;
1132 *eof = 1;
1133 *start = page + off;
1134 return ((count < len-off) ? count : len-off);
1137 /* ------------------------------------------------------------- */
1139 static struct capi_driver_interface di = {
1140 drivercb_attach_ctr,
1141 drivercb_detach_ctr,
1144 struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
1146 struct capi_driver **pp;
1148 MOD_INC_USE_COUNT;
1149 spin_lock(&drivers_lock);
1150 for (pp = &drivers; *pp; pp = &(*pp)->next) ;
1151 driver->next = 0;
1152 *pp = driver;
1153 spin_unlock(&drivers_lock);
1154 printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name);
1155 sprintf(driver->procfn, "capi/drivers/%s", driver->name);
1156 driver->procent = create_proc_entry(driver->procfn, 0, 0);
1157 if (driver->procent) {
1158 if (driver->driver_read_proc) {
1159 driver->procent->read_proc =
1160 (int (*)(char *,char **,off_t,int,int *,void *))
1161 driver->driver_read_proc;
1162 } else {
1163 driver->procent->read_proc = driver_read_proc;
1165 driver->procent->data = driver;
1167 return &di;
1170 void detach_capi_driver(struct capi_driver *driver)
1172 struct capi_driver **pp;
1173 spin_lock(&drivers_lock);
1174 for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ;
1175 if (*pp) {
1176 *pp = (*pp)->next;
1177 printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
1178 } else {
1179 printk(KERN_ERR "kcapi: driver %s double detach ?\n", driver->name);
1181 spin_unlock(&drivers_lock);
1182 if (driver->procent) {
1183 remove_proc_entry(driver->procfn, 0);
1184 driver->procent = 0;
1186 MOD_DEC_USE_COUNT;
1189 /* ------------------------------------------------------------- */
1190 /* -------- CAPI2.0 Interface ---------------------------------- */
1191 /* ------------------------------------------------------------- */
1193 static __u16 capi_isinstalled(void)
1195 int i;
1196 for (i = 0; i < CAPI_MAXCONTR; i++) {
1197 if (cards[i].cardstate == CARD_RUNNING)
1198 return CAPI_NOERROR;
1200 return CAPI_REGNOTINSTALLED;
1203 static __u16 capi_register(capi_register_params * rparam, __u16 * applidp)
1205 int appl;
1206 int i;
1208 if (rparam->datablklen < 128)
1209 return CAPI_LOGBLKSIZETOSMALL;
1211 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
1212 if (APPL_IS_FREE(appl))
1213 break;
1215 if (appl > CAPI_MAXAPPL)
1216 return CAPI_TOOMANYAPPLS;
1218 APPL_MARK_USED(appl);
1219 skb_queue_head_init(&APPL(appl)->recv_queue);
1220 APPL(appl)->nncci = 0;
1222 memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
1224 for (i = 0; i < CAPI_MAXCONTR; i++) {
1225 if (cards[i].cardstate != CARD_RUNNING)
1226 continue;
1227 cards[i].driver->register_appl(&cards[i], appl,
1228 &APPL(appl)->rparam);
1230 *applidp = appl;
1231 printk(KERN_INFO "kcapi: appl %d up\n", appl);
1233 return CAPI_NOERROR;
1236 static __u16 capi_release(__u16 applid)
1238 struct sk_buff *skb;
1239 int i;
1241 if (!VALID_APPLID(applid) || APPL(applid)->releasing)
1242 return CAPI_ILLAPPNR;
1243 APPL(applid)->releasing++;
1244 while ((skb = skb_dequeue(&APPL(applid)->recv_queue)) != 0)
1245 kfree_skb(skb);
1246 for (i = 0; i < CAPI_MAXCONTR; i++) {
1247 if (cards[i].cardstate != CARD_RUNNING)
1248 continue;
1249 APPL(applid)->releasing++;
1250 cards[i].driver->release_appl(&cards[i], applid);
1252 APPL(applid)->releasing--;
1253 if (APPL(applid)->releasing <= 0) {
1254 APPL(applid)->signal = 0;
1255 APPL_MARK_FREE(applid);
1256 printk(KERN_INFO "kcapi: appl %d down\n", applid);
1258 return CAPI_NOERROR;
1261 static __u16 capi_put_message(__u16 applid, struct sk_buff *skb)
1263 struct capi_ncci *np;
1264 __u32 contr;
1265 int showctl = 0;
1266 __u8 cmd, subcmd;
1268 if (ncards == 0)
1269 return CAPI_REGNOTINSTALLED;
1270 if (!VALID_APPLID(applid))
1271 return CAPI_ILLAPPNR;
1272 if (skb->len < 12
1273 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
1274 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
1275 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
1276 contr = CAPIMSG_CONTROLLER(skb->data);
1277 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) {
1278 contr = 1;
1279 if (CARD(contr)->cardstate != CARD_RUNNING)
1280 return CAPI_REGNOTINSTALLED;
1282 if (CARD(contr)->blocked)
1283 return CAPI_SENDQUEUEFULL;
1285 cmd = CAPIMSG_COMMAND(skb->data);
1286 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
1288 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
1289 if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0
1290 && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)
1291 return CAPI_SENDQUEUEFULL;
1292 CARD(contr)->nsentdatapkt++;
1293 APPL(applid)->nsentdatapkt++;
1294 if (CARD(contr)->traceflag > 2) showctl |= 2;
1295 } else {
1296 CARD(contr)->nsentctlpkt++;
1297 APPL(applid)->nsentctlpkt++;
1298 if (CARD(contr)->traceflag) showctl |= 2;
1300 showctl |= (CARD(contr)->traceflag & 1);
1301 if (showctl & 2) {
1302 if (showctl & 1) {
1303 printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n",
1304 (unsigned long) contr,
1305 CAPIMSG_APPID(skb->data),
1306 capi_cmd2str(cmd, subcmd),
1307 CAPIMSG_LEN(skb->data));
1308 } else {
1309 printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n",
1310 (unsigned long) contr,
1311 capi_message2str(skb->data));
1315 CARD(contr)->driver->send_message(CARD(contr), skb);
1316 return CAPI_NOERROR;
1319 static __u16 capi_get_message(__u16 applid, struct sk_buff **msgp)
1321 struct sk_buff *skb;
1323 if (!VALID_APPLID(applid))
1324 return CAPI_ILLAPPNR;
1325 if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0)
1326 return CAPI_RECEIVEQUEUEEMPTY;
1327 *msgp = skb;
1328 return CAPI_NOERROR;
1331 static __u16 capi_set_signal(__u16 applid,
1332 void (*signal) (__u16 applid, void *param),
1333 void *param)
1335 if (!VALID_APPLID(applid))
1336 return CAPI_ILLAPPNR;
1337 APPL(applid)->signal = signal;
1338 APPL(applid)->param = param;
1339 return CAPI_NOERROR;
1342 static __u16 capi_get_manufacturer(__u32 contr, __u8 buf[CAPI_MANUFACTURER_LEN])
1344 if (contr == 0) {
1345 strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
1346 return CAPI_NOERROR;
1348 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1349 return CAPI_REGNOTINSTALLED;
1351 strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN);
1352 return CAPI_NOERROR;
1355 static __u16 capi_get_version(__u32 contr, struct capi_version *verp)
1357 if (contr == 0) {
1358 *verp = driver_version;
1359 return CAPI_NOERROR;
1361 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1362 return CAPI_REGNOTINSTALLED;
1364 memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version));
1365 return CAPI_NOERROR;
1368 static __u16 capi_get_serial(__u32 contr, __u8 serial[CAPI_SERIAL_LEN])
1370 if (contr == 0) {
1371 strncpy(serial, driver_serial, CAPI_SERIAL_LEN);
1372 return CAPI_NOERROR;
1374 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1375 return CAPI_REGNOTINSTALLED;
1377 strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN);
1378 return CAPI_NOERROR;
1381 static __u16 capi_get_profile(__u32 contr, struct capi_profile *profp)
1383 if (contr == 0) {
1384 profp->ncontroller = ncards;
1385 return CAPI_NOERROR;
1387 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1388 return CAPI_REGNOTINSTALLED;
1390 memcpy((void *) profp, &CARD(contr)->profile,
1391 sizeof(struct capi_profile));
1392 return CAPI_NOERROR;
1395 static struct capi_driver *find_driver(char *name)
1397 struct capi_driver *dp;
1398 spin_lock(&drivers_lock);
1399 for (dp = drivers; dp; dp = dp->next)
1400 if (strcmp(dp->name, name) == 0)
1401 break;
1402 spin_unlock(&drivers_lock);
1403 return dp;
1406 #ifdef CONFIG_AVMB1_COMPAT
1407 static int old_capi_manufacturer(unsigned int cmd, void *data)
1409 avmb1_loadandconfigdef ldef;
1410 avmb1_extcarddef cdef;
1411 avmb1_resetdef rdef;
1412 avmb1_getdef gdef;
1413 struct capi_driver *driver;
1414 struct capi_ctr *card;
1415 capicardparams cparams;
1416 capiloaddata ldata;
1417 int retval;
1419 switch (cmd) {
1420 case AVMB1_ADDCARD:
1421 case AVMB1_ADDCARD_WITH_TYPE:
1422 if (cmd == AVMB1_ADDCARD) {
1423 if ((retval = copy_from_user((void *) &cdef, data,
1424 sizeof(avmb1_carddef))))
1425 return retval;
1426 cdef.cardtype = AVM_CARDTYPE_B1;
1427 } else {
1428 if ((retval = copy_from_user((void *) &cdef, data,
1429 sizeof(avmb1_extcarddef))))
1430 return retval;
1432 cparams.port = cdef.port;
1433 cparams.irq = cdef.irq;
1434 cparams.cardnr = cdef.cardnr;
1436 switch (cdef.cardtype) {
1437 case AVM_CARDTYPE_B1:
1438 driver = find_driver("b1isa");
1439 break;
1440 case AVM_CARDTYPE_T1:
1441 driver = find_driver("t1isa");
1442 break;
1443 default:
1444 driver = 0;
1445 break;
1447 if (!driver) {
1448 printk(KERN_ERR "kcapi: driver not loaded.\n");
1449 return -EIO;
1451 if (!driver->add_card) {
1452 printk(KERN_ERR "kcapi: driver has no add card function.\n");
1453 return -EIO;
1456 return driver->add_card(driver, &cparams);
1458 case AVMB1_LOAD:
1459 case AVMB1_LOAD_AND_CONFIG:
1461 if (cmd == AVMB1_LOAD) {
1462 if ((retval = copy_from_user((void *) &ldef, data,
1463 sizeof(avmb1_loaddef))))
1464 return retval;
1465 ldef.t4config.len = 0;
1466 ldef.t4config.data = 0;
1467 } else {
1468 if ((retval = copy_from_user((void *) &ldef, data,
1469 sizeof(avmb1_loadandconfigdef))))
1470 return retval;
1472 if (!VALID_CARD(ldef.contr))
1473 return -ESRCH;
1475 card = CARD(ldef.contr);
1476 if (card->cardstate == CARD_FREE)
1477 return -ESRCH;
1478 if (card->driver->load_firmware == 0) {
1479 printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name);
1480 return -ESRCH;
1483 if (ldef.t4file.len <= 0) {
1484 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
1485 return -EINVAL;
1487 if (ldef.t4file.data == 0) {
1488 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
1489 return -EINVAL;
1492 ldata.firmware.user = 1;
1493 ldata.firmware.data = ldef.t4file.data;
1494 ldata.firmware.len = ldef.t4file.len;
1495 ldata.configuration.user = 1;
1496 ldata.configuration.data = ldef.t4config.data;
1497 ldata.configuration.len = ldef.t4config.len;
1499 if (card->cardstate != CARD_DETECTED) {
1500 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
1501 return -EBUSY;
1503 card->cardstate = CARD_LOADING;
1505 retval = card->driver->load_firmware(card, &ldata);
1507 if (retval) {
1508 card->cardstate = CARD_DETECTED;
1509 return retval;
1512 while (card->cardstate != CARD_RUNNING) {
1514 set_current_state(TASK_INTERRUPTIBLE);
1515 schedule_timeout(HZ/10); /* 0.1 sec */
1517 if (signal_pending(current))
1518 return -EINTR;
1520 return 0;
1522 case AVMB1_RESETCARD:
1523 if ((retval = copy_from_user((void *) &rdef, data,
1524 sizeof(avmb1_resetdef))))
1525 return retval;
1526 if (!VALID_CARD(rdef.contr))
1527 return -ESRCH;
1528 card = CARD(rdef.contr);
1530 if (card->cardstate == CARD_FREE)
1531 return -ESRCH;
1532 if (card->cardstate == CARD_DETECTED)
1533 return 0;
1535 card->driver->reset_ctr(card);
1537 while (card->cardstate > CARD_DETECTED) {
1539 set_current_state(TASK_INTERRUPTIBLE);
1540 schedule_timeout(HZ/10); /* 0.1 sec */
1542 if (signal_pending(current))
1543 return -EINTR;
1545 return 0;
1547 case AVMB1_GET_CARDINFO:
1548 if ((retval = copy_from_user((void *) &gdef, data,
1549 sizeof(avmb1_getdef))))
1550 return retval;
1552 if (!VALID_CARD(gdef.contr))
1553 return -ESRCH;
1555 card = CARD(gdef.contr);
1557 if (card->cardstate == CARD_FREE)
1558 return -ESRCH;
1560 gdef.cardstate = card->cardstate;
1561 if (card->driver == find_driver("t1isa"))
1562 gdef.cardtype = AVM_CARDTYPE_T1;
1563 else gdef.cardtype = AVM_CARDTYPE_B1;
1565 if ((retval = copy_to_user(data, (void *) &gdef,
1566 sizeof(avmb1_getdef))))
1567 return retval;
1569 return 0;
1571 case AVMB1_REMOVECARD:
1572 if ((retval = copy_from_user((void *) &rdef, data,
1573 sizeof(avmb1_resetdef))))
1574 return retval;
1576 if (!VALID_CARD(rdef.contr))
1577 return -ESRCH;
1578 card = CARD(rdef.contr);
1580 if (card->cardstate == CARD_FREE)
1581 return -ESRCH;
1583 if (card->cardstate != CARD_DETECTED)
1584 return -EBUSY;
1586 card->driver->remove_ctr(card);
1588 while (card->cardstate != CARD_FREE) {
1590 set_current_state(TASK_INTERRUPTIBLE);
1591 schedule_timeout(HZ/10); /* 0.1 sec */
1593 if (signal_pending(current))
1594 return -EINTR;
1596 return 0;
1598 return -EINVAL;
1600 #endif
1602 static int capi_manufacturer(unsigned int cmd, void *data)
1604 struct capi_ctr *card;
1605 int retval;
1607 switch (cmd) {
1608 #ifdef CONFIG_AVMB1_COMPAT
1609 case AVMB1_ADDCARD:
1610 case AVMB1_ADDCARD_WITH_TYPE:
1611 case AVMB1_LOAD:
1612 case AVMB1_LOAD_AND_CONFIG:
1613 case AVMB1_RESETCARD:
1614 case AVMB1_GET_CARDINFO:
1615 case AVMB1_REMOVECARD:
1616 return old_capi_manufacturer(cmd, data);
1617 #endif
1618 case KCAPI_CMD_TRACE:
1620 kcapi_flagdef fdef;
1622 if ((retval = copy_from_user((void *) &fdef, data,
1623 sizeof(kcapi_flagdef))))
1624 return retval;
1626 if (!VALID_CARD(fdef.contr))
1627 return -ESRCH;
1628 card = CARD(fdef.contr);
1629 if (card->cardstate == CARD_FREE)
1630 return -ESRCH;
1631 card->traceflag = fdef.flag;
1632 printk(KERN_INFO "kcapi: contr %d set trace=%d\n",
1633 card->cnr, card->traceflag);
1634 return 0;
1637 case KCAPI_CMD_ADDCARD:
1639 struct capi_driver *driver;
1640 capicardparams cparams;
1641 kcapi_carddef cdef;
1643 if ((retval = copy_from_user((void *) &cdef, data,
1644 sizeof(cdef))))
1645 return retval;
1647 cparams.port = cdef.port;
1648 cparams.irq = cdef.irq;
1649 cparams.membase = cdef.membase;
1650 cparams.cardnr = cdef.cardnr;
1651 cparams.cardtype = 0;
1652 cdef.driver[sizeof(cdef.driver)-1] = 0;
1654 if ((driver = find_driver(cdef.driver)) == 0) {
1655 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
1656 cdef.driver);
1657 return -ESRCH;
1660 if (!driver->add_card) {
1661 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
1662 return -EIO;
1665 return driver->add_card(driver, &cparams);
1668 default:
1669 printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
1670 cmd);
1671 break;
1674 return -EINVAL;
1677 struct capi_interface avmb1_interface =
1679 capi_isinstalled,
1680 capi_register,
1681 capi_release,
1682 capi_put_message,
1683 capi_get_message,
1684 capi_set_signal,
1685 capi_get_manufacturer,
1686 capi_get_version,
1687 capi_get_serial,
1688 capi_get_profile,
1689 capi_manufacturer
1692 /* ------------------------------------------------------------- */
1693 /* -------- Exported Functions --------------------------------- */
1694 /* ------------------------------------------------------------- */
1696 struct capi_interface *attach_capi_interface(struct capi_interface_user *userp)
1698 struct capi_interface_user *p;
1700 MOD_INC_USE_COUNT;
1701 spin_lock(&capi_users_lock);
1702 for (p = capi_users; p; p = p->next) {
1703 if (p == userp) {
1704 spin_unlock(&capi_users_lock);
1705 printk(KERN_ERR "kcapi: double attach from %s\n",
1706 userp->name);
1707 MOD_DEC_USE_COUNT;
1708 return 0;
1711 userp->next = capi_users;
1712 capi_users = userp;
1713 spin_unlock(&capi_users_lock);
1714 printk(KERN_NOTICE "kcapi: %s attached\n", userp->name);
1716 return &avmb1_interface;
1719 int detach_capi_interface(struct capi_interface_user *userp)
1721 struct capi_interface_user **pp;
1723 spin_lock(&capi_users_lock);
1724 for (pp = &capi_users; *pp; pp = &(*pp)->next) {
1725 if (*pp == userp) {
1726 *pp = userp->next;
1727 spin_unlock(&capi_users_lock);
1728 userp->next = 0;
1729 printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);
1730 MOD_DEC_USE_COUNT;
1731 return 0;
1734 spin_unlock(&capi_users_lock);
1735 printk(KERN_ERR "kcapi: double detach from %s\n", userp->name);
1736 return -1;
1739 /* ------------------------------------------------------------- */
1740 /* -------- Init & Cleanup ------------------------------------- */
1741 /* ------------------------------------------------------------- */
1743 EXPORT_SYMBOL(attach_capi_interface);
1744 EXPORT_SYMBOL(detach_capi_interface);
1745 EXPORT_SYMBOL(attach_capi_driver);
1746 EXPORT_SYMBOL(detach_capi_driver);
1749 * init / exit functions
1752 static int __init kcapi_init(void)
1754 char *p;
1755 char rev[10];
1757 MOD_INC_USE_COUNT;
1759 skb_queue_head_init(&recv_queue);
1761 tq_state_notify.routine = notify_handler;
1762 tq_state_notify.data = 0;
1764 tq_recv_notify.routine = recv_handler;
1765 tq_recv_notify.data = 0;
1767 proc_capi_init();
1769 if ((p = strchr(revision, ':'))) {
1770 strcpy(rev, p + 1);
1771 p = strchr(rev, '$');
1772 *p = 0;
1773 } else
1774 strcpy(rev, "1.0");
1776 #ifdef MODULE
1777 printk(KERN_NOTICE "CAPI-driver Rev%s: loaded\n", rev);
1778 #else
1779 printk(KERN_NOTICE "CAPI-driver Rev%s: started\n", rev);
1780 #endif
1781 MOD_DEC_USE_COUNT;
1782 return 0;
1785 static void __exit kcapi_exit(void)
1787 char rev[10];
1788 char *p;
1790 if ((p = strchr(revision, ':'))) {
1791 strcpy(rev, p + 1);
1792 p = strchr(rev, '$');
1793 *p = 0;
1794 } else {
1795 strcpy(rev, "1.0");
1798 proc_capi_exit();
1799 printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev);
1802 module_init(kcapi_init);
1803 module_exit(kcapi_exit);