1 /* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $
3 * Kernel CAPI 2.0 Module
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
6 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #define CONFIG_AVMB1_COMPAT
16 #include <linux/module.h>
18 #include <linux/interrupt.h>
19 #include <linux/ioport.h>
20 #include <linux/proc_fs.h>
21 #include <linux/seq_file.h>
22 #include <linux/skbuff.h>
23 #include <linux/workqueue.h>
24 #include <linux/capi.h>
25 #include <linux/kernelcapi.h>
26 #include <linux/init.h>
27 #include <linux/moduleparam.h>
28 #include <linux/delay.h>
29 #include <asm/uaccess.h>
30 #include <linux/isdn/capicmd.h>
31 #include <linux/isdn/capiutil.h>
32 #ifdef CONFIG_AVMB1_COMPAT
33 #include <linux/b1lli.h>
36 static char *revision
= "$Revision: 1.1.2.8 $";
38 /* ------------------------------------------------------------- */
40 static int showcapimsgs
= 0;
42 MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
43 MODULE_AUTHOR("Carsten Paeth");
44 MODULE_LICENSE("GPL");
45 module_param(showcapimsgs
, uint
, 0);
47 /* ------------------------------------------------------------- */
49 struct capi_notifier
{
50 struct work_struct work
;
57 /* ------------------------------------------------------------- */
59 static struct capi_version driver_version
= {2, 0, 1, 1<<4};
60 static char driver_serial
[CAPI_SERIAL_LEN
] = "0004711";
61 static char capi_manufakturer
[64] = "AVM Berlin";
63 #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
65 LIST_HEAD(capi_drivers
);
66 DEFINE_RWLOCK(capi_drivers_list_lock
);
68 static DEFINE_RWLOCK(application_lock
);
69 static DECLARE_MUTEX(controller_sem
);
71 struct capi20_appl
*capi_applications
[CAPI_MAXAPPL
];
72 struct capi_ctr
*capi_cards
[CAPI_MAXCONTR
];
76 /* -------- controller ref counting -------------------------------------- */
78 static inline struct capi_ctr
*
79 capi_ctr_get(struct capi_ctr
*card
)
81 if (!try_module_get(card
->owner
))
87 capi_ctr_put(struct capi_ctr
*card
)
89 module_put(card
->owner
);
92 /* ------------------------------------------------------------- */
94 static inline struct capi_ctr
*get_capi_ctr_by_nr(u16 contr
)
96 if (contr
- 1 >= CAPI_MAXCONTR
)
99 return capi_cards
[contr
- 1];
102 static inline struct capi20_appl
*get_capi_appl_by_nr(u16 applid
)
104 if (applid
- 1 >= CAPI_MAXAPPL
)
107 return capi_applications
[applid
- 1];
110 /* -------- util functions ------------------------------------ */
112 static inline int capi_cmd_valid(u8 cmd
)
117 case CAPI_CONNECT_ACTIVE
:
118 case CAPI_CONNECT_B3_ACTIVE
:
119 case CAPI_CONNECT_B3
:
120 case CAPI_CONNECT_B3_T90_ACTIVE
:
122 case CAPI_DISCONNECT_B3
:
123 case CAPI_DISCONNECT
:
127 case CAPI_MANUFACTURER
:
129 case CAPI_SELECT_B_PROTOCOL
:
135 static inline int capi_subcmd_valid(u8 subcmd
)
147 /* ------------------------------------------------------------ */
149 static void register_appl(struct capi_ctr
*card
, u16 applid
, capi_register_params
*rparam
)
151 card
= capi_ctr_get(card
);
154 card
->register_appl(card
, applid
, rparam
);
156 printk(KERN_WARNING
"%s: cannot get card resources\n", __FUNCTION__
);
160 static void release_appl(struct capi_ctr
*card
, u16 applid
)
162 DBG("applid %#x", applid
);
164 card
->release_appl(card
, applid
);
168 /* -------- KCI_CONTRUP --------------------------------------- */
170 static void notify_up(u32 contr
)
172 struct capi_ctr
*card
= get_capi_ctr_by_nr(contr
);
173 struct capi20_appl
*ap
;
176 if (showcapimsgs
& 1) {
177 printk(KERN_DEBUG
"kcapi: notify up contr %d\n", contr
);
180 printk(KERN_WARNING
"%s: invalid contr %d\n", __FUNCTION__
, contr
);
183 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
184 ap
= get_capi_appl_by_nr(applid
);
185 if (!ap
|| ap
->release_in_progress
) continue;
186 register_appl(card
, applid
, &ap
->rparam
);
187 if (ap
->callback
&& !ap
->release_in_progress
)
188 ap
->callback(KCI_CONTRUP
, contr
, &card
->profile
);
192 /* -------- KCI_CONTRDOWN ------------------------------------- */
194 static void notify_down(u32 contr
)
196 struct capi20_appl
*ap
;
199 if (showcapimsgs
& 1) {
200 printk(KERN_DEBUG
"kcapi: notify down contr %d\n", contr
);
203 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
204 ap
= get_capi_appl_by_nr(applid
);
205 if (ap
&& ap
->callback
&& !ap
->release_in_progress
)
206 ap
->callback(KCI_CONTRDOWN
, contr
, NULL
);
210 static void notify_handler(void *data
)
212 struct capi_notifier
*np
= data
;
216 notify_up(np
->controller
);
219 notify_down(np
->controller
);
227 * The notifier will result in adding/deleteing of devices. Devices can
228 * only removed in user process, not in bh.
230 static int notify_push(unsigned int cmd
, u32 controller
, u16 applid
, u32 ncci
)
232 struct capi_notifier
*np
= kmalloc(sizeof(*np
), GFP_ATOMIC
);
237 INIT_WORK(&np
->work
, notify_handler
, np
);
239 np
->controller
= controller
;
243 schedule_work(&np
->work
);
248 /* -------- Receiver ------------------------------------------ */
250 static void recv_handler(void *_ap
)
253 struct capi20_appl
*ap
= (struct capi20_appl
*) _ap
;
255 if ((!ap
) || (ap
->release_in_progress
))
259 while ((skb
= skb_dequeue(&ap
->recv_queue
))) {
260 if (CAPIMSG_CMD(skb
->data
) == CAPI_DATA_B3_IND
)
265 ap
->recv_message(ap
, skb
);
270 void capi_ctr_handle_message(struct capi_ctr
* card
, u16 appl
, struct sk_buff
*skb
)
272 struct capi20_appl
*ap
;
277 if (card
->cardstate
!= CARD_RUNNING
) {
278 printk(KERN_INFO
"kcapi: controller %d not active, got: %s",
279 card
->cnr
, capi_message2str(skb
->data
));
283 cmd
= CAPIMSG_COMMAND(skb
->data
);
284 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
285 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_IND
) {
286 card
->nrecvdatapkt
++;
287 if (card
->traceflag
> 2) showctl
|= 2;
290 if (card
->traceflag
) showctl
|= 2;
292 showctl
|= (card
->traceflag
& 1);
295 printk(KERN_DEBUG
"kcapi: got [0x%lx] id#%d %s len=%u\n",
296 (unsigned long) card
->cnr
,
297 CAPIMSG_APPID(skb
->data
),
298 capi_cmd2str(cmd
, subcmd
),
299 CAPIMSG_LEN(skb
->data
));
301 printk(KERN_DEBUG
"kcapi: got [0x%lx] %s\n",
302 (unsigned long) card
->cnr
,
303 capi_message2str(skb
->data
));
308 read_lock_irqsave(&application_lock
, flags
);
309 ap
= get_capi_appl_by_nr(CAPIMSG_APPID(skb
->data
));
310 if ((!ap
) || (ap
->release_in_progress
)) {
311 read_unlock_irqrestore(&application_lock
, flags
);
312 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s)\n",
313 CAPIMSG_APPID(skb
->data
), capi_message2str(skb
->data
));
316 skb_queue_tail(&ap
->recv_queue
, skb
);
317 schedule_work(&ap
->recv_work
);
318 read_unlock_irqrestore(&application_lock
, flags
);
326 EXPORT_SYMBOL(capi_ctr_handle_message
);
328 void capi_ctr_ready(struct capi_ctr
* card
)
330 card
->cardstate
= CARD_RUNNING
;
332 printk(KERN_NOTICE
"kcapi: card %d \"%s\" ready.\n",
333 card
->cnr
, card
->name
);
335 notify_push(KCI_CONTRUP
, card
->cnr
, 0, 0);
338 EXPORT_SYMBOL(capi_ctr_ready
);
340 void capi_ctr_reseted(struct capi_ctr
* card
)
346 if (card
->cardstate
== CARD_DETECTED
)
349 card
->cardstate
= CARD_DETECTED
;
351 memset(card
->manu
, 0, sizeof(card
->manu
));
352 memset(&card
->version
, 0, sizeof(card
->version
));
353 memset(&card
->profile
, 0, sizeof(card
->profile
));
354 memset(card
->serial
, 0, sizeof(card
->serial
));
356 for (appl
= 1; appl
<= CAPI_MAXAPPL
; appl
++) {
357 struct capi20_appl
*ap
= get_capi_appl_by_nr(appl
);
358 if (!ap
|| ap
->release_in_progress
)
364 printk(KERN_NOTICE
"kcapi: card %d down.\n", card
->cnr
);
366 notify_push(KCI_CONTRDOWN
, card
->cnr
, 0, 0);
369 EXPORT_SYMBOL(capi_ctr_reseted
);
371 void capi_ctr_suspend_output(struct capi_ctr
*card
)
373 if (!card
->blocked
) {
374 printk(KERN_DEBUG
"kcapi: card %d suspend\n", card
->cnr
);
379 EXPORT_SYMBOL(capi_ctr_suspend_output
);
381 void capi_ctr_resume_output(struct capi_ctr
*card
)
384 printk(KERN_DEBUG
"kcapi: card %d resume\n", card
->cnr
);
389 EXPORT_SYMBOL(capi_ctr_resume_output
);
391 /* ------------------------------------------------------------- */
394 attach_capi_ctr(struct capi_ctr
*card
)
398 down(&controller_sem
);
400 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
401 if (capi_cards
[i
] == NULL
)
404 if (i
== CAPI_MAXCONTR
) {
406 printk(KERN_ERR
"kcapi: out of controller slots\n");
409 capi_cards
[i
] = card
;
413 card
->nrecvctlpkt
= 0;
414 card
->nrecvdatapkt
= 0;
415 card
->nsentctlpkt
= 0;
416 card
->nsentdatapkt
= 0;
418 card
->cardstate
= CARD_DETECTED
;
420 card
->traceflag
= showcapimsgs
;
422 sprintf(card
->procfn
, "capi/controllers/%d", card
->cnr
);
423 card
->procent
= create_proc_entry(card
->procfn
, 0, NULL
);
425 card
->procent
->read_proc
=
426 (int (*)(char *,char **,off_t
,int,int *,void *))
428 card
->procent
->data
= card
;
432 printk(KERN_NOTICE
"kcapi: Controller %d: %s attached\n",
433 card
->cnr
, card
->name
);
437 EXPORT_SYMBOL(attach_capi_ctr
);
439 int detach_capi_ctr(struct capi_ctr
*card
)
441 if (card
->cardstate
!= CARD_DETECTED
)
442 capi_ctr_reseted(card
);
447 remove_proc_entry(card
->procfn
, NULL
);
448 card
->procent
= NULL
;
450 capi_cards
[card
->cnr
- 1] = NULL
;
451 printk(KERN_NOTICE
"kcapi: Controller %d: %s unregistered\n",
452 card
->cnr
, card
->name
);
457 EXPORT_SYMBOL(detach_capi_ctr
);
459 void register_capi_driver(struct capi_driver
*driver
)
463 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
464 list_add_tail(&driver
->list
, &capi_drivers
);
465 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
468 EXPORT_SYMBOL(register_capi_driver
);
470 void unregister_capi_driver(struct capi_driver
*driver
)
474 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
475 list_del(&driver
->list
);
476 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
479 EXPORT_SYMBOL(unregister_capi_driver
);
481 /* ------------------------------------------------------------- */
482 /* -------- CAPI2.0 Interface ---------------------------------- */
483 /* ------------------------------------------------------------- */
485 u16
capi20_isinstalled(void)
488 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
489 if (capi_cards
[i
] && capi_cards
[i
]->cardstate
== CARD_RUNNING
)
492 return CAPI_REGNOTINSTALLED
;
495 EXPORT_SYMBOL(capi20_isinstalled
);
497 u16
capi20_register(struct capi20_appl
*ap
)
505 if (ap
->rparam
.datablklen
< 128)
506 return CAPI_LOGBLKSIZETOSMALL
;
508 write_lock_irqsave(&application_lock
, flags
);
510 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
511 if (capi_applications
[applid
- 1] == NULL
)
514 if (applid
> CAPI_MAXAPPL
) {
515 write_unlock_irqrestore(&application_lock
, flags
);
516 return CAPI_TOOMANYAPPLS
;
520 capi_applications
[applid
- 1] = ap
;
523 ap
->nrecvdatapkt
= 0;
525 ap
->nsentdatapkt
= 0;
527 init_MUTEX(&ap
->recv_sem
);
528 skb_queue_head_init(&ap
->recv_queue
);
529 INIT_WORK(&ap
->recv_work
, recv_handler
, (void *)ap
);
530 ap
->release_in_progress
= 0;
532 write_unlock_irqrestore(&application_lock
, flags
);
534 down(&controller_sem
);
535 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
536 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
538 register_appl(capi_cards
[i
], applid
, &ap
->rparam
);
542 if (showcapimsgs
& 1) {
543 printk(KERN_DEBUG
"kcapi: appl %d up\n", applid
);
549 EXPORT_SYMBOL(capi20_register
);
551 u16
capi20_release(struct capi20_appl
*ap
)
556 DBG("applid %#x", ap
->applid
);
558 write_lock_irqsave(&application_lock
, flags
);
559 ap
->release_in_progress
= 1;
560 capi_applications
[ap
->applid
- 1] = NULL
;
561 write_unlock_irqrestore(&application_lock
, flags
);
563 down(&controller_sem
);
564 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
565 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
567 release_appl(capi_cards
[i
], ap
->applid
);
571 flush_scheduled_work();
572 skb_queue_purge(&ap
->recv_queue
);
574 if (showcapimsgs
& 1) {
575 printk(KERN_DEBUG
"kcapi: appl %d down\n", ap
->applid
);
581 EXPORT_SYMBOL(capi20_release
);
583 u16
capi20_put_message(struct capi20_appl
*ap
, struct sk_buff
*skb
)
585 struct capi_ctr
*card
;
589 DBG("applid %#x", ap
->applid
);
592 return CAPI_REGNOTINSTALLED
;
593 if ((ap
->applid
== 0) || ap
->release_in_progress
)
594 return CAPI_ILLAPPNR
;
596 || !capi_cmd_valid(CAPIMSG_COMMAND(skb
->data
))
597 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb
->data
)))
598 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL
;
599 card
= get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb
->data
));
600 if (!card
|| card
->cardstate
!= CARD_RUNNING
) {
601 card
= get_capi_ctr_by_nr(1); // XXX why?
602 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
603 return CAPI_REGNOTINSTALLED
;
606 return CAPI_SENDQUEUEFULL
;
608 cmd
= CAPIMSG_COMMAND(skb
->data
);
609 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
611 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_REQ
) {
612 card
->nsentdatapkt
++;
614 if (card
->traceflag
> 2) showctl
|= 2;
618 if (card
->traceflag
) showctl
|= 2;
620 showctl
|= (card
->traceflag
& 1);
623 printk(KERN_DEBUG
"kcapi: put [%#x] id#%d %s len=%u\n",
624 CAPIMSG_CONTROLLER(skb
->data
),
625 CAPIMSG_APPID(skb
->data
),
626 capi_cmd2str(cmd
, subcmd
),
627 CAPIMSG_LEN(skb
->data
));
629 printk(KERN_DEBUG
"kcapi: put [%#x] %s\n",
630 CAPIMSG_CONTROLLER(skb
->data
),
631 capi_message2str(skb
->data
));
635 return card
->send_message(card
, skb
);
638 EXPORT_SYMBOL(capi20_put_message
);
640 u16
capi20_get_manufacturer(u32 contr
, u8
*buf
)
642 struct capi_ctr
*card
;
645 strlcpy(buf
, capi_manufakturer
, CAPI_MANUFACTURER_LEN
);
648 card
= get_capi_ctr_by_nr(contr
);
649 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
650 return CAPI_REGNOTINSTALLED
;
651 strlcpy(buf
, card
->manu
, CAPI_MANUFACTURER_LEN
);
655 EXPORT_SYMBOL(capi20_get_manufacturer
);
657 u16
capi20_get_version(u32 contr
, struct capi_version
*verp
)
659 struct capi_ctr
*card
;
662 *verp
= driver_version
;
665 card
= get_capi_ctr_by_nr(contr
);
666 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
667 return CAPI_REGNOTINSTALLED
;
669 memcpy((void *) verp
, &card
->version
, sizeof(capi_version
));
673 EXPORT_SYMBOL(capi20_get_version
);
675 u16
capi20_get_serial(u32 contr
, u8
*serial
)
677 struct capi_ctr
*card
;
680 strlcpy(serial
, driver_serial
, CAPI_SERIAL_LEN
);
683 card
= get_capi_ctr_by_nr(contr
);
684 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
685 return CAPI_REGNOTINSTALLED
;
687 strlcpy((void *) serial
, card
->serial
, CAPI_SERIAL_LEN
);
691 EXPORT_SYMBOL(capi20_get_serial
);
693 u16
capi20_get_profile(u32 contr
, struct capi_profile
*profp
)
695 struct capi_ctr
*card
;
698 profp
->ncontroller
= ncards
;
701 card
= get_capi_ctr_by_nr(contr
);
702 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
703 return CAPI_REGNOTINSTALLED
;
705 memcpy((void *) profp
, &card
->profile
,
706 sizeof(struct capi_profile
));
710 EXPORT_SYMBOL(capi20_get_profile
);
712 #ifdef CONFIG_AVMB1_COMPAT
713 static int old_capi_manufacturer(unsigned int cmd
, void __user
*data
)
715 avmb1_loadandconfigdef ldef
;
716 avmb1_extcarddef cdef
;
718 capicardparams cparams
;
719 struct capi_ctr
*card
;
720 struct capi_driver
*driver
= NULL
;
728 case AVMB1_ADDCARD_WITH_TYPE
:
729 if (cmd
== AVMB1_ADDCARD
) {
730 if ((retval
= copy_from_user(&cdef
, data
,
731 sizeof(avmb1_carddef
))))
733 cdef
.cardtype
= AVM_CARDTYPE_B1
;
735 if ((retval
= copy_from_user(&cdef
, data
,
736 sizeof(avmb1_extcarddef
))))
739 cparams
.port
= cdef
.port
;
740 cparams
.irq
= cdef
.irq
;
741 cparams
.cardnr
= cdef
.cardnr
;
743 read_lock_irqsave(&capi_drivers_list_lock
, flags
);
744 switch (cdef
.cardtype
) {
745 case AVM_CARDTYPE_B1
:
746 list_for_each(l
, &capi_drivers
) {
747 driver
= list_entry(l
, struct capi_driver
, list
);
748 if (strcmp(driver
->name
, "b1isa") == 0)
752 case AVM_CARDTYPE_T1
:
753 list_for_each(l
, &capi_drivers
) {
754 driver
= list_entry(l
, struct capi_driver
, list
);
755 if (strcmp(driver
->name
, "t1isa") == 0)
764 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
765 printk(KERN_ERR
"kcapi: driver not loaded.\n");
768 if (!driver
->add_card
) {
769 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
770 printk(KERN_ERR
"kcapi: driver has no add card function.\n");
774 retval
= driver
->add_card(driver
, &cparams
);
775 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
779 case AVMB1_LOAD_AND_CONFIG
:
781 if (cmd
== AVMB1_LOAD
) {
782 if (copy_from_user(&ldef
, data
,
783 sizeof(avmb1_loaddef
)))
785 ldef
.t4config
.len
= 0;
786 ldef
.t4config
.data
= NULL
;
788 if (copy_from_user(&ldef
, data
,
789 sizeof(avmb1_loadandconfigdef
)))
792 card
= get_capi_ctr_by_nr(ldef
.contr
);
793 card
= capi_ctr_get(card
);
796 if (card
->load_firmware
== 0) {
797 printk(KERN_DEBUG
"kcapi: load: no load function\n");
801 if (ldef
.t4file
.len
<= 0) {
802 printk(KERN_DEBUG
"kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef
.t4file
.len
);
805 if (ldef
.t4file
.data
== 0) {
806 printk(KERN_DEBUG
"kcapi: load: invalid parameter: dataptr is 0\n");
810 ldata
.firmware
.user
= 1;
811 ldata
.firmware
.data
= ldef
.t4file
.data
;
812 ldata
.firmware
.len
= ldef
.t4file
.len
;
813 ldata
.configuration
.user
= 1;
814 ldata
.configuration
.data
= ldef
.t4config
.data
;
815 ldata
.configuration
.len
= ldef
.t4config
.len
;
817 if (card
->cardstate
!= CARD_DETECTED
) {
818 printk(KERN_INFO
"kcapi: load: contr=%d not in detect state\n", ldef
.contr
);
821 card
->cardstate
= CARD_LOADING
;
823 retval
= card
->load_firmware(card
, &ldata
);
826 card
->cardstate
= CARD_DETECTED
;
831 while (card
->cardstate
!= CARD_RUNNING
) {
833 msleep_interruptible(100); /* 0.1 sec */
835 if (signal_pending(current
)) {
843 case AVMB1_RESETCARD
:
844 if (copy_from_user(&rdef
, data
, sizeof(avmb1_resetdef
)))
846 card
= get_capi_ctr_by_nr(rdef
.contr
);
850 if (card
->cardstate
== CARD_DETECTED
)
853 card
->reset_ctr(card
);
855 while (card
->cardstate
> CARD_DETECTED
) {
857 msleep_interruptible(100); /* 0.1 sec */
859 if (signal_pending(current
))
869 int capi20_manufacturer(unsigned int cmd
, void __user
*data
)
871 struct capi_ctr
*card
;
874 #ifdef CONFIG_AVMB1_COMPAT
876 case AVMB1_LOAD_AND_CONFIG
:
877 case AVMB1_RESETCARD
:
878 case AVMB1_GET_CARDINFO
:
879 case AVMB1_REMOVECARD
:
880 return old_capi_manufacturer(cmd
, data
);
882 case KCAPI_CMD_TRACE
:
886 if (copy_from_user(&fdef
, data
, sizeof(kcapi_flagdef
)))
889 card
= get_capi_ctr_by_nr(fdef
.contr
);
893 card
->traceflag
= fdef
.flag
;
894 printk(KERN_INFO
"kcapi: contr %d set trace=%d\n",
895 card
->cnr
, card
->traceflag
);
898 case KCAPI_CMD_ADDCARD
:
901 struct capi_driver
*driver
= NULL
;
902 capicardparams cparams
;
906 if ((retval
= copy_from_user(&cdef
, data
, sizeof(cdef
))))
909 cparams
.port
= cdef
.port
;
910 cparams
.irq
= cdef
.irq
;
911 cparams
.membase
= cdef
.membase
;
912 cparams
.cardnr
= cdef
.cardnr
;
913 cparams
.cardtype
= 0;
914 cdef
.driver
[sizeof(cdef
.driver
)-1] = 0;
916 list_for_each(l
, &capi_drivers
) {
917 driver
= list_entry(l
, struct capi_driver
, list
);
918 if (strcmp(driver
->name
, cdef
.driver
) == 0)
922 printk(KERN_ERR
"kcapi: driver \"%s\" not loaded.\n",
927 if (!driver
->add_card
) {
928 printk(KERN_ERR
"kcapi: driver \"%s\" has no add card function.\n", cdef
.driver
);
932 return driver
->add_card(driver
, &cparams
);
936 printk(KERN_ERR
"kcapi: manufacturer command %d unknown.\n",
944 EXPORT_SYMBOL(capi20_manufacturer
);
947 void capi20_set_callback(struct capi20_appl
*ap
,
948 void (*callback
) (unsigned int cmd
, __u32 contr
, void *data
))
950 ap
->callback
= callback
;
953 EXPORT_SYMBOL(capi20_set_callback
);
955 /* ------------------------------------------------------------- */
956 /* -------- Init & Cleanup ------------------------------------- */
957 /* ------------------------------------------------------------- */
960 * init / exit functions
963 static int __init
kcapi_init(void)
970 if ((p
= strchr(revision
, ':')) != 0 && p
[1]) {
971 strlcpy(rev
, p
+ 2, sizeof(rev
));
972 if ((p
= strchr(rev
, '$')) != 0 && p
> rev
)
977 printk(KERN_NOTICE
"CAPI Subsystem Rev %s\n", rev
);
982 static void __exit
kcapi_exit(void)
986 /* make sure all notifiers are finished */
987 flush_scheduled_work();
990 module_init(kcapi_init
);
991 module_exit(kcapi_exit
);