- Kai Germaschewski: ymfpci cleanups and resource leak fixes
[davej-history.git] / drivers / isdn / avmb1 / kcapi.c
blobbf6571856f7b752d40e38875a5d644f04f1dc560
1 /*
2 * $Id: kcapi.c,v 1.21 2000/11/23 20:45:14 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 2000/11/23 20:45:14 kai
10 * fixed module_init/exit stuff
11 * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
13 * Revision 1.20 2000/11/19 17:01:53 kai
14 * compatibility cleanup - part 2
16 * Revision 1.19 2000/11/01 14:05:02 calle
17 * - use module_init/module_exit from linux/init.h.
18 * - all static struct variables are initialized with "membername:" now.
19 * - avm_cs.c, let it work with newer pcmcia-cs.
21 * Revision 1.18 2000/07/20 10:22:27 calle
22 * - Made procfs function cleaner and removed variable "begin".
24 * Revision 1.17 2000/04/21 13:00:56 calle
25 * Bugfix: driver_proc_info was also wrong.
27 * Revision 1.16 2000/04/21 12:38:42 calle
28 * Bugfix: error in proc_ functions, begin-off => off-begin
30 * Revision 1.15 2000/04/06 15:01:25 calle
31 * Bugfix: crash in capidrv.c when reseting a capi controller.
32 * - changed code order on remove of controller.
33 * - using tq schedule for notifier in kcapi.c.
34 * - now using spin_lock_irqsave() and spin_unlock_irqrestore().
35 * strange: sometimes even MP hang on unload of isdn.o ...
37 * Revision 1.14 2000/04/03 13:29:25 calle
38 * make Tim Waugh happy (module unload races in 2.3.99-pre3).
39 * no real problem there, but now it is much cleaner ...
41 * Revision 1.13 2000/03/03 15:50:42 calle
42 * - kernel CAPI:
43 * - Changed parameter "param" in capi_signal from __u32 to void *.
44 * - rewrote notifier handling in kcapi.c
45 * - new notifier NCCI_UP and NCCI_DOWN
46 * - User CAPI:
47 * - /dev/capi20 is now a cloning device.
48 * - middleware extentions prepared.
49 * - capidrv.c
50 * - locking of list operations and module count updates.
52 * Revision 1.12 2000/01/28 16:45:39 calle
53 * new manufacturer command KCAPI_CMD_ADDCARD (generic addcard),
54 * will search named driver and call the add_card function if one exist.
56 * Revision 1.11 1999/11/23 13:29:29 calle
57 * Bugfix: incoming capi message were never traced.
59 * Revision 1.10 1999/10/26 15:30:32 calle
60 * Generate error message if user want to add card, but driver module is
61 * not loaded.
63 * Revision 1.9 1999/10/11 22:04:12 keil
64 * COMPAT_NEED_UACCESS (no include in isdn_compat.h)
66 * Revision 1.8 1999/09/10 17:24:18 calle
67 * Changes for proposed standard for CAPI2.0:
68 * - AK148 "Linux Exention"
70 * Revision 1.7 1999/09/04 06:20:05 keil
71 * Changes from kernel set_current_state()
73 * Revision 1.6 1999/07/20 06:41:49 calle
74 * Bugfix: After the redesign of the AVM B1 driver, the driver didn't even
75 * compile, if not selected as modules.
77 * Revision 1.5 1999/07/09 15:05:48 keil
78 * compat.h is now isdn_compat.h
80 * Revision 1.4 1999/07/08 14:15:17 calle
81 * Forgot to count down ncards in drivercb_detach_ctr.
83 * Revision 1.3 1999/07/06 07:42:02 calle
84 * - changes in /proc interface
85 * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
87 * Revision 1.2 1999/07/05 15:09:52 calle
88 * - renamed "appl_release" to "appl_released".
89 * - version und profile data now cleared on controller reset
90 * - extended /proc interface, to allow driver and controller specific
91 * informations to include by driver hackers.
93 * Revision 1.1 1999/07/01 15:26:42 calle
94 * complete new version (I love it):
95 * + new hardware independed "capi_driver" interface that will make it easy to:
96 * - support other controllers with CAPI-2.0 (i.e. USB Controller)
97 * - write a CAPI-2.0 for the passive cards
98 * - support serial link CAPI-2.0 boxes.
99 * + wrote "capi_driver" for all supported cards.
100 * + "capi_driver" (supported cards) now have to be configured with
101 * make menuconfig, in the past all supported cards where included
102 * at once.
103 * + new and better informations in /proc/capi/
104 * + new ioctl to switch trace of capi messages per controller
105 * using "avmcapictrl trace [contr] on|off|...."
106 * + complete testcircle with all supported cards and also the
107 * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
110 #define CONFIG_AVMB1_COMPAT
112 #include <linux/config.h>
113 #include <linux/module.h>
114 #include <linux/kernel.h>
115 #include <linux/mm.h>
116 #include <linux/interrupt.h>
117 #include <linux/ioport.h>
118 #include <asm/segment.h>
119 #include <linux/proc_fs.h>
120 #include <linux/skbuff.h>
121 #include <linux/tqueue.h>
122 #include <linux/capi.h>
123 #include <linux/kernelcapi.h>
124 #include <linux/locks.h>
125 #include <linux/init.h>
126 #include <asm/uaccess.h>
127 #include "capicmd.h"
128 #include "capiutil.h"
129 #include "capilli.h"
130 #ifdef CONFIG_AVMB1_COMPAT
131 #include <linux/b1lli.h>
132 #endif
134 static char *revision = "$Revision: 1.21 $";
136 /* ------------------------------------------------------------- */
138 #define CARD_FREE 0
139 #define CARD_DETECTED 1
140 #define CARD_LOADING 2
141 #define CARD_RUNNING 3
143 /* ------------------------------------------------------------- */
145 int showcapimsgs = 0;
147 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
148 MODULE_PARM(showcapimsgs, "0-4i");
150 /* ------------------------------------------------------------- */
152 struct msgidqueue {
153 struct msgidqueue *next;
154 __u16 msgid;
157 struct capi_ncci {
158 struct capi_ncci *next;
159 __u16 applid;
160 __u32 ncci;
161 __u32 winsize;
162 int nmsg;
163 struct msgidqueue *msgidqueue;
164 struct msgidqueue *msgidlast;
165 struct msgidqueue *msgidfree;
166 struct msgidqueue msgidpool[CAPI_MAXDATAWINDOW];
169 struct capi_appl {
170 __u16 applid;
171 capi_register_params rparam;
172 int releasing;
173 void *param;
174 void (*signal) (__u16 applid, void *param);
175 struct sk_buff_head recv_queue;
176 int nncci;
177 struct capi_ncci *nccilist;
179 unsigned long nrecvctlpkt;
180 unsigned long nrecvdatapkt;
181 unsigned long nsentctlpkt;
182 unsigned long nsentdatapkt;
185 struct capi_notifier {
186 struct capi_notifier *next;
187 unsigned int cmd;
188 __u32 controller;
189 __u16 applid;
190 __u32 ncci;
193 /* ------------------------------------------------------------- */
195 static struct capi_version driver_version = {2, 0, 1, 1<<4};
196 static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
197 static char capi_manufakturer[64] = "AVM Berlin";
199 #define APPL(a) (&applications[(a)-1])
200 #define VALID_APPLID(a) ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a)
201 #define APPL_IS_FREE(a) (APPL(a)->applid == 0)
202 #define APPL_MARK_FREE(a) do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0);
203 #define APPL_MARK_USED(a) do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0);
205 #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
207 #define VALID_CARD(c) ((c) > 0 && (c) <= CAPI_MAXCONTR)
208 #define CARD(c) (&cards[(c)-1])
209 #define CARDNR(cp) (((cp)-cards)+1)
211 static struct capi_appl applications[CAPI_MAXAPPL];
212 static struct capi_ctr cards[CAPI_MAXCONTR];
213 static int ncards = 0;
214 static struct sk_buff_head recv_queue;
215 static struct capi_interface_user *capi_users = 0;
216 static spinlock_t capi_users_lock = SPIN_LOCK_UNLOCKED;
217 static struct capi_driver *drivers;
218 static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
220 static struct tq_struct tq_state_notify;
221 static struct tq_struct tq_recv_notify;
223 /* -------- util functions ------------------------------------ */
225 static char *cardstate2str(unsigned short cardstate)
227 switch (cardstate) {
228 default:
229 case CARD_FREE: return "free";
230 case CARD_DETECTED: return "detected";
231 case CARD_LOADING: return "loading";
232 case CARD_RUNNING: return "running";
236 static inline int capi_cmd_valid(__u8 cmd)
238 switch (cmd) {
239 case CAPI_ALERT:
240 case CAPI_CONNECT:
241 case CAPI_CONNECT_ACTIVE:
242 case CAPI_CONNECT_B3_ACTIVE:
243 case CAPI_CONNECT_B3:
244 case CAPI_CONNECT_B3_T90_ACTIVE:
245 case CAPI_DATA_B3:
246 case CAPI_DISCONNECT_B3:
247 case CAPI_DISCONNECT:
248 case CAPI_FACILITY:
249 case CAPI_INFO:
250 case CAPI_LISTEN:
251 case CAPI_MANUFACTURER:
252 case CAPI_RESET_B3:
253 case CAPI_SELECT_B_PROTOCOL:
254 return 1;
256 return 0;
259 static inline int capi_subcmd_valid(__u8 subcmd)
261 switch (subcmd) {
262 case CAPI_REQ:
263 case CAPI_CONF:
264 case CAPI_IND:
265 case CAPI_RESP:
266 return 1;
268 return 0;
271 /* -------- /proc functions ----------------------------------- */
273 * /proc/capi/applications:
274 * applid l3cnt dblkcnt dblklen #ncci recvqueuelen
276 static int proc_applications_read_proc(char *page, char **start, off_t off,
277 int count, int *eof, void *data)
279 struct capi_appl *ap;
280 int i;
281 int len = 0;
283 for (i=0; i < CAPI_MAXAPPL; i++) {
284 ap = &applications[i];
285 if (ap->applid == 0) continue;
286 len += sprintf(page+len, "%u %d %d %d %d %d\n",
287 ap->applid,
288 ap->rparam.level3cnt,
289 ap->rparam.datablkcnt,
290 ap->rparam.datablklen,
291 ap->nncci,
292 skb_queue_len(&ap->recv_queue));
293 if (len <= off) {
294 off -= len;
295 len = 0;
296 } else {
297 if (len-off > count)
298 goto endloop;
301 endloop:
302 *start = page+off;
303 if (len < count)
304 *eof = 1;
305 if (len>count) len = count;
306 if (len<0) len = 0;
307 return len;
311 * /proc/capi/ncci:
312 * applid ncci winsize nblk
314 static int proc_ncci_read_proc(char *page, char **start, off_t off,
315 int count, int *eof, void *data)
317 struct capi_appl *ap;
318 struct capi_ncci *np;
319 int i;
320 int len = 0;
322 for (i=0; i < CAPI_MAXAPPL; i++) {
323 ap = &applications[i];
324 if (ap->applid == 0) continue;
325 for (np = ap->nccilist; np; np = np->next) {
326 len += sprintf(page+len, "%d 0x%x %d %d\n",
327 np->applid,
328 np->ncci,
329 np->winsize,
330 np->nmsg);
331 if (len <= off) {
332 off -= len;
333 len = 0;
334 } else {
335 if (len-off > count)
336 goto endloop;
340 endloop:
341 *start = page+off;
342 if (len < count)
343 *eof = 1;
344 if (len>count) len = count;
345 if (len<0) len = 0;
346 return len;
350 * /proc/capi/driver:
351 * driver ncontroller
353 static int proc_driver_read_proc(char *page, char **start, off_t off,
354 int count, int *eof, void *data)
356 struct capi_driver *driver;
357 int len = 0;
359 spin_lock(&drivers_lock);
360 for (driver = drivers; driver; driver = driver->next) {
361 len += sprintf(page+len, "%-32s %d %s\n",
362 driver->name,
363 driver->ncontroller,
364 driver->revision);
365 if (len <= off) {
366 off -= len;
367 len = 0;
368 } else {
369 if (len-off > count)
370 goto endloop;
373 endloop:
374 spin_unlock(&drivers_lock);
375 *start = page+off;
376 if (len < count)
377 *eof = 1;
378 if (len>count) len = count;
379 if (len<0) len = 0;
380 return len;
384 * /proc/capi/users:
385 * name
387 static int proc_users_read_proc(char *page, char **start, off_t off,
388 int count, int *eof, void *data)
390 struct capi_interface_user *cp;
391 int len = 0;
393 spin_lock(&capi_users_lock);
394 for (cp = capi_users; cp ; cp = cp->next) {
395 len += sprintf(page+len, "%s\n", cp->name);
396 if (len <= off) {
397 off -= len;
398 len = 0;
399 } else {
400 if (len-off > count)
401 goto endloop;
404 endloop:
405 spin_unlock(&capi_users_lock);
406 *start = page+off;
407 if (len < count)
408 *eof = 1;
409 if (len>count) len = count;
410 if (len<0) len = 0;
411 return len;
415 * /proc/capi/controller:
416 * cnr driver cardstate name driverinfo
418 static int proc_controller_read_proc(char *page, char **start, off_t off,
419 int count, int *eof, void *data)
421 struct capi_ctr *cp;
422 int i;
423 int len = 0;
425 for (i=0; i < CAPI_MAXCONTR; i++) {
426 cp = &cards[i];
427 if (cp->cardstate == CARD_FREE) continue;
428 len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n",
429 cp->cnr, cp->driver->name,
430 cardstate2str(cp->cardstate),
431 cp->name,
432 cp->driver->procinfo ? cp->driver->procinfo(cp) : ""
434 if (len <= off) {
435 off -= len;
436 len = 0;
437 } else {
438 if (len-off > count)
439 goto endloop;
442 endloop:
443 *start = page+off;
444 if (len < count)
445 *eof = 1;
446 if (len>count) len = count;
447 if (len<0) len = 0;
448 return len;
452 * /proc/capi/applstats:
453 * applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
455 static int proc_applstats_read_proc(char *page, char **start, off_t off,
456 int count, int *eof, void *data)
458 struct capi_appl *ap;
459 int i;
460 int len = 0;
462 for (i=0; i < CAPI_MAXAPPL; i++) {
463 ap = &applications[i];
464 if (ap->applid == 0) continue;
465 len += sprintf(page+len, "%u %lu %lu %lu %lu\n",
466 ap->applid,
467 ap->nrecvctlpkt,
468 ap->nrecvdatapkt,
469 ap->nsentctlpkt,
470 ap->nsentdatapkt);
471 if (len <= off) {
472 off -= len;
473 len = 0;
474 } else {
475 if (len-off > count)
476 goto endloop;
479 endloop:
480 *start = page+off;
481 if (len < count)
482 *eof = 1;
483 if (len>count) len = count;
484 if (len<0) len = 0;
485 return len;
489 * /proc/capi/contrstats:
490 * cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
492 static int proc_contrstats_read_proc(char *page, char **start, off_t off,
493 int count, int *eof, void *data)
495 struct capi_ctr *cp;
496 int i;
497 int len = 0;
499 for (i=0; i < CAPI_MAXCONTR; i++) {
500 cp = &cards[i];
501 if (cp->cardstate == CARD_FREE) continue;
502 len += sprintf(page+len, "%d %lu %lu %lu %lu\n",
503 cp->cnr,
504 cp->nrecvctlpkt,
505 cp->nrecvdatapkt,
506 cp->nsentctlpkt,
507 cp->nsentdatapkt);
508 if (len <= off) {
509 off -= len;
510 len = 0;
511 } else {
512 if (len-off > count)
513 goto endloop;
516 endloop:
517 *start = page+off;
518 if (len < count)
519 *eof = 1;
520 if (len>count) len = count;
521 if (len<0) len = 0;
522 return len;
525 static struct procfsentries {
526 char *name;
527 mode_t mode;
528 int (*read_proc)(char *page, char **start, off_t off,
529 int count, int *eof, void *data);
530 struct proc_dir_entry *procent;
531 } procfsentries[] = {
532 { "capi", S_IFDIR, 0 },
533 { "capi/applications", 0 , proc_applications_read_proc },
534 { "capi/ncci", 0 , proc_ncci_read_proc },
535 { "capi/driver", 0 , proc_driver_read_proc },
536 { "capi/users", 0 , proc_users_read_proc },
537 { "capi/controller", 0 , proc_controller_read_proc },
538 { "capi/applstats", 0 , proc_applstats_read_proc },
539 { "capi/contrstats", 0 , proc_contrstats_read_proc },
540 { "capi/drivers", S_IFDIR, 0 },
541 { "capi/controllers", S_IFDIR, 0 },
544 static void proc_capi_init(void)
546 int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
547 int i;
549 for (i=0; i < nelem; i++) {
550 struct procfsentries *p = procfsentries + i;
551 p->procent = create_proc_entry(p->name, p->mode, 0);
552 if (p->procent) p->procent->read_proc = p->read_proc;
556 static void proc_capi_exit(void)
558 int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
559 int i;
561 for (i=nelem-1; i >= 0; i--) {
562 struct procfsentries *p = procfsentries + i;
563 if (p->procent) {
564 remove_proc_entry(p->name, 0);
565 p->procent = 0;
570 /* -------- Notifier handling --------------------------------- */
572 static struct capi_notifier_list{
573 struct capi_notifier *head;
574 struct capi_notifier *tail;
575 } notifier_list;
577 static spinlock_t notifier_lock = SPIN_LOCK_UNLOCKED;
579 static inline void notify_enqueue(struct capi_notifier *np)
581 struct capi_notifier_list *q = &notifier_list;
582 unsigned long flags;
584 spin_lock_irqsave(&notifier_lock, flags);
585 if (q->tail) {
586 q->tail->next = np;
587 q->tail = np;
588 } else {
589 q->head = q->tail = np;
591 spin_unlock_irqrestore(&notifier_lock, flags);
594 static inline struct capi_notifier *notify_dequeue(void)
596 struct capi_notifier_list *q = &notifier_list;
597 struct capi_notifier *np = 0;
598 unsigned long flags;
600 spin_lock_irqsave(&notifier_lock, flags);
601 if (q->head) {
602 np = q->head;
603 if ((q->head = np->next) == 0)
604 q->tail = 0;
605 np->next = 0;
607 spin_unlock_irqrestore(&notifier_lock, flags);
608 return np;
611 static int notify_push(unsigned int cmd, __u32 controller,
612 __u16 applid, __u32 ncci)
614 struct capi_notifier *np;
616 MOD_INC_USE_COUNT;
617 np = (struct capi_notifier *)kmalloc(sizeof(struct capi_notifier), GFP_ATOMIC);
618 if (!np) {
619 MOD_DEC_USE_COUNT;
620 return -1;
622 memset(np, 0, sizeof(struct capi_notifier));
623 np->cmd = cmd;
624 np->controller = controller;
625 np->applid = applid;
626 np->ncci = ncci;
627 notify_enqueue(np);
629 * The notifier will result in adding/deleteing
630 * of devices. Devices can only removed in
631 * user process, not in bh.
633 MOD_INC_USE_COUNT;
634 if (schedule_task(&tq_state_notify) == 0)
635 MOD_DEC_USE_COUNT;
636 return 0;
639 /* -------- KCI_CONTRUP --------------------------------------- */
641 static void notify_up(__u32 contr)
643 struct capi_interface_user *p;
645 printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
646 spin_lock(&capi_users_lock);
647 for (p = capi_users; p; p = p->next) {
648 if (!p->callback) continue;
649 (*p->callback) (KCI_CONTRUP, contr, &CARD(contr)->profile);
651 spin_unlock(&capi_users_lock);
654 /* -------- KCI_CONTRDOWN ------------------------------------- */
656 static void notify_down(__u32 contr)
658 struct capi_interface_user *p;
659 printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);
660 spin_lock(&capi_users_lock);
661 for (p = capi_users; p; p = p->next) {
662 if (!p->callback) continue;
663 (*p->callback) (KCI_CONTRDOWN, contr, 0);
665 spin_unlock(&capi_users_lock);
668 /* -------- KCI_NCCIUP ---------------------------------------- */
670 static void notify_ncciup(__u32 contr, __u16 applid, __u32 ncci)
672 struct capi_interface_user *p;
673 struct capi_ncciinfo n;
674 n.applid = applid;
675 n.ncci = ncci;
676 /*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/
677 spin_lock(&capi_users_lock);
678 for (p = capi_users; p; p = p->next) {
679 if (!p->callback) continue;
680 (*p->callback) (KCI_NCCIUP, contr, &n);
682 spin_unlock(&capi_users_lock);
685 /* -------- KCI_NCCIDOWN -------------------------------------- */
687 static void notify_nccidown(__u32 contr, __u16 applid, __u32 ncci)
689 struct capi_interface_user *p;
690 struct capi_ncciinfo n;
691 n.applid = applid;
692 n.ncci = ncci;
693 /*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/
694 spin_lock(&capi_users_lock);
695 for (p = capi_users; p; p = p->next) {
696 if (!p->callback) continue;
697 (*p->callback) (KCI_NCCIDOWN, contr, &n);
699 spin_unlock(&capi_users_lock);
702 /* ------------------------------------------------------------ */
704 static void inline notify_doit(struct capi_notifier *np)
706 switch (np->cmd) {
707 case KCI_CONTRUP:
708 notify_up(np->controller);
709 break;
710 case KCI_CONTRDOWN:
711 notify_down(np->controller);
712 break;
713 case KCI_NCCIUP:
714 notify_ncciup(np->controller, np->applid, np->ncci);
715 break;
716 case KCI_NCCIDOWN:
717 notify_nccidown(np->controller, np->applid, np->ncci);
718 break;
722 static void notify_handler(void *dummy)
724 struct capi_notifier *np;
726 while ((np = notify_dequeue()) != 0) {
727 notify_doit(np);
728 kfree(np);
729 MOD_DEC_USE_COUNT;
731 MOD_DEC_USE_COUNT;
734 /* -------- NCCI Handling ------------------------------------- */
736 static inline void mq_init(struct capi_ncci * np)
738 int i;
739 np->msgidqueue = 0;
740 np->msgidlast = 0;
741 np->nmsg = 0;
742 memset(np->msgidpool, 0, sizeof(np->msgidpool));
743 np->msgidfree = &np->msgidpool[0];
744 for (i = 1; i < np->winsize; i++) {
745 np->msgidpool[i].next = np->msgidfree;
746 np->msgidfree = &np->msgidpool[i];
750 static inline int mq_enqueue(struct capi_ncci * np, __u16 msgid)
752 struct msgidqueue *mq;
753 if ((mq = np->msgidfree) == 0)
754 return 0;
755 np->msgidfree = mq->next;
756 mq->msgid = msgid;
757 mq->next = 0;
758 if (np->msgidlast)
759 np->msgidlast->next = mq;
760 np->msgidlast = mq;
761 if (!np->msgidqueue)
762 np->msgidqueue = mq;
763 np->nmsg++;
764 return 1;
767 static inline int mq_dequeue(struct capi_ncci * np, __u16 msgid)
769 struct msgidqueue **pp;
770 for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
771 if ((*pp)->msgid == msgid) {
772 struct msgidqueue *mq = *pp;
773 *pp = mq->next;
774 if (mq == np->msgidlast)
775 np->msgidlast = 0;
776 mq->next = np->msgidfree;
777 np->msgidfree = mq;
778 np->nmsg--;
779 return 1;
782 return 0;
785 static void controllercb_appl_registered(struct capi_ctr * card, __u16 appl)
789 static void controllercb_appl_released(struct capi_ctr * card, __u16 appl)
791 struct capi_ncci **pp, **nextpp;
792 for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
793 if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
794 struct capi_ncci *np = *pp;
795 *pp = np->next;
796 printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", appl, np->ncci);
797 kfree(np);
798 APPL(appl)->nncci--;
799 nextpp = pp;
800 } else {
801 nextpp = &(*pp)->next;
804 APPL(appl)->releasing--;
805 if (APPL(appl)->releasing <= 0) {
806 APPL(appl)->signal = 0;
807 APPL_MARK_FREE(appl);
808 printk(KERN_INFO "kcapi: appl %d down\n", appl);
812 * ncci managment
815 static void controllercb_new_ncci(struct capi_ctr * card,
816 __u16 appl, __u32 ncci, __u32 winsize)
818 struct capi_ncci *np;
819 if (!VALID_APPLID(appl)) {
820 printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl);
821 return;
823 if ((np = (struct capi_ncci *) kmalloc(sizeof(struct capi_ncci), GFP_ATOMIC)) == 0) {
824 printk(KERN_ERR "capi_new_ncci: alloc failed ncci 0x%x\n", ncci);
825 return;
827 if (winsize > CAPI_MAXDATAWINDOW) {
828 printk(KERN_ERR "capi_new_ncci: winsize %d too big, set to %d\n",
829 winsize, CAPI_MAXDATAWINDOW);
830 winsize = CAPI_MAXDATAWINDOW;
832 np->applid = appl;
833 np->ncci = ncci;
834 np->winsize = winsize;
835 mq_init(np);
836 np->next = APPL(appl)->nccilist;
837 APPL(appl)->nccilist = np;
838 APPL(appl)->nncci++;
839 printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci);
841 notify_push(KCI_NCCIUP, CARDNR(card), appl, ncci);
844 static void controllercb_free_ncci(struct capi_ctr * card,
845 __u16 appl, __u32 ncci)
847 struct capi_ncci **pp;
848 if (!VALID_APPLID(appl)) {
849 printk(KERN_ERR "free_ncci: illegal appl %d\n", appl);
850 return;
852 for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) {
853 if ((*pp)->ncci == ncci) {
854 struct capi_ncci *np = *pp;
855 *pp = np->next;
856 kfree(np);
857 APPL(appl)->nncci--;
858 printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci);
859 notify_push(KCI_NCCIDOWN, CARDNR(card), appl, ncci);
860 return;
863 printk(KERN_ERR "free_ncci: ncci 0x%x not found\n", ncci);
867 static struct capi_ncci *find_ncci(struct capi_appl * app, __u32 ncci)
869 struct capi_ncci *np;
870 for (np = app->nccilist; np; np = np->next) {
871 if (np->ncci == ncci)
872 return np;
874 return 0;
877 /* -------- Receiver ------------------------------------------ */
879 static void recv_handler(void *dummy)
881 struct sk_buff *skb;
883 while ((skb = skb_dequeue(&recv_queue)) != 0) {
884 __u16 appl = CAPIMSG_APPID(skb->data);
885 struct capi_ncci *np;
886 if (!VALID_APPLID(appl)) {
887 printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n",
888 appl, capi_message2str(skb->data));
889 kfree_skb(skb);
890 continue;
892 if (APPL(appl)->signal == 0) {
893 printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n",
894 appl);
895 kfree_skb(skb);
896 continue;
898 if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
899 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF
900 && (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0
901 && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) {
902 printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
903 CAPIMSG_MSGID(skb->data), np->ncci);
905 if ( CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
906 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
907 APPL(appl)->nrecvdatapkt++;
908 } else {
909 APPL(appl)->nrecvctlpkt++;
911 skb_queue_tail(&APPL(appl)->recv_queue, skb);
912 (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param);
916 static void controllercb_handle_capimsg(struct capi_ctr * card,
917 __u16 appl, struct sk_buff *skb)
919 int showctl = 0;
920 __u8 cmd, subcmd;
922 if (card->cardstate != CARD_RUNNING) {
923 printk(KERN_INFO "kcapi: controller %d not active, got: %s",
924 card->cnr, capi_message2str(skb->data));
925 goto error;
927 cmd = CAPIMSG_COMMAND(skb->data);
928 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
929 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
930 card->nrecvdatapkt++;
931 if (card->traceflag > 2) showctl |= 2;
932 } else {
933 card->nrecvctlpkt++;
934 if (card->traceflag) showctl |= 2;
936 showctl |= (card->traceflag & 1);
937 if (showctl & 2) {
938 if (showctl & 1) {
939 printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n",
940 (unsigned long) card->cnr,
941 CAPIMSG_APPID(skb->data),
942 capi_cmd2str(cmd, subcmd),
943 CAPIMSG_LEN(skb->data));
944 } else {
945 printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n",
946 (unsigned long) card->cnr,
947 capi_message2str(skb->data));
951 skb_queue_tail(&recv_queue, skb);
952 queue_task(&tq_recv_notify, &tq_immediate);
953 mark_bh(IMMEDIATE_BH);
954 return;
956 error:
957 kfree_skb(skb);
960 static void controllercb_ready(struct capi_ctr * card)
962 __u16 appl;
964 card->cardstate = CARD_RUNNING;
966 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
967 if (!VALID_APPLID(appl)) continue;
968 if (APPL(appl)->releasing) continue;
969 card->driver->register_appl(card, appl, &APPL(appl)->rparam);
972 printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
973 CARDNR(card), card->name);
975 notify_push(KCI_CONTRUP, CARDNR(card), 0, 0);
978 static void controllercb_reseted(struct capi_ctr * card)
980 __u16 appl;
982 if (card->cardstate == CARD_FREE)
983 return;
984 if (card->cardstate == CARD_DETECTED)
985 return;
987 card->cardstate = CARD_DETECTED;
989 memset(card->manu, 0, sizeof(card->manu));
990 memset(&card->version, 0, sizeof(card->version));
991 memset(&card->profile, 0, sizeof(card->profile));
992 memset(card->serial, 0, sizeof(card->serial));
994 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
995 struct capi_ncci **pp, **nextpp;
996 for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
997 if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
998 struct capi_ncci *np = *pp;
999 *pp = np->next;
1000 printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci);
1001 notify_push(KCI_NCCIDOWN, CARDNR(card), appl, np->ncci);
1002 kfree(np);
1003 nextpp = pp;
1004 } else {
1005 nextpp = &(*pp)->next;
1010 printk(KERN_NOTICE "kcapi: card %d down.\n", CARDNR(card));
1012 notify_push(KCI_CONTRDOWN, CARDNR(card), 0, 0);
1015 static void controllercb_suspend_output(struct capi_ctr *card)
1017 if (!card->blocked) {
1018 printk(KERN_DEBUG "kcapi: card %d suspend\n", CARDNR(card));
1019 card->blocked = 1;
1023 static void controllercb_resume_output(struct capi_ctr *card)
1025 if (card->blocked) {
1026 printk(KERN_DEBUG "kcapi: card %d resume\n", CARDNR(card));
1027 card->blocked = 0;
1031 /* ------------------------------------------------------------- */
1034 struct capi_ctr *
1035 drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
1037 struct capi_ctr *card, **pp;
1038 int i;
1040 for (i=0; i < CAPI_MAXCONTR && cards[i].cardstate != CARD_FREE; i++) ;
1042 if (i == CAPI_MAXCONTR) {
1043 printk(KERN_ERR "kcapi: out of controller slots\n");
1044 return 0;
1046 card = &cards[i];
1047 memset(card, 0, sizeof(struct capi_ctr));
1048 card->driver = driver;
1049 card->cnr = CARDNR(card);
1050 strncpy(card->name, name, sizeof(card->name));
1051 card->cardstate = CARD_DETECTED;
1052 card->blocked = 0;
1053 card->driverdata = driverdata;
1054 card->traceflag = showcapimsgs;
1056 card->ready = controllercb_ready;
1057 card->reseted = controllercb_reseted;
1058 card->suspend_output = controllercb_suspend_output;
1059 card->resume_output = controllercb_resume_output;
1060 card->handle_capimsg = controllercb_handle_capimsg;
1061 card->appl_registered = controllercb_appl_registered;
1062 card->appl_released = controllercb_appl_released;
1063 card->new_ncci = controllercb_new_ncci;
1064 card->free_ncci = controllercb_free_ncci;
1066 for (pp = &driver->controller; *pp; pp = &(*pp)->next) ;
1067 card->next = 0;
1068 *pp = card;
1069 driver->ncontroller++;
1070 sprintf(card->procfn, "capi/controllers/%d", card->cnr);
1071 card->procent = create_proc_entry(card->procfn, 0, 0);
1072 if (card->procent) {
1073 card->procent->read_proc =
1074 (int (*)(char *,char **,off_t,int,int *,void *))
1075 driver->ctr_read_proc;
1076 card->procent->data = card;
1079 ncards++;
1080 printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n",
1081 card->cnr, card->name);
1082 return card;
1085 static int drivercb_detach_ctr(struct capi_ctr *card)
1087 struct capi_driver *driver = card->driver;
1088 struct capi_ctr **pp;
1090 if (card->cardstate == CARD_FREE)
1091 return 0;
1092 if (card->cardstate != CARD_DETECTED)
1093 controllercb_reseted(card);
1094 for (pp = &driver->controller; *pp ; pp = &(*pp)->next) {
1095 if (*pp == card) {
1096 *pp = card->next;
1097 driver->ncontroller--;
1098 ncards--;
1099 break;
1102 if (card->procent) {
1103 remove_proc_entry(card->procfn, 0);
1104 card->procent = 0;
1106 card->cardstate = CARD_FREE;
1107 printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n",
1108 card->cnr, card->name);
1109 return 0;
1112 /* ------------------------------------------------------------- */
1114 /* fallback if no driver read_proc function defined by driver */
1116 static int driver_read_proc(char *page, char **start, off_t off,
1117 int count, int *eof, void *data)
1119 struct capi_driver *driver = (struct capi_driver *)data;
1120 int len = 0;
1122 len += sprintf(page+len, "%-16s %s\n", "name", driver->name);
1123 len += sprintf(page+len, "%-16s %s\n", "revision", driver->revision);
1125 if (len < off)
1126 return 0;
1127 *eof = 1;
1128 *start = page + off;
1129 return ((count < len-off) ? count : len-off);
1132 /* ------------------------------------------------------------- */
1134 static struct capi_driver_interface di = {
1135 drivercb_attach_ctr,
1136 drivercb_detach_ctr,
1139 struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
1141 struct capi_driver **pp;
1143 MOD_INC_USE_COUNT;
1144 spin_lock(&drivers_lock);
1145 for (pp = &drivers; *pp; pp = &(*pp)->next) ;
1146 driver->next = 0;
1147 *pp = driver;
1148 spin_unlock(&drivers_lock);
1149 printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name);
1150 sprintf(driver->procfn, "capi/drivers/%s", driver->name);
1151 driver->procent = create_proc_entry(driver->procfn, 0, 0);
1152 if (driver->procent) {
1153 if (driver->driver_read_proc) {
1154 driver->procent->read_proc =
1155 (int (*)(char *,char **,off_t,int,int *,void *))
1156 driver->driver_read_proc;
1157 } else {
1158 driver->procent->read_proc = driver_read_proc;
1160 driver->procent->data = driver;
1162 return &di;
1165 void detach_capi_driver(struct capi_driver *driver)
1167 struct capi_driver **pp;
1168 spin_lock(&drivers_lock);
1169 for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ;
1170 if (*pp) {
1171 *pp = (*pp)->next;
1172 printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
1173 } else {
1174 printk(KERN_ERR "kcapi: driver %s double detach ?\n", driver->name);
1176 spin_unlock(&drivers_lock);
1177 if (driver->procent) {
1178 remove_proc_entry(driver->procfn, 0);
1179 driver->procent = 0;
1181 MOD_DEC_USE_COUNT;
1184 /* ------------------------------------------------------------- */
1185 /* -------- CAPI2.0 Interface ---------------------------------- */
1186 /* ------------------------------------------------------------- */
1188 static __u16 capi_isinstalled(void)
1190 int i;
1191 for (i = 0; i < CAPI_MAXCONTR; i++) {
1192 if (cards[i].cardstate == CARD_RUNNING)
1193 return CAPI_NOERROR;
1195 return CAPI_REGNOTINSTALLED;
1198 static __u16 capi_register(capi_register_params * rparam, __u16 * applidp)
1200 int appl;
1201 int i;
1203 if (rparam->datablklen < 128)
1204 return CAPI_LOGBLKSIZETOSMALL;
1206 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
1207 if (APPL_IS_FREE(appl))
1208 break;
1210 if (appl > CAPI_MAXAPPL)
1211 return CAPI_TOOMANYAPPLS;
1213 APPL_MARK_USED(appl);
1214 skb_queue_head_init(&APPL(appl)->recv_queue);
1215 APPL(appl)->nncci = 0;
1217 memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
1219 for (i = 0; i < CAPI_MAXCONTR; i++) {
1220 if (cards[i].cardstate != CARD_RUNNING)
1221 continue;
1222 cards[i].driver->register_appl(&cards[i], appl,
1223 &APPL(appl)->rparam);
1225 *applidp = appl;
1226 printk(KERN_INFO "kcapi: appl %d up\n", appl);
1228 return CAPI_NOERROR;
1231 static __u16 capi_release(__u16 applid)
1233 struct sk_buff *skb;
1234 int i;
1236 if (!VALID_APPLID(applid) || APPL(applid)->releasing)
1237 return CAPI_ILLAPPNR;
1238 APPL(applid)->releasing++;
1239 while ((skb = skb_dequeue(&APPL(applid)->recv_queue)) != 0)
1240 kfree_skb(skb);
1241 for (i = 0; i < CAPI_MAXCONTR; i++) {
1242 if (cards[i].cardstate != CARD_RUNNING)
1243 continue;
1244 APPL(applid)->releasing++;
1245 cards[i].driver->release_appl(&cards[i], applid);
1247 APPL(applid)->releasing--;
1248 if (APPL(applid)->releasing <= 0) {
1249 APPL(applid)->signal = 0;
1250 APPL_MARK_FREE(applid);
1251 printk(KERN_INFO "kcapi: appl %d down\n", applid);
1253 return CAPI_NOERROR;
1256 static __u16 capi_put_message(__u16 applid, struct sk_buff *skb)
1258 struct capi_ncci *np;
1259 __u32 contr;
1260 int showctl = 0;
1261 __u8 cmd, subcmd;
1263 if (ncards == 0)
1264 return CAPI_REGNOTINSTALLED;
1265 if (!VALID_APPLID(applid))
1266 return CAPI_ILLAPPNR;
1267 if (skb->len < 12
1268 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
1269 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
1270 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
1271 contr = CAPIMSG_CONTROLLER(skb->data);
1272 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) {
1273 contr = 1;
1274 if (CARD(contr)->cardstate != CARD_RUNNING)
1275 return CAPI_REGNOTINSTALLED;
1277 if (CARD(contr)->blocked)
1278 return CAPI_SENDQUEUEFULL;
1280 cmd = CAPIMSG_COMMAND(skb->data);
1281 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
1283 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
1284 if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0
1285 && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)
1286 return CAPI_SENDQUEUEFULL;
1287 CARD(contr)->nsentdatapkt++;
1288 APPL(applid)->nsentdatapkt++;
1289 if (CARD(contr)->traceflag > 2) showctl |= 2;
1290 } else {
1291 CARD(contr)->nsentctlpkt++;
1292 APPL(applid)->nsentctlpkt++;
1293 if (CARD(contr)->traceflag) showctl |= 2;
1295 showctl |= (CARD(contr)->traceflag & 1);
1296 if (showctl & 2) {
1297 if (showctl & 1) {
1298 printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n",
1299 (unsigned long) contr,
1300 CAPIMSG_APPID(skb->data),
1301 capi_cmd2str(cmd, subcmd),
1302 CAPIMSG_LEN(skb->data));
1303 } else {
1304 printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n",
1305 (unsigned long) contr,
1306 capi_message2str(skb->data));
1310 CARD(contr)->driver->send_message(CARD(contr), skb);
1311 return CAPI_NOERROR;
1314 static __u16 capi_get_message(__u16 applid, struct sk_buff **msgp)
1316 struct sk_buff *skb;
1318 if (!VALID_APPLID(applid))
1319 return CAPI_ILLAPPNR;
1320 if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0)
1321 return CAPI_RECEIVEQUEUEEMPTY;
1322 *msgp = skb;
1323 return CAPI_NOERROR;
1326 static __u16 capi_set_signal(__u16 applid,
1327 void (*signal) (__u16 applid, void *param),
1328 void *param)
1330 if (!VALID_APPLID(applid))
1331 return CAPI_ILLAPPNR;
1332 APPL(applid)->signal = signal;
1333 APPL(applid)->param = param;
1334 return CAPI_NOERROR;
1337 static __u16 capi_get_manufacturer(__u32 contr, __u8 buf[CAPI_MANUFACTURER_LEN])
1339 if (contr == 0) {
1340 strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
1341 return CAPI_NOERROR;
1343 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1344 return CAPI_REGNOTINSTALLED;
1346 strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN);
1347 return CAPI_NOERROR;
1350 static __u16 capi_get_version(__u32 contr, struct capi_version *verp)
1352 if (contr == 0) {
1353 *verp = driver_version;
1354 return CAPI_NOERROR;
1356 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1357 return CAPI_REGNOTINSTALLED;
1359 memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version));
1360 return CAPI_NOERROR;
1363 static __u16 capi_get_serial(__u32 contr, __u8 serial[CAPI_SERIAL_LEN])
1365 if (contr == 0) {
1366 strncpy(serial, driver_serial, CAPI_SERIAL_LEN);
1367 return CAPI_NOERROR;
1369 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1370 return CAPI_REGNOTINSTALLED;
1372 strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN);
1373 return CAPI_NOERROR;
1376 static __u16 capi_get_profile(__u32 contr, struct capi_profile *profp)
1378 if (contr == 0) {
1379 profp->ncontroller = ncards;
1380 return CAPI_NOERROR;
1382 if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1383 return CAPI_REGNOTINSTALLED;
1385 memcpy((void *) profp, &CARD(contr)->profile,
1386 sizeof(struct capi_profile));
1387 return CAPI_NOERROR;
1390 static struct capi_driver *find_driver(char *name)
1392 struct capi_driver *dp;
1393 spin_lock(&drivers_lock);
1394 for (dp = drivers; dp; dp = dp->next)
1395 if (strcmp(dp->name, name) == 0)
1396 break;
1397 spin_unlock(&drivers_lock);
1398 return dp;
1401 #ifdef CONFIG_AVMB1_COMPAT
1402 static int old_capi_manufacturer(unsigned int cmd, void *data)
1404 avmb1_loadandconfigdef ldef;
1405 avmb1_extcarddef cdef;
1406 avmb1_resetdef rdef;
1407 avmb1_getdef gdef;
1408 struct capi_driver *driver;
1409 struct capi_ctr *card;
1410 capicardparams cparams;
1411 capiloaddata ldata;
1412 int retval;
1414 switch (cmd) {
1415 case AVMB1_ADDCARD:
1416 case AVMB1_ADDCARD_WITH_TYPE:
1417 if (cmd == AVMB1_ADDCARD) {
1418 if ((retval = copy_from_user((void *) &cdef, data,
1419 sizeof(avmb1_carddef))))
1420 return retval;
1421 cdef.cardtype = AVM_CARDTYPE_B1;
1422 } else {
1423 if ((retval = copy_from_user((void *) &cdef, data,
1424 sizeof(avmb1_extcarddef))))
1425 return retval;
1427 cparams.port = cdef.port;
1428 cparams.irq = cdef.irq;
1429 cparams.cardnr = cdef.cardnr;
1431 switch (cdef.cardtype) {
1432 case AVM_CARDTYPE_B1:
1433 driver = find_driver("b1isa");
1434 break;
1435 case AVM_CARDTYPE_T1:
1436 driver = find_driver("t1isa");
1437 break;
1438 default:
1439 driver = 0;
1440 break;
1442 if (!driver) {
1443 printk(KERN_ERR "kcapi: driver not loaded.\n");
1444 return -EIO;
1446 if (!driver->add_card) {
1447 printk(KERN_ERR "kcapi: driver has no add card function.\n");
1448 return -EIO;
1451 return driver->add_card(driver, &cparams);
1453 case AVMB1_LOAD:
1454 case AVMB1_LOAD_AND_CONFIG:
1456 if (cmd == AVMB1_LOAD) {
1457 if ((retval = copy_from_user((void *) &ldef, data,
1458 sizeof(avmb1_loaddef))))
1459 return retval;
1460 ldef.t4config.len = 0;
1461 ldef.t4config.data = 0;
1462 } else {
1463 if ((retval = copy_from_user((void *) &ldef, data,
1464 sizeof(avmb1_loadandconfigdef))))
1465 return retval;
1467 if (!VALID_CARD(ldef.contr))
1468 return -ESRCH;
1470 card = CARD(ldef.contr);
1471 if (card->cardstate == CARD_FREE)
1472 return -ESRCH;
1473 if (card->driver->load_firmware == 0) {
1474 printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name);
1475 return -ESRCH;
1478 if (ldef.t4file.len <= 0) {
1479 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
1480 return -EINVAL;
1482 if (ldef.t4file.data == 0) {
1483 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
1484 return -EINVAL;
1487 ldata.firmware.user = 1;
1488 ldata.firmware.data = ldef.t4file.data;
1489 ldata.firmware.len = ldef.t4file.len;
1490 ldata.configuration.user = 1;
1491 ldata.configuration.data = ldef.t4config.data;
1492 ldata.configuration.len = ldef.t4config.len;
1494 if (card->cardstate != CARD_DETECTED) {
1495 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
1496 return -EBUSY;
1498 card->cardstate = CARD_LOADING;
1500 retval = card->driver->load_firmware(card, &ldata);
1502 if (retval) {
1503 card->cardstate = CARD_DETECTED;
1504 return retval;
1507 while (card->cardstate != CARD_RUNNING) {
1509 set_current_state(TASK_INTERRUPTIBLE);
1510 schedule_timeout(HZ/10); /* 0.1 sec */
1512 if (signal_pending(current))
1513 return -EINTR;
1515 return 0;
1517 case AVMB1_RESETCARD:
1518 if ((retval = copy_from_user((void *) &rdef, data,
1519 sizeof(avmb1_resetdef))))
1520 return retval;
1521 if (!VALID_CARD(rdef.contr))
1522 return -ESRCH;
1523 card = CARD(rdef.contr);
1525 if (card->cardstate == CARD_FREE)
1526 return -ESRCH;
1527 if (card->cardstate == CARD_DETECTED)
1528 return 0;
1530 card->driver->reset_ctr(card);
1532 while (card->cardstate > CARD_DETECTED) {
1534 set_current_state(TASK_INTERRUPTIBLE);
1535 schedule_timeout(HZ/10); /* 0.1 sec */
1537 if (signal_pending(current))
1538 return -EINTR;
1540 return 0;
1542 case AVMB1_GET_CARDINFO:
1543 if ((retval = copy_from_user((void *) &gdef, data,
1544 sizeof(avmb1_getdef))))
1545 return retval;
1547 if (!VALID_CARD(gdef.contr))
1548 return -ESRCH;
1550 card = CARD(gdef.contr);
1552 if (card->cardstate == CARD_FREE)
1553 return -ESRCH;
1555 gdef.cardstate = card->cardstate;
1556 if (card->driver == find_driver("t1isa"))
1557 gdef.cardtype = AVM_CARDTYPE_T1;
1558 else gdef.cardtype = AVM_CARDTYPE_B1;
1560 if ((retval = copy_to_user(data, (void *) &gdef,
1561 sizeof(avmb1_getdef))))
1562 return retval;
1564 return 0;
1566 case AVMB1_REMOVECARD:
1567 if ((retval = copy_from_user((void *) &rdef, data,
1568 sizeof(avmb1_resetdef))))
1569 return retval;
1571 if (!VALID_CARD(rdef.contr))
1572 return -ESRCH;
1573 card = CARD(rdef.contr);
1575 if (card->cardstate == CARD_FREE)
1576 return -ESRCH;
1578 if (card->cardstate != CARD_DETECTED)
1579 return -EBUSY;
1581 card->driver->remove_ctr(card);
1583 while (card->cardstate != CARD_FREE) {
1585 set_current_state(TASK_INTERRUPTIBLE);
1586 schedule_timeout(HZ/10); /* 0.1 sec */
1588 if (signal_pending(current))
1589 return -EINTR;
1591 return 0;
1593 return -EINVAL;
1595 #endif
1597 static int capi_manufacturer(unsigned int cmd, void *data)
1599 struct capi_ctr *card;
1600 int retval;
1602 switch (cmd) {
1603 #ifdef CONFIG_AVMB1_COMPAT
1604 case AVMB1_ADDCARD:
1605 case AVMB1_ADDCARD_WITH_TYPE:
1606 case AVMB1_LOAD:
1607 case AVMB1_LOAD_AND_CONFIG:
1608 case AVMB1_RESETCARD:
1609 case AVMB1_GET_CARDINFO:
1610 case AVMB1_REMOVECARD:
1611 return old_capi_manufacturer(cmd, data);
1612 #endif
1613 case KCAPI_CMD_TRACE:
1615 kcapi_flagdef fdef;
1617 if ((retval = copy_from_user((void *) &fdef, data,
1618 sizeof(kcapi_flagdef))))
1619 return retval;
1621 if (!VALID_CARD(fdef.contr))
1622 return -ESRCH;
1623 card = CARD(fdef.contr);
1624 if (card->cardstate == CARD_FREE)
1625 return -ESRCH;
1626 card->traceflag = fdef.flag;
1627 printk(KERN_INFO "kcapi: contr %d set trace=%d\n",
1628 card->cnr, card->traceflag);
1629 return 0;
1632 case KCAPI_CMD_ADDCARD:
1634 struct capi_driver *driver;
1635 capicardparams cparams;
1636 kcapi_carddef cdef;
1638 if ((retval = copy_from_user((void *) &cdef, data,
1639 sizeof(cdef))))
1640 return retval;
1642 cparams.port = cdef.port;
1643 cparams.irq = cdef.irq;
1644 cparams.membase = cdef.membase;
1645 cparams.cardnr = cdef.cardnr;
1646 cparams.cardtype = 0;
1647 cdef.driver[sizeof(cdef.driver)-1] = 0;
1649 if ((driver = find_driver(cdef.driver)) == 0) {
1650 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
1651 cdef.driver);
1652 return -ESRCH;
1655 if (!driver->add_card) {
1656 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
1657 return -EIO;
1660 return driver->add_card(driver, &cparams);
1663 default:
1664 printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
1665 cmd);
1666 break;
1669 return -EINVAL;
1672 struct capi_interface avmb1_interface =
1674 capi_isinstalled,
1675 capi_register,
1676 capi_release,
1677 capi_put_message,
1678 capi_get_message,
1679 capi_set_signal,
1680 capi_get_manufacturer,
1681 capi_get_version,
1682 capi_get_serial,
1683 capi_get_profile,
1684 capi_manufacturer
1687 /* ------------------------------------------------------------- */
1688 /* -------- Exported Functions --------------------------------- */
1689 /* ------------------------------------------------------------- */
1691 struct capi_interface *attach_capi_interface(struct capi_interface_user *userp)
1693 struct capi_interface_user *p;
1695 MOD_INC_USE_COUNT;
1696 spin_lock(&capi_users_lock);
1697 for (p = capi_users; p; p = p->next) {
1698 if (p == userp) {
1699 spin_unlock(&capi_users_lock);
1700 printk(KERN_ERR "kcapi: double attach from %s\n",
1701 userp->name);
1702 MOD_DEC_USE_COUNT;
1703 return 0;
1706 userp->next = capi_users;
1707 capi_users = userp;
1708 spin_unlock(&capi_users_lock);
1709 printk(KERN_NOTICE "kcapi: %s attached\n", userp->name);
1711 return &avmb1_interface;
1714 int detach_capi_interface(struct capi_interface_user *userp)
1716 struct capi_interface_user **pp;
1718 spin_lock(&capi_users_lock);
1719 for (pp = &capi_users; *pp; pp = &(*pp)->next) {
1720 if (*pp == userp) {
1721 *pp = userp->next;
1722 spin_unlock(&capi_users_lock);
1723 userp->next = 0;
1724 printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);
1725 MOD_DEC_USE_COUNT;
1726 return 0;
1729 spin_unlock(&capi_users_lock);
1730 printk(KERN_ERR "kcapi: double detach from %s\n", userp->name);
1731 return -1;
1734 /* ------------------------------------------------------------- */
1735 /* -------- Init & Cleanup ------------------------------------- */
1736 /* ------------------------------------------------------------- */
1738 EXPORT_SYMBOL(attach_capi_interface);
1739 EXPORT_SYMBOL(detach_capi_interface);
1740 EXPORT_SYMBOL(attach_capi_driver);
1741 EXPORT_SYMBOL(detach_capi_driver);
1744 * init / exit functions
1747 static int __init kcapi_init(void)
1749 char *p;
1750 char rev[10];
1752 MOD_INC_USE_COUNT;
1754 skb_queue_head_init(&recv_queue);
1756 tq_state_notify.routine = notify_handler;
1757 tq_state_notify.data = 0;
1759 tq_recv_notify.routine = recv_handler;
1760 tq_recv_notify.data = 0;
1762 proc_capi_init();
1764 if ((p = strchr(revision, ':'))) {
1765 strcpy(rev, p + 1);
1766 p = strchr(rev, '$');
1767 *p = 0;
1768 } else
1769 strcpy(rev, "1.0");
1771 #ifdef MODULE
1772 printk(KERN_NOTICE "CAPI-driver Rev%s: loaded\n", rev);
1773 #else
1774 printk(KERN_NOTICE "CAPI-driver Rev%s: started\n", rev);
1775 #endif
1776 MOD_DEC_USE_COUNT;
1777 return 0;
1780 static void __exit kcapi_exit(void)
1782 char rev[10];
1783 char *p;
1785 if ((p = strchr(revision, ':'))) {
1786 strcpy(rev, p + 1);
1787 p = strchr(rev, '$');
1788 *p = 0;
1789 } else {
1790 strcpy(rev, "1.0");
1793 proc_capi_exit();
1794 printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev);
1797 module_init(kcapi_init);
1798 module_exit(kcapi_exit);