/* $Id: kcapi.c,v 1.1.2.8 2004/03/26 19:57:20 armin Exp $
 * 
 * Kernel CAPI 2.0 Module
 * 
 * Copyright 1999 by Carsten Paeth <calle@calle.de>
 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
 * 
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#define AVMB1_COMPAT

#include "kcapi.h"
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/capi.h>
#include <linux/kernelcapi.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>
#ifdef AVMB1_COMPAT
#include <linux/b1lli.h>
#endif
#include <linux/mutex.h>

static char *revision = "$Revision: 1.1.2.8 $";

/* ------------------------------------------------------------- */

static int showcapimsgs = 0;

MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
module_param(showcapimsgs, uint, 0);

/* ------------------------------------------------------------- */

struct capi_notifier {
	struct work_struct work;
	unsigned int cmd;
	u32 controller;
	u16 applid;
	u32 ncci;
};

/* ------------------------------------------------------------- */

static struct capi_version driver_version = {2, 0, 1, 1<<4};
static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
static char capi_manufakturer[64] = "AVM Berlin";

#define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)

LIST_HEAD(capi_drivers);
DEFINE_RWLOCK(capi_drivers_list_lock);

static DEFINE_RWLOCK(application_lock);
static DEFINE_MUTEX(controller_mutex);

struct capi20_appl *capi_applications[CAPI_MAXAPPL];
struct capi_ctr *capi_cards[CAPI_MAXCONTR];

static int ncards;

/* -------- controller ref counting -------------------------------------- */

static inline struct capi_ctr *
capi_ctr_get(struct capi_ctr *card)
{
	if (!try_module_get(card->owner))
		return NULL;
	return card;
}

static inline void
capi_ctr_put(struct capi_ctr *card)
{
	module_put(card->owner);
}

/* ------------------------------------------------------------- */

static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
{
	if (contr - 1 >= CAPI_MAXCONTR)
		return NULL;

	return capi_cards[contr - 1];
}

static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
{
	if (applid - 1 >= CAPI_MAXAPPL)
		return NULL;

	return capi_applications[applid - 1];
}

/* -------- util functions ------------------------------------ */

static inline int capi_cmd_valid(u8 cmd)
{
	switch (cmd) {
	case CAPI_ALERT:
	case CAPI_CONNECT:
	case CAPI_CONNECT_ACTIVE:
	case CAPI_CONNECT_B3_ACTIVE:
	case CAPI_CONNECT_B3:
	case CAPI_CONNECT_B3_T90_ACTIVE:
	case CAPI_DATA_B3:
	case CAPI_DISCONNECT_B3:
	case CAPI_DISCONNECT:
	case CAPI_FACILITY:
	case CAPI_INFO:
	case CAPI_LISTEN:
	case CAPI_MANUFACTURER:
	case CAPI_RESET_B3:
	case CAPI_SELECT_B_PROTOCOL:
		return 1;
	}
	return 0;
}

static inline int capi_subcmd_valid(u8 subcmd)
{
	switch (subcmd) {
	case CAPI_REQ:
	case CAPI_CONF:
	case CAPI_IND:
	case CAPI_RESP:
		return 1;
	}
	return 0;
}

/* ------------------------------------------------------------ */

static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam)
{
	card = capi_ctr_get(card);

	if (card)
		card->register_appl(card, applid, rparam);
	else
		printk(KERN_WARNING "%s: cannot get card resources\n", __func__);
}


static void release_appl(struct capi_ctr *card, u16 applid)
{
	DBG("applid %#x", applid);
	
	card->release_appl(card, applid);
	capi_ctr_put(card);
}

/* -------- KCI_CONTRUP --------------------------------------- */

static void notify_up(u32 contr)
{
	struct capi_ctr *card = get_capi_ctr_by_nr(contr);
	struct capi20_appl *ap;
	u16 applid;

	if (showcapimsgs & 1) {
	        printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
	}
	if (!card) {
		printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
		return;
	}
	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
		ap = get_capi_appl_by_nr(applid);
		if (!ap || ap->release_in_progress) continue;
		register_appl(card, applid, &ap->rparam);
		if (ap->callback && !ap->release_in_progress)
			ap->callback(KCI_CONTRUP, contr, &card->profile);
	}
}

/* -------- KCI_CONTRDOWN ------------------------------------- */

static void notify_down(u32 contr)
{
	struct capi20_appl *ap;
	u16 applid;

	if (showcapimsgs & 1) {
        	printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
	}

	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
		ap = get_capi_appl_by_nr(applid);
		if (ap && ap->callback && !ap->release_in_progress)
			ap->callback(KCI_CONTRDOWN, contr, NULL);
	}
}

static void notify_handler(struct work_struct *work)
{
	struct capi_notifier *np =
		container_of(work, struct capi_notifier, work);

	switch (np->cmd) {
	case KCI_CONTRUP:
		notify_up(np->controller);
		break;
	case KCI_CONTRDOWN:
		notify_down(np->controller);
		break;
	}

	kfree(np);
}

/*
 * The notifier will result in adding/deleteing of devices. Devices can
 * only removed in user process, not in bh.
 */
static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci)
{
	struct capi_notifier *np = kmalloc(sizeof(*np), GFP_ATOMIC);

	if (!np)
		return -ENOMEM;

	INIT_WORK(&np->work, notify_handler);
	np->cmd = cmd;
	np->controller = controller;
	np->applid = applid;
	np->ncci = ncci;

	schedule_work(&np->work);
	return 0;
}

	
/* -------- Receiver ------------------------------------------ */

static void recv_handler(struct work_struct *work)
{
	struct sk_buff *skb;
	struct capi20_appl *ap =
		container_of(work, struct capi20_appl, recv_work);

	if ((!ap) || (ap->release_in_progress))
		return;

	mutex_lock(&ap->recv_mtx);
	while ((skb = skb_dequeue(&ap->recv_queue))) {
		if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_IND)
			ap->nrecvdatapkt++;
		else
			ap->nrecvctlpkt++;

		ap->recv_message(ap, skb);
	}
	mutex_unlock(&ap->recv_mtx);
}

/**
 * capi_ctr_handle_message() - handle incoming CAPI message
 * @card:	controller descriptor structure.
 * @appl:	application ID.
 * @skb:	message.
 *
 * Called by hardware driver to pass a CAPI message to the application.
 */

void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb)
{
	struct capi20_appl *ap;
	int showctl = 0;
	u8 cmd, subcmd;
	unsigned long flags;
	_cdebbuf *cdb;

	if (card->cardstate != CARD_RUNNING) {
		cdb = capi_message2str(skb->data);
		if (cdb) {
			printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
				card->cnr, cdb->buf);
			cdebbuf_free(cdb);
		} else
			printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
				card->cnr);
		goto error;
	}

	cmd = CAPIMSG_COMMAND(skb->data);
        subcmd = CAPIMSG_SUBCOMMAND(skb->data);
	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
		card->nrecvdatapkt++;
	        if (card->traceflag > 2) showctl |= 2;
	} else {
		card->nrecvctlpkt++;
	        if (card->traceflag) showctl |= 2;
	}
	showctl |= (card->traceflag & 1);
	if (showctl & 2) {
		if (showctl & 1) {
			printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
			       card->cnr, CAPIMSG_APPID(skb->data),
			       capi_cmd2str(cmd, subcmd),
			       CAPIMSG_LEN(skb->data));
		} else {
			cdb = capi_message2str(skb->data);
			if (cdb) {
				printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
					card->cnr, cdb->buf);
				cdebbuf_free(cdb);
			} else
				printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
					card->cnr, CAPIMSG_APPID(skb->data),
					capi_cmd2str(cmd, subcmd),
					CAPIMSG_LEN(skb->data));
		}

	}

	read_lock_irqsave(&application_lock, flags);
	ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
	if ((!ap) || (ap->release_in_progress)) {
		read_unlock_irqrestore(&application_lock, flags);
		cdb = capi_message2str(skb->data);
		if (cdb) {
			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
			CAPIMSG_APPID(skb->data), cdb->buf);
			cdebbuf_free(cdb);
		} else
			printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s) cannot trace\n",
				CAPIMSG_APPID(skb->data),
				capi_cmd2str(cmd, subcmd));
		goto error;
	}
	skb_queue_tail(&ap->recv_queue, skb);
	schedule_work(&ap->recv_work);
	read_unlock_irqrestore(&application_lock, flags);

	return;

error:
	kfree_skb(skb);
}

EXPORT_SYMBOL(capi_ctr_handle_message);

/**
 * capi_ctr_ready() - signal CAPI controller ready
 * @card:	controller descriptor structure.
 *
 * Called by hardware driver to signal that the controller is up and running.
 */

void capi_ctr_ready(struct capi_ctr * card)
{
	card->cardstate = CARD_RUNNING;

        printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n",
	       card->cnr, card->name);

	notify_push(KCI_CONTRUP, card->cnr, 0, 0);
}

EXPORT_SYMBOL(capi_ctr_ready);

/**
 * capi_ctr_down() - signal CAPI controller not ready
 * @card:	controller descriptor structure.
 *
 * Called by hardware driver to signal that the controller is down and
 * unavailable for use.
 */

void capi_ctr_down(struct capi_ctr * card)
{
	u16 appl;

	DBG("");

        if (card->cardstate == CARD_DETECTED)
		return;

        card->cardstate = CARD_DETECTED;

	memset(card->manu, 0, sizeof(card->manu));
	memset(&card->version, 0, sizeof(card->version));
	memset(&card->profile, 0, sizeof(card->profile));
	memset(card->serial, 0, sizeof(card->serial));

	for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
		struct capi20_appl *ap = get_capi_appl_by_nr(appl);
		if (!ap || ap->release_in_progress)
			continue;

		capi_ctr_put(card);
	}

	printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr);

	notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
}

EXPORT_SYMBOL(capi_ctr_down);

/**
 * capi_ctr_suspend_output() - suspend controller
 * @card:	controller descriptor structure.
 *
 * Called by hardware driver to stop data flow.
 */

void capi_ctr_suspend_output(struct capi_ctr *card)
{
	if (!card->blocked) {
		printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr);
		card->blocked = 1;
	}
}

EXPORT_SYMBOL(capi_ctr_suspend_output);

/**
 * capi_ctr_resume_output() - resume controller
 * @card:	controller descriptor structure.
 *
 * Called by hardware driver to resume data flow.
 */

void capi_ctr_resume_output(struct capi_ctr *card)
{
	if (card->blocked) {
		printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr);
		card->blocked = 0;
	}
}

EXPORT_SYMBOL(capi_ctr_resume_output);

/* ------------------------------------------------------------- */

/**
 * attach_capi_ctr() - register CAPI controller
 * @card:	controller descriptor structure.
 *
 * Called by hardware driver to register a controller with the CAPI subsystem.
 * Return value: 0 on success, error code < 0 on error
 */

int
attach_capi_ctr(struct capi_ctr *card)
{
	int i;

	mutex_lock(&controller_mutex);

	for (i = 0; i < CAPI_MAXCONTR; i++) {
		if (capi_cards[i] == NULL)
			break;
	}
	if (i == CAPI_MAXCONTR) {
		mutex_unlock(&controller_mutex);
		printk(KERN_ERR "kcapi: out of controller slots\n");
	   	return -EBUSY;
	}
	capi_cards[i] = card;

	mutex_unlock(&controller_mutex);

	card->nrecvctlpkt = 0;
	card->nrecvdatapkt = 0;
	card->nsentctlpkt = 0;
	card->nsentdatapkt = 0;
	card->cnr = i + 1;
	card->cardstate = CARD_DETECTED;
	card->blocked = 0;
	card->traceflag = showcapimsgs;

	sprintf(card->procfn, "capi/controllers/%d", card->cnr);
	card->procent = create_proc_entry(card->procfn, 0, NULL);
	if (card->procent) {
	   card->procent->read_proc = 
		(int (*)(char *,char **,off_t,int,int *,void *))
			card->ctr_read_proc;
	   card->procent->data = card;
	}

	ncards++;
	printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",
			card->cnr, card->name);
	return 0;
}

EXPORT_SYMBOL(attach_capi_ctr);

/**
 * detach_capi_ctr() - unregister CAPI controller
 * @card:	controller descriptor structure.
 *
 * Called by hardware driver to remove the registration of a controller
 * with the CAPI subsystem.
 * Return value: 0 on success, error code < 0 on error
 */

int detach_capi_ctr(struct capi_ctr *card)
{
        if (card->cardstate != CARD_DETECTED)
		capi_ctr_down(card);

	ncards--;

	if (card->procent) {
	   remove_proc_entry(card->procfn, NULL);
	   card->procent = NULL;
	}
	capi_cards[card->cnr - 1] = NULL;
	printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n",
			card->cnr, card->name);

	return 0;
}

EXPORT_SYMBOL(detach_capi_ctr);

/**
 * register_capi_driver() - register CAPI driver
 * @driver:	driver descriptor structure.
 *
 * Called by hardware driver to register itself with the CAPI subsystem.
 */

void register_capi_driver(struct capi_driver *driver)
{
	unsigned long flags;

	write_lock_irqsave(&capi_drivers_list_lock, flags);
	list_add_tail(&driver->list, &capi_drivers);
	write_unlock_irqrestore(&capi_drivers_list_lock, flags);
}

EXPORT_SYMBOL(register_capi_driver);

/**
 * unregister_capi_driver() - unregister CAPI driver
 * @driver:	driver descriptor structure.
 *
 * Called by hardware driver to unregister itself from the CAPI subsystem.
 */

void unregister_capi_driver(struct capi_driver *driver)
{
	unsigned long flags;

	write_lock_irqsave(&capi_drivers_list_lock, flags);
	list_del(&driver->list);
	write_unlock_irqrestore(&capi_drivers_list_lock, flags);
}

EXPORT_SYMBOL(unregister_capi_driver);

/* ------------------------------------------------------------- */
/* -------- CAPI2.0 Interface ---------------------------------- */
/* ------------------------------------------------------------- */

/**
 * capi20_isinstalled() - CAPI 2.0 operation CAPI_INSTALLED
 *
 * Return value: CAPI result code (CAPI_NOERROR if at least one ISDN controller
 *	is ready for use, CAPI_REGNOTINSTALLED otherwise)
 */

u16 capi20_isinstalled(void)
{
	int i;
	for (i = 0; i < CAPI_MAXCONTR; i++) {
		if (capi_cards[i] && capi_cards[i]->cardstate == CARD_RUNNING)
			return CAPI_NOERROR;
	}
	return CAPI_REGNOTINSTALLED;
}

EXPORT_SYMBOL(capi20_isinstalled);

/**
 * capi20_register() - CAPI 2.0 operation CAPI_REGISTER
 * @ap:		CAPI application descriptor structure.
 *
 * Register an application's presence with CAPI.
 * A unique application ID is assigned and stored in @ap->applid.
 * After this function returns successfully, the message receive
 * callback function @ap->recv_message() may be called at any time
 * until capi20_release() has been called for the same @ap.
 * Return value: CAPI result code
 */

u16 capi20_register(struct capi20_appl *ap)
{
	int i;
	u16 applid;
	unsigned long flags;

	DBG("");

	if (ap->rparam.datablklen < 128)
		return CAPI_LOGBLKSIZETOSMALL;

	write_lock_irqsave(&application_lock, flags);

	for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
		if (capi_applications[applid - 1] == NULL)
			break;
	}
	if (applid > CAPI_MAXAPPL) {
		write_unlock_irqrestore(&application_lock, flags);
		return CAPI_TOOMANYAPPLS;
	}

	ap->applid = applid;
	capi_applications[applid - 1] = ap;

	ap->nrecvctlpkt = 0;
	ap->nrecvdatapkt = 0;
	ap->nsentctlpkt = 0;
	ap->nsentdatapkt = 0;
	ap->callback = NULL;
	mutex_init(&ap->recv_mtx);
	skb_queue_head_init(&ap->recv_queue);
	INIT_WORK(&ap->recv_work, recv_handler);
	ap->release_in_progress = 0;

	write_unlock_irqrestore(&application_lock, flags);
	
	mutex_lock(&controller_mutex);
	for (i = 0; i < CAPI_MAXCONTR; i++) {
		if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING)
			continue;
		register_appl(capi_cards[i], applid, &ap->rparam);
	}
	mutex_unlock(&controller_mutex);

	if (showcapimsgs & 1) {
		printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
	}

	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capi20_register);

/**
 * capi20_release() - CAPI 2.0 operation CAPI_RELEASE
 * @ap:		CAPI application descriptor structure.
 *
 * Terminate an application's registration with CAPI.
 * After this function returns successfully, the message receive
 * callback function @ap->recv_message() will no longer be called.
 * Return value: CAPI result code
 */

u16 capi20_release(struct capi20_appl *ap)
{
	int i;
	unsigned long flags;

	DBG("applid %#x", ap->applid);

	write_lock_irqsave(&application_lock, flags);
	ap->release_in_progress = 1;
	capi_applications[ap->applid - 1] = NULL;
	write_unlock_irqrestore(&application_lock, flags);

	mutex_lock(&controller_mutex);
	for (i = 0; i < CAPI_MAXCONTR; i++) {
		if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING)
			continue;
		release_appl(capi_cards[i], ap->applid);
	}
	mutex_unlock(&controller_mutex);

	flush_scheduled_work();
	skb_queue_purge(&ap->recv_queue);

	if (showcapimsgs & 1) {
		printk(KERN_DEBUG "kcapi: appl %d down\n", ap->applid);
	}

	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capi20_release);

/**
 * capi20_put_message() - CAPI 2.0 operation CAPI_PUT_MESSAGE
 * @ap:		CAPI application descriptor structure.
 * @skb:	CAPI message.
 *
 * Transfer a single message to CAPI.
 * Return value: CAPI result code
 */

u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
{
	struct capi_ctr *card;
	int showctl = 0;
	u8 cmd, subcmd;

	DBG("applid %#x", ap->applid);
 
	if (ncards == 0)
		return CAPI_REGNOTINSTALLED;
	if ((ap->applid == 0) || ap->release_in_progress)
		return CAPI_ILLAPPNR;
	if (skb->len < 12
	    || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
	    || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
	card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
	if (!card || card->cardstate != CARD_RUNNING) {
		card = get_capi_ctr_by_nr(1); // XXX why?
	        if (!card || card->cardstate != CARD_RUNNING) 
			return CAPI_REGNOTINSTALLED;
	}
	if (card->blocked)
		return CAPI_SENDQUEUEFULL;

	cmd = CAPIMSG_COMMAND(skb->data);
        subcmd = CAPIMSG_SUBCOMMAND(skb->data);

	if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
		card->nsentdatapkt++;
		ap->nsentdatapkt++;
	        if (card->traceflag > 2) showctl |= 2;
	} else {
		card->nsentctlpkt++;
		ap->nsentctlpkt++;
	        if (card->traceflag) showctl |= 2;
	}
	showctl |= (card->traceflag & 1);
	if (showctl & 2) {
		if (showctl & 1) {
			printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
			       CAPIMSG_CONTROLLER(skb->data),
			       CAPIMSG_APPID(skb->data),
			       capi_cmd2str(cmd, subcmd),
			       CAPIMSG_LEN(skb->data));
		} else {
			_cdebbuf *cdb = capi_message2str(skb->data);
			if (cdb) {
				printk(KERN_DEBUG "kcapi: put [%03d] %s\n",
					CAPIMSG_CONTROLLER(skb->data),
					cdb->buf);
				cdebbuf_free(cdb);
			} else
				printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u cannot trace\n",
					CAPIMSG_CONTROLLER(skb->data),
					CAPIMSG_APPID(skb->data),
					capi_cmd2str(cmd, subcmd),
					CAPIMSG_LEN(skb->data));
		}
	}
	return card->send_message(card, skb);
}

EXPORT_SYMBOL(capi20_put_message);

/**
 * capi20_get_manufacturer() - CAPI 2.0 operation CAPI_GET_MANUFACTURER
 * @contr:	controller number.
 * @buf:	result buffer (64 bytes).
 *
 * Retrieve information about the manufacturer of the specified ISDN controller
 * or (for @contr == 0) the driver itself.
 * Return value: CAPI result code
 */

u16 capi20_get_manufacturer(u32 contr, u8 *buf)
{
	struct capi_ctr *card;

	if (contr == 0) {
		strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
		return CAPI_NOERROR;
	}
	card = get_capi_ctr_by_nr(contr);
	if (!card || card->cardstate != CARD_RUNNING) 
		return CAPI_REGNOTINSTALLED;
	strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN);
	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capi20_get_manufacturer);

/**
 * capi20_get_version() - CAPI 2.0 operation CAPI_GET_VERSION
 * @contr:	controller number.
 * @verp:	result structure.
 *
 * Retrieve version information for the specified ISDN controller
 * or (for @contr == 0) the driver itself.
 * Return value: CAPI result code
 */

u16 capi20_get_version(u32 contr, struct capi_version *verp)
{
	struct capi_ctr *card;

	if (contr == 0) {
		*verp = driver_version;
		return CAPI_NOERROR;
	}
	card = get_capi_ctr_by_nr(contr);
	if (!card || card->cardstate != CARD_RUNNING) 
		return CAPI_REGNOTINSTALLED;

	memcpy((void *) verp, &card->version, sizeof(capi_version));
	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capi20_get_version);

/**
 * capi20_get_serial() - CAPI 2.0 operation CAPI_GET_SERIAL_NUMBER
 * @contr:	controller number.
 * @serial:	result buffer (8 bytes).
 *
 * Retrieve the serial number of the specified ISDN controller
 * or (for @contr == 0) the driver itself.
 * Return value: CAPI result code
 */

u16 capi20_get_serial(u32 contr, u8 *serial)
{
	struct capi_ctr *card;

	if (contr == 0) {
		strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
		return CAPI_NOERROR;
	}
	card = get_capi_ctr_by_nr(contr);
	if (!card || card->cardstate != CARD_RUNNING) 
		return CAPI_REGNOTINSTALLED;

	strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN);
	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capi20_get_serial);

/**
 * capi20_get_profile() - CAPI 2.0 operation CAPI_GET_PROFILE
 * @contr:	controller number.
 * @profp:	result structure.
 *
 * Retrieve capability information for the specified ISDN controller
 * or (for @contr == 0) the number of installed controllers.
 * Return value: CAPI result code
 */

u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
{
	struct capi_ctr *card;

	if (contr == 0) {
		profp->ncontroller = ncards;
		return CAPI_NOERROR;
	}
	card = get_capi_ctr_by_nr(contr);
	if (!card || card->cardstate != CARD_RUNNING) 
		return CAPI_REGNOTINSTALLED;

	memcpy((void *) profp, &card->profile,
			sizeof(struct capi_profile));
	return CAPI_NOERROR;
}

EXPORT_SYMBOL(capi20_get_profile);

#ifdef AVMB1_COMPAT
static int old_capi_manufacturer(unsigned int cmd, void __user *data)
{
	avmb1_loadandconfigdef ldef;
	avmb1_extcarddef cdef;
	avmb1_resetdef rdef;
	capicardparams cparams;
	struct capi_ctr *card;
	struct capi_driver *driver = NULL;
	capiloaddata ldata;
	struct list_head *l;
	unsigned long flags;
	int retval;

	switch (cmd) {
	case AVMB1_ADDCARD:
	case AVMB1_ADDCARD_WITH_TYPE:
		if (cmd == AVMB1_ADDCARD) {
		   if ((retval = copy_from_user(&cdef, data,
					    sizeof(avmb1_carddef))))
			   return retval;
		   cdef.cardtype = AVM_CARDTYPE_B1;
		} else {
		   if ((retval = copy_from_user(&cdef, data,
					    sizeof(avmb1_extcarddef))))
			   return retval;
		}
		cparams.port = cdef.port;
		cparams.irq = cdef.irq;
		cparams.cardnr = cdef.cardnr;

		read_lock_irqsave(&capi_drivers_list_lock, flags);
                switch (cdef.cardtype) {
			case AVM_CARDTYPE_B1:
				list_for_each(l, &capi_drivers) {
					driver = list_entry(l, struct capi_driver, list);
					if (strcmp(driver->name, "b1isa") == 0)
						break;
				}
				break;
			case AVM_CARDTYPE_T1:
				list_for_each(l, &capi_drivers) {
					driver = list_entry(l, struct capi_driver, list);
					if (strcmp(driver->name, "t1isa") == 0)
						break;
				}
				break;
			default:
				driver = NULL;
				break;
		}
		if (!driver) {
			read_unlock_irqrestore(&capi_drivers_list_lock, flags);
			printk(KERN_ERR "kcapi: driver not loaded.\n");
			return -EIO;
		}
		if (!driver->add_card) {
			read_unlock_irqrestore(&capi_drivers_list_lock, flags);
			printk(KERN_ERR "kcapi: driver has no add card function.\n");
			return -EIO;
		}

		retval = driver->add_card(driver, &cparams);
		read_unlock_irqrestore(&capi_drivers_list_lock, flags);
		return retval;

	case AVMB1_LOAD:
	case AVMB1_LOAD_AND_CONFIG:

		if (cmd == AVMB1_LOAD) {
			if (copy_from_user(&ldef, data,
					   sizeof(avmb1_loaddef)))
				return -EFAULT;
			ldef.t4config.len = 0;
			ldef.t4config.data = NULL;
		} else {
			if (copy_from_user(&ldef, data,
					   sizeof(avmb1_loadandconfigdef)))
				return -EFAULT;
		}
		card = get_capi_ctr_by_nr(ldef.contr);
		if (!card)
			return -EINVAL;
		card = capi_ctr_get(card);
		if (!card)
			return -ESRCH;
		if (card->load_firmware == NULL) {
			printk(KERN_DEBUG "kcapi: load: no load function\n");
			capi_ctr_put(card);
			return -ESRCH;
		}

		if (ldef.t4file.len <= 0) {
			printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
			capi_ctr_put(card);
			return -EINVAL;
		}
		if (ldef.t4file.data == NULL) {
			printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
			capi_ctr_put(card);
			return -EINVAL;
		}

		ldata.firmware.user = 1;
		ldata.firmware.data = ldef.t4file.data;
		ldata.firmware.len = ldef.t4file.len;
		ldata.configuration.user = 1;
		ldata.configuration.data = ldef.t4config.data;
		ldata.configuration.len = ldef.t4config.len;

		if (card->cardstate != CARD_DETECTED) {
			printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
			capi_ctr_put(card);
			return -EBUSY;
		}
		card->cardstate = CARD_LOADING;

		retval = card->load_firmware(card, &ldata);

		if (retval) {
			card->cardstate = CARD_DETECTED;
			capi_ctr_put(card);
			return retval;
		}

		while (card->cardstate != CARD_RUNNING) {

			msleep_interruptible(100);	/* 0.1 sec */

			if (signal_pending(current)) {
				capi_ctr_put(card);
				return -EINTR;
			}
		}
		capi_ctr_put(card);
		return 0;

	case AVMB1_RESETCARD:
		if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef)))
			return -EFAULT;
		card = get_capi_ctr_by_nr(rdef.contr);
		if (!card)
			return -ESRCH;

		if (card->cardstate == CARD_DETECTED)
			return 0;

		card->reset_ctr(card);

		while (card->cardstate > CARD_DETECTED) {

			msleep_interruptible(100);	/* 0.1 sec */

			if (signal_pending(current))
				return -EINTR;
		}
		return 0;

	}
	return -EINVAL;
}
#endif

/**
 * capi20_manufacturer() - CAPI 2.0 operation CAPI_MANUFACTURER
 * @cmd:	command.
 * @data:	parameter.
 *
 * Perform manufacturer specific command.
 * Return value: CAPI result code
 */

int capi20_manufacturer(unsigned int cmd, void __user *data)
{
        struct capi_ctr *card;

	switch (cmd) {
#ifdef AVMB1_COMPAT
	case AVMB1_LOAD:
	case AVMB1_LOAD_AND_CONFIG:
	case AVMB1_RESETCARD:
	case AVMB1_GET_CARDINFO:
	case AVMB1_REMOVECARD:
		return old_capi_manufacturer(cmd, data);
#endif
	case KCAPI_CMD_TRACE:
	{
		kcapi_flagdef fdef;

		if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
			return -EFAULT;

		card = get_capi_ctr_by_nr(fdef.contr);
		if (!card)
			return -ESRCH;

		card->traceflag = fdef.flag;
		printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
			card->cnr, card->traceflag);
		return 0;
	}
	case KCAPI_CMD_ADDCARD:
	{
		struct list_head *l;
		struct capi_driver *driver = NULL;
		capicardparams cparams;
		kcapi_carddef cdef;
		int retval;

		if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
			return retval;

		cparams.port = cdef.port;
		cparams.irq = cdef.irq;
		cparams.membase = cdef.membase;
		cparams.cardnr = cdef.cardnr;
		cparams.cardtype = 0;
		cdef.driver[sizeof(cdef.driver)-1] = 0;

		list_for_each(l, &capi_drivers) {
			driver = list_entry(l, struct capi_driver, list);
			if (strcmp(driver->name, cdef.driver) == 0)
				break;
		}
		if (driver == NULL) {
			printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
					cdef.driver);
			return -ESRCH;
		}

		if (!driver->add_card) {
			printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
			return -EIO;
		}

		return driver->add_card(driver, &cparams);
	}

	default:
		printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
					cmd);
		break;

	}
	return -EINVAL;
}

EXPORT_SYMBOL(capi20_manufacturer);

/* temporary hack */

/**
 * capi20_set_callback() - set CAPI application notification callback function
 * @ap:		CAPI application descriptor structure.
 * @callback:	callback function (NULL to remove).
 *
 * If not NULL, the callback function will be called to notify the
 * application of the addition or removal of a controller.
 * The first argument (cmd) will tell whether the controller was added
 * (KCI_CONTRUP) or removed (KCI_CONTRDOWN).
 * The second argument (contr) will be the controller number.
 * For cmd==KCI_CONTRUP the third argument (data) will be a pointer to the
 * new controller's capability profile structure.
 */

void capi20_set_callback(struct capi20_appl *ap,
			 void (*callback) (unsigned int cmd, __u32 contr, void *data))
{
	ap->callback = callback;
}

EXPORT_SYMBOL(capi20_set_callback);

/* ------------------------------------------------------------- */
/* -------- Init & Cleanup ------------------------------------- */
/* ------------------------------------------------------------- */

/*
 * init / exit functions
 */

static int __init kcapi_init(void)
{
	char *p;
	char rev[32];
	int ret;

	ret = cdebug_init();
	if (ret)
		return ret;
        kcapi_proc_init();

	if ((p = strchr(revision, ':')) != NULL && p[1]) {
		strlcpy(rev, p + 2, sizeof(rev));
		if ((p = strchr(rev, '$')) != NULL && p > rev)
		   *(p-1) = 0;
	} else
		strcpy(rev, "1.0");

        printk(KERN_NOTICE "CAPI Subsystem Rev %s\n", rev);

	return 0;
}

static void __exit kcapi_exit(void)
{
        kcapi_proc_exit();

	/* make sure all notifiers are finished */
	flush_scheduled_work();
	cdebug_exit();
}

module_init(kcapi_init);
module_exit(kcapi_exit);
