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>
35 #include <linux/mutex.h>
37 static char *revision
= "$Revision: 1.1.2.8 $";
39 /* ------------------------------------------------------------- */
41 static int showcapimsgs
= 0;
43 MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
44 MODULE_AUTHOR("Carsten Paeth");
45 MODULE_LICENSE("GPL");
46 module_param(showcapimsgs
, uint
, 0);
48 /* ------------------------------------------------------------- */
50 struct capi_notifier
{
51 struct work_struct work
;
58 /* ------------------------------------------------------------- */
60 static struct capi_version driver_version
= {2, 0, 1, 1<<4};
61 static char driver_serial
[CAPI_SERIAL_LEN
] = "0004711";
62 static char capi_manufakturer
[64] = "AVM Berlin";
64 #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
66 LIST_HEAD(capi_drivers
);
67 DEFINE_RWLOCK(capi_drivers_list_lock
);
69 static DEFINE_RWLOCK(application_lock
);
70 static DEFINE_MUTEX(controller_mutex
);
72 struct capi20_appl
*capi_applications
[CAPI_MAXAPPL
];
73 struct capi_ctr
*capi_cards
[CAPI_MAXCONTR
];
77 /* -------- controller ref counting -------------------------------------- */
79 static inline struct capi_ctr
*
80 capi_ctr_get(struct capi_ctr
*card
)
82 if (!try_module_get(card
->owner
))
88 capi_ctr_put(struct capi_ctr
*card
)
90 module_put(card
->owner
);
93 /* ------------------------------------------------------------- */
95 static inline struct capi_ctr
*get_capi_ctr_by_nr(u16 contr
)
97 if (contr
- 1 >= CAPI_MAXCONTR
)
100 return capi_cards
[contr
- 1];
103 static inline struct capi20_appl
*get_capi_appl_by_nr(u16 applid
)
105 if (applid
- 1 >= CAPI_MAXAPPL
)
108 return capi_applications
[applid
- 1];
111 /* -------- util functions ------------------------------------ */
113 static inline int capi_cmd_valid(u8 cmd
)
118 case CAPI_CONNECT_ACTIVE
:
119 case CAPI_CONNECT_B3_ACTIVE
:
120 case CAPI_CONNECT_B3
:
121 case CAPI_CONNECT_B3_T90_ACTIVE
:
123 case CAPI_DISCONNECT_B3
:
124 case CAPI_DISCONNECT
:
128 case CAPI_MANUFACTURER
:
130 case CAPI_SELECT_B_PROTOCOL
:
136 static inline int capi_subcmd_valid(u8 subcmd
)
148 /* ------------------------------------------------------------ */
150 static void register_appl(struct capi_ctr
*card
, u16 applid
, capi_register_params
*rparam
)
152 card
= capi_ctr_get(card
);
155 card
->register_appl(card
, applid
, rparam
);
157 printk(KERN_WARNING
"%s: cannot get card resources\n", __FUNCTION__
);
161 static void release_appl(struct capi_ctr
*card
, u16 applid
)
163 DBG("applid %#x", applid
);
165 card
->release_appl(card
, applid
);
169 /* -------- KCI_CONTRUP --------------------------------------- */
171 static void notify_up(u32 contr
)
173 struct capi_ctr
*card
= get_capi_ctr_by_nr(contr
);
174 struct capi20_appl
*ap
;
177 if (showcapimsgs
& 1) {
178 printk(KERN_DEBUG
"kcapi: notify up contr %d\n", contr
);
181 printk(KERN_WARNING
"%s: invalid contr %d\n", __FUNCTION__
, contr
);
184 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
185 ap
= get_capi_appl_by_nr(applid
);
186 if (!ap
|| ap
->release_in_progress
) continue;
187 register_appl(card
, applid
, &ap
->rparam
);
188 if (ap
->callback
&& !ap
->release_in_progress
)
189 ap
->callback(KCI_CONTRUP
, contr
, &card
->profile
);
193 /* -------- KCI_CONTRDOWN ------------------------------------- */
195 static void notify_down(u32 contr
)
197 struct capi20_appl
*ap
;
200 if (showcapimsgs
& 1) {
201 printk(KERN_DEBUG
"kcapi: notify down contr %d\n", contr
);
204 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
205 ap
= get_capi_appl_by_nr(applid
);
206 if (ap
&& ap
->callback
&& !ap
->release_in_progress
)
207 ap
->callback(KCI_CONTRDOWN
, contr
, NULL
);
211 static void notify_handler(void *data
)
213 struct capi_notifier
*np
= data
;
217 notify_up(np
->controller
);
220 notify_down(np
->controller
);
228 * The notifier will result in adding/deleteing of devices. Devices can
229 * only removed in user process, not in bh.
231 static int notify_push(unsigned int cmd
, u32 controller
, u16 applid
, u32 ncci
)
233 struct capi_notifier
*np
= kmalloc(sizeof(*np
), GFP_ATOMIC
);
238 INIT_WORK(&np
->work
, notify_handler
, np
);
240 np
->controller
= controller
;
244 schedule_work(&np
->work
);
249 /* -------- Receiver ------------------------------------------ */
251 static void recv_handler(void *_ap
)
254 struct capi20_appl
*ap
= (struct capi20_appl
*) _ap
;
256 if ((!ap
) || (ap
->release_in_progress
))
260 while ((skb
= skb_dequeue(&ap
->recv_queue
))) {
261 if (CAPIMSG_CMD(skb
->data
) == CAPI_DATA_B3_IND
)
266 ap
->recv_message(ap
, skb
);
271 void capi_ctr_handle_message(struct capi_ctr
* card
, u16 appl
, struct sk_buff
*skb
)
273 struct capi20_appl
*ap
;
278 if (card
->cardstate
!= CARD_RUNNING
) {
279 printk(KERN_INFO
"kcapi: controller %d not active, got: %s",
280 card
->cnr
, capi_message2str(skb
->data
));
284 cmd
= CAPIMSG_COMMAND(skb
->data
);
285 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
286 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_IND
) {
287 card
->nrecvdatapkt
++;
288 if (card
->traceflag
> 2) showctl
|= 2;
291 if (card
->traceflag
) showctl
|= 2;
293 showctl
|= (card
->traceflag
& 1);
296 printk(KERN_DEBUG
"kcapi: got [0x%lx] id#%d %s len=%u\n",
297 (unsigned long) card
->cnr
,
298 CAPIMSG_APPID(skb
->data
),
299 capi_cmd2str(cmd
, subcmd
),
300 CAPIMSG_LEN(skb
->data
));
302 printk(KERN_DEBUG
"kcapi: got [0x%lx] %s\n",
303 (unsigned long) card
->cnr
,
304 capi_message2str(skb
->data
));
309 read_lock_irqsave(&application_lock
, flags
);
310 ap
= get_capi_appl_by_nr(CAPIMSG_APPID(skb
->data
));
311 if ((!ap
) || (ap
->release_in_progress
)) {
312 read_unlock_irqrestore(&application_lock
, flags
);
313 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s)\n",
314 CAPIMSG_APPID(skb
->data
), capi_message2str(skb
->data
));
317 skb_queue_tail(&ap
->recv_queue
, skb
);
318 schedule_work(&ap
->recv_work
);
319 read_unlock_irqrestore(&application_lock
, flags
);
327 EXPORT_SYMBOL(capi_ctr_handle_message
);
329 void capi_ctr_ready(struct capi_ctr
* card
)
331 card
->cardstate
= CARD_RUNNING
;
333 printk(KERN_NOTICE
"kcapi: card %d \"%s\" ready.\n",
334 card
->cnr
, card
->name
);
336 notify_push(KCI_CONTRUP
, card
->cnr
, 0, 0);
339 EXPORT_SYMBOL(capi_ctr_ready
);
341 void capi_ctr_reseted(struct capi_ctr
* card
)
347 if (card
->cardstate
== CARD_DETECTED
)
350 card
->cardstate
= CARD_DETECTED
;
352 memset(card
->manu
, 0, sizeof(card
->manu
));
353 memset(&card
->version
, 0, sizeof(card
->version
));
354 memset(&card
->profile
, 0, sizeof(card
->profile
));
355 memset(card
->serial
, 0, sizeof(card
->serial
));
357 for (appl
= 1; appl
<= CAPI_MAXAPPL
; appl
++) {
358 struct capi20_appl
*ap
= get_capi_appl_by_nr(appl
);
359 if (!ap
|| ap
->release_in_progress
)
365 printk(KERN_NOTICE
"kcapi: card %d down.\n", card
->cnr
);
367 notify_push(KCI_CONTRDOWN
, card
->cnr
, 0, 0);
370 EXPORT_SYMBOL(capi_ctr_reseted
);
372 void capi_ctr_suspend_output(struct capi_ctr
*card
)
374 if (!card
->blocked
) {
375 printk(KERN_DEBUG
"kcapi: card %d suspend\n", card
->cnr
);
380 EXPORT_SYMBOL(capi_ctr_suspend_output
);
382 void capi_ctr_resume_output(struct capi_ctr
*card
)
385 printk(KERN_DEBUG
"kcapi: card %d resume\n", card
->cnr
);
390 EXPORT_SYMBOL(capi_ctr_resume_output
);
392 /* ------------------------------------------------------------- */
395 attach_capi_ctr(struct capi_ctr
*card
)
399 mutex_lock(&controller_mutex
);
401 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
402 if (capi_cards
[i
] == NULL
)
405 if (i
== CAPI_MAXCONTR
) {
406 mutex_unlock(&controller_mutex
);
407 printk(KERN_ERR
"kcapi: out of controller slots\n");
410 capi_cards
[i
] = card
;
412 mutex_unlock(&controller_mutex
);
414 card
->nrecvctlpkt
= 0;
415 card
->nrecvdatapkt
= 0;
416 card
->nsentctlpkt
= 0;
417 card
->nsentdatapkt
= 0;
419 card
->cardstate
= CARD_DETECTED
;
421 card
->traceflag
= showcapimsgs
;
423 sprintf(card
->procfn
, "capi/controllers/%d", card
->cnr
);
424 card
->procent
= create_proc_entry(card
->procfn
, 0, NULL
);
426 card
->procent
->read_proc
=
427 (int (*)(char *,char **,off_t
,int,int *,void *))
429 card
->procent
->data
= card
;
433 printk(KERN_NOTICE
"kcapi: Controller %d: %s attached\n",
434 card
->cnr
, card
->name
);
438 EXPORT_SYMBOL(attach_capi_ctr
);
440 int detach_capi_ctr(struct capi_ctr
*card
)
442 if (card
->cardstate
!= CARD_DETECTED
)
443 capi_ctr_reseted(card
);
448 remove_proc_entry(card
->procfn
, NULL
);
449 card
->procent
= NULL
;
451 capi_cards
[card
->cnr
- 1] = NULL
;
452 printk(KERN_NOTICE
"kcapi: Controller %d: %s unregistered\n",
453 card
->cnr
, card
->name
);
458 EXPORT_SYMBOL(detach_capi_ctr
);
460 void register_capi_driver(struct capi_driver
*driver
)
464 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
465 list_add_tail(&driver
->list
, &capi_drivers
);
466 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
469 EXPORT_SYMBOL(register_capi_driver
);
471 void unregister_capi_driver(struct capi_driver
*driver
)
475 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
476 list_del(&driver
->list
);
477 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
480 EXPORT_SYMBOL(unregister_capi_driver
);
482 /* ------------------------------------------------------------- */
483 /* -------- CAPI2.0 Interface ---------------------------------- */
484 /* ------------------------------------------------------------- */
486 u16
capi20_isinstalled(void)
489 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
490 if (capi_cards
[i
] && capi_cards
[i
]->cardstate
== CARD_RUNNING
)
493 return CAPI_REGNOTINSTALLED
;
496 EXPORT_SYMBOL(capi20_isinstalled
);
498 u16
capi20_register(struct capi20_appl
*ap
)
506 if (ap
->rparam
.datablklen
< 128)
507 return CAPI_LOGBLKSIZETOSMALL
;
509 write_lock_irqsave(&application_lock
, flags
);
511 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
512 if (capi_applications
[applid
- 1] == NULL
)
515 if (applid
> CAPI_MAXAPPL
) {
516 write_unlock_irqrestore(&application_lock
, flags
);
517 return CAPI_TOOMANYAPPLS
;
521 capi_applications
[applid
- 1] = ap
;
524 ap
->nrecvdatapkt
= 0;
526 ap
->nsentdatapkt
= 0;
528 init_MUTEX(&ap
->recv_sem
);
529 skb_queue_head_init(&ap
->recv_queue
);
530 INIT_WORK(&ap
->recv_work
, recv_handler
, (void *)ap
);
531 ap
->release_in_progress
= 0;
533 write_unlock_irqrestore(&application_lock
, flags
);
535 mutex_lock(&controller_mutex
);
536 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
537 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
539 register_appl(capi_cards
[i
], applid
, &ap
->rparam
);
541 mutex_unlock(&controller_mutex
);
543 if (showcapimsgs
& 1) {
544 printk(KERN_DEBUG
"kcapi: appl %d up\n", applid
);
550 EXPORT_SYMBOL(capi20_register
);
552 u16
capi20_release(struct capi20_appl
*ap
)
557 DBG("applid %#x", ap
->applid
);
559 write_lock_irqsave(&application_lock
, flags
);
560 ap
->release_in_progress
= 1;
561 capi_applications
[ap
->applid
- 1] = NULL
;
562 write_unlock_irqrestore(&application_lock
, flags
);
564 mutex_lock(&controller_mutex
);
565 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
566 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
568 release_appl(capi_cards
[i
], ap
->applid
);
570 mutex_unlock(&controller_mutex
);
572 flush_scheduled_work();
573 skb_queue_purge(&ap
->recv_queue
);
575 if (showcapimsgs
& 1) {
576 printk(KERN_DEBUG
"kcapi: appl %d down\n", ap
->applid
);
582 EXPORT_SYMBOL(capi20_release
);
584 u16
capi20_put_message(struct capi20_appl
*ap
, struct sk_buff
*skb
)
586 struct capi_ctr
*card
;
590 DBG("applid %#x", ap
->applid
);
593 return CAPI_REGNOTINSTALLED
;
594 if ((ap
->applid
== 0) || ap
->release_in_progress
)
595 return CAPI_ILLAPPNR
;
597 || !capi_cmd_valid(CAPIMSG_COMMAND(skb
->data
))
598 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb
->data
)))
599 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL
;
600 card
= get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb
->data
));
601 if (!card
|| card
->cardstate
!= CARD_RUNNING
) {
602 card
= get_capi_ctr_by_nr(1); // XXX why?
603 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
604 return CAPI_REGNOTINSTALLED
;
607 return CAPI_SENDQUEUEFULL
;
609 cmd
= CAPIMSG_COMMAND(skb
->data
);
610 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
612 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_REQ
) {
613 card
->nsentdatapkt
++;
615 if (card
->traceflag
> 2) showctl
|= 2;
619 if (card
->traceflag
) showctl
|= 2;
621 showctl
|= (card
->traceflag
& 1);
624 printk(KERN_DEBUG
"kcapi: put [%#x] id#%d %s len=%u\n",
625 CAPIMSG_CONTROLLER(skb
->data
),
626 CAPIMSG_APPID(skb
->data
),
627 capi_cmd2str(cmd
, subcmd
),
628 CAPIMSG_LEN(skb
->data
));
630 printk(KERN_DEBUG
"kcapi: put [%#x] %s\n",
631 CAPIMSG_CONTROLLER(skb
->data
),
632 capi_message2str(skb
->data
));
636 return card
->send_message(card
, skb
);
639 EXPORT_SYMBOL(capi20_put_message
);
641 u16
capi20_get_manufacturer(u32 contr
, u8
*buf
)
643 struct capi_ctr
*card
;
646 strlcpy(buf
, capi_manufakturer
, CAPI_MANUFACTURER_LEN
);
649 card
= get_capi_ctr_by_nr(contr
);
650 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
651 return CAPI_REGNOTINSTALLED
;
652 strlcpy(buf
, card
->manu
, CAPI_MANUFACTURER_LEN
);
656 EXPORT_SYMBOL(capi20_get_manufacturer
);
658 u16
capi20_get_version(u32 contr
, struct capi_version
*verp
)
660 struct capi_ctr
*card
;
663 *verp
= driver_version
;
666 card
= get_capi_ctr_by_nr(contr
);
667 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
668 return CAPI_REGNOTINSTALLED
;
670 memcpy((void *) verp
, &card
->version
, sizeof(capi_version
));
674 EXPORT_SYMBOL(capi20_get_version
);
676 u16
capi20_get_serial(u32 contr
, u8
*serial
)
678 struct capi_ctr
*card
;
681 strlcpy(serial
, driver_serial
, CAPI_SERIAL_LEN
);
684 card
= get_capi_ctr_by_nr(contr
);
685 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
686 return CAPI_REGNOTINSTALLED
;
688 strlcpy((void *) serial
, card
->serial
, CAPI_SERIAL_LEN
);
692 EXPORT_SYMBOL(capi20_get_serial
);
694 u16
capi20_get_profile(u32 contr
, struct capi_profile
*profp
)
696 struct capi_ctr
*card
;
699 profp
->ncontroller
= ncards
;
702 card
= get_capi_ctr_by_nr(contr
);
703 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
704 return CAPI_REGNOTINSTALLED
;
706 memcpy((void *) profp
, &card
->profile
,
707 sizeof(struct capi_profile
));
711 EXPORT_SYMBOL(capi20_get_profile
);
713 #ifdef CONFIG_AVMB1_COMPAT
714 static int old_capi_manufacturer(unsigned int cmd
, void __user
*data
)
716 avmb1_loadandconfigdef ldef
;
717 avmb1_extcarddef cdef
;
719 capicardparams cparams
;
720 struct capi_ctr
*card
;
721 struct capi_driver
*driver
= NULL
;
729 case AVMB1_ADDCARD_WITH_TYPE
:
730 if (cmd
== AVMB1_ADDCARD
) {
731 if ((retval
= copy_from_user(&cdef
, data
,
732 sizeof(avmb1_carddef
))))
734 cdef
.cardtype
= AVM_CARDTYPE_B1
;
736 if ((retval
= copy_from_user(&cdef
, data
,
737 sizeof(avmb1_extcarddef
))))
740 cparams
.port
= cdef
.port
;
741 cparams
.irq
= cdef
.irq
;
742 cparams
.cardnr
= cdef
.cardnr
;
744 read_lock_irqsave(&capi_drivers_list_lock
, flags
);
745 switch (cdef
.cardtype
) {
746 case AVM_CARDTYPE_B1
:
747 list_for_each(l
, &capi_drivers
) {
748 driver
= list_entry(l
, struct capi_driver
, list
);
749 if (strcmp(driver
->name
, "b1isa") == 0)
753 case AVM_CARDTYPE_T1
:
754 list_for_each(l
, &capi_drivers
) {
755 driver
= list_entry(l
, struct capi_driver
, list
);
756 if (strcmp(driver
->name
, "t1isa") == 0)
765 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
766 printk(KERN_ERR
"kcapi: driver not loaded.\n");
769 if (!driver
->add_card
) {
770 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
771 printk(KERN_ERR
"kcapi: driver has no add card function.\n");
775 retval
= driver
->add_card(driver
, &cparams
);
776 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
780 case AVMB1_LOAD_AND_CONFIG
:
782 if (cmd
== AVMB1_LOAD
) {
783 if (copy_from_user(&ldef
, data
,
784 sizeof(avmb1_loaddef
)))
786 ldef
.t4config
.len
= 0;
787 ldef
.t4config
.data
= NULL
;
789 if (copy_from_user(&ldef
, data
,
790 sizeof(avmb1_loadandconfigdef
)))
793 card
= get_capi_ctr_by_nr(ldef
.contr
);
794 card
= capi_ctr_get(card
);
797 if (card
->load_firmware
== 0) {
798 printk(KERN_DEBUG
"kcapi: load: no load function\n");
802 if (ldef
.t4file
.len
<= 0) {
803 printk(KERN_DEBUG
"kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef
.t4file
.len
);
806 if (ldef
.t4file
.data
== 0) {
807 printk(KERN_DEBUG
"kcapi: load: invalid parameter: dataptr is 0\n");
811 ldata
.firmware
.user
= 1;
812 ldata
.firmware
.data
= ldef
.t4file
.data
;
813 ldata
.firmware
.len
= ldef
.t4file
.len
;
814 ldata
.configuration
.user
= 1;
815 ldata
.configuration
.data
= ldef
.t4config
.data
;
816 ldata
.configuration
.len
= ldef
.t4config
.len
;
818 if (card
->cardstate
!= CARD_DETECTED
) {
819 printk(KERN_INFO
"kcapi: load: contr=%d not in detect state\n", ldef
.contr
);
822 card
->cardstate
= CARD_LOADING
;
824 retval
= card
->load_firmware(card
, &ldata
);
827 card
->cardstate
= CARD_DETECTED
;
832 while (card
->cardstate
!= CARD_RUNNING
) {
834 msleep_interruptible(100); /* 0.1 sec */
836 if (signal_pending(current
)) {
844 case AVMB1_RESETCARD
:
845 if (copy_from_user(&rdef
, data
, sizeof(avmb1_resetdef
)))
847 card
= get_capi_ctr_by_nr(rdef
.contr
);
851 if (card
->cardstate
== CARD_DETECTED
)
854 card
->reset_ctr(card
);
856 while (card
->cardstate
> CARD_DETECTED
) {
858 msleep_interruptible(100); /* 0.1 sec */
860 if (signal_pending(current
))
870 int capi20_manufacturer(unsigned int cmd
, void __user
*data
)
872 struct capi_ctr
*card
;
875 #ifdef CONFIG_AVMB1_COMPAT
877 case AVMB1_LOAD_AND_CONFIG
:
878 case AVMB1_RESETCARD
:
879 case AVMB1_GET_CARDINFO
:
880 case AVMB1_REMOVECARD
:
881 return old_capi_manufacturer(cmd
, data
);
883 case KCAPI_CMD_TRACE
:
887 if (copy_from_user(&fdef
, data
, sizeof(kcapi_flagdef
)))
890 card
= get_capi_ctr_by_nr(fdef
.contr
);
894 card
->traceflag
= fdef
.flag
;
895 printk(KERN_INFO
"kcapi: contr %d set trace=%d\n",
896 card
->cnr
, card
->traceflag
);
899 case KCAPI_CMD_ADDCARD
:
902 struct capi_driver
*driver
= NULL
;
903 capicardparams cparams
;
907 if ((retval
= copy_from_user(&cdef
, data
, sizeof(cdef
))))
910 cparams
.port
= cdef
.port
;
911 cparams
.irq
= cdef
.irq
;
912 cparams
.membase
= cdef
.membase
;
913 cparams
.cardnr
= cdef
.cardnr
;
914 cparams
.cardtype
= 0;
915 cdef
.driver
[sizeof(cdef
.driver
)-1] = 0;
917 list_for_each(l
, &capi_drivers
) {
918 driver
= list_entry(l
, struct capi_driver
, list
);
919 if (strcmp(driver
->name
, cdef
.driver
) == 0)
923 printk(KERN_ERR
"kcapi: driver \"%s\" not loaded.\n",
928 if (!driver
->add_card
) {
929 printk(KERN_ERR
"kcapi: driver \"%s\" has no add card function.\n", cdef
.driver
);
933 return driver
->add_card(driver
, &cparams
);
937 printk(KERN_ERR
"kcapi: manufacturer command %d unknown.\n",
945 EXPORT_SYMBOL(capi20_manufacturer
);
948 void capi20_set_callback(struct capi20_appl
*ap
,
949 void (*callback
) (unsigned int cmd
, __u32 contr
, void *data
))
951 ap
->callback
= callback
;
954 EXPORT_SYMBOL(capi20_set_callback
);
956 /* ------------------------------------------------------------- */
957 /* -------- Init & Cleanup ------------------------------------- */
958 /* ------------------------------------------------------------- */
961 * init / exit functions
964 static int __init
kcapi_init(void)
971 if ((p
= strchr(revision
, ':')) != 0 && p
[1]) {
972 strlcpy(rev
, p
+ 2, sizeof(rev
));
973 if ((p
= strchr(rev
, '$')) != 0 && p
> rev
)
978 printk(KERN_NOTICE
"CAPI Subsystem Rev %s\n", rev
);
983 static void __exit
kcapi_exit(void)
987 /* make sure all notifiers are finished */
988 flush_scheduled_work();
991 module_init(kcapi_init
);
992 module_exit(kcapi_exit
);