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.
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>
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", __func__
);
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", __func__
, 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(struct work_struct
*work
)
213 struct capi_notifier
*np
=
214 container_of(work
, struct capi_notifier
, work
);
218 notify_up(np
->controller
);
221 notify_down(np
->controller
);
229 * The notifier will result in adding/deleteing of devices. Devices can
230 * only removed in user process, not in bh.
232 static int notify_push(unsigned int cmd
, u32 controller
, u16 applid
, u32 ncci
)
234 struct capi_notifier
*np
= kmalloc(sizeof(*np
), GFP_ATOMIC
);
239 INIT_WORK(&np
->work
, notify_handler
);
241 np
->controller
= controller
;
245 schedule_work(&np
->work
);
250 /* -------- Receiver ------------------------------------------ */
252 static void recv_handler(struct work_struct
*work
)
255 struct capi20_appl
*ap
=
256 container_of(work
, struct capi20_appl
, recv_work
);
258 if ((!ap
) || (ap
->release_in_progress
))
261 mutex_lock(&ap
->recv_mtx
);
262 while ((skb
= skb_dequeue(&ap
->recv_queue
))) {
263 if (CAPIMSG_CMD(skb
->data
) == CAPI_DATA_B3_IND
)
268 ap
->recv_message(ap
, skb
);
270 mutex_unlock(&ap
->recv_mtx
);
273 void capi_ctr_handle_message(struct capi_ctr
* card
, u16 appl
, struct sk_buff
*skb
)
275 struct capi20_appl
*ap
;
281 if (card
->cardstate
!= CARD_RUNNING
) {
282 cdb
= capi_message2str(skb
->data
);
284 printk(KERN_INFO
"kcapi: controller [%03d] not active, got: %s",
285 card
->cnr
, cdb
->buf
);
288 printk(KERN_INFO
"kcapi: controller [%03d] not active, cannot trace\n",
293 cmd
= CAPIMSG_COMMAND(skb
->data
);
294 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
295 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_IND
) {
296 card
->nrecvdatapkt
++;
297 if (card
->traceflag
> 2) showctl
|= 2;
300 if (card
->traceflag
) showctl
|= 2;
302 showctl
|= (card
->traceflag
& 1);
305 printk(KERN_DEBUG
"kcapi: got [%03d] id#%d %s len=%u\n",
306 card
->cnr
, CAPIMSG_APPID(skb
->data
),
307 capi_cmd2str(cmd
, subcmd
),
308 CAPIMSG_LEN(skb
->data
));
310 cdb
= capi_message2str(skb
->data
);
312 printk(KERN_DEBUG
"kcapi: got [%03d] %s\n",
313 card
->cnr
, cdb
->buf
);
316 printk(KERN_DEBUG
"kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
317 card
->cnr
, CAPIMSG_APPID(skb
->data
),
318 capi_cmd2str(cmd
, subcmd
),
319 CAPIMSG_LEN(skb
->data
));
324 read_lock_irqsave(&application_lock
, flags
);
325 ap
= get_capi_appl_by_nr(CAPIMSG_APPID(skb
->data
));
326 if ((!ap
) || (ap
->release_in_progress
)) {
327 read_unlock_irqrestore(&application_lock
, flags
);
328 cdb
= capi_message2str(skb
->data
);
330 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s)\n",
331 CAPIMSG_APPID(skb
->data
), cdb
->buf
);
334 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s) cannot trace\n",
335 CAPIMSG_APPID(skb
->data
),
336 capi_cmd2str(cmd
, subcmd
));
339 skb_queue_tail(&ap
->recv_queue
, skb
);
340 schedule_work(&ap
->recv_work
);
341 read_unlock_irqrestore(&application_lock
, flags
);
349 EXPORT_SYMBOL(capi_ctr_handle_message
);
351 void capi_ctr_ready(struct capi_ctr
* card
)
353 card
->cardstate
= CARD_RUNNING
;
355 printk(KERN_NOTICE
"kcapi: card [%03d] \"%s\" ready.\n",
356 card
->cnr
, card
->name
);
358 notify_push(KCI_CONTRUP
, card
->cnr
, 0, 0);
361 EXPORT_SYMBOL(capi_ctr_ready
);
363 void capi_ctr_reseted(struct capi_ctr
* card
)
369 if (card
->cardstate
== CARD_DETECTED
)
372 card
->cardstate
= CARD_DETECTED
;
374 memset(card
->manu
, 0, sizeof(card
->manu
));
375 memset(&card
->version
, 0, sizeof(card
->version
));
376 memset(&card
->profile
, 0, sizeof(card
->profile
));
377 memset(card
->serial
, 0, sizeof(card
->serial
));
379 for (appl
= 1; appl
<= CAPI_MAXAPPL
; appl
++) {
380 struct capi20_appl
*ap
= get_capi_appl_by_nr(appl
);
381 if (!ap
|| ap
->release_in_progress
)
387 printk(KERN_NOTICE
"kcapi: card [%03d] down.\n", card
->cnr
);
389 notify_push(KCI_CONTRDOWN
, card
->cnr
, 0, 0);
392 EXPORT_SYMBOL(capi_ctr_reseted
);
394 void capi_ctr_suspend_output(struct capi_ctr
*card
)
396 if (!card
->blocked
) {
397 printk(KERN_DEBUG
"kcapi: card [%03d] suspend\n", card
->cnr
);
402 EXPORT_SYMBOL(capi_ctr_suspend_output
);
404 void capi_ctr_resume_output(struct capi_ctr
*card
)
407 printk(KERN_DEBUG
"kcapi: card [%03d] resume\n", card
->cnr
);
412 EXPORT_SYMBOL(capi_ctr_resume_output
);
414 /* ------------------------------------------------------------- */
417 attach_capi_ctr(struct capi_ctr
*card
)
421 mutex_lock(&controller_mutex
);
423 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
424 if (capi_cards
[i
] == NULL
)
427 if (i
== CAPI_MAXCONTR
) {
428 mutex_unlock(&controller_mutex
);
429 printk(KERN_ERR
"kcapi: out of controller slots\n");
432 capi_cards
[i
] = card
;
434 mutex_unlock(&controller_mutex
);
436 card
->nrecvctlpkt
= 0;
437 card
->nrecvdatapkt
= 0;
438 card
->nsentctlpkt
= 0;
439 card
->nsentdatapkt
= 0;
441 card
->cardstate
= CARD_DETECTED
;
443 card
->traceflag
= showcapimsgs
;
445 sprintf(card
->procfn
, "capi/controllers/%d", card
->cnr
);
446 card
->procent
= create_proc_entry(card
->procfn
, 0, NULL
);
448 card
->procent
->read_proc
=
449 (int (*)(char *,char **,off_t
,int,int *,void *))
451 card
->procent
->data
= card
;
455 printk(KERN_NOTICE
"kcapi: Controller [%03d]: %s attached\n",
456 card
->cnr
, card
->name
);
460 EXPORT_SYMBOL(attach_capi_ctr
);
462 int detach_capi_ctr(struct capi_ctr
*card
)
464 if (card
->cardstate
!= CARD_DETECTED
)
465 capi_ctr_reseted(card
);
470 remove_proc_entry(card
->procfn
, NULL
);
471 card
->procent
= NULL
;
473 capi_cards
[card
->cnr
- 1] = NULL
;
474 printk(KERN_NOTICE
"kcapi: Controller [%03d]: %s unregistered\n",
475 card
->cnr
, card
->name
);
480 EXPORT_SYMBOL(detach_capi_ctr
);
482 void register_capi_driver(struct capi_driver
*driver
)
486 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
487 list_add_tail(&driver
->list
, &capi_drivers
);
488 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
491 EXPORT_SYMBOL(register_capi_driver
);
493 void unregister_capi_driver(struct capi_driver
*driver
)
497 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
498 list_del(&driver
->list
);
499 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
502 EXPORT_SYMBOL(unregister_capi_driver
);
504 /* ------------------------------------------------------------- */
505 /* -------- CAPI2.0 Interface ---------------------------------- */
506 /* ------------------------------------------------------------- */
508 u16
capi20_isinstalled(void)
511 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
512 if (capi_cards
[i
] && capi_cards
[i
]->cardstate
== CARD_RUNNING
)
515 return CAPI_REGNOTINSTALLED
;
518 EXPORT_SYMBOL(capi20_isinstalled
);
520 u16
capi20_register(struct capi20_appl
*ap
)
528 if (ap
->rparam
.datablklen
< 128)
529 return CAPI_LOGBLKSIZETOSMALL
;
531 write_lock_irqsave(&application_lock
, flags
);
533 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
534 if (capi_applications
[applid
- 1] == NULL
)
537 if (applid
> CAPI_MAXAPPL
) {
538 write_unlock_irqrestore(&application_lock
, flags
);
539 return CAPI_TOOMANYAPPLS
;
543 capi_applications
[applid
- 1] = ap
;
546 ap
->nrecvdatapkt
= 0;
548 ap
->nsentdatapkt
= 0;
550 mutex_init(&ap
->recv_mtx
);
551 skb_queue_head_init(&ap
->recv_queue
);
552 INIT_WORK(&ap
->recv_work
, recv_handler
);
553 ap
->release_in_progress
= 0;
555 write_unlock_irqrestore(&application_lock
, flags
);
557 mutex_lock(&controller_mutex
);
558 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
559 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
561 register_appl(capi_cards
[i
], applid
, &ap
->rparam
);
563 mutex_unlock(&controller_mutex
);
565 if (showcapimsgs
& 1) {
566 printk(KERN_DEBUG
"kcapi: appl %d up\n", applid
);
572 EXPORT_SYMBOL(capi20_register
);
574 u16
capi20_release(struct capi20_appl
*ap
)
579 DBG("applid %#x", ap
->applid
);
581 write_lock_irqsave(&application_lock
, flags
);
582 ap
->release_in_progress
= 1;
583 capi_applications
[ap
->applid
- 1] = NULL
;
584 write_unlock_irqrestore(&application_lock
, flags
);
586 mutex_lock(&controller_mutex
);
587 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
588 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
590 release_appl(capi_cards
[i
], ap
->applid
);
592 mutex_unlock(&controller_mutex
);
594 flush_scheduled_work();
595 skb_queue_purge(&ap
->recv_queue
);
597 if (showcapimsgs
& 1) {
598 printk(KERN_DEBUG
"kcapi: appl %d down\n", ap
->applid
);
604 EXPORT_SYMBOL(capi20_release
);
606 u16
capi20_put_message(struct capi20_appl
*ap
, struct sk_buff
*skb
)
608 struct capi_ctr
*card
;
612 DBG("applid %#x", ap
->applid
);
615 return CAPI_REGNOTINSTALLED
;
616 if ((ap
->applid
== 0) || ap
->release_in_progress
)
617 return CAPI_ILLAPPNR
;
619 || !capi_cmd_valid(CAPIMSG_COMMAND(skb
->data
))
620 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb
->data
)))
621 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL
;
622 card
= get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb
->data
));
623 if (!card
|| card
->cardstate
!= CARD_RUNNING
) {
624 card
= get_capi_ctr_by_nr(1); // XXX why?
625 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
626 return CAPI_REGNOTINSTALLED
;
629 return CAPI_SENDQUEUEFULL
;
631 cmd
= CAPIMSG_COMMAND(skb
->data
);
632 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
634 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_REQ
) {
635 card
->nsentdatapkt
++;
637 if (card
->traceflag
> 2) showctl
|= 2;
641 if (card
->traceflag
) showctl
|= 2;
643 showctl
|= (card
->traceflag
& 1);
646 printk(KERN_DEBUG
"kcapi: put [%03d] id#%d %s len=%u\n",
647 CAPIMSG_CONTROLLER(skb
->data
),
648 CAPIMSG_APPID(skb
->data
),
649 capi_cmd2str(cmd
, subcmd
),
650 CAPIMSG_LEN(skb
->data
));
652 _cdebbuf
*cdb
= capi_message2str(skb
->data
);
654 printk(KERN_DEBUG
"kcapi: put [%03d] %s\n",
655 CAPIMSG_CONTROLLER(skb
->data
),
659 printk(KERN_DEBUG
"kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
660 CAPIMSG_CONTROLLER(skb
->data
),
661 CAPIMSG_APPID(skb
->data
),
662 capi_cmd2str(cmd
, subcmd
),
663 CAPIMSG_LEN(skb
->data
));
666 return card
->send_message(card
, skb
);
669 EXPORT_SYMBOL(capi20_put_message
);
671 u16
capi20_get_manufacturer(u32 contr
, u8
*buf
)
673 struct capi_ctr
*card
;
676 strlcpy(buf
, capi_manufakturer
, CAPI_MANUFACTURER_LEN
);
679 card
= get_capi_ctr_by_nr(contr
);
680 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
681 return CAPI_REGNOTINSTALLED
;
682 strlcpy(buf
, card
->manu
, CAPI_MANUFACTURER_LEN
);
686 EXPORT_SYMBOL(capi20_get_manufacturer
);
688 u16
capi20_get_version(u32 contr
, struct capi_version
*verp
)
690 struct capi_ctr
*card
;
693 *verp
= driver_version
;
696 card
= get_capi_ctr_by_nr(contr
);
697 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
698 return CAPI_REGNOTINSTALLED
;
700 memcpy((void *) verp
, &card
->version
, sizeof(capi_version
));
704 EXPORT_SYMBOL(capi20_get_version
);
706 u16
capi20_get_serial(u32 contr
, u8
*serial
)
708 struct capi_ctr
*card
;
711 strlcpy(serial
, driver_serial
, CAPI_SERIAL_LEN
);
714 card
= get_capi_ctr_by_nr(contr
);
715 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
716 return CAPI_REGNOTINSTALLED
;
718 strlcpy((void *) serial
, card
->serial
, CAPI_SERIAL_LEN
);
722 EXPORT_SYMBOL(capi20_get_serial
);
724 u16
capi20_get_profile(u32 contr
, struct capi_profile
*profp
)
726 struct capi_ctr
*card
;
729 profp
->ncontroller
= ncards
;
732 card
= get_capi_ctr_by_nr(contr
);
733 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
734 return CAPI_REGNOTINSTALLED
;
736 memcpy((void *) profp
, &card
->profile
,
737 sizeof(struct capi_profile
));
741 EXPORT_SYMBOL(capi20_get_profile
);
744 static int old_capi_manufacturer(unsigned int cmd
, void __user
*data
)
746 avmb1_loadandconfigdef ldef
;
747 avmb1_extcarddef cdef
;
749 capicardparams cparams
;
750 struct capi_ctr
*card
;
751 struct capi_driver
*driver
= NULL
;
759 case AVMB1_ADDCARD_WITH_TYPE
:
760 if (cmd
== AVMB1_ADDCARD
) {
761 if ((retval
= copy_from_user(&cdef
, data
,
762 sizeof(avmb1_carddef
))))
764 cdef
.cardtype
= AVM_CARDTYPE_B1
;
766 if ((retval
= copy_from_user(&cdef
, data
,
767 sizeof(avmb1_extcarddef
))))
770 cparams
.port
= cdef
.port
;
771 cparams
.irq
= cdef
.irq
;
772 cparams
.cardnr
= cdef
.cardnr
;
774 read_lock_irqsave(&capi_drivers_list_lock
, flags
);
775 switch (cdef
.cardtype
) {
776 case AVM_CARDTYPE_B1
:
777 list_for_each(l
, &capi_drivers
) {
778 driver
= list_entry(l
, struct capi_driver
, list
);
779 if (strcmp(driver
->name
, "b1isa") == 0)
783 case AVM_CARDTYPE_T1
:
784 list_for_each(l
, &capi_drivers
) {
785 driver
= list_entry(l
, struct capi_driver
, list
);
786 if (strcmp(driver
->name
, "t1isa") == 0)
795 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
796 printk(KERN_ERR
"kcapi: driver not loaded.\n");
799 if (!driver
->add_card
) {
800 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
801 printk(KERN_ERR
"kcapi: driver has no add card function.\n");
805 retval
= driver
->add_card(driver
, &cparams
);
806 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
810 case AVMB1_LOAD_AND_CONFIG
:
812 if (cmd
== AVMB1_LOAD
) {
813 if (copy_from_user(&ldef
, data
,
814 sizeof(avmb1_loaddef
)))
816 ldef
.t4config
.len
= 0;
817 ldef
.t4config
.data
= NULL
;
819 if (copy_from_user(&ldef
, data
,
820 sizeof(avmb1_loadandconfigdef
)))
823 card
= get_capi_ctr_by_nr(ldef
.contr
);
826 card
= capi_ctr_get(card
);
829 if (card
->load_firmware
== NULL
) {
830 printk(KERN_DEBUG
"kcapi: load: no load function\n");
834 if (ldef
.t4file
.len
<= 0) {
835 printk(KERN_DEBUG
"kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef
.t4file
.len
);
838 if (ldef
.t4file
.data
== NULL
) {
839 printk(KERN_DEBUG
"kcapi: load: invalid parameter: dataptr is 0\n");
843 ldata
.firmware
.user
= 1;
844 ldata
.firmware
.data
= ldef
.t4file
.data
;
845 ldata
.firmware
.len
= ldef
.t4file
.len
;
846 ldata
.configuration
.user
= 1;
847 ldata
.configuration
.data
= ldef
.t4config
.data
;
848 ldata
.configuration
.len
= ldef
.t4config
.len
;
850 if (card
->cardstate
!= CARD_DETECTED
) {
851 printk(KERN_INFO
"kcapi: load: contr=%d not in detect state\n", ldef
.contr
);
854 card
->cardstate
= CARD_LOADING
;
856 retval
= card
->load_firmware(card
, &ldata
);
859 card
->cardstate
= CARD_DETECTED
;
864 while (card
->cardstate
!= CARD_RUNNING
) {
866 msleep_interruptible(100); /* 0.1 sec */
868 if (signal_pending(current
)) {
876 case AVMB1_RESETCARD
:
877 if (copy_from_user(&rdef
, data
, sizeof(avmb1_resetdef
)))
879 card
= get_capi_ctr_by_nr(rdef
.contr
);
883 if (card
->cardstate
== CARD_DETECTED
)
886 card
->reset_ctr(card
);
888 while (card
->cardstate
> CARD_DETECTED
) {
890 msleep_interruptible(100); /* 0.1 sec */
892 if (signal_pending(current
))
902 int capi20_manufacturer(unsigned int cmd
, void __user
*data
)
904 struct capi_ctr
*card
;
909 case AVMB1_LOAD_AND_CONFIG
:
910 case AVMB1_RESETCARD
:
911 case AVMB1_GET_CARDINFO
:
912 case AVMB1_REMOVECARD
:
913 return old_capi_manufacturer(cmd
, data
);
915 case KCAPI_CMD_TRACE
:
919 if (copy_from_user(&fdef
, data
, sizeof(kcapi_flagdef
)))
922 card
= get_capi_ctr_by_nr(fdef
.contr
);
926 card
->traceflag
= fdef
.flag
;
927 printk(KERN_INFO
"kcapi: contr [%03d] set trace=%d\n",
928 card
->cnr
, card
->traceflag
);
931 case KCAPI_CMD_ADDCARD
:
934 struct capi_driver
*driver
= NULL
;
935 capicardparams cparams
;
939 if ((retval
= copy_from_user(&cdef
, data
, sizeof(cdef
))))
942 cparams
.port
= cdef
.port
;
943 cparams
.irq
= cdef
.irq
;
944 cparams
.membase
= cdef
.membase
;
945 cparams
.cardnr
= cdef
.cardnr
;
946 cparams
.cardtype
= 0;
947 cdef
.driver
[sizeof(cdef
.driver
)-1] = 0;
949 list_for_each(l
, &capi_drivers
) {
950 driver
= list_entry(l
, struct capi_driver
, list
);
951 if (strcmp(driver
->name
, cdef
.driver
) == 0)
954 if (driver
== NULL
) {
955 printk(KERN_ERR
"kcapi: driver \"%s\" not loaded.\n",
960 if (!driver
->add_card
) {
961 printk(KERN_ERR
"kcapi: driver \"%s\" has no add card function.\n", cdef
.driver
);
965 return driver
->add_card(driver
, &cparams
);
969 printk(KERN_ERR
"kcapi: manufacturer command %d unknown.\n",
977 EXPORT_SYMBOL(capi20_manufacturer
);
980 void capi20_set_callback(struct capi20_appl
*ap
,
981 void (*callback
) (unsigned int cmd
, __u32 contr
, void *data
))
983 ap
->callback
= callback
;
986 EXPORT_SYMBOL(capi20_set_callback
);
988 /* ------------------------------------------------------------- */
989 /* -------- Init & Cleanup ------------------------------------- */
990 /* ------------------------------------------------------------- */
993 * init / exit functions
996 static int __init
kcapi_init(void)
1002 ret
= cdebug_init();
1007 if ((p
= strchr(revision
, ':')) != NULL
&& p
[1]) {
1008 strlcpy(rev
, p
+ 2, sizeof(rev
));
1009 if ((p
= strchr(rev
, '$')) != NULL
&& p
> rev
)
1014 printk(KERN_NOTICE
"CAPI Subsystem Rev %s\n", rev
);
1019 static void __exit
kcapi_exit(void)
1023 /* make sure all notifiers are finished */
1024 flush_scheduled_work();
1028 module_init(kcapi_init
);
1029 module_exit(kcapi_exit
);