/* $Id: capifunc.c,v 1.61.4.7 2005/02/11 19:40:25 armin Exp $
 *
 * ISDN interface module for Eicon active cards DIVA.
 * CAPI Interface common functions
 *
 * Copyright 2000-2003 by Armin Schindler (mac@melware.de)
 * Copyright 2000-2003 Cytronics & Melware (info@melware.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include "platform.h"
#include "os_capi.h"
#include "di_defs.h"
#include "capi20.h"
#include "divacapi.h"
#include "divasync.h"
#include "capifunc.h"

#define DBG_MINIMUM  (DL_LOG + DL_FTL + DL_ERR)
#define DBG_DEFAULT  (DBG_MINIMUM + DL_XLOG + DL_REG)

DIVA_CAPI_ADAPTER *adapter = (DIVA_CAPI_ADAPTER *) NULL;
APPL *application = (APPL *) NULL;
byte max_appl = MAX_APPL;
byte max_adapter = 0;
static CAPI_MSG *mapped_msg = (CAPI_MSG *) NULL;

byte UnMapController(byte);
char DRIVERRELEASE_CAPI[32];

extern void AutomaticLaw(DIVA_CAPI_ADAPTER *);
extern void callback(ENTITY *);
extern word api_remove_start(void);
extern word CapiRelease(word);
extern word CapiRegister(word);
extern word api_put(APPL *, CAPI_MSG *);

static diva_os_spin_lock_t api_lock;

static LIST_HEAD(cards);

static dword notify_handle;
static void DIRequest(ENTITY *e);
static DESCRIPTOR MAdapter;
static DESCRIPTOR DAdapter;
static byte ControllerMap[MAX_DESCRIPTORS + 1];


static void diva_register_appl(struct capi_ctr *, __u16,
			       capi_register_params *);
static void diva_release_appl(struct capi_ctr *, __u16);
static char *diva_procinfo(struct capi_ctr *);
static u16 diva_send_message(struct capi_ctr *,
			     diva_os_message_buffer_s *);
extern void diva_os_set_controller_struct(struct capi_ctr *);

extern void DIVA_DIDD_Read(DESCRIPTOR *, int);

/*
 * debug
 */
static void no_printf(unsigned char *, ...);
#include "debuglib.c"
static void xlog(char *x, ...)
{
#ifndef DIVA_NO_DEBUGLIB
	va_list ap;
	if (myDriverDebugHandle.dbgMask & DL_XLOG) {
		va_start(ap, x);
		if (myDriverDebugHandle.dbg_irq) {
			myDriverDebugHandle.dbg_irq(myDriverDebugHandle.id,
						    DLI_XLOG, x, ap);
		} else if (myDriverDebugHandle.dbg_old) {
			myDriverDebugHandle.dbg_old(myDriverDebugHandle.id,
						    x, ap);
		}
		va_end(ap);
	}
#endif
}

/*
 * info for proc
 */
static char *diva_procinfo(struct capi_ctr *ctrl)
{
	return (ctrl->serial);
}

/*
 * stop debugging
 */
static void stop_dbg(void)
{
	DbgDeregister();
	memset(&MAdapter, 0, sizeof(MAdapter));
	dprintf = no_printf;
}

/*
 * dummy debug function
 */
static void no_printf(unsigned char *x, ...)
{
}

/*
 * Controller mapping
 */
byte MapController(byte Controller)
{
	byte i;
	byte MappedController = 0;
	byte ctrl = Controller & 0x7f;	/* mask external controller bit off */

	for (i = 1; i < max_adapter + 1; i++) {
		if (ctrl == ControllerMap[i]) {
			MappedController = (byte) i;
			break;
		}
	}
	if (i > max_adapter) {
		ControllerMap[0] = ctrl;
		MappedController = 0;
	}
	return (MappedController | (Controller & 0x80));	/* put back external controller bit */
}

/*
 * Controller unmapping
 */
byte UnMapController(byte MappedController)
{
	byte Controller;
	byte ctrl = MappedController & 0x7f;	/* mask external controller bit off */

	if (ctrl <= max_adapter) {
		Controller = ControllerMap[ctrl];
	} else {
		Controller = 0;
	}

	return (Controller | (MappedController & 0x80));	/* put back external controller bit */
}

/*
 * find a new free id
 */
static int find_free_id(void)
{
	int num = 0;
	DIVA_CAPI_ADAPTER *a;

	while (num < MAX_DESCRIPTORS) {
		a = &adapter[num];
		if (!a->Id)
			break;
		num++;
	}
	return (num + 1);
}

/*
 * find a card structure by controller number
 */
static diva_card *find_card_by_ctrl(word controller)
{
	struct list_head *tmp;
	diva_card *card;

	list_for_each(tmp, &cards) {
		card = list_entry(tmp, diva_card, list);
		if (ControllerMap[card->Id] == controller) {
			if (card->remove_in_progress)
				card = NULL;
			return (card);
		}
	}
	return (diva_card *) 0;
}

/*
 * Buffer RX/TX
 */
void *TransmitBufferSet(APPL *appl, dword ref)
{
	appl->xbuffer_used[ref] = true;
	DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
		return (void *)(long)ref;
}

void *TransmitBufferGet(APPL *appl, void *p)
{
	if (appl->xbuffer_internal[(dword)(long)p])
		return appl->xbuffer_internal[(dword)(long)p];

	return appl->xbuffer_ptr[(dword)(long)p];
}

void TransmitBufferFree(APPL *appl, void *p)
{
	appl->xbuffer_used[(dword)(long)p] = false;
	DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword)(long)p) + 1))
		}

void *ReceiveBufferGet(APPL *appl, int Num)
{
	return &appl->ReceiveBuffer[Num * appl->MaxDataLength];
}

/*
 * api_remove_start/complete for cleanup
 */
void api_remove_complete(void)
{
	DBG_PRV1(("api_remove_complete"))
		}

/*
 * main function called by message.c
 */
void sendf(APPL *appl, word command, dword Id, word Number, byte *format, ...)
{
	word i, j;
	word length = 12, dlength = 0;
	byte *write;
	CAPI_MSG msg;
	byte *string = NULL;
	va_list ap;
	diva_os_message_buffer_s *dmb;
	diva_card *card = NULL;
	dword tmp;

	if (!appl)
		return;

	DBG_PRV1(("sendf(a=%d,cmd=%x,format=%s)",
		  appl->Id, command, (byte *) format))

		PUT_WORD(&msg.header.appl_id, appl->Id);
	PUT_WORD(&msg.header.command, command);
	if ((byte) (command >> 8) == 0x82)
		Number = appl->Number++;
	PUT_WORD(&msg.header.number, Number);

	PUT_DWORD(&msg.header.controller, Id);
	write = (byte *)&msg;
	write += 12;

	va_start(ap, format);
	for (i = 0; format[i]; i++) {
		switch (format[i]) {
		case 'b':
			tmp = va_arg(ap, dword);
			*(byte *) write = (byte) (tmp & 0xff);
			write += 1;
			length += 1;
			break;
		case 'w':
			tmp = va_arg(ap, dword);
			PUT_WORD(write, (tmp & 0xffff));
			write += 2;
			length += 2;
			break;
		case 'd':
			tmp = va_arg(ap, dword);
			PUT_DWORD(write, tmp);
			write += 4;
			length += 4;
			break;
		case 's':
		case 'S':
			string = va_arg(ap, byte *);
			length += string[0] + 1;
			for (j = 0; j <= string[0]; j++)
				*write++ = string[j];
			break;
		}
	}
	va_end(ap);

	PUT_WORD(&msg.header.length, length);
	msg.header.controller = UnMapController(msg.header.controller);

	if (command == _DATA_B3_I)
		dlength = GET_WORD(
			((byte *)&msg.info.data_b3_ind.Data_Length));

	if (!(dmb = diva_os_alloc_message_buffer(length + dlength,
						 (void **) &write))) {
		DBG_ERR(("sendf: alloc_message_buffer failed, incoming msg dropped."))
			return;
	}

	/* copy msg header to sk_buff */
	memcpy(write, (byte *)&msg, length);

	/* if DATA_B3_IND, copy data too */
	if (command == _DATA_B3_I) {
		dword data = GET_DWORD(&msg.info.data_b3_ind.Data);
		memcpy(write + length, (void *)(long)data, dlength);
	}

#ifndef DIVA_NO_DEBUGLIB
	if (myDriverDebugHandle.dbgMask & DL_XLOG) {
		switch (command) {
		default:
			xlog("\x00\x02", &msg, 0x81, length);
			break;
		case _DATA_B3_R | CONFIRM:
			if (myDriverDebugHandle.dbgMask & DL_BLK)
				xlog("\x00\x02", &msg, 0x81, length);
			break;
		case _DATA_B3_I:
			if (myDriverDebugHandle.dbgMask & DL_BLK) {
				xlog("\x00\x02", &msg, 0x81, length);
				for (i = 0; i < dlength; i += 256) {
					DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
						 ((dlength - i) < 256) ? (dlength - i) : 256))
						if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
							break; /* not more if not explicitly requested */
				}
			}
			break;
		}
	}
#endif

	/* find the card structure for this controller */
	if (!(card = find_card_by_ctrl(write[8] & 0x7f))) {
		DBG_ERR(("sendf - controller %d not found, incoming msg dropped",
			 write[8] & 0x7f))
			diva_os_free_message_buffer(dmb);
		return;
	}
	/* send capi msg to capi layer */
	capi_ctr_handle_message(&card->capi_ctrl, appl->Id, dmb);
}

/*
 * cleanup adapter
 */
static void clean_adapter(int id, struct list_head *free_mem_q)
{
	DIVA_CAPI_ADAPTER *a;
	int i, k;

	a = &adapter[id];
	k = li_total_channels - a->li_channels;
	if (k == 0) {
		if (li_config_table) {
			list_add((struct list_head *)li_config_table, free_mem_q);
			li_config_table = NULL;
		}
	} else {
		if (a->li_base < k) {
			memmove(&li_config_table[a->li_base],
				&li_config_table[a->li_base + a->li_channels],
				(k - a->li_base) * sizeof(LI_CONFIG));
			for (i = 0; i < k; i++) {
				memmove(&li_config_table[i].flag_table[a->li_base],
					&li_config_table[i].flag_table[a->li_base + a->li_channels],
					k - a->li_base);
				memmove(&li_config_table[i].
					coef_table[a->li_base],
					&li_config_table[i].coef_table[a->li_base + a->li_channels],
					k - a->li_base);
			}
		}
	}
	li_total_channels = k;
	for (i = id; i < max_adapter; i++) {
		if (adapter[i].request)
			adapter[i].li_base -= a->li_channels;
	}
	if (a->plci)
		list_add((struct list_head *)a->plci, free_mem_q);

	memset(a, 0x00, sizeof(DIVA_CAPI_ADAPTER));
	while ((max_adapter != 0) && !adapter[max_adapter - 1].request)
		max_adapter--;
}

/*
 * remove a card, but ensures consistent state of LI tables
 * in the time adapter is removed
 */
static void divacapi_remove_card(DESCRIPTOR *d)
{
	diva_card *card = NULL;
	diva_os_spin_lock_magic_t old_irql;
	LIST_HEAD(free_mem_q);
	struct list_head *link;
	struct list_head *tmp;

	/*
	 * Set "remove in progress flag".
	 * Ensures that there is no call from sendf to CAPI in
	 * the time CAPI controller is about to be removed.
	 */
	diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card");
	list_for_each(tmp, &cards) {
		card = list_entry(tmp, diva_card, list);
		if (card->d.request == d->request) {
			card->remove_in_progress = 1;
			list_del(tmp);
			break;
		}
	}
	diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");

	if (card) {
		/*
		 * Detach CAPI. Sendf cannot call to CAPI any more.
		 * After detach no call to send_message() is done too.
		 */
		detach_capi_ctr(&card->capi_ctrl);

		/*
		 * Now get API lock (to ensure stable state of LI tables)
		 * and update the adapter map/LI table.
		 */
		diva_os_enter_spin_lock(&api_lock, &old_irql, "remove card");

		clean_adapter(card->Id - 1, &free_mem_q);
		DBG_TRC(("DelAdapterMap (%d) -> (%d)",
			 ControllerMap[card->Id], card->Id))
			ControllerMap[card->Id] = 0;
		DBG_TRC(("adapter remove, max_adapter=%d",
			 max_adapter));
		diva_os_leave_spin_lock(&api_lock, &old_irql, "remove card");

		/* After releasing the lock, we can free the memory */
		diva_os_free(0, card);
	}

	/* free queued memory areas */
	list_for_each_safe(link, tmp, &free_mem_q) {
		list_del(link);
		diva_os_free(0, link);
	}
}

/*
 * remove cards
 */
static void divacapi_remove_cards(void)
{
	DESCRIPTOR d;
	struct list_head *tmp;
	diva_card *card;
	diva_os_spin_lock_magic_t old_irql;

rescan:
	diva_os_enter_spin_lock(&api_lock, &old_irql, "remove cards");
	list_for_each(tmp, &cards) {
		card = list_entry(tmp, diva_card, list);
		diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");
		d.request = card->d.request;
		divacapi_remove_card(&d);
		goto rescan;
	}
	diva_os_leave_spin_lock(&api_lock, &old_irql, "remove cards");
}

/*
 * sync_callback
 */
static void sync_callback(ENTITY *e)
{
	diva_os_spin_lock_magic_t old_irql;

	DBG_TRC(("cb:Id=%x,Rc=%x,Ind=%x", e->Id, e->Rc, e->Ind))

		diva_os_enter_spin_lock(&api_lock, &old_irql, "sync_callback");
	callback(e);
	diva_os_leave_spin_lock(&api_lock, &old_irql, "sync_callback");
}

/*
 * add a new card
 */
static int diva_add_card(DESCRIPTOR *d)
{
	int k = 0, i = 0;
	diva_os_spin_lock_magic_t old_irql;
	diva_card *card = NULL;
	struct capi_ctr *ctrl = NULL;
	DIVA_CAPI_ADAPTER *a = NULL;
	IDI_SYNC_REQ sync_req;
	char serial[16];
	void *mem_to_free;
	LI_CONFIG *new_li_config_table;
	int j;

	if (!(card = (diva_card *) diva_os_malloc(0, sizeof(diva_card)))) {
		DBG_ERR(("diva_add_card: failed to allocate card struct."))
			return (0);
	}
	memset((char *) card, 0x00, sizeof(diva_card));
	memcpy(&card->d, d, sizeof(DESCRIPTOR));
	sync_req.GetName.Req = 0;
	sync_req.GetName.Rc = IDI_SYNC_REQ_GET_NAME;
	card->d.request((ENTITY *)&sync_req);
	strlcpy(card->name, sync_req.GetName.name, sizeof(card->name));
	ctrl = &card->capi_ctrl;
	strcpy(ctrl->name, card->name);
	ctrl->register_appl = diva_register_appl;
	ctrl->release_appl = diva_release_appl;
	ctrl->send_message = diva_send_message;
	ctrl->procinfo = diva_procinfo;
	ctrl->driverdata = card;
	diva_os_set_controller_struct(ctrl);

	if (attach_capi_ctr(ctrl)) {
		DBG_ERR(("diva_add_card: failed to attach controller."))
			diva_os_free(0, card);
		return (0);
	}

	diva_os_enter_spin_lock(&api_lock, &old_irql, "find id");
	card->Id = find_free_id();
	diva_os_leave_spin_lock(&api_lock, &old_irql, "find id");

	strlcpy(ctrl->manu, M_COMPANY, sizeof(ctrl->manu));
	ctrl->version.majorversion = 2;
	ctrl->version.minorversion = 0;
	ctrl->version.majormanuversion = DRRELMAJOR;
	ctrl->version.minormanuversion = DRRELMINOR;
	sync_req.GetSerial.Req = 0;
	sync_req.GetSerial.Rc = IDI_SYNC_REQ_GET_SERIAL;
	sync_req.GetSerial.serial = 0;
	card->d.request((ENTITY *)&sync_req);
	if ((i = ((sync_req.GetSerial.serial & 0xff000000) >> 24))) {
		sprintf(serial, "%ld-%d",
			sync_req.GetSerial.serial & 0x00ffffff, i + 1);
	} else {
		sprintf(serial, "%ld", sync_req.GetSerial.serial);
	}
	serial[CAPI_SERIAL_LEN - 1] = 0;
	strlcpy(ctrl->serial, serial, sizeof(ctrl->serial));

	a = &adapter[card->Id - 1];
	card->adapter = a;
	a->os_card = card;
	ControllerMap[card->Id] = (byte) (ctrl->cnr);

	DBG_TRC(("AddAdapterMap (%d) -> (%d)", ctrl->cnr, card->Id))

		sync_req.xdi_capi_prms.Req = 0;
	sync_req.xdi_capi_prms.Rc = IDI_SYNC_REQ_XDI_GET_CAPI_PARAMS;
	sync_req.xdi_capi_prms.info.structure_length =
		sizeof(diva_xdi_get_capi_parameters_t);
	card->d.request((ENTITY *)&sync_req);
	a->flag_dynamic_l1_down =
		sync_req.xdi_capi_prms.info.flag_dynamic_l1_down;
	a->group_optimization_enabled =
		sync_req.xdi_capi_prms.info.group_optimization_enabled;
	a->request = DIRequest;	/* card->d.request; */
	a->max_plci = card->d.channels + 30;
	a->max_listen = (card->d.channels > 2) ? 8 : 2;
	if (!
	    (a->plci =
	     (PLCI *) diva_os_malloc(0, sizeof(PLCI) * a->max_plci))) {
		DBG_ERR(("diva_add_card: failed alloc plci struct."))
			memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
		return (0);
	}
	memset(a->plci, 0, sizeof(PLCI) * a->max_plci);

	for (k = 0; k < a->max_plci; k++) {
		a->Id = (byte) card->Id;
		a->plci[k].Sig.callback = sync_callback;
		a->plci[k].Sig.XNum = 1;
		a->plci[k].Sig.X = a->plci[k].XData;
		a->plci[k].Sig.user[0] = (word) (card->Id - 1);
		a->plci[k].Sig.user[1] = (word) k;
		a->plci[k].NL.callback = sync_callback;
		a->plci[k].NL.XNum = 1;
		a->plci[k].NL.X = a->plci[k].XData;
		a->plci[k].NL.user[0] = (word) ((card->Id - 1) | 0x8000);
		a->plci[k].NL.user[1] = (word) k;
		a->plci[k].adapter = a;
	}

	a->profile.Number = card->Id;
	a->profile.Channels = card->d.channels;
	if (card->d.features & DI_FAX3) {
		a->profile.Global_Options = 0x71;
		if (card->d.features & DI_CODEC)
			a->profile.Global_Options |= 0x6;
#if IMPLEMENT_DTMF
		a->profile.Global_Options |= 0x8;
#endif				/* IMPLEMENT_DTMF */
		a->profile.Global_Options |= 0x80; /* Line Interconnect */
#if IMPLEMENT_ECHO_CANCELLER
		a->profile.Global_Options |= 0x100;
#endif				/* IMPLEMENT_ECHO_CANCELLER */
		a->profile.B1_Protocols = 0xdf;
		a->profile.B2_Protocols = 0x1fdb;
		a->profile.B3_Protocols = 0xb7;
		a->manufacturer_features = MANUFACTURER_FEATURE_HARDDTMF;
	} else {
		a->profile.Global_Options = 0x71;
		if (card->d.features & DI_CODEC)
			a->profile.Global_Options |= 0x2;
		a->profile.B1_Protocols = 0x43;
		a->profile.B2_Protocols = 0x1f0f;
		a->profile.B3_Protocols = 0x07;
		a->manufacturer_features = 0;
	}

	a->li_pri = (a->profile.Channels > 2);
	a->li_channels = a->li_pri ? MIXER_CHANNELS_PRI : MIXER_CHANNELS_BRI;
	a->li_base = 0;
	for (i = 0; &adapter[i] != a; i++) {
		if (adapter[i].request)
			a->li_base = adapter[i].li_base + adapter[i].li_channels;
	}
	k = li_total_channels + a->li_channels;
	new_li_config_table =
		(LI_CONFIG *) diva_os_malloc(0, ((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * k) * ((k + 3) & ~3));
	if (new_li_config_table == NULL) {
		DBG_ERR(("diva_add_card: failed alloc li_config table."))
			memset(a, 0, sizeof(DIVA_CAPI_ADAPTER));
		return (0);
	}

	/* Prevent access to line interconnect table in process update */
	diva_os_enter_spin_lock(&api_lock, &old_irql, "add card");

	j = 0;
	for (i = 0; i < k; i++) {
		if ((i >= a->li_base) && (i < a->li_base + a->li_channels))
			memset(&new_li_config_table[i], 0, sizeof(LI_CONFIG));
		else
			memcpy(&new_li_config_table[i], &li_config_table[j], sizeof(LI_CONFIG));
		new_li_config_table[i].flag_table =
			((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i) * ((k + 3) & ~3));
		new_li_config_table[i].coef_table =
			((byte *) new_li_config_table) + (((k * sizeof(LI_CONFIG) + 3) & ~3) + (2 * i + 1) * ((k + 3) & ~3));
		if ((i >= a->li_base) && (i < a->li_base + a->li_channels)) {
			new_li_config_table[i].adapter = a;
			memset(&new_li_config_table[i].flag_table[0], 0, k);
			memset(&new_li_config_table[i].coef_table[0], 0, k);
		} else {
			if (a->li_base != 0) {
				memcpy(&new_li_config_table[i].flag_table[0],
				       &li_config_table[j].flag_table[0],
				       a->li_base);
				memcpy(&new_li_config_table[i].coef_table[0],
				       &li_config_table[j].coef_table[0],
				       a->li_base);
			}
			memset(&new_li_config_table[i].flag_table[a->li_base], 0, a->li_channels);
			memset(&new_li_config_table[i].coef_table[a->li_base], 0, a->li_channels);
			if (a->li_base + a->li_channels < k) {
				memcpy(&new_li_config_table[i].flag_table[a->li_base +
									  a->li_channels],
				       &li_config_table[j].flag_table[a->li_base],
				       k - (a->li_base + a->li_channels));
				memcpy(&new_li_config_table[i].coef_table[a->li_base +
									  a->li_channels],
				       &li_config_table[j].coef_table[a->li_base],
				       k - (a->li_base + a->li_channels));
			}
			j++;
		}
	}
	li_total_channels = k;

	mem_to_free = li_config_table;

	li_config_table = new_li_config_table;
	for (i = card->Id; i < max_adapter; i++) {
		if (adapter[i].request)
			adapter[i].li_base += a->li_channels;
	}

	if (a == &adapter[max_adapter])
		max_adapter++;

	list_add(&(card->list), &cards);
	AutomaticLaw(a);

	diva_os_leave_spin_lock(&api_lock, &old_irql, "add card");

	if (mem_to_free) {
		diva_os_free(0, mem_to_free);
	}

	i = 0;
	while (i++ < 30) {
		if (a->automatic_law > 3)
			break;
		diva_os_sleep(10);
	}

	/* profile information */
	PUT_WORD(&ctrl->profile.nbchannel, card->d.channels);
	ctrl->profile.goptions = a->profile.Global_Options;
	ctrl->profile.support1 = a->profile.B1_Protocols;
	ctrl->profile.support2 = a->profile.B2_Protocols;
	ctrl->profile.support3 = a->profile.B3_Protocols;
	/* manufacturer profile information */
	ctrl->profile.manu[0] = a->man_profile.private_options;
	ctrl->profile.manu[1] = a->man_profile.rtp_primary_payloads;
	ctrl->profile.manu[2] = a->man_profile.rtp_additional_payloads;
	ctrl->profile.manu[3] = 0;
	ctrl->profile.manu[4] = 0;

	capi_ctr_ready(ctrl);

	DBG_TRC(("adapter added, max_adapter=%d", max_adapter));
	return (1);
}

/*
 *  register appl
 */
static void diva_register_appl(struct capi_ctr *ctrl, __u16 appl,
			       capi_register_params *rp)
{
	APPL *this;
	word bnum, xnum;
	int i = 0;
	unsigned char *p;
	void *DataNCCI, *DataFlags, *ReceiveBuffer, *xbuffer_used;
	void **xbuffer_ptr, **xbuffer_internal;
	diva_os_spin_lock_magic_t old_irql;
	unsigned int mem_len;
	int nconn = rp->level3cnt;


	if (diva_os_in_irq()) {
		DBG_ERR(("CAPI_REGISTER - in irq context !"))
			return;
	}

	DBG_TRC(("application register Id=%d", appl))

		if (appl > MAX_APPL) {
			DBG_ERR(("CAPI_REGISTER - appl.Id exceeds MAX_APPL"))
				return;
		}

	if (nconn <= 0)
		nconn = ctrl->profile.nbchannel * -nconn;

	if (nconn == 0)
		nconn = ctrl->profile.nbchannel;

	DBG_LOG(("CAPI_REGISTER - Id = %d", appl))
		DBG_LOG(("  MaxLogicalConnections = %d(%d)", nconn, rp->level3cnt))
		DBG_LOG(("  MaxBDataBuffers       = %d", rp->datablkcnt))
		DBG_LOG(("  MaxBDataLength        = %d", rp->datablklen))

		if (nconn < 1 ||
		    nconn > 255 ||
		    rp->datablklen < 80 ||
		    rp->datablklen > 2150 || rp->datablkcnt > 255) {
			DBG_ERR(("CAPI_REGISTER - invalid parameters"))
				return;
		}

	if (application[appl - 1].Id == appl) {
		DBG_LOG(("CAPI_REGISTER - appl already registered"))
			return;	/* appl already registered */
	}

	/* alloc memory */

	bnum = nconn * rp->datablkcnt;
	xnum = nconn * MAX_DATA_B3;

	mem_len  = bnum * sizeof(word);		/* DataNCCI */
	mem_len += bnum * sizeof(word);		/* DataFlags */
	mem_len += bnum * rp->datablklen;	/* ReceiveBuffer */
	mem_len += xnum;			/* xbuffer_used */
	mem_len += xnum * sizeof(void *);	/* xbuffer_ptr */
	mem_len += xnum * sizeof(void *);	/* xbuffer_internal */
	mem_len += xnum * rp->datablklen;	/* xbuffer_ptr[xnum] */

	DBG_LOG(("  Allocated Memory      = %d", mem_len))
		if (!(p = diva_os_malloc(0, mem_len))) {
			DBG_ERR(("CAPI_REGISTER - memory allocation failed"))
				return;
		}
	memset(p, 0, mem_len);

	DataNCCI = (void *)p;
	p += bnum * sizeof(word);
	DataFlags = (void *)p;
	p += bnum * sizeof(word);
	ReceiveBuffer = (void *)p;
	p += bnum * rp->datablklen;
	xbuffer_used = (void *)p;
	p += xnum;
	xbuffer_ptr = (void **)p;
	p += xnum * sizeof(void *);
	xbuffer_internal = (void **)p;
	p += xnum * sizeof(void *);
	for (i = 0; i < xnum; i++) {
		xbuffer_ptr[i] = (void *)p;
		p += rp->datablklen;
	}

	/* initialize application data */
	diva_os_enter_spin_lock(&api_lock, &old_irql, "register_appl");

	this = &application[appl - 1];
	memset(this, 0, sizeof(APPL));

	this->Id = appl;

	for (i = 0; i < max_adapter; i++) {
		adapter[i].CIP_Mask[appl - 1] = 0;
	}

	this->queue_size = 1000;

	this->MaxNCCI = (byte) nconn;
	this->MaxNCCIData = (byte) rp->datablkcnt;
	this->MaxBuffer = bnum;
	this->MaxDataLength = rp->datablklen;

	this->DataNCCI = DataNCCI;
	this->DataFlags = DataFlags;
	this->ReceiveBuffer = ReceiveBuffer;
	this->xbuffer_used = xbuffer_used;
	this->xbuffer_ptr = xbuffer_ptr;
	this->xbuffer_internal = xbuffer_internal;
	for (i = 0; i < xnum; i++) {
		this->xbuffer_ptr[i] = xbuffer_ptr[i];
	}

	CapiRegister(this->Id);
	diva_os_leave_spin_lock(&api_lock, &old_irql, "register_appl");

}

/*
 *  release appl
 */
static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl)
{
	diva_os_spin_lock_magic_t old_irql;
	APPL *this = &application[appl - 1];
	void *mem_to_free = NULL;

	DBG_TRC(("application %d(%d) cleanup", this->Id, appl))

		if (diva_os_in_irq()) {
			DBG_ERR(("CAPI_RELEASE - in irq context !"))
				return;
		}

	diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl");
	if (this->Id) {
		CapiRelease(this->Id);
		mem_to_free = this->DataNCCI;
		this->DataNCCI = NULL;
		this->Id = 0;
	}
	diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl");

	if (mem_to_free)
		diva_os_free(0, mem_to_free);

}

/*
 *  send message
 */
static u16 diva_send_message(struct capi_ctr *ctrl,
			     diva_os_message_buffer_s *dmb)
{
	int i = 0;
	word ret = 0;
	diva_os_spin_lock_magic_t old_irql;
	CAPI_MSG *msg = (CAPI_MSG *) DIVA_MESSAGE_BUFFER_DATA(dmb);
	APPL *this = &application[GET_WORD(&msg->header.appl_id) - 1];
	diva_card *card = ctrl->driverdata;
	__u32 length = DIVA_MESSAGE_BUFFER_LEN(dmb);
	word clength = GET_WORD(&msg->header.length);
	word command = GET_WORD(&msg->header.command);
	u16 retval = CAPI_NOERROR;

	if (diva_os_in_irq()) {
		DBG_ERR(("CAPI_SEND_MSG - in irq context !"))
			return CAPI_REGOSRESOURCEERR;
	}
	DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command))

		if (card->remove_in_progress) {
			DBG_ERR(("CAPI_SEND_MSG - remove in progress!"))
				return CAPI_REGOSRESOURCEERR;
		}

	diva_os_enter_spin_lock(&api_lock, &old_irql, "send message");

	if (!this->Id) {
		diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
		return CAPI_ILLAPPNR;
	}

	/* patch controller number */
	msg->header.controller = ControllerMap[card->Id]
		| (msg->header.controller & 0x80);	/* preserve external controller bit */

	switch (command) {
	default:
		xlog("\x00\x02", msg, 0x80, clength);
		break;

	case _DATA_B3_I | RESPONSE:
#ifndef DIVA_NO_DEBUGLIB
		if (myDriverDebugHandle.dbgMask & DL_BLK)
			xlog("\x00\x02", msg, 0x80, clength);
#endif
		break;

	case _DATA_B3_R:
#ifndef DIVA_NO_DEBUGLIB
		if (myDriverDebugHandle.dbgMask & DL_BLK)
			xlog("\x00\x02", msg, 0x80, clength);
#endif

		if (clength == 24)
			clength = 22;	/* workaround for PPcom bug */
		/* header is always 22      */
		if (GET_WORD(&msg->info.data_b3_req.Data_Length) >
		    this->MaxDataLength
		    || GET_WORD(&msg->info.data_b3_req.Data_Length) >
		    (length - clength)) {
			DBG_ERR(("Write - invalid message size"))
				retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
			goto write_end;
		}

		for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI)
			     && this->xbuffer_used[i]; i++);
		if (i == (MAX_DATA_B3 * this->MaxNCCI)) {
			DBG_ERR(("Write - too many data pending"))
				retval = CAPI_SENDQUEUEFULL;
			goto write_end;
		}
		msg->info.data_b3_req.Data = i;

		this->xbuffer_internal[i] = NULL;
		memcpy(this->xbuffer_ptr[i], &((__u8 *) msg)[clength],
		       GET_WORD(&msg->info.data_b3_req.Data_Length));

#ifndef DIVA_NO_DEBUGLIB
		if ((myDriverDebugHandle.dbgMask & DL_BLK)
		    && (myDriverDebugHandle.dbgMask & DL_XLOG)) {
			int j;
			for (j = 0; j <
				     GET_WORD(&msg->info.data_b3_req.Data_Length);
			     j += 256) {
				DBG_BLK((((char *) this->xbuffer_ptr[i]) + j,
					 ((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
					  256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256))
					if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
						break;	/* not more if not explicitly requested */
			}
		}
#endif
		break;
	}

	memcpy(mapped_msg, msg, (__u32) clength);
	mapped_msg->header.controller = MapController(mapped_msg->header.controller);
	mapped_msg->header.length = clength;
	mapped_msg->header.command = command;
	mapped_msg->header.number = GET_WORD(&msg->header.number);

	ret = api_put(this, mapped_msg);
	switch (ret) {
	case 0:
		break;
	case _BAD_MSG:
		DBG_ERR(("Write - bad message"))
			retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
		break;
	case _QUEUE_FULL:
		DBG_ERR(("Write - queue full"))
			retval = CAPI_SENDQUEUEFULL;
		break;
	default:
		DBG_ERR(("Write - api_put returned unknown error"))
			retval = CAPI_UNKNOWNNOTPAR;
		break;
	}

write_end:
	diva_os_leave_spin_lock(&api_lock, &old_irql, "send message");
	if (retval == CAPI_NOERROR)
		diva_os_free_message_buffer(dmb);
	return retval;
}


/*
 * cards request function
 */
static void DIRequest(ENTITY *e)
{
	DIVA_CAPI_ADAPTER *a = &(adapter[(byte) e->user[0]]);
	diva_card *os_card = (diva_card *) a->os_card;

	if (e->Req && (a->FlowControlIdTable[e->ReqCh] == e->Id)) {
		a->FlowControlSkipTable[e->ReqCh] = 1;
	}

	(*(os_card->d.request)) (e);
}

/*
 * callback function from didd
 */
static void didd_callback(void *context, DESCRIPTOR *adapter, int removal)
{
	if (adapter->type == IDI_DADAPTER) {
		DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
		return;
	} else if (adapter->type == IDI_DIMAINT) {
		if (removal) {
			stop_dbg();
		} else {
			memcpy(&MAdapter, adapter, sizeof(MAdapter));
			dprintf = (DIVA_DI_PRINTF) MAdapter.request;
			DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
		}
	} else if ((adapter->type > 0) && (adapter->type < 16)) {	/* IDI Adapter */
		if (removal) {
			divacapi_remove_card(adapter);
		} else {
			diva_add_card(adapter);
		}
	}
	return;
}

/*
 * connect to didd
 */
static int divacapi_connect_didd(void)
{
	int x = 0;
	int dadapter = 0;
	IDI_SYNC_REQ req;
	DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];

	DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));

	for (x = 0; x < MAX_DESCRIPTORS; x++) {
		if (DIDD_Table[x].type == IDI_DIMAINT) {	/* MAINT found */
			memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
			dprintf = (DIVA_DI_PRINTF) MAdapter.request;
			DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT);
			break;
		}
	}
	for (x = 0; x < MAX_DESCRIPTORS; x++) {
		if (DIDD_Table[x].type == IDI_DADAPTER) {	/* DADAPTER found */
			dadapter = 1;
			memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
			req.didd_notify.e.Req = 0;
			req.didd_notify.e.Rc =
				IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
			req.didd_notify.info.callback = (void *)didd_callback;
			req.didd_notify.info.context = NULL;
			DAdapter.request((ENTITY *)&req);
			if (req.didd_notify.e.Rc != 0xff) {
				stop_dbg();
				return (0);
			}
			notify_handle = req.didd_notify.info.handle;
		}
		else if ((DIDD_Table[x].type > 0) && (DIDD_Table[x].type < 16)) {	/* IDI Adapter found */
			diva_add_card(&DIDD_Table[x]);
		}
	}

	if (!dadapter) {
		stop_dbg();
	}

	return (dadapter);
}

/*
 * diconnect from didd
 */
static void divacapi_disconnect_didd(void)
{
	IDI_SYNC_REQ req;

	stop_dbg();

	req.didd_notify.e.Req = 0;
	req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
	req.didd_notify.info.handle = notify_handle;
	DAdapter.request((ENTITY *)&req);
}

/*
 * we do not provide date/time here,
 * the application should do this.
 */
int fax_head_line_time(char *buffer)
{
	return (0);
}

/*
 * init (alloc) main structures
 */
static int __init init_main_structs(void)
{
	if (!(mapped_msg = (CAPI_MSG *) diva_os_malloc(0, MAX_MSG_SIZE))) {
		DBG_ERR(("init: failed alloc mapped_msg."))
			return 0;
	}

	if (!(adapter = diva_os_malloc(0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS))) {
		DBG_ERR(("init: failed alloc adapter struct."))
			diva_os_free(0, mapped_msg);
		return 0;
	}
	memset(adapter, 0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS);

	if (!(application = diva_os_malloc(0, sizeof(APPL) * MAX_APPL))) {
		DBG_ERR(("init: failed alloc application struct."))
			diva_os_free(0, mapped_msg);
		diva_os_free(0, adapter);
		return 0;
	}
	memset(application, 0, sizeof(APPL) * MAX_APPL);

	return (1);
}

/*
 * remove (free) main structures
 */
static void remove_main_structs(void)
{
	if (application)
		diva_os_free(0, application);
	if (adapter)
		diva_os_free(0, adapter);
	if (mapped_msg)
		diva_os_free(0, mapped_msg);
}

/*
 * api_remove_start
 */
static void do_api_remove_start(void)
{
	diva_os_spin_lock_magic_t old_irql;
	int ret = 1, count = 100;

	do {
		diva_os_enter_spin_lock(&api_lock, &old_irql, "api remove start");
		ret = api_remove_start();
		diva_os_leave_spin_lock(&api_lock, &old_irql, "api remove start");

		diva_os_sleep(10);
	} while (ret && count--);

	if (ret)
		DBG_ERR(("could not remove signaling ID's"))
			}

/*
 * init
 */
int __init init_capifunc(void)
{
	diva_os_initialize_spin_lock(&api_lock, "capifunc");
	memset(ControllerMap, 0, MAX_DESCRIPTORS + 1);
	max_adapter = 0;


	if (!init_main_structs()) {
		DBG_ERR(("init: failed to init main structs."))
			diva_os_destroy_spin_lock(&api_lock, "capifunc");
		return (0);
	}

	if (!divacapi_connect_didd()) {
		DBG_ERR(("init: failed to connect to DIDD."))
			do_api_remove_start();
		divacapi_remove_cards();
		remove_main_structs();
		diva_os_destroy_spin_lock(&api_lock, "capifunc");
		return (0);
	}

	return (1);
}

/*
 * finit
 */
void __exit finit_capifunc(void)
{
	do_api_remove_start();
	divacapi_disconnect_didd();
	divacapi_remove_cards();
	remove_main_structs();
	diva_os_destroy_spin_lock(&api_lock, "capifunc");
}
