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
);
274 * capi_ctr_handle_message() - handle incoming CAPI message
275 * @card: controller descriptor structure.
276 * @appl: application ID.
279 * Called by hardware driver to pass a CAPI message to the application.
282 void capi_ctr_handle_message(struct capi_ctr
* card
, u16 appl
, struct sk_buff
*skb
)
284 struct capi20_appl
*ap
;
290 if (card
->cardstate
!= CARD_RUNNING
) {
291 cdb
= capi_message2str(skb
->data
);
293 printk(KERN_INFO
"kcapi: controller [%03d] not active, got: %s",
294 card
->cnr
, cdb
->buf
);
297 printk(KERN_INFO
"kcapi: controller [%03d] not active, cannot trace\n",
302 cmd
= CAPIMSG_COMMAND(skb
->data
);
303 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
304 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_IND
) {
305 card
->nrecvdatapkt
++;
306 if (card
->traceflag
> 2) showctl
|= 2;
309 if (card
->traceflag
) showctl
|= 2;
311 showctl
|= (card
->traceflag
& 1);
314 printk(KERN_DEBUG
"kcapi: got [%03d] id#%d %s len=%u\n",
315 card
->cnr
, CAPIMSG_APPID(skb
->data
),
316 capi_cmd2str(cmd
, subcmd
),
317 CAPIMSG_LEN(skb
->data
));
319 cdb
= capi_message2str(skb
->data
);
321 printk(KERN_DEBUG
"kcapi: got [%03d] %s\n",
322 card
->cnr
, cdb
->buf
);
325 printk(KERN_DEBUG
"kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
326 card
->cnr
, CAPIMSG_APPID(skb
->data
),
327 capi_cmd2str(cmd
, subcmd
),
328 CAPIMSG_LEN(skb
->data
));
333 read_lock_irqsave(&application_lock
, flags
);
334 ap
= get_capi_appl_by_nr(CAPIMSG_APPID(skb
->data
));
335 if ((!ap
) || (ap
->release_in_progress
)) {
336 read_unlock_irqrestore(&application_lock
, flags
);
337 cdb
= capi_message2str(skb
->data
);
339 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s)\n",
340 CAPIMSG_APPID(skb
->data
), cdb
->buf
);
343 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s) cannot trace\n",
344 CAPIMSG_APPID(skb
->data
),
345 capi_cmd2str(cmd
, subcmd
));
348 skb_queue_tail(&ap
->recv_queue
, skb
);
349 schedule_work(&ap
->recv_work
);
350 read_unlock_irqrestore(&application_lock
, flags
);
358 EXPORT_SYMBOL(capi_ctr_handle_message
);
361 * capi_ctr_ready() - signal CAPI controller ready
362 * @card: controller descriptor structure.
364 * Called by hardware driver to signal that the controller is up and running.
367 void capi_ctr_ready(struct capi_ctr
* card
)
369 card
->cardstate
= CARD_RUNNING
;
371 printk(KERN_NOTICE
"kcapi: card [%03d] \"%s\" ready.\n",
372 card
->cnr
, card
->name
);
374 notify_push(KCI_CONTRUP
, card
->cnr
, 0, 0);
377 EXPORT_SYMBOL(capi_ctr_ready
);
380 * capi_ctr_down() - signal CAPI controller not ready
381 * @card: controller descriptor structure.
383 * Called by hardware driver to signal that the controller is down and
384 * unavailable for use.
387 void capi_ctr_down(struct capi_ctr
* card
)
393 if (card
->cardstate
== CARD_DETECTED
)
396 card
->cardstate
= CARD_DETECTED
;
398 memset(card
->manu
, 0, sizeof(card
->manu
));
399 memset(&card
->version
, 0, sizeof(card
->version
));
400 memset(&card
->profile
, 0, sizeof(card
->profile
));
401 memset(card
->serial
, 0, sizeof(card
->serial
));
403 for (appl
= 1; appl
<= CAPI_MAXAPPL
; appl
++) {
404 struct capi20_appl
*ap
= get_capi_appl_by_nr(appl
);
405 if (!ap
|| ap
->release_in_progress
)
411 printk(KERN_NOTICE
"kcapi: card [%03d] down.\n", card
->cnr
);
413 notify_push(KCI_CONTRDOWN
, card
->cnr
, 0, 0);
416 EXPORT_SYMBOL(capi_ctr_down
);
419 * capi_ctr_suspend_output() - suspend controller
420 * @card: controller descriptor structure.
422 * Called by hardware driver to stop data flow.
425 void capi_ctr_suspend_output(struct capi_ctr
*card
)
427 if (!card
->blocked
) {
428 printk(KERN_DEBUG
"kcapi: card [%03d] suspend\n", card
->cnr
);
433 EXPORT_SYMBOL(capi_ctr_suspend_output
);
436 * capi_ctr_resume_output() - resume controller
437 * @card: controller descriptor structure.
439 * Called by hardware driver to resume data flow.
442 void capi_ctr_resume_output(struct capi_ctr
*card
)
445 printk(KERN_DEBUG
"kcapi: card [%03d] resume\n", card
->cnr
);
450 EXPORT_SYMBOL(capi_ctr_resume_output
);
452 /* ------------------------------------------------------------- */
455 * attach_capi_ctr() - register CAPI controller
456 * @card: controller descriptor structure.
458 * Called by hardware driver to register a controller with the CAPI subsystem.
459 * Return value: 0 on success, error code < 0 on error
463 attach_capi_ctr(struct capi_ctr
*card
)
467 mutex_lock(&controller_mutex
);
469 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
470 if (capi_cards
[i
] == NULL
)
473 if (i
== CAPI_MAXCONTR
) {
474 mutex_unlock(&controller_mutex
);
475 printk(KERN_ERR
"kcapi: out of controller slots\n");
478 capi_cards
[i
] = card
;
480 mutex_unlock(&controller_mutex
);
482 card
->nrecvctlpkt
= 0;
483 card
->nrecvdatapkt
= 0;
484 card
->nsentctlpkt
= 0;
485 card
->nsentdatapkt
= 0;
487 card
->cardstate
= CARD_DETECTED
;
489 card
->traceflag
= showcapimsgs
;
491 sprintf(card
->procfn
, "capi/controllers/%d", card
->cnr
);
492 card
->procent
= create_proc_entry(card
->procfn
, 0, NULL
);
494 card
->procent
->read_proc
=
495 (int (*)(char *,char **,off_t
,int,int *,void *))
497 card
->procent
->data
= card
;
501 printk(KERN_NOTICE
"kcapi: Controller [%03d]: %s attached\n",
502 card
->cnr
, card
->name
);
506 EXPORT_SYMBOL(attach_capi_ctr
);
509 * detach_capi_ctr() - unregister CAPI controller
510 * @card: controller descriptor structure.
512 * Called by hardware driver to remove the registration of a controller
513 * with the CAPI subsystem.
514 * Return value: 0 on success, error code < 0 on error
517 int detach_capi_ctr(struct capi_ctr
*card
)
519 if (card
->cardstate
!= CARD_DETECTED
)
525 remove_proc_entry(card
->procfn
, NULL
);
526 card
->procent
= NULL
;
528 capi_cards
[card
->cnr
- 1] = NULL
;
529 printk(KERN_NOTICE
"kcapi: Controller [%03d]: %s unregistered\n",
530 card
->cnr
, card
->name
);
535 EXPORT_SYMBOL(detach_capi_ctr
);
538 * register_capi_driver() - register CAPI driver
539 * @driver: driver descriptor structure.
541 * Called by hardware driver to register itself with the CAPI subsystem.
544 void register_capi_driver(struct capi_driver
*driver
)
548 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
549 list_add_tail(&driver
->list
, &capi_drivers
);
550 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
553 EXPORT_SYMBOL(register_capi_driver
);
556 * unregister_capi_driver() - unregister CAPI driver
557 * @driver: driver descriptor structure.
559 * Called by hardware driver to unregister itself from the CAPI subsystem.
562 void unregister_capi_driver(struct capi_driver
*driver
)
566 write_lock_irqsave(&capi_drivers_list_lock
, flags
);
567 list_del(&driver
->list
);
568 write_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
571 EXPORT_SYMBOL(unregister_capi_driver
);
573 /* ------------------------------------------------------------- */
574 /* -------- CAPI2.0 Interface ---------------------------------- */
575 /* ------------------------------------------------------------- */
578 * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
580 * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
581 * is ready for use, CAPI_REGNOTINSTALLED otherwise)
584 u16
capi20_isinstalled(void)
587 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
588 if (capi_cards
[i
] && capi_cards
[i
]->cardstate
== CARD_RUNNING
)
591 return CAPI_REGNOTINSTALLED
;
594 EXPORT_SYMBOL(capi20_isinstalled
);
597 * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
598 * @ap: CAPI application descriptor structure.
600 * Register an application's presence with CAPI.
601 * A unique application ID is assigned and stored in @ap->applid.
602 * After this function returns successfully, the message receive
603 * callback function @ap->recv_message() may be called at any time
604 * until capi20_release() has been called for the same @ap.
605 * Return value: CAPI result code
608 u16
capi20_register(struct capi20_appl
*ap
)
616 if (ap
->rparam
.datablklen
< 128)
617 return CAPI_LOGBLKSIZETOSMALL
;
619 write_lock_irqsave(&application_lock
, flags
);
621 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
622 if (capi_applications
[applid
- 1] == NULL
)
625 if (applid
> CAPI_MAXAPPL
) {
626 write_unlock_irqrestore(&application_lock
, flags
);
627 return CAPI_TOOMANYAPPLS
;
631 capi_applications
[applid
- 1] = ap
;
634 ap
->nrecvdatapkt
= 0;
636 ap
->nsentdatapkt
= 0;
638 mutex_init(&ap
->recv_mtx
);
639 skb_queue_head_init(&ap
->recv_queue
);
640 INIT_WORK(&ap
->recv_work
, recv_handler
);
641 ap
->release_in_progress
= 0;
643 write_unlock_irqrestore(&application_lock
, flags
);
645 mutex_lock(&controller_mutex
);
646 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
647 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
649 register_appl(capi_cards
[i
], applid
, &ap
->rparam
);
651 mutex_unlock(&controller_mutex
);
653 if (showcapimsgs
& 1) {
654 printk(KERN_DEBUG
"kcapi: appl %d up\n", applid
);
660 EXPORT_SYMBOL(capi20_register
);
663 * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
664 * @ap: CAPI application descriptor structure.
666 * Terminate an application's registration with CAPI.
667 * After this function returns successfully, the message receive
668 * callback function @ap->recv_message() will no longer be called.
669 * Return value: CAPI result code
672 u16
capi20_release(struct capi20_appl
*ap
)
677 DBG("applid %#x", ap
->applid
);
679 write_lock_irqsave(&application_lock
, flags
);
680 ap
->release_in_progress
= 1;
681 capi_applications
[ap
->applid
- 1] = NULL
;
682 write_unlock_irqrestore(&application_lock
, flags
);
684 mutex_lock(&controller_mutex
);
685 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
686 if (!capi_cards
[i
] || capi_cards
[i
]->cardstate
!= CARD_RUNNING
)
688 release_appl(capi_cards
[i
], ap
->applid
);
690 mutex_unlock(&controller_mutex
);
692 flush_scheduled_work();
693 skb_queue_purge(&ap
->recv_queue
);
695 if (showcapimsgs
& 1) {
696 printk(KERN_DEBUG
"kcapi: appl %d down\n", ap
->applid
);
702 EXPORT_SYMBOL(capi20_release
);
705 * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
706 * @ap: CAPI application descriptor structure.
707 * @skb: CAPI message.
709 * Transfer a single message to CAPI.
710 * Return value: CAPI result code
713 u16
capi20_put_message(struct capi20_appl
*ap
, struct sk_buff
*skb
)
715 struct capi_ctr
*card
;
719 DBG("applid %#x", ap
->applid
);
722 return CAPI_REGNOTINSTALLED
;
723 if ((ap
->applid
== 0) || ap
->release_in_progress
)
724 return CAPI_ILLAPPNR
;
726 || !capi_cmd_valid(CAPIMSG_COMMAND(skb
->data
))
727 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb
->data
)))
728 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL
;
729 card
= get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb
->data
));
730 if (!card
|| card
->cardstate
!= CARD_RUNNING
) {
731 card
= get_capi_ctr_by_nr(1); // XXX why?
732 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
733 return CAPI_REGNOTINSTALLED
;
736 return CAPI_SENDQUEUEFULL
;
738 cmd
= CAPIMSG_COMMAND(skb
->data
);
739 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
741 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_REQ
) {
742 card
->nsentdatapkt
++;
744 if (card
->traceflag
> 2) showctl
|= 2;
748 if (card
->traceflag
) showctl
|= 2;
750 showctl
|= (card
->traceflag
& 1);
753 printk(KERN_DEBUG
"kcapi: put [%03d] id#%d %s len=%u\n",
754 CAPIMSG_CONTROLLER(skb
->data
),
755 CAPIMSG_APPID(skb
->data
),
756 capi_cmd2str(cmd
, subcmd
),
757 CAPIMSG_LEN(skb
->data
));
759 _cdebbuf
*cdb
= capi_message2str(skb
->data
);
761 printk(KERN_DEBUG
"kcapi: put [%03d] %s\n",
762 CAPIMSG_CONTROLLER(skb
->data
),
766 printk(KERN_DEBUG
"kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
767 CAPIMSG_CONTROLLER(skb
->data
),
768 CAPIMSG_APPID(skb
->data
),
769 capi_cmd2str(cmd
, subcmd
),
770 CAPIMSG_LEN(skb
->data
));
773 return card
->send_message(card
, skb
);
776 EXPORT_SYMBOL(capi20_put_message
);
779 * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
780 * @contr: controller number.
781 * @buf: result buffer (64 bytes).
783 * Retrieve information about the manufacturer of the specified ISDN controller
784 * or (for @contr == 0) the driver itself.
785 * Return value: CAPI result code
788 u16
capi20_get_manufacturer(u32 contr
, u8
*buf
)
790 struct capi_ctr
*card
;
793 strlcpy(buf
, capi_manufakturer
, CAPI_MANUFACTURER_LEN
);
796 card
= get_capi_ctr_by_nr(contr
);
797 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
798 return CAPI_REGNOTINSTALLED
;
799 strlcpy(buf
, card
->manu
, CAPI_MANUFACTURER_LEN
);
803 EXPORT_SYMBOL(capi20_get_manufacturer
);
806 * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
807 * @contr: controller number.
808 * @verp: result structure.
810 * Retrieve version information for the specified ISDN controller
811 * or (for @contr == 0) the driver itself.
812 * Return value: CAPI result code
815 u16
capi20_get_version(u32 contr
, struct capi_version
*verp
)
817 struct capi_ctr
*card
;
820 *verp
= driver_version
;
823 card
= get_capi_ctr_by_nr(contr
);
824 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
825 return CAPI_REGNOTINSTALLED
;
827 memcpy((void *) verp
, &card
->version
, sizeof(capi_version
));
831 EXPORT_SYMBOL(capi20_get_version
);
834 * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
835 * @contr: controller number.
836 * @serial: result buffer (8 bytes).
838 * Retrieve the serial number of the specified ISDN controller
839 * or (for @contr == 0) the driver itself.
840 * Return value: CAPI result code
843 u16
capi20_get_serial(u32 contr
, u8
*serial
)
845 struct capi_ctr
*card
;
848 strlcpy(serial
, driver_serial
, CAPI_SERIAL_LEN
);
851 card
= get_capi_ctr_by_nr(contr
);
852 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
853 return CAPI_REGNOTINSTALLED
;
855 strlcpy((void *) serial
, card
->serial
, CAPI_SERIAL_LEN
);
859 EXPORT_SYMBOL(capi20_get_serial
);
862 * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
863 * @contr: controller number.
864 * @profp: result structure.
866 * Retrieve capability information for the specified ISDN controller
867 * or (for @contr == 0) the number of installed controllers.
868 * Return value: CAPI result code
871 u16
capi20_get_profile(u32 contr
, struct capi_profile
*profp
)
873 struct capi_ctr
*card
;
876 profp
->ncontroller
= ncards
;
879 card
= get_capi_ctr_by_nr(contr
);
880 if (!card
|| card
->cardstate
!= CARD_RUNNING
)
881 return CAPI_REGNOTINSTALLED
;
883 memcpy((void *) profp
, &card
->profile
,
884 sizeof(struct capi_profile
));
888 EXPORT_SYMBOL(capi20_get_profile
);
891 static int old_capi_manufacturer(unsigned int cmd
, void __user
*data
)
893 avmb1_loadandconfigdef ldef
;
894 avmb1_extcarddef cdef
;
896 capicardparams cparams
;
897 struct capi_ctr
*card
;
898 struct capi_driver
*driver
= NULL
;
906 case AVMB1_ADDCARD_WITH_TYPE
:
907 if (cmd
== AVMB1_ADDCARD
) {
908 if ((retval
= copy_from_user(&cdef
, data
,
909 sizeof(avmb1_carddef
))))
911 cdef
.cardtype
= AVM_CARDTYPE_B1
;
913 if ((retval
= copy_from_user(&cdef
, data
,
914 sizeof(avmb1_extcarddef
))))
917 cparams
.port
= cdef
.port
;
918 cparams
.irq
= cdef
.irq
;
919 cparams
.cardnr
= cdef
.cardnr
;
921 read_lock_irqsave(&capi_drivers_list_lock
, flags
);
922 switch (cdef
.cardtype
) {
923 case AVM_CARDTYPE_B1
:
924 list_for_each(l
, &capi_drivers
) {
925 driver
= list_entry(l
, struct capi_driver
, list
);
926 if (strcmp(driver
->name
, "b1isa") == 0)
930 case AVM_CARDTYPE_T1
:
931 list_for_each(l
, &capi_drivers
) {
932 driver
= list_entry(l
, struct capi_driver
, list
);
933 if (strcmp(driver
->name
, "t1isa") == 0)
942 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
943 printk(KERN_ERR
"kcapi: driver not loaded.\n");
946 if (!driver
->add_card
) {
947 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
948 printk(KERN_ERR
"kcapi: driver has no add card function.\n");
952 retval
= driver
->add_card(driver
, &cparams
);
953 read_unlock_irqrestore(&capi_drivers_list_lock
, flags
);
957 case AVMB1_LOAD_AND_CONFIG
:
959 if (cmd
== AVMB1_LOAD
) {
960 if (copy_from_user(&ldef
, data
,
961 sizeof(avmb1_loaddef
)))
963 ldef
.t4config
.len
= 0;
964 ldef
.t4config
.data
= NULL
;
966 if (copy_from_user(&ldef
, data
,
967 sizeof(avmb1_loadandconfigdef
)))
970 card
= get_capi_ctr_by_nr(ldef
.contr
);
973 card
= capi_ctr_get(card
);
976 if (card
->load_firmware
== NULL
) {
977 printk(KERN_DEBUG
"kcapi: load: no load function\n");
982 if (ldef
.t4file
.len
<= 0) {
983 printk(KERN_DEBUG
"kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef
.t4file
.len
);
987 if (ldef
.t4file
.data
== NULL
) {
988 printk(KERN_DEBUG
"kcapi: load: invalid parameter: dataptr is 0\n");
993 ldata
.firmware
.user
= 1;
994 ldata
.firmware
.data
= ldef
.t4file
.data
;
995 ldata
.firmware
.len
= ldef
.t4file
.len
;
996 ldata
.configuration
.user
= 1;
997 ldata
.configuration
.data
= ldef
.t4config
.data
;
998 ldata
.configuration
.len
= ldef
.t4config
.len
;
1000 if (card
->cardstate
!= CARD_DETECTED
) {
1001 printk(KERN_INFO
"kcapi: load: contr=%d not in detect state\n", ldef
.contr
);
1005 card
->cardstate
= CARD_LOADING
;
1007 retval
= card
->load_firmware(card
, &ldata
);
1010 card
->cardstate
= CARD_DETECTED
;
1015 while (card
->cardstate
!= CARD_RUNNING
) {
1017 msleep_interruptible(100); /* 0.1 sec */
1019 if (signal_pending(current
)) {
1027 case AVMB1_RESETCARD
:
1028 if (copy_from_user(&rdef
, data
, sizeof(avmb1_resetdef
)))
1030 card
= get_capi_ctr_by_nr(rdef
.contr
);
1034 if (card
->cardstate
== CARD_DETECTED
)
1037 card
->reset_ctr(card
);
1039 while (card
->cardstate
> CARD_DETECTED
) {
1041 msleep_interruptible(100); /* 0.1 sec */
1043 if (signal_pending(current
))
1054 * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
1058 * Perform manufacturer specific command.
1059 * Return value: CAPI result code
1062 int capi20_manufacturer(unsigned int cmd
, void __user
*data
)
1064 struct capi_ctr
*card
;
1069 case AVMB1_LOAD_AND_CONFIG
:
1070 case AVMB1_RESETCARD
:
1071 case AVMB1_GET_CARDINFO
:
1072 case AVMB1_REMOVECARD
:
1073 return old_capi_manufacturer(cmd
, data
);
1075 case KCAPI_CMD_TRACE
:
1079 if (copy_from_user(&fdef
, data
, sizeof(kcapi_flagdef
)))
1082 card
= get_capi_ctr_by_nr(fdef
.contr
);
1086 card
->traceflag
= fdef
.flag
;
1087 printk(KERN_INFO
"kcapi: contr [%03d] set trace=%d\n",
1088 card
->cnr
, card
->traceflag
);
1091 case KCAPI_CMD_ADDCARD
:
1093 struct list_head
*l
;
1094 struct capi_driver
*driver
= NULL
;
1095 capicardparams cparams
;
1099 if ((retval
= copy_from_user(&cdef
, data
, sizeof(cdef
))))
1102 cparams
.port
= cdef
.port
;
1103 cparams
.irq
= cdef
.irq
;
1104 cparams
.membase
= cdef
.membase
;
1105 cparams
.cardnr
= cdef
.cardnr
;
1106 cparams
.cardtype
= 0;
1107 cdef
.driver
[sizeof(cdef
.driver
)-1] = 0;
1109 list_for_each(l
, &capi_drivers
) {
1110 driver
= list_entry(l
, struct capi_driver
, list
);
1111 if (strcmp(driver
->name
, cdef
.driver
) == 0)
1114 if (driver
== NULL
) {
1115 printk(KERN_ERR
"kcapi: driver \"%s\" not loaded.\n",
1120 if (!driver
->add_card
) {
1121 printk(KERN_ERR
"kcapi: driver \"%s\" has no add card function.\n", cdef
.driver
);
1125 return driver
->add_card(driver
, &cparams
);
1129 printk(KERN_ERR
"kcapi: manufacturer command %d unknown.\n",
1137 EXPORT_SYMBOL(capi20_manufacturer
);
1139 /* temporary hack */
1142 * capi20_set_callback() - set CAPI application notification callback function
1143 * @ap: CAPI application descriptor structure.
1144 * @callback: callback function (NULL to remove).
1146 * If not NULL, the callback function will be called to notify the
1147 * application of the addition or removal of a controller.
1148 * The first argument (cmd) will tell whether the controller was added
1149 * (KCI_CONTRUP) or removed (KCI_CONTRDOWN).
1150 * The second argument (contr) will be the controller number.
1151 * For cmd==KCI_CONTRUP the third argument (data) will be a pointer to the
1152 * new controller's capability profile structure.
1155 void capi20_set_callback(struct capi20_appl
*ap
,
1156 void (*callback
) (unsigned int cmd
, __u32 contr
, void *data
))
1158 ap
->callback
= callback
;
1161 EXPORT_SYMBOL(capi20_set_callback
);
1163 /* ------------------------------------------------------------- */
1164 /* -------- Init & Cleanup ------------------------------------- */
1165 /* ------------------------------------------------------------- */
1168 * init / exit functions
1171 static int __init
kcapi_init(void)
1177 ret
= cdebug_init();
1182 if ((p
= strchr(revision
, ':')) != NULL
&& p
[1]) {
1183 strlcpy(rev
, p
+ 2, sizeof(rev
));
1184 if ((p
= strchr(rev
, '$')) != NULL
&& p
> rev
)
1189 printk(KERN_NOTICE
"CAPI Subsystem Rev %s\n", rev
);
1194 static void __exit
kcapi_exit(void)
1198 /* make sure all notifiers are finished */
1199 flush_scheduled_work();
1203 module_init(kcapi_init
);
1204 module_exit(kcapi_exit
);