cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kcapi.c (21397B)


      1/* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $
      2 *
      3 * Kernel CAPI 2.0 Module
      4 *
      5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
      6 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
      7 *
      8 * This software may be used and distributed according to the terms
      9 * of the GNU General Public License, incorporated herein by reference.
     10 *
     11 */
     12
     13#include "kcapi.h"
     14#include <linux/module.h>
     15#include <linux/mm.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>
     34
     35static int showcapimsgs;
     36static struct workqueue_struct *kcapi_wq;
     37
     38module_param(showcapimsgs, uint, 0);
     39
     40/* ------------------------------------------------------------- */
     41
     42struct capictr_event {
     43	struct work_struct work;
     44	unsigned int type;
     45	u32 controller;
     46};
     47
     48/* ------------------------------------------------------------- */
     49
     50static const struct capi_version driver_version = {2, 0, 1, 1 << 4};
     51static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
     52static char capi_manufakturer[64] = "AVM Berlin";
     53
     54#define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
     55
     56struct capi_ctr *capi_controller[CAPI_MAXCONTR];
     57DEFINE_MUTEX(capi_controller_lock);
     58
     59struct capi20_appl *capi_applications[CAPI_MAXAPPL];
     60
     61static int ncontrollers;
     62
     63/* -------- controller ref counting -------------------------------------- */
     64
     65static inline struct capi_ctr *
     66capi_ctr_get(struct capi_ctr *ctr)
     67{
     68	if (!try_module_get(ctr->owner))
     69		return NULL;
     70	return ctr;
     71}
     72
     73static inline void
     74capi_ctr_put(struct capi_ctr *ctr)
     75{
     76	module_put(ctr->owner);
     77}
     78
     79/* ------------------------------------------------------------- */
     80
     81static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
     82{
     83	if (contr < 1 || contr - 1 >= CAPI_MAXCONTR)
     84		return NULL;
     85
     86	return capi_controller[contr - 1];
     87}
     88
     89static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid)
     90{
     91	lockdep_assert_held(&capi_controller_lock);
     92
     93	if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
     94		return NULL;
     95
     96	return capi_applications[applid - 1];
     97}
     98
     99static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
    100{
    101	if (applid < 1 || applid - 1 >= CAPI_MAXAPPL)
    102		return NULL;
    103
    104	return rcu_dereference(capi_applications[applid - 1]);
    105}
    106
    107/* -------- util functions ------------------------------------ */
    108
    109static inline int capi_cmd_valid(u8 cmd)
    110{
    111	switch (cmd) {
    112	case CAPI_ALERT:
    113	case CAPI_CONNECT:
    114	case CAPI_CONNECT_ACTIVE:
    115	case CAPI_CONNECT_B3_ACTIVE:
    116	case CAPI_CONNECT_B3:
    117	case CAPI_CONNECT_B3_T90_ACTIVE:
    118	case CAPI_DATA_B3:
    119	case CAPI_DISCONNECT_B3:
    120	case CAPI_DISCONNECT:
    121	case CAPI_FACILITY:
    122	case CAPI_INFO:
    123	case CAPI_LISTEN:
    124	case CAPI_MANUFACTURER:
    125	case CAPI_RESET_B3:
    126	case CAPI_SELECT_B_PROTOCOL:
    127		return 1;
    128	}
    129	return 0;
    130}
    131
    132static inline int capi_subcmd_valid(u8 subcmd)
    133{
    134	switch (subcmd) {
    135	case CAPI_REQ:
    136	case CAPI_CONF:
    137	case CAPI_IND:
    138	case CAPI_RESP:
    139		return 1;
    140	}
    141	return 0;
    142}
    143
    144/* ------------------------------------------------------------ */
    145
    146static void
    147register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
    148{
    149	ctr = capi_ctr_get(ctr);
    150
    151	if (ctr)
    152		ctr->register_appl(ctr, applid, rparam);
    153	else
    154		printk(KERN_WARNING "%s: cannot get controller resources\n",
    155		       __func__);
    156}
    157
    158
    159static void release_appl(struct capi_ctr *ctr, u16 applid)
    160{
    161	DBG("applid %#x", applid);
    162
    163	ctr->release_appl(ctr, applid);
    164	capi_ctr_put(ctr);
    165}
    166
    167static void notify_up(u32 contr)
    168{
    169	struct capi20_appl *ap;
    170	struct capi_ctr *ctr;
    171	u16 applid;
    172
    173	mutex_lock(&capi_controller_lock);
    174
    175	if (showcapimsgs & 1)
    176		printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
    177
    178	ctr = get_capi_ctr_by_nr(contr);
    179	if (ctr) {
    180		if (ctr->state == CAPI_CTR_RUNNING)
    181			goto unlock_out;
    182
    183		ctr->state = CAPI_CTR_RUNNING;
    184
    185		for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
    186			ap = __get_capi_appl_by_nr(applid);
    187			if (ap)
    188				register_appl(ctr, applid, &ap->rparam);
    189		}
    190	} else
    191		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
    192
    193unlock_out:
    194	mutex_unlock(&capi_controller_lock);
    195}
    196
    197static void ctr_down(struct capi_ctr *ctr, int new_state)
    198{
    199	struct capi20_appl *ap;
    200	u16 applid;
    201
    202	if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
    203		return;
    204
    205	ctr->state = new_state;
    206
    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));
    211
    212	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
    213		ap = __get_capi_appl_by_nr(applid);
    214		if (ap)
    215			capi_ctr_put(ctr);
    216	}
    217}
    218
    219static void notify_down(u32 contr)
    220{
    221	struct capi_ctr *ctr;
    222
    223	mutex_lock(&capi_controller_lock);
    224
    225	if (showcapimsgs & 1)
    226		printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
    227
    228	ctr = get_capi_ctr_by_nr(contr);
    229	if (ctr)
    230		ctr_down(ctr, CAPI_CTR_DETECTED);
    231	else
    232		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
    233
    234	mutex_unlock(&capi_controller_lock);
    235}
    236
    237static void do_notify_work(struct work_struct *work)
    238{
    239	struct capictr_event *event =
    240		container_of(work, struct capictr_event, work);
    241
    242	switch (event->type) {
    243	case CAPICTR_UP:
    244		notify_up(event->controller);
    245		break;
    246	case CAPICTR_DOWN:
    247		notify_down(event->controller);
    248		break;
    249	}
    250
    251	kfree(event);
    252}
    253
    254static int notify_push(unsigned int event_type, u32 controller)
    255{
    256	struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
    257
    258	if (!event)
    259		return -ENOMEM;
    260
    261	INIT_WORK(&event->work, do_notify_work);
    262	event->type = event_type;
    263	event->controller = controller;
    264
    265	queue_work(kcapi_wq, &event->work);
    266	return 0;
    267}
    268
    269/* -------- Receiver ------------------------------------------ */
    270
    271static void recv_handler(struct work_struct *work)
    272{
    273	struct sk_buff *skb;
    274	struct capi20_appl *ap =
    275		container_of(work, struct capi20_appl, recv_work);
    276
    277	if ((!ap) || (ap->release_in_progress))
    278		return;
    279
    280	mutex_lock(&ap->recv_mtx);
    281	while ((skb = skb_dequeue(&ap->recv_queue))) {
    282		if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND)
    283			ap->nrecvdatapkt++;
    284		else
    285			ap->nrecvctlpkt++;
    286
    287		ap->recv_message(ap, skb);
    288	}
    289	mutex_unlock(&ap->recv_mtx);
    290}
    291
    292/**
    293 * capi_ctr_handle_message() - handle incoming CAPI message
    294 * @ctr:	controller descriptor structure.
    295 * @appl:	application ID.
    296 * @skb:	message.
    297 *
    298 * Called by hardware driver to pass a CAPI message to the application.
    299 */
    300
    301void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
    302			     struct sk_buff *skb)
    303{
    304	struct capi20_appl *ap;
    305	int showctl = 0;
    306	u8 cmd, subcmd;
    307	_cdebbuf *cdb;
    308
    309	if (ctr->state != CAPI_CTR_RUNNING) {
    310		cdb = capi_message2str(skb->data);
    311		if (cdb) {
    312			printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
    313			       ctr->cnr, cdb->buf);
    314			cdebbuf_free(cdb);
    315		} else
    316			printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
    317			       ctr->cnr);
    318		goto error;
    319	}
    320
    321	cmd = CAPIMSG_COMMAND(skb->data);
    322	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
    323	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
    324		ctr->nrecvdatapkt++;
    325		if (ctr->traceflag > 2)
    326			showctl |= 2;
    327	} else {
    328		ctr->nrecvctlpkt++;
    329		if (ctr->traceflag)
    330			showctl |= 2;
    331	}
    332	showctl |= (ctr->traceflag & 1);
    333	if (showctl & 2) {
    334		if (showctl & 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));
    339		} else {
    340			cdb = capi_message2str(skb->data);
    341			if (cdb) {
    342				printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
    343				       ctr->cnr, cdb->buf);
    344				cdebbuf_free(cdb);
    345			} else
    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));
    350		}
    351
    352	}
    353
    354	rcu_read_lock();
    355	ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
    356	if (!ap) {
    357		rcu_read_unlock();
    358		cdb = capi_message2str(skb->data);
    359		if (cdb) {
    360			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
    361			       CAPIMSG_APPID(skb->data), cdb->buf);
    362			cdebbuf_free(cdb);
    363		} else
    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));
    367		goto error;
    368	}
    369	skb_queue_tail(&ap->recv_queue, skb);
    370	queue_work(kcapi_wq, &ap->recv_work);
    371	rcu_read_unlock();
    372
    373	return;
    374
    375error:
    376	kfree_skb(skb);
    377}
    378
    379EXPORT_SYMBOL(capi_ctr_handle_message);
    380
    381/**
    382 * capi_ctr_ready() - signal CAPI controller ready
    383 * @ctr:	controller descriptor structure.
    384 *
    385 * Called by hardware driver to signal that the controller is up and running.
    386 */
    387
    388void capi_ctr_ready(struct capi_ctr *ctr)
    389{
    390	printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
    391	       ctr->cnr, ctr->name);
    392
    393	notify_push(CAPICTR_UP, ctr->cnr);
    394}
    395
    396EXPORT_SYMBOL(capi_ctr_ready);
    397
    398/**
    399 * capi_ctr_down() - signal CAPI controller not ready
    400 * @ctr:	controller descriptor structure.
    401 *
    402 * Called by hardware driver to signal that the controller is down and
    403 * unavailable for use.
    404 */
    405
    406void capi_ctr_down(struct capi_ctr *ctr)
    407{
    408	printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
    409
    410	notify_push(CAPICTR_DOWN, ctr->cnr);
    411}
    412
    413EXPORT_SYMBOL(capi_ctr_down);
    414
    415/* ------------------------------------------------------------- */
    416
    417/**
    418 * attach_capi_ctr() - register CAPI controller
    419 * @ctr:	controller descriptor structure.
    420 *
    421 * Called by hardware driver to register a controller with the CAPI subsystem.
    422 * Return value: 0 on success, error code < 0 on error
    423 */
    424
    425int attach_capi_ctr(struct capi_ctr *ctr)
    426{
    427	int i;
    428
    429	mutex_lock(&capi_controller_lock);
    430
    431	for (i = 0; i < CAPI_MAXCONTR; i++) {
    432		if (!capi_controller[i])
    433			break;
    434	}
    435	if (i == CAPI_MAXCONTR) {
    436		mutex_unlock(&capi_controller_lock);
    437		printk(KERN_ERR "kcapi: out of controller slots\n");
    438		return -EBUSY;
    439	}
    440	capi_controller[i] = ctr;
    441
    442	ctr->nrecvctlpkt = 0;
    443	ctr->nrecvdatapkt = 0;
    444	ctr->nsentctlpkt = 0;
    445	ctr->nsentdatapkt = 0;
    446	ctr->cnr = i + 1;
    447	ctr->state = CAPI_CTR_DETECTED;
    448	ctr->blocked = 0;
    449	ctr->traceflag = showcapimsgs;
    450
    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);
    454
    455	ncontrollers++;
    456
    457	mutex_unlock(&capi_controller_lock);
    458
    459	printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
    460	       ctr->cnr, ctr->name);
    461	return 0;
    462}
    463
    464EXPORT_SYMBOL(attach_capi_ctr);
    465
    466/**
    467 * detach_capi_ctr() - unregister CAPI controller
    468 * @ctr:	controller descriptor structure.
    469 *
    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
    473 */
    474
    475int detach_capi_ctr(struct capi_ctr *ctr)
    476{
    477	int err = 0;
    478
    479	mutex_lock(&capi_controller_lock);
    480
    481	ctr_down(ctr, CAPI_CTR_DETACHED);
    482
    483	if (ctr->cnr < 1 || ctr->cnr - 1 >= CAPI_MAXCONTR) {
    484		err = -EINVAL;
    485		goto unlock_out;
    486	}
    487
    488	if (capi_controller[ctr->cnr - 1] != ctr) {
    489		err = -EINVAL;
    490		goto unlock_out;
    491	}
    492	capi_controller[ctr->cnr - 1] = NULL;
    493	ncontrollers--;
    494
    495	if (ctr->procent)
    496		remove_proc_entry(ctr->procfn, NULL);
    497
    498	printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
    499	       ctr->cnr, ctr->name);
    500
    501unlock_out:
    502	mutex_unlock(&capi_controller_lock);
    503
    504	return err;
    505}
    506
    507EXPORT_SYMBOL(detach_capi_ctr);
    508
    509/* ------------------------------------------------------------- */
    510/* -------- CAPI2.0 Interface ---------------------------------- */
    511/* ------------------------------------------------------------- */
    512
    513/**
    514 * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
    515 *
    516 * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
    517 *	is ready for use, CAPI_REGNOTINSTALLED otherwise)
    518 */
    519
    520u16 capi20_isinstalled(void)
    521{
    522	u16 ret = CAPI_REGNOTINSTALLED;
    523	int i;
    524
    525	mutex_lock(&capi_controller_lock);
    526
    527	for (i = 0; i < CAPI_MAXCONTR; i++)
    528		if (capi_controller[i] &&
    529		    capi_controller[i]->state == CAPI_CTR_RUNNING) {
    530			ret = CAPI_NOERROR;
    531			break;
    532		}
    533
    534	mutex_unlock(&capi_controller_lock);
    535
    536	return ret;
    537}
    538
    539/**
    540 * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
    541 * @ap:		CAPI application descriptor structure.
    542 *
    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
    549 */
    550
    551u16 capi20_register(struct capi20_appl *ap)
    552{
    553	int i;
    554	u16 applid;
    555
    556	DBG("");
    557
    558	if (ap->rparam.datablklen < 128)
    559		return CAPI_LOGBLKSIZETOSMALL;
    560
    561	ap->nrecvctlpkt = 0;
    562	ap->nrecvdatapkt = 0;
    563	ap->nsentctlpkt = 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;
    569
    570	mutex_lock(&capi_controller_lock);
    571
    572	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
    573		if (capi_applications[applid - 1] == NULL)
    574			break;
    575	}
    576	if (applid > CAPI_MAXAPPL) {
    577		mutex_unlock(&capi_controller_lock);
    578		return CAPI_TOOMANYAPPLS;
    579	}
    580
    581	ap->applid = applid;
    582	capi_applications[applid - 1] = ap;
    583
    584	for (i = 0; i < CAPI_MAXCONTR; i++) {
    585		if (!capi_controller[i] ||
    586		    capi_controller[i]->state != CAPI_CTR_RUNNING)
    587			continue;
    588		register_appl(capi_controller[i], applid, &ap->rparam);
    589	}
    590
    591	mutex_unlock(&capi_controller_lock);
    592
    593	if (showcapimsgs & 1) {
    594		printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
    595	}
    596
    597	return CAPI_NOERROR;
    598}
    599
    600/**
    601 * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
    602 * @ap:		CAPI application descriptor structure.
    603 *
    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
    608 */
    609
    610u16 capi20_release(struct capi20_appl *ap)
    611{
    612	int i;
    613
    614	DBG("applid %#x", ap->applid);
    615
    616	mutex_lock(&capi_controller_lock);
    617
    618	ap->release_in_progress = 1;
    619	capi_applications[ap->applid - 1] = NULL;
    620
    621	synchronize_rcu();
    622
    623	for (i = 0; i < CAPI_MAXCONTR; i++) {
    624		if (!capi_controller[i] ||
    625		    capi_controller[i]->state != CAPI_CTR_RUNNING)
    626			continue;
    627		release_appl(capi_controller[i], ap->applid);
    628	}
    629
    630	mutex_unlock(&capi_controller_lock);
    631
    632	flush_workqueue(kcapi_wq);
    633	skb_queue_purge(&ap->recv_queue);
    634
    635	if (showcapimsgs & 1) {
    636		printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
    637	}
    638
    639	return CAPI_NOERROR;
    640}
    641
    642/**
    643 * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
    644 * @ap:		CAPI application descriptor structure.
    645 * @skb:	CAPI message.
    646 *
    647 * Transfer a single message to CAPI.
    648 * Return value: CAPI result code
    649 */
    650
    651u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
    652{
    653	struct capi_ctr *ctr;
    654	int showctl = 0;
    655	u8 cmd, subcmd;
    656
    657	DBG("applid %#x", ap->applid);
    658
    659	if (ncontrollers == 0)
    660		return CAPI_REGNOTINSTALLED;
    661	if ((ap->applid == 0) || ap->release_in_progress)
    662		return CAPI_ILLAPPNR;
    663	if (skb->len < 12
    664	    || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
    665	    || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
    666		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
    667
    668	/*
    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.
    672	 */
    673	ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
    674	if (!ctr || ctr->state != CAPI_CTR_RUNNING)
    675		return CAPI_REGNOTINSTALLED;
    676	if (ctr->blocked)
    677		return CAPI_SENDQUEUEFULL;
    678
    679	cmd = CAPIMSG_COMMAND(skb->data);
    680	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
    681
    682	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
    683		ctr->nsentdatapkt++;
    684		ap->nsentdatapkt++;
    685		if (ctr->traceflag > 2)
    686			showctl |= 2;
    687	} else {
    688		ctr->nsentctlpkt++;
    689		ap->nsentctlpkt++;
    690		if (ctr->traceflag)
    691			showctl |= 2;
    692	}
    693	showctl |= (ctr->traceflag & 1);
    694	if (showctl & 2) {
    695		if (showctl & 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));
    701		} else {
    702			_cdebbuf *cdb = capi_message2str(skb->data);
    703			if (cdb) {
    704				printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
    705				       CAPIMSG_CONTROLLER(skb->data),
    706				       cdb->buf);
    707				cdebbuf_free(cdb);
    708			} else
    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));
    714		}
    715	}
    716	return ctr->send_message(ctr, skb);
    717}
    718
    719/**
    720 * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
    721 * @contr:	controller number.
    722 * @buf:	result buffer (64 bytes).
    723 *
    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
    727 */
    728
    729u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
    730{
    731	struct capi_ctr *ctr;
    732	u16 ret;
    733
    734	if (contr == 0) {
    735		strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
    736		return CAPI_NOERROR;
    737	}
    738
    739	mutex_lock(&capi_controller_lock);
    740
    741	ctr = get_capi_ctr_by_nr(contr);
    742	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
    743		strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
    744		ret = CAPI_NOERROR;
    745	} else
    746		ret = CAPI_REGNOTINSTALLED;
    747
    748	mutex_unlock(&capi_controller_lock);
    749	return ret;
    750}
    751
    752/**
    753 * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
    754 * @contr:	controller number.
    755 * @verp:	result structure.
    756 *
    757 * Retrieve version information for the specified ISDN controller
    758 * or (for @contr == 0) the driver itself.
    759 * Return value: CAPI result code
    760 */
    761
    762u16 capi20_get_version(u32 contr, struct capi_version *verp)
    763{
    764	struct capi_ctr *ctr;
    765	u16 ret;
    766
    767	if (contr == 0) {
    768		*verp = driver_version;
    769		return CAPI_NOERROR;
    770	}
    771
    772	mutex_lock(&capi_controller_lock);
    773
    774	ctr = get_capi_ctr_by_nr(contr);
    775	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
    776		memcpy(verp, &ctr->version, sizeof(capi_version));
    777		ret = CAPI_NOERROR;
    778	} else
    779		ret = CAPI_REGNOTINSTALLED;
    780
    781	mutex_unlock(&capi_controller_lock);
    782	return ret;
    783}
    784
    785/**
    786 * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
    787 * @contr:	controller number.
    788 * @serial:	result buffer (8 bytes).
    789 *
    790 * Retrieve the serial number of the specified ISDN controller
    791 * or (for @contr == 0) the driver itself.
    792 * Return value: CAPI result code
    793 */
    794
    795u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN])
    796{
    797	struct capi_ctr *ctr;
    798	u16 ret;
    799
    800	if (contr == 0) {
    801		strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
    802		return CAPI_NOERROR;
    803	}
    804
    805	mutex_lock(&capi_controller_lock);
    806
    807	ctr = get_capi_ctr_by_nr(contr);
    808	if (ctr && ctr->state == CAPI_CTR_RUNNING) {
    809		strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN);
    810		ret = CAPI_NOERROR;
    811	} else
    812		ret = CAPI_REGNOTINSTALLED;
    813
    814	mutex_unlock(&capi_controller_lock);
    815	return ret;
    816}
    817
    818/**
    819 * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
    820 * @contr:	controller number.
    821 * @profp:	result structure.
    822 *
    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
    826 */
    827
    828u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
    829{
    830	struct capi_ctr *ctr;
    831	u16 ret;
    832
    833	if (contr == 0) {
    834		profp->ncontroller = ncontrollers;
    835		return CAPI_NOERROR;
    836	}
    837
    838	mutex_lock(&capi_controller_lock);
    839
    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));
    843		ret = CAPI_NOERROR;
    844	} else
    845		ret = CAPI_REGNOTINSTALLED;
    846
    847	mutex_unlock(&capi_controller_lock);
    848	return ret;
    849}
    850
    851/**
    852 * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
    853 * @cmd:	command.
    854 * @data:	parameter.
    855 *
    856 * Perform manufacturer specific command.
    857 * Return value: CAPI result code
    858 */
    859
    860int capi20_manufacturer(unsigned long cmd, void __user *data)
    861{
    862	struct capi_ctr *ctr;
    863	int retval;
    864
    865	switch (cmd) {
    866	case KCAPI_CMD_TRACE:
    867	{
    868		kcapi_flagdef fdef;
    869
    870		if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
    871			return -EFAULT;
    872
    873		mutex_lock(&capi_controller_lock);
    874
    875		ctr = get_capi_ctr_by_nr(fdef.contr);
    876		if (ctr) {
    877			ctr->traceflag = fdef.flag;
    878			printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
    879			       ctr->cnr, ctr->traceflag);
    880			retval = 0;
    881		} else
    882			retval = -ESRCH;
    883
    884		mutex_unlock(&capi_controller_lock);
    885
    886		return retval;
    887	}
    888
    889	default:
    890		printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
    891		       cmd);
    892		break;
    893
    894	}
    895	return -EINVAL;
    896}
    897
    898/* ------------------------------------------------------------- */
    899/* -------- Init & Cleanup ------------------------------------- */
    900/* ------------------------------------------------------------- */
    901
    902/*
    903 * init / exit functions
    904 */
    905
    906int __init kcapi_init(void)
    907{
    908	int err;
    909
    910	kcapi_wq = alloc_workqueue("kcapi", 0, 0);
    911	if (!kcapi_wq)
    912		return -ENOMEM;
    913
    914	err = cdebug_init();
    915	if (err) {
    916		destroy_workqueue(kcapi_wq);
    917		return err;
    918	}
    919
    920	kcapi_proc_init();
    921	return 0;
    922}
    923
    924void kcapi_exit(void)
    925{
    926	kcapi_proc_exit();
    927
    928	cdebug_exit();
    929	destroy_workqueue(kcapi_wq);
    930}