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.
14 #include <linux/module.h>
16 #include <linux/interrupt.h>
17 #include <linux/ioport.h>
18 #include <linux/proc_fs.h>
19 #include <linux/sched/signal.h>
20 #include <linux/seq_file.h>
21 #include <linux/skbuff.h>
22 #include <linux/workqueue.h>
23 #include <linux/capi.h>
24 #include <linux/kernelcapi.h>
25 #include <linux/init.h>
26 #include <linux/moduleparam.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/uaccess.h>
30 #include <linux/isdn/capicmd.h>
31 #include <linux/isdn/capiutil.h>
32 #include <linux/mutex.h>
33 #include <linux/rcupdate.h>
35 static int showcapimsgs
;
36 static struct workqueue_struct
*kcapi_wq
;
38 module_param(showcapimsgs
, uint
, 0);
40 /* ------------------------------------------------------------- */
42 struct capictr_event
{
43 struct work_struct work
;
48 /* ------------------------------------------------------------- */
50 static const struct capi_version driver_version
= {2, 0, 1, 1 << 4};
51 static char driver_serial
[CAPI_SERIAL_LEN
] = "0004711";
52 static char capi_manufakturer
[64] = "AVM Berlin";
54 #define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
56 struct capi_ctr
*capi_controller
[CAPI_MAXCONTR
];
57 DEFINE_MUTEX(capi_controller_lock
);
59 struct capi20_appl
*capi_applications
[CAPI_MAXAPPL
];
61 static int ncontrollers
;
63 /* -------- controller ref counting -------------------------------------- */
65 static inline struct capi_ctr
*
66 capi_ctr_get(struct capi_ctr
*ctr
)
68 if (!try_module_get(ctr
->owner
))
74 capi_ctr_put(struct capi_ctr
*ctr
)
76 module_put(ctr
->owner
);
79 /* ------------------------------------------------------------- */
81 static inline struct capi_ctr
*get_capi_ctr_by_nr(u16 contr
)
83 if (contr
< 1 || contr
- 1 >= CAPI_MAXCONTR
)
86 return capi_controller
[contr
- 1];
89 static inline struct capi20_appl
*__get_capi_appl_by_nr(u16 applid
)
91 lockdep_assert_held(&capi_controller_lock
);
93 if (applid
< 1 || applid
- 1 >= CAPI_MAXAPPL
)
96 return capi_applications
[applid
- 1];
99 static inline struct capi20_appl
*get_capi_appl_by_nr(u16 applid
)
101 if (applid
< 1 || applid
- 1 >= CAPI_MAXAPPL
)
104 return rcu_dereference(capi_applications
[applid
- 1]);
107 /* -------- util functions ------------------------------------ */
109 static inline int capi_cmd_valid(u8 cmd
)
114 case CAPI_CONNECT_ACTIVE
:
115 case CAPI_CONNECT_B3_ACTIVE
:
116 case CAPI_CONNECT_B3
:
117 case CAPI_CONNECT_B3_T90_ACTIVE
:
119 case CAPI_DISCONNECT_B3
:
120 case CAPI_DISCONNECT
:
124 case CAPI_MANUFACTURER
:
126 case CAPI_SELECT_B_PROTOCOL
:
132 static inline int capi_subcmd_valid(u8 subcmd
)
144 /* ------------------------------------------------------------ */
147 register_appl(struct capi_ctr
*ctr
, u16 applid
, capi_register_params
*rparam
)
149 ctr
= capi_ctr_get(ctr
);
152 ctr
->register_appl(ctr
, applid
, rparam
);
154 printk(KERN_WARNING
"%s: cannot get controller resources\n",
159 static void release_appl(struct capi_ctr
*ctr
, u16 applid
)
161 DBG("applid %#x", applid
);
163 ctr
->release_appl(ctr
, applid
);
167 static void notify_up(u32 contr
)
169 struct capi20_appl
*ap
;
170 struct capi_ctr
*ctr
;
173 mutex_lock(&capi_controller_lock
);
175 if (showcapimsgs
& 1)
176 printk(KERN_DEBUG
"kcapi: notify up contr %d\n", contr
);
178 ctr
= get_capi_ctr_by_nr(contr
);
180 if (ctr
->state
== CAPI_CTR_RUNNING
)
183 ctr
->state
= CAPI_CTR_RUNNING
;
185 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
186 ap
= __get_capi_appl_by_nr(applid
);
188 register_appl(ctr
, applid
, &ap
->rparam
);
191 printk(KERN_WARNING
"%s: invalid contr %d\n", __func__
, contr
);
194 mutex_unlock(&capi_controller_lock
);
197 static void ctr_down(struct capi_ctr
*ctr
, int new_state
)
199 struct capi20_appl
*ap
;
202 if (ctr
->state
== CAPI_CTR_DETECTED
|| ctr
->state
== CAPI_CTR_DETACHED
)
205 ctr
->state
= new_state
;
207 memset(ctr
->manu
, 0, sizeof(ctr
->manu
));
208 memset(&ctr
->version
, 0, sizeof(ctr
->version
));
209 memset(&ctr
->profile
, 0, sizeof(ctr
->profile
));
210 memset(ctr
->serial
, 0, sizeof(ctr
->serial
));
212 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
213 ap
= __get_capi_appl_by_nr(applid
);
219 static void notify_down(u32 contr
)
221 struct capi_ctr
*ctr
;
223 mutex_lock(&capi_controller_lock
);
225 if (showcapimsgs
& 1)
226 printk(KERN_DEBUG
"kcapi: notify down contr %d\n", contr
);
228 ctr
= get_capi_ctr_by_nr(contr
);
230 ctr_down(ctr
, CAPI_CTR_DETECTED
);
232 printk(KERN_WARNING
"%s: invalid contr %d\n", __func__
, contr
);
234 mutex_unlock(&capi_controller_lock
);
237 static void do_notify_work(struct work_struct
*work
)
239 struct capictr_event
*event
=
240 container_of(work
, struct capictr_event
, work
);
242 switch (event
->type
) {
244 notify_up(event
->controller
);
247 notify_down(event
->controller
);
254 static int notify_push(unsigned int event_type
, u32 controller
)
256 struct capictr_event
*event
= kmalloc(sizeof(*event
), GFP_ATOMIC
);
261 INIT_WORK(&event
->work
, do_notify_work
);
262 event
->type
= event_type
;
263 event
->controller
= controller
;
265 queue_work(kcapi_wq
, &event
->work
);
269 /* -------- Receiver ------------------------------------------ */
271 static void recv_handler(struct work_struct
*work
)
274 struct capi20_appl
*ap
=
275 container_of(work
, struct capi20_appl
, recv_work
);
277 if ((!ap
) || (ap
->release_in_progress
))
280 mutex_lock(&ap
->recv_mtx
);
281 while ((skb
= skb_dequeue(&ap
->recv_queue
))) {
282 if (CAPIMSG_CMD(skb
->data
) == CAPI_DATA_B3_IND
)
287 ap
->recv_message(ap
, skb
);
289 mutex_unlock(&ap
->recv_mtx
);
293 * capi_ctr_handle_message() - handle incoming CAPI message
294 * @ctr: controller descriptor structure.
295 * @appl: application ID.
298 * Called by hardware driver to pass a CAPI message to the application.
301 void capi_ctr_handle_message(struct capi_ctr
*ctr
, u16 appl
,
304 struct capi20_appl
*ap
;
309 if (ctr
->state
!= CAPI_CTR_RUNNING
) {
310 cdb
= capi_message2str(skb
->data
);
312 printk(KERN_INFO
"kcapi: controller [%03d] not active, got: %s",
316 printk(KERN_INFO
"kcapi: controller [%03d] not active, cannot trace\n",
321 cmd
= CAPIMSG_COMMAND(skb
->data
);
322 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
323 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_IND
) {
325 if (ctr
->traceflag
> 2)
332 showctl
|= (ctr
->traceflag
& 1);
335 printk(KERN_DEBUG
"kcapi: got [%03d] id#%d %s len=%u\n",
336 ctr
->cnr
, CAPIMSG_APPID(skb
->data
),
337 capi_cmd2str(cmd
, subcmd
),
338 CAPIMSG_LEN(skb
->data
));
340 cdb
= capi_message2str(skb
->data
);
342 printk(KERN_DEBUG
"kcapi: got [%03d] %s\n",
346 printk(KERN_DEBUG
"kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
347 ctr
->cnr
, CAPIMSG_APPID(skb
->data
),
348 capi_cmd2str(cmd
, subcmd
),
349 CAPIMSG_LEN(skb
->data
));
355 ap
= get_capi_appl_by_nr(CAPIMSG_APPID(skb
->data
));
358 cdb
= capi_message2str(skb
->data
);
360 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s)\n",
361 CAPIMSG_APPID(skb
->data
), cdb
->buf
);
364 printk(KERN_ERR
"kcapi: handle_message: applid %d state released (%s) cannot trace\n",
365 CAPIMSG_APPID(skb
->data
),
366 capi_cmd2str(cmd
, subcmd
));
369 skb_queue_tail(&ap
->recv_queue
, skb
);
370 queue_work(kcapi_wq
, &ap
->recv_work
);
379 EXPORT_SYMBOL(capi_ctr_handle_message
);
382 * capi_ctr_ready() - signal CAPI controller ready
383 * @ctr: controller descriptor structure.
385 * Called by hardware driver to signal that the controller is up and running.
388 void capi_ctr_ready(struct capi_ctr
*ctr
)
390 printk(KERN_NOTICE
"kcapi: controller [%03d] \"%s\" ready.\n",
391 ctr
->cnr
, ctr
->name
);
393 notify_push(CAPICTR_UP
, ctr
->cnr
);
396 EXPORT_SYMBOL(capi_ctr_ready
);
399 * capi_ctr_down() - signal CAPI controller not ready
400 * @ctr: controller descriptor structure.
402 * Called by hardware driver to signal that the controller is down and
403 * unavailable for use.
406 void capi_ctr_down(struct capi_ctr
*ctr
)
408 printk(KERN_NOTICE
"kcapi: controller [%03d] down.\n", ctr
->cnr
);
410 notify_push(CAPICTR_DOWN
, ctr
->cnr
);
413 EXPORT_SYMBOL(capi_ctr_down
);
415 /* ------------------------------------------------------------- */
418 * attach_capi_ctr() - register CAPI controller
419 * @ctr: controller descriptor structure.
421 * Called by hardware driver to register a controller with the CAPI subsystem.
422 * Return value: 0 on success, error code < 0 on error
425 int attach_capi_ctr(struct capi_ctr
*ctr
)
429 mutex_lock(&capi_controller_lock
);
431 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
432 if (!capi_controller
[i
])
435 if (i
== CAPI_MAXCONTR
) {
436 mutex_unlock(&capi_controller_lock
);
437 printk(KERN_ERR
"kcapi: out of controller slots\n");
440 capi_controller
[i
] = ctr
;
442 ctr
->nrecvctlpkt
= 0;
443 ctr
->nrecvdatapkt
= 0;
444 ctr
->nsentctlpkt
= 0;
445 ctr
->nsentdatapkt
= 0;
447 ctr
->state
= CAPI_CTR_DETECTED
;
449 ctr
->traceflag
= showcapimsgs
;
451 sprintf(ctr
->procfn
, "capi/controllers/%d", ctr
->cnr
);
452 ctr
->procent
= proc_create_single_data(ctr
->procfn
, 0, NULL
,
453 ctr
->proc_show
, ctr
);
457 mutex_unlock(&capi_controller_lock
);
459 printk(KERN_NOTICE
"kcapi: controller [%03d]: %s attached\n",
460 ctr
->cnr
, ctr
->name
);
464 EXPORT_SYMBOL(attach_capi_ctr
);
467 * detach_capi_ctr() - unregister CAPI controller
468 * @ctr: controller descriptor structure.
470 * Called by hardware driver to remove the registration of a controller
471 * with the CAPI subsystem.
472 * Return value: 0 on success, error code < 0 on error
475 int detach_capi_ctr(struct capi_ctr
*ctr
)
479 mutex_lock(&capi_controller_lock
);
481 ctr_down(ctr
, CAPI_CTR_DETACHED
);
483 if (ctr
->cnr
< 1 || ctr
->cnr
- 1 >= CAPI_MAXCONTR
) {
488 if (capi_controller
[ctr
->cnr
- 1] != ctr
) {
492 capi_controller
[ctr
->cnr
- 1] = NULL
;
496 remove_proc_entry(ctr
->procfn
, NULL
);
498 printk(KERN_NOTICE
"kcapi: controller [%03d]: %s unregistered\n",
499 ctr
->cnr
, ctr
->name
);
502 mutex_unlock(&capi_controller_lock
);
507 EXPORT_SYMBOL(detach_capi_ctr
);
509 /* ------------------------------------------------------------- */
510 /* -------- CAPI2.0 Interface ---------------------------------- */
511 /* ------------------------------------------------------------- */
514 * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
516 * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
517 * is ready for use, CAPI_REGNOTINSTALLED otherwise)
520 u16
capi20_isinstalled(void)
522 u16 ret
= CAPI_REGNOTINSTALLED
;
525 mutex_lock(&capi_controller_lock
);
527 for (i
= 0; i
< CAPI_MAXCONTR
; i
++)
528 if (capi_controller
[i
] &&
529 capi_controller
[i
]->state
== CAPI_CTR_RUNNING
) {
534 mutex_unlock(&capi_controller_lock
);
540 * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
541 * @ap: CAPI application descriptor structure.
543 * Register an application's presence with CAPI.
544 * A unique application ID is assigned and stored in @ap->applid.
545 * After this function returns successfully, the message receive
546 * callback function @ap->recv_message() may be called at any time
547 * until capi20_release() has been called for the same @ap.
548 * Return value: CAPI result code
551 u16
capi20_register(struct capi20_appl
*ap
)
558 if (ap
->rparam
.datablklen
< 128)
559 return CAPI_LOGBLKSIZETOSMALL
;
562 ap
->nrecvdatapkt
= 0;
564 ap
->nsentdatapkt
= 0;
565 mutex_init(&ap
->recv_mtx
);
566 skb_queue_head_init(&ap
->recv_queue
);
567 INIT_WORK(&ap
->recv_work
, recv_handler
);
568 ap
->release_in_progress
= 0;
570 mutex_lock(&capi_controller_lock
);
572 for (applid
= 1; applid
<= CAPI_MAXAPPL
; applid
++) {
573 if (capi_applications
[applid
- 1] == NULL
)
576 if (applid
> CAPI_MAXAPPL
) {
577 mutex_unlock(&capi_controller_lock
);
578 return CAPI_TOOMANYAPPLS
;
582 capi_applications
[applid
- 1] = ap
;
584 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
585 if (!capi_controller
[i
] ||
586 capi_controller
[i
]->state
!= CAPI_CTR_RUNNING
)
588 register_appl(capi_controller
[i
], applid
, &ap
->rparam
);
591 mutex_unlock(&capi_controller_lock
);
593 if (showcapimsgs
& 1) {
594 printk(KERN_DEBUG
"kcapi: appl %d up\n", applid
);
601 * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
602 * @ap: CAPI application descriptor structure.
604 * Terminate an application's registration with CAPI.
605 * After this function returns successfully, the message receive
606 * callback function @ap->recv_message() will no longer be called.
607 * Return value: CAPI result code
610 u16
capi20_release(struct capi20_appl
*ap
)
614 DBG("applid %#x", ap
->applid
);
616 mutex_lock(&capi_controller_lock
);
618 ap
->release_in_progress
= 1;
619 capi_applications
[ap
->applid
- 1] = NULL
;
623 for (i
= 0; i
< CAPI_MAXCONTR
; i
++) {
624 if (!capi_controller
[i
] ||
625 capi_controller
[i
]->state
!= CAPI_CTR_RUNNING
)
627 release_appl(capi_controller
[i
], ap
->applid
);
630 mutex_unlock(&capi_controller_lock
);
632 flush_workqueue(kcapi_wq
);
633 skb_queue_purge(&ap
->recv_queue
);
635 if (showcapimsgs
& 1) {
636 printk(KERN_DEBUG
"kcapi: appl %d down\n", ap
->applid
);
643 * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
644 * @ap: CAPI application descriptor structure.
645 * @skb: CAPI message.
647 * Transfer a single message to CAPI.
648 * Return value: CAPI result code
651 u16
capi20_put_message(struct capi20_appl
*ap
, struct sk_buff
*skb
)
653 struct capi_ctr
*ctr
;
657 DBG("applid %#x", ap
->applid
);
659 if (ncontrollers
== 0)
660 return CAPI_REGNOTINSTALLED
;
661 if ((ap
->applid
== 0) || ap
->release_in_progress
)
662 return CAPI_ILLAPPNR
;
664 || !capi_cmd_valid(CAPIMSG_COMMAND(skb
->data
))
665 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb
->data
)))
666 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL
;
669 * The controller reference is protected by the existence of the
670 * application passed to us. We assume that the caller properly
671 * synchronizes this service with capi20_release.
673 ctr
= get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb
->data
));
674 if (!ctr
|| ctr
->state
!= CAPI_CTR_RUNNING
)
675 return CAPI_REGNOTINSTALLED
;
677 return CAPI_SENDQUEUEFULL
;
679 cmd
= CAPIMSG_COMMAND(skb
->data
);
680 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
682 if (cmd
== CAPI_DATA_B3
&& subcmd
== CAPI_REQ
) {
685 if (ctr
->traceflag
> 2)
693 showctl
|= (ctr
->traceflag
& 1);
696 printk(KERN_DEBUG
"kcapi: put [%03d] id#%d %s len=%u\n",
697 CAPIMSG_CONTROLLER(skb
->data
),
698 CAPIMSG_APPID(skb
->data
),
699 capi_cmd2str(cmd
, subcmd
),
700 CAPIMSG_LEN(skb
->data
));
702 _cdebbuf
*cdb
= capi_message2str(skb
->data
);
704 printk(KERN_DEBUG
"kcapi: put [%03d] %s\n",
705 CAPIMSG_CONTROLLER(skb
->data
),
709 printk(KERN_DEBUG
"kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
710 CAPIMSG_CONTROLLER(skb
->data
),
711 CAPIMSG_APPID(skb
->data
),
712 capi_cmd2str(cmd
, subcmd
),
713 CAPIMSG_LEN(skb
->data
));
716 return ctr
->send_message(ctr
, skb
);
720 * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
721 * @contr: controller number.
722 * @buf: result buffer (64 bytes).
724 * Retrieve information about the manufacturer of the specified ISDN controller
725 * or (for @contr == 0) the driver itself.
726 * Return value: CAPI result code
729 u16
capi20_get_manufacturer(u32 contr
, u8 buf
[CAPI_MANUFACTURER_LEN
])
731 struct capi_ctr
*ctr
;
735 strscpy_pad(buf
, capi_manufakturer
, CAPI_MANUFACTURER_LEN
);
739 mutex_lock(&capi_controller_lock
);
741 ctr
= get_capi_ctr_by_nr(contr
);
742 if (ctr
&& ctr
->state
== CAPI_CTR_RUNNING
) {
743 strscpy_pad(buf
, ctr
->manu
, CAPI_MANUFACTURER_LEN
);
746 ret
= CAPI_REGNOTINSTALLED
;
748 mutex_unlock(&capi_controller_lock
);
753 * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
754 * @contr: controller number.
755 * @verp: result structure.
757 * Retrieve version information for the specified ISDN controller
758 * or (for @contr == 0) the driver itself.
759 * Return value: CAPI result code
762 u16
capi20_get_version(u32 contr
, struct capi_version
*verp
)
764 struct capi_ctr
*ctr
;
768 *verp
= driver_version
;
772 mutex_lock(&capi_controller_lock
);
774 ctr
= get_capi_ctr_by_nr(contr
);
775 if (ctr
&& ctr
->state
== CAPI_CTR_RUNNING
) {
776 memcpy(verp
, &ctr
->version
, sizeof(capi_version
));
779 ret
= CAPI_REGNOTINSTALLED
;
781 mutex_unlock(&capi_controller_lock
);
786 * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
787 * @contr: controller number.
788 * @serial: result buffer (8 bytes).
790 * Retrieve the serial number of the specified ISDN controller
791 * or (for @contr == 0) the driver itself.
792 * Return value: CAPI result code
795 u16
capi20_get_serial(u32 contr
, u8 serial
[CAPI_SERIAL_LEN
])
797 struct capi_ctr
*ctr
;
801 strscpy(serial
, driver_serial
, CAPI_SERIAL_LEN
);
805 mutex_lock(&capi_controller_lock
);
807 ctr
= get_capi_ctr_by_nr(contr
);
808 if (ctr
&& ctr
->state
== CAPI_CTR_RUNNING
) {
809 strscpy(serial
, ctr
->serial
, CAPI_SERIAL_LEN
);
812 ret
= CAPI_REGNOTINSTALLED
;
814 mutex_unlock(&capi_controller_lock
);
819 * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
820 * @contr: controller number.
821 * @profp: result structure.
823 * Retrieve capability information for the specified ISDN controller
824 * or (for @contr == 0) the number of installed controllers.
825 * Return value: CAPI result code
828 u16
capi20_get_profile(u32 contr
, struct capi_profile
*profp
)
830 struct capi_ctr
*ctr
;
834 profp
->ncontroller
= ncontrollers
;
838 mutex_lock(&capi_controller_lock
);
840 ctr
= get_capi_ctr_by_nr(contr
);
841 if (ctr
&& ctr
->state
== CAPI_CTR_RUNNING
) {
842 memcpy(profp
, &ctr
->profile
, sizeof(struct capi_profile
));
845 ret
= CAPI_REGNOTINSTALLED
;
847 mutex_unlock(&capi_controller_lock
);
852 * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
856 * Perform manufacturer specific command.
857 * Return value: CAPI result code
860 int capi20_manufacturer(unsigned long cmd
, void __user
*data
)
862 struct capi_ctr
*ctr
;
866 case KCAPI_CMD_TRACE
:
870 if (copy_from_user(&fdef
, data
, sizeof(kcapi_flagdef
)))
873 mutex_lock(&capi_controller_lock
);
875 ctr
= get_capi_ctr_by_nr(fdef
.contr
);
877 ctr
->traceflag
= fdef
.flag
;
878 printk(KERN_INFO
"kcapi: contr [%03d] set trace=%d\n",
879 ctr
->cnr
, ctr
->traceflag
);
884 mutex_unlock(&capi_controller_lock
);
890 printk(KERN_ERR
"kcapi: manufacturer command %lu unknown.\n",
898 /* ------------------------------------------------------------- */
899 /* -------- Init & Cleanup ------------------------------------- */
900 /* ------------------------------------------------------------- */
903 * init / exit functions
906 int __init
kcapi_init(void)
910 kcapi_wq
= alloc_workqueue("kcapi", 0, 0);
916 destroy_workqueue(kcapi_wq
);
920 if (IS_ENABLED(CONFIG_PROC_FS
))
926 void kcapi_exit(void)
928 if (IS_ENABLED(CONFIG_PROC_FS
))
932 destroy_workqueue(kcapi_wq
);