/*
 * Kernel CAPI interface for the Gigaset driver
 *
 * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
 *
 * =====================================================================
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation; either version 2 of
 *	the License, or (at your option) any later version.
 * =====================================================================
 */

#include "gigaset.h"
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/isdn/capilli.h>
#include <linux/isdn/capicmd.h>
#include <linux/isdn/capiutil.h>

/* missing from kernelcapi.h */
#define CapiNcpiNotSupportedByProtocol	0x0001
#define CapiFlagsNotSupportedByProtocol	0x0002
#define CapiAlertAlreadySent		0x0003
#define CapiFacilitySpecificFunctionNotSupported	0x3011

/* missing from capicmd.h */
#define CAPI_CONNECT_IND_BASELEN	(CAPI_MSG_BASELEN+4+2+8*1)
#define CAPI_CONNECT_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN+4+3*1)
#define CAPI_CONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN+4+1)
#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN	(CAPI_MSG_BASELEN+4+1)
#define CAPI_DATA_B3_REQ_LEN64		(CAPI_MSG_BASELEN+4+4+2+2+2+8)
#define CAPI_DATA_B3_CONF_LEN		(CAPI_MSG_BASELEN+4+2+2)
#define CAPI_DISCONNECT_IND_LEN		(CAPI_MSG_BASELEN+4+2)
#define CAPI_DISCONNECT_B3_IND_BASELEN	(CAPI_MSG_BASELEN+4+2+1)
#define CAPI_FACILITY_CONF_BASELEN	(CAPI_MSG_BASELEN+4+2+2+1)
/* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
#define CAPI_STDCONF_LEN		(CAPI_MSG_BASELEN+4+2)

#define CAPI_FACILITY_HANDSET	0x0000
#define CAPI_FACILITY_DTMF	0x0001
#define CAPI_FACILITY_V42BIS	0x0002
#define CAPI_FACILITY_SUPPSVC	0x0003
#define CAPI_FACILITY_WAKEUP	0x0004
#define CAPI_FACILITY_LI	0x0005

#define CAPI_SUPPSVC_GETSUPPORTED	0x0000

/* missing from capiutil.h */
#define CAPIMSG_PLCI_PART(m)	CAPIMSG_U8(m, 9)
#define CAPIMSG_NCCI_PART(m)	CAPIMSG_U16(m, 10)
#define CAPIMSG_HANDLE_REQ(m)	CAPIMSG_U16(m, 18) /* DATA_B3_REQ/_IND only! */
#define CAPIMSG_FLAGS(m)	CAPIMSG_U16(m, 20)
#define CAPIMSG_SETCONTROLLER(m, contr)	capimsg_setu8(m, 8, contr)
#define CAPIMSG_SETPLCI_PART(m, plci)	capimsg_setu8(m, 9, plci)
#define CAPIMSG_SETNCCI_PART(m, ncci)	capimsg_setu16(m, 10, ncci)
#define CAPIMSG_SETFLAGS(m, flags)	capimsg_setu16(m, 20, flags)

/* parameters with differing location in DATA_B3_CONF/_RESP: */
#define CAPIMSG_SETHANDLE_CONF(m, handle)	capimsg_setu16(m, 12, handle)
#define	CAPIMSG_SETINFO_CONF(m, info)		capimsg_setu16(m, 14, info)

/* Flags (DATA_B3_REQ/_IND) */
#define CAPI_FLAGS_DELIVERY_CONFIRMATION	0x04
#define CAPI_FLAGS_RESERVED			(~0x1f)

/* buffer sizes */
#define MAX_BC_OCTETS 11
#define MAX_HLC_OCTETS 3
#define MAX_NUMBER_DIGITS 20
#define MAX_FMT_IE_LEN 20

/* values for bcs->apconnstate */
#define APCONN_NONE	0	/* inactive/listening */
#define APCONN_SETUP	1	/* connecting */
#define APCONN_ACTIVE	2	/* B channel up */

/* registered application data structure */
struct gigaset_capi_appl {
	struct list_head ctrlist;
	struct gigaset_capi_appl *bcnext;
	u16 id;
	struct capi_register_params rp;
	u16 nextMessageNumber;
	u32 listenInfoMask;
	u32 listenCIPmask;
};

/* CAPI specific controller data structure */
struct gigaset_capi_ctr {
	struct capi_ctr ctr;
	struct list_head appls;
	struct sk_buff_head sendqueue;
	atomic_t sendqlen;
	/* two _cmsg structures possibly used concurrently: */
	_cmsg hcmsg;	/* for message composition triggered from hardware */
	_cmsg acmsg;	/* for dissection of messages sent from application */
	u8 bc_buf[MAX_BC_OCTETS+1];
	u8 hlc_buf[MAX_HLC_OCTETS+1];
	u8 cgpty_buf[MAX_NUMBER_DIGITS+3];
	u8 cdpty_buf[MAX_NUMBER_DIGITS+2];
};

/* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
static struct {
	u8 *bc;
	u8 *hlc;
} cip2bchlc[] = {
	[1] = { "8090A3", NULL },
		/* Speech (A-law) */
	[2] = { "8890", NULL },
		/* Unrestricted digital information */
	[3] = { "8990", NULL },
		/* Restricted digital information */
	[4] = { "9090A3", NULL },
		/* 3,1 kHz audio (A-law) */
	[5] = { "9190", NULL },
		/* 7 kHz audio */
	[6] = { "9890", NULL },
		/* Video */
	[7] = { "88C0C6E6", NULL },
		/* Packet mode */
	[8] = { "8890218F", NULL },
		/* 56 kbit/s rate adaptation */
	[9] = { "9190A5", NULL },
		/* Unrestricted digital information with tones/announcements */
	[16] = { "8090A3", "9181" },
		/* Telephony */
	[17] = { "9090A3", "9184" },
		/* Group 2/3 facsimile */
	[18] = { "8890", "91A1" },
		/* Group 4 facsimile Class 1 */
	[19] = { "8890", "91A4" },
		/* Teletex service basic and mixed mode
		   and Group 4 facsimile service Classes II and III */
	[20] = { "8890", "91A8" },
		/* Teletex service basic and processable mode */
	[21] = { "8890", "91B1" },
		/* Teletex service basic mode */
	[22] = { "8890", "91B2" },
		/* International interworking for Videotex */
	[23] = { "8890", "91B5" },
		/* Telex */
	[24] = { "8890", "91B8" },
		/* Message Handling Systems in accordance with X.400 */
	[25] = { "8890", "91C1" },
		/* OSI application in accordance with X.200 */
	[26] = { "9190A5", "9181" },
		/* 7 kHz telephony */
	[27] = { "9190A5", "916001" },
		/* Video telephony, first connection */
	[28] = { "8890", "916002" },
		/* Video telephony, second connection */
};

/*
 * helper functions
 * ================
 */

/*
 * emit unsupported parameter warning
 */
static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
				       char *msgname, char *paramname)
{
	if (param && *param)
		dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
			 msgname, paramname);
}

/*
 * convert an IE from Gigaset hex string to ETSI binary representation
 * including length byte
 * return value: result length, -1 on error
 */
static int encode_ie(char *in, u8 *out, int maxlen)
{
	int l = 0;
	while (*in) {
		if (!isxdigit(in[0]) || !isxdigit(in[1]) || l >= maxlen)
			return -1;
		out[++l] = (hex_to_bin(in[0]) << 4) + hex_to_bin(in[1]);
		in += 2;
	}
	out[0] = l;
	return l;
}

/*
 * convert an IE from ETSI binary representation including length byte
 * to Gigaset hex string
 */
static void decode_ie(u8 *in, char *out)
{
	int i = *in;
	while (i-- > 0) {
		/* ToDo: conversion to upper case necessary? */
		*out++ = toupper(hex_asc_hi(*++in));
		*out++ = toupper(hex_asc_lo(*in));
	}
}

/*
 * retrieve application data structure for an application ID
 */
static inline struct gigaset_capi_appl *
get_appl(struct gigaset_capi_ctr *iif, u16 appl)
{
	struct gigaset_capi_appl *ap;

	list_for_each_entry(ap, &iif->appls, ctrlist)
		if (ap->id == appl)
			return ap;
	return NULL;
}

/*
 * dump CAPI message to kernel messages for debugging
 */
static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
{
#ifdef CONFIG_GIGASET_DEBUG
	_cdebbuf *cdb;

	if (!(gigaset_debuglevel & level))
		return;

	cdb = capi_cmsg2str(p);
	if (cdb) {
		gig_dbg(level, "%s: [%d] %s", tag, p->ApplId, cdb->buf);
		cdebbuf_free(cdb);
	} else {
		gig_dbg(level, "%s: [%d] %s", tag, p->ApplId,
			capi_cmd2str(p->Command, p->Subcommand));
	}
#endif
}

static inline void dump_rawmsg(enum debuglevel level, const char *tag,
			       unsigned char *data)
{
#ifdef CONFIG_GIGASET_DEBUG
	char *dbgline;
	int i, l;

	if (!(gigaset_debuglevel & level))
		return;

	l = CAPIMSG_LEN(data);
	if (l < 12) {
		gig_dbg(level, "%s: ??? LEN=%04d", tag, l);
		return;
	}
	gig_dbg(level, "%s: 0x%02x:0x%02x: ID=%03d #0x%04x LEN=%04d NCCI=0x%x",
		tag, CAPIMSG_COMMAND(data), CAPIMSG_SUBCOMMAND(data),
		CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
		CAPIMSG_CONTROL(data));
	l -= 12;
	dbgline = kmalloc(3*l, GFP_ATOMIC);
	if (!dbgline)
		return;
	for (i = 0; i < l; i++) {
		dbgline[3*i] = hex_asc_hi(data[12+i]);
		dbgline[3*i+1] = hex_asc_lo(data[12+i]);
		dbgline[3*i+2] = ' ';
	}
	dbgline[3*l-1] = '\0';
	gig_dbg(level, "  %s", dbgline);
	kfree(dbgline);
	if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
	    (CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
	     CAPIMSG_SUBCOMMAND(data) == CAPI_IND) &&
	    CAPIMSG_DATALEN(data) > 0) {
		l = CAPIMSG_DATALEN(data);
		dbgline = kmalloc(3*l, GFP_ATOMIC);
		if (!dbgline)
			return;
		data += CAPIMSG_LEN(data);
		for (i = 0; i < l; i++) {
			dbgline[3*i] = hex_asc_hi(data[i]);
			dbgline[3*i+1] = hex_asc_lo(data[i]);
			dbgline[3*i+2] = ' ';
		}
		dbgline[3*l-1] = '\0';
		gig_dbg(level, "  %s", dbgline);
		kfree(dbgline);
	}
#endif
}

/*
 * format CAPI IE as string
 */

static const char *format_ie(const char *ie)
{
	static char result[3*MAX_FMT_IE_LEN];
	int len, count;
	char *pout = result;

	if (!ie)
		return "NULL";

	count = len = ie[0];
	if (count > MAX_FMT_IE_LEN)
		count = MAX_FMT_IE_LEN-1;
	while (count--) {
		*pout++ = hex_asc_hi(*++ie);
		*pout++ = hex_asc_lo(*ie);
		*pout++ = ' ';
	}
	if (len > MAX_FMT_IE_LEN) {
		*pout++ = '.';
		*pout++ = '.';
		*pout++ = '.';
	}
	*--pout = 0;
	return result;
}

/*
 * emit DATA_B3_CONF message
 */
static void send_data_b3_conf(struct cardstate *cs, struct capi_ctr *ctr,
			      u16 appl, u16 msgid, int channel,
			      u16 handle, u16 info)
{
	struct sk_buff *cskb;
	u8 *msg;

	cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
	if (!cskb) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	/* frequent message, avoid _cmsg overhead */
	msg = __skb_put(cskb, CAPI_DATA_B3_CONF_LEN);
	CAPIMSG_SETLEN(msg, CAPI_DATA_B3_CONF_LEN);
	CAPIMSG_SETAPPID(msg, appl);
	CAPIMSG_SETCOMMAND(msg, CAPI_DATA_B3);
	CAPIMSG_SETSUBCOMMAND(msg,  CAPI_CONF);
	CAPIMSG_SETMSGID(msg, msgid);
	CAPIMSG_SETCONTROLLER(msg, ctr->cnr);
	CAPIMSG_SETPLCI_PART(msg, channel);
	CAPIMSG_SETNCCI_PART(msg, 1);
	CAPIMSG_SETHANDLE_CONF(msg, handle);
	CAPIMSG_SETINFO_CONF(msg, info);

	/* emit message */
	dump_rawmsg(DEBUG_MCMD, __func__, msg);
	capi_ctr_handle_message(ctr, appl, cskb);
}


/*
 * driver interface functions
 * ==========================
 */

/**
 * gigaset_skb_sent() - acknowledge transmission of outgoing skb
 * @bcs:	B channel descriptor structure.
 * @skb:	sent data.
 *
 * Called by hardware module {bas,ser,usb}_gigaset when the data in a
 * skb has been successfully sent, for signalling completion to the LL.
 */
void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct gigaset_capi_appl *ap = bcs->ap;
	unsigned char *req = skb_mac_header(dskb);
	u16 flags;

	/* update statistics */
	++bcs->trans_up;

	if (!ap) {
		gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
		return;
	}

	/* don't send further B3 messages if disconnected */
	if (bcs->apconnstate < APCONN_ACTIVE) {
		gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
		return;
	}

	/*
	 * send DATA_B3_CONF if "delivery confirmation" bit was set in request;
	 * otherwise it has already been sent by do_data_b3_req()
	 */
	flags = CAPIMSG_FLAGS(req);
	if (flags & CAPI_FLAGS_DELIVERY_CONFIRMATION)
		send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req),
				  bcs->channel + 1, CAPIMSG_HANDLE_REQ(req),
				  (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
					CapiFlagsNotSupportedByProtocol :
					CAPI_NOERROR);
}
EXPORT_SYMBOL_GPL(gigaset_skb_sent);

/**
 * gigaset_skb_rcvd() - pass received skb to LL
 * @bcs:	B channel descriptor structure.
 * @skb:	received data.
 *
 * Called by hardware module {bas,ser,usb}_gigaset when user data has
 * been successfully received, for passing to the LL.
 * Warning: skb must not be accessed anymore!
 */
void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct gigaset_capi_appl *ap = bcs->ap;
	int len = skb->len;

	/* update statistics */
	bcs->trans_down++;

	if (!ap) {
		gig_dbg(DEBUG_MCMD, "%s: application gone", __func__);
		dev_kfree_skb_any(skb);
		return;
	}

	/* don't send further B3 messages if disconnected */
	if (bcs->apconnstate < APCONN_ACTIVE) {
		gig_dbg(DEBUG_MCMD, "%s: disconnected", __func__);
		dev_kfree_skb_any(skb);
		return;
	}

	/*
	 * prepend DATA_B3_IND message to payload
	 * Parameters: NCCI = 1, all others 0/unused
	 * frequent message, avoid _cmsg overhead
	 */
	skb_push(skb, CAPI_DATA_B3_REQ_LEN);
	CAPIMSG_SETLEN(skb->data, CAPI_DATA_B3_REQ_LEN);
	CAPIMSG_SETAPPID(skb->data, ap->id);
	CAPIMSG_SETCOMMAND(skb->data, CAPI_DATA_B3);
	CAPIMSG_SETSUBCOMMAND(skb->data,  CAPI_IND);
	CAPIMSG_SETMSGID(skb->data, ap->nextMessageNumber++);
	CAPIMSG_SETCONTROLLER(skb->data, iif->ctr.cnr);
	CAPIMSG_SETPLCI_PART(skb->data, bcs->channel + 1);
	CAPIMSG_SETNCCI_PART(skb->data, 1);
	/* Data parameter not used */
	CAPIMSG_SETDATALEN(skb->data, len);
	/* Data handle parameter not used */
	CAPIMSG_SETFLAGS(skb->data, 0);
	/* Data64 parameter not present */

	/* emit message */
	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_IND", skb->data);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}
EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);

/**
 * gigaset_isdn_rcv_err() - signal receive error
 * @bcs:	B channel descriptor structure.
 *
 * Called by hardware module {bas,ser,usb}_gigaset when a receive error
 * has occurred, for signalling to the LL.
 */
void gigaset_isdn_rcv_err(struct bc_state *bcs)
{
	/* if currently ignoring packets, just count down */
	if (bcs->ignore) {
		bcs->ignore--;
		return;
	}

	/* update statistics */
	bcs->corrupted++;

	/* ToDo: signal error -> LL */
}
EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);

/**
 * gigaset_isdn_icall() - signal incoming call
 * @at_state:	connection state structure.
 *
 * Called by main module at tasklet level to notify the LL that an incoming
 * call has been received. @at_state contains the parameters of the call.
 *
 * Return value: call disposition (ICALL_*)
 */
int gigaset_isdn_icall(struct at_state_t *at_state)
{
	struct cardstate *cs = at_state->cs;
	struct bc_state *bcs = at_state->bcs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct gigaset_capi_appl *ap;
	u32 actCIPmask;
	struct sk_buff *skb;
	unsigned int msgsize;
	unsigned long flags;
	int i;

	/*
	 * ToDo: signal calls without a free B channel, too
	 * (requires a u8 handle for the at_state structure that can
	 * be stored in the PLCI and used in the CONNECT_RESP message
	 * handler to retrieve it)
	 */
	if (!bcs)
		return ICALL_IGNORE;

	/* prepare CONNECT_IND message, using B channel number as PLCI */
	capi_cmsg_header(&iif->hcmsg, 0, CAPI_CONNECT, CAPI_IND, 0,
			 iif->ctr.cnr | ((bcs->channel + 1) << 8));

	/* minimum size, all structs empty */
	msgsize = CAPI_CONNECT_IND_BASELEN;

	/* Bearer Capability (mandatory) */
	if (at_state->str_var[STR_ZBC]) {
		/* pass on BC from Gigaset */
		if (encode_ie(at_state->str_var[STR_ZBC], iif->bc_buf,
			      MAX_BC_OCTETS) < 0) {
			dev_warn(cs->dev, "RING ignored - bad BC %s\n",
				 at_state->str_var[STR_ZBC]);
			return ICALL_IGNORE;
		}

		/* look up corresponding CIP value */
		iif->hcmsg.CIPValue = 0;	/* default if nothing found */
		for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
			if (cip2bchlc[i].bc != NULL &&
			    cip2bchlc[i].hlc == NULL &&
			    !strcmp(cip2bchlc[i].bc,
				    at_state->str_var[STR_ZBC])) {
				iif->hcmsg.CIPValue = i;
				break;
			}
	} else {
		/* no BC (internal call): assume CIP 1 (speech, A-law) */
		iif->hcmsg.CIPValue = 1;
		encode_ie(cip2bchlc[1].bc, iif->bc_buf, MAX_BC_OCTETS);
	}
	iif->hcmsg.BC = iif->bc_buf;
	msgsize += iif->hcmsg.BC[0];

	/* High Layer Compatibility (optional) */
	if (at_state->str_var[STR_ZHLC]) {
		/* pass on HLC from Gigaset */
		if (encode_ie(at_state->str_var[STR_ZHLC], iif->hlc_buf,
			      MAX_HLC_OCTETS) < 0) {
			dev_warn(cs->dev, "RING ignored - bad HLC %s\n",
				 at_state->str_var[STR_ZHLC]);
			return ICALL_IGNORE;
		}
		iif->hcmsg.HLC = iif->hlc_buf;
		msgsize += iif->hcmsg.HLC[0];

		/* look up corresponding CIP value */
		/* keep BC based CIP value if none found */
		if (at_state->str_var[STR_ZBC])
			for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
				if (cip2bchlc[i].hlc != NULL &&
				    !strcmp(cip2bchlc[i].hlc,
					    at_state->str_var[STR_ZHLC]) &&
				    !strcmp(cip2bchlc[i].bc,
					    at_state->str_var[STR_ZBC])) {
					iif->hcmsg.CIPValue = i;
					break;
				}
	}

	/* Called Party Number (optional) */
	if (at_state->str_var[STR_ZCPN]) {
		i = strlen(at_state->str_var[STR_ZCPN]);
		if (i > MAX_NUMBER_DIGITS) {
			dev_warn(cs->dev, "RING ignored - bad number %s\n",
				 at_state->str_var[STR_ZBC]);
			return ICALL_IGNORE;
		}
		iif->cdpty_buf[0] = i + 1;
		iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
		memcpy(iif->cdpty_buf+2, at_state->str_var[STR_ZCPN], i);
		iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
		msgsize += iif->hcmsg.CalledPartyNumber[0];
	}

	/* Calling Party Number (optional) */
	if (at_state->str_var[STR_NMBR]) {
		i = strlen(at_state->str_var[STR_NMBR]);
		if (i > MAX_NUMBER_DIGITS) {
			dev_warn(cs->dev, "RING ignored - bad number %s\n",
				 at_state->str_var[STR_ZBC]);
			return ICALL_IGNORE;
		}
		iif->cgpty_buf[0] = i + 2;
		iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
		iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
		memcpy(iif->cgpty_buf+3, at_state->str_var[STR_NMBR], i);
		iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
		msgsize += iif->hcmsg.CallingPartyNumber[0];
	}

	/* remaining parameters (not supported, always left NULL):
	 * - CalledPartySubaddress
	 * - CallingPartySubaddress
	 * - AdditionalInfo
	 *   - BChannelinformation
	 *   - Keypadfacility
	 *   - Useruserdata
	 *   - Facilitydataarray
	 */

	gig_dbg(DEBUG_CMD, "icall: PLCI %x CIP %d BC %s",
		iif->hcmsg.adr.adrPLCI, iif->hcmsg.CIPValue,
		format_ie(iif->hcmsg.BC));
	gig_dbg(DEBUG_CMD, "icall: HLC %s",
		format_ie(iif->hcmsg.HLC));
	gig_dbg(DEBUG_CMD, "icall: CgPty %s",
		format_ie(iif->hcmsg.CallingPartyNumber));
	gig_dbg(DEBUG_CMD, "icall: CdPty %s",
		format_ie(iif->hcmsg.CalledPartyNumber));

	/* scan application list for matching listeners */
	spin_lock_irqsave(&bcs->aplock, flags);
	if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE) {
		dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n",
			 __func__, bcs->ap, bcs->apconnstate);
		bcs->ap = NULL;
		bcs->apconnstate = APCONN_NONE;
	}
	spin_unlock_irqrestore(&bcs->aplock, flags);
	actCIPmask = 1 | (1 << iif->hcmsg.CIPValue);
	list_for_each_entry(ap, &iif->appls, ctrlist)
		if (actCIPmask & ap->listenCIPmask) {
			/* build CONNECT_IND message for this application */
			iif->hcmsg.ApplId = ap->id;
			iif->hcmsg.Messagenumber = ap->nextMessageNumber++;

			skb = alloc_skb(msgsize, GFP_ATOMIC);
			if (!skb) {
				dev_err(cs->dev, "%s: out of memory\n",
					__func__);
				break;
			}
			capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
			dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);

			/* add to listeners on this B channel, update state */
			spin_lock_irqsave(&bcs->aplock, flags);
			ap->bcnext = bcs->ap;
			bcs->ap = ap;
			bcs->chstate |= CHS_NOTIFY_LL;
			bcs->apconnstate = APCONN_SETUP;
			spin_unlock_irqrestore(&bcs->aplock, flags);

			/* emit message */
			capi_ctr_handle_message(&iif->ctr, ap->id, skb);
		}

	/*
	 * Return "accept" if any listeners.
	 * Gigaset will send ALERTING.
	 * There doesn't seem to be a way to avoid this.
	 */
	return bcs->ap ? ICALL_ACCEPT : ICALL_IGNORE;
}

/*
 * send a DISCONNECT_IND message to an application
 * does not sleep, clobbers the controller's hcmsg structure
 */
static void send_disconnect_ind(struct bc_state *bcs,
				struct gigaset_capi_appl *ap, u16 reason)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct sk_buff *skb;

	if (bcs->apconnstate == APCONN_NONE)
		return;

	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND,
			 ap->nextMessageNumber++,
			 iif->ctr.cnr | ((bcs->channel + 1) << 8));
	iif->hcmsg.Reason = reason;
	skb = alloc_skb(CAPI_DISCONNECT_IND_LEN, GFP_ATOMIC);
	if (!skb) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN));
	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}

/*
 * send a DISCONNECT_B3_IND message to an application
 * Parameters: NCCI = 1, NCPI empty, Reason_B3 = 0
 * does not sleep, clobbers the controller's hcmsg structure
 */
static void send_disconnect_b3_ind(struct bc_state *bcs,
				   struct gigaset_capi_appl *ap)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct sk_buff *skb;

	/* nothing to do if no logical connection active */
	if (bcs->apconnstate < APCONN_ACTIVE)
		return;
	bcs->apconnstate = APCONN_SETUP;

	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
			 ap->nextMessageNumber++,
			 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
	skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_ATOMIC);
	if (!skb) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	capi_cmsg2message(&iif->hcmsg,
			  __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN));
	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}

/**
 * gigaset_isdn_connD() - signal D channel connect
 * @bcs:	B channel descriptor structure.
 *
 * Called by main module at tasklet level to notify the LL that the D channel
 * connection has been established.
 */
void gigaset_isdn_connD(struct bc_state *bcs)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct gigaset_capi_appl *ap;
	struct sk_buff *skb;
	unsigned int msgsize;
	unsigned long flags;

	spin_lock_irqsave(&bcs->aplock, flags);
	ap = bcs->ap;
	if (!ap) {
		spin_unlock_irqrestore(&bcs->aplock, flags);
		gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
		return;
	}
	if (bcs->apconnstate == APCONN_NONE) {
		spin_unlock_irqrestore(&bcs->aplock, flags);
		dev_warn(cs->dev, "%s: application %u not connected\n",
			 __func__, ap->id);
		return;
	}
	spin_unlock_irqrestore(&bcs->aplock, flags);
	while (ap->bcnext) {
		/* this should never happen */
		dev_warn(cs->dev, "%s: dropping extra application %u\n",
			 __func__, ap->bcnext->id);
		send_disconnect_ind(bcs, ap->bcnext,
				    CapiCallGivenToOtherApplication);
		ap->bcnext = ap->bcnext->bcnext;
	}

	/* prepare CONNECT_ACTIVE_IND message
	 * Note: LLC not supported by device
	 */
	capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_CONNECT_ACTIVE, CAPI_IND,
			 ap->nextMessageNumber++,
			 iif->ctr.cnr | ((bcs->channel + 1) << 8));

	/* minimum size, all structs empty */
	msgsize = CAPI_CONNECT_ACTIVE_IND_BASELEN;

	/* ToDo: set parameter: Connected number
	 * (requires ev-layer state machine extension to collect
	 * ZCON device reply)
	 */

	/* build and emit CONNECT_ACTIVE_IND message */
	skb = alloc_skb(msgsize, GFP_ATOMIC);
	if (!skb) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}

/**
 * gigaset_isdn_hupD() - signal D channel hangup
 * @bcs:	B channel descriptor structure.
 *
 * Called by main module at tasklet level to notify the LL that the D channel
 * connection has been shut down.
 */
void gigaset_isdn_hupD(struct bc_state *bcs)
{
	struct gigaset_capi_appl *ap;
	unsigned long flags;

	/*
	 * ToDo: pass on reason code reported by device
	 * (requires ev-layer state machine extension to collect
	 * ZCAU device reply)
	 */
	spin_lock_irqsave(&bcs->aplock, flags);
	while (bcs->ap != NULL) {
		ap = bcs->ap;
		bcs->ap = ap->bcnext;
		spin_unlock_irqrestore(&bcs->aplock, flags);
		send_disconnect_b3_ind(bcs, ap);
		send_disconnect_ind(bcs, ap, 0);
		spin_lock_irqsave(&bcs->aplock, flags);
	}
	bcs->apconnstate = APCONN_NONE;
	spin_unlock_irqrestore(&bcs->aplock, flags);
}

/**
 * gigaset_isdn_connB() - signal B channel connect
 * @bcs:	B channel descriptor structure.
 *
 * Called by main module at tasklet level to notify the LL that the B channel
 * connection has been established.
 */
void gigaset_isdn_connB(struct bc_state *bcs)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_ctr *iif = cs->iif;
	struct gigaset_capi_appl *ap;
	struct sk_buff *skb;
	unsigned long flags;
	unsigned int msgsize;
	u8 command;

	spin_lock_irqsave(&bcs->aplock, flags);
	ap = bcs->ap;
	if (!ap) {
		spin_unlock_irqrestore(&bcs->aplock, flags);
		gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
		return;
	}
	if (!bcs->apconnstate) {
		spin_unlock_irqrestore(&bcs->aplock, flags);
		dev_warn(cs->dev, "%s: application %u not connected\n",
			 __func__, ap->id);
		return;
	}

	/*
	 * emit CONNECT_B3_ACTIVE_IND if we already got CONNECT_B3_REQ;
	 * otherwise we have to emit CONNECT_B3_IND first, and follow up with
	 * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP
	 * Parameters in both cases always: NCCI = 1, NCPI empty
	 */
	if (bcs->apconnstate >= APCONN_ACTIVE) {
		command = CAPI_CONNECT_B3_ACTIVE;
		msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
	} else {
		command = CAPI_CONNECT_B3;
		msgsize = CAPI_CONNECT_B3_IND_BASELEN;
	}
	bcs->apconnstate = APCONN_ACTIVE;

	spin_unlock_irqrestore(&bcs->aplock, flags);

	while (ap->bcnext) {
		/* this should never happen */
		dev_warn(cs->dev, "%s: dropping extra application %u\n",
			 __func__, ap->bcnext->id);
		send_disconnect_ind(bcs, ap->bcnext,
				    CapiCallGivenToOtherApplication);
		ap->bcnext = ap->bcnext->bcnext;
	}

	capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND,
			 ap->nextMessageNumber++,
			 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
	skb = alloc_skb(msgsize, GFP_ATOMIC);
	if (!skb) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
	dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}

/**
 * gigaset_isdn_hupB() - signal B channel hangup
 * @bcs:	B channel descriptor structure.
 *
 * Called by main module to notify the LL that the B channel connection has
 * been shut down.
 */
void gigaset_isdn_hupB(struct bc_state *bcs)
{
	struct gigaset_capi_appl *ap = bcs->ap;

	/* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */

	if (!ap) {
		gig_dbg(DEBUG_CMD, "%s: application gone", __func__);
		return;
	}

	send_disconnect_b3_ind(bcs, ap);
}

/**
 * gigaset_isdn_start() - signal device availability
 * @cs:		device descriptor structure.
 *
 * Called by main module to notify the LL that the device is available for
 * use.
 */
void gigaset_isdn_start(struct cardstate *cs)
{
	struct gigaset_capi_ctr *iif = cs->iif;

	/* fill profile data: manufacturer name */
	strcpy(iif->ctr.manu, "Siemens");
	/* CAPI and device version */
	iif->ctr.version.majorversion = 2;		/* CAPI 2.0 */
	iif->ctr.version.minorversion = 0;
	/* ToDo: check/assert cs->gotfwver? */
	iif->ctr.version.majormanuversion = cs->fwver[0];
	iif->ctr.version.minormanuversion = cs->fwver[1];
	/* number of B channels supported */
	iif->ctr.profile.nbchannel = cs->channels;
	/* global options: internal controller, supplementary services */
	iif->ctr.profile.goptions = 0x11;
	/* B1 protocols: 64 kbit/s HDLC or transparent */
	iif->ctr.profile.support1 =  0x03;
	/* B2 protocols: transparent only */
	/* ToDo: X.75 SLP ? */
	iif->ctr.profile.support2 =  0x02;
	/* B3 protocols: transparent only */
	iif->ctr.profile.support3 =  0x01;
	/* no serial number */
	strcpy(iif->ctr.serial, "0");
	capi_ctr_ready(&iif->ctr);
}

/**
 * gigaset_isdn_stop() - signal device unavailability
 * @cs:		device descriptor structure.
 *
 * Called by main module to notify the LL that the device is no longer
 * available for use.
 */
void gigaset_isdn_stop(struct cardstate *cs)
{
	struct gigaset_capi_ctr *iif = cs->iif;
	capi_ctr_down(&iif->ctr);
}

/*
 * kernel CAPI callback methods
 * ============================
 */

/*
 * register CAPI application
 */
static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
			   capi_register_params *rp)
{
	struct gigaset_capi_ctr *iif
		= container_of(ctr, struct gigaset_capi_ctr, ctr);
	struct cardstate *cs = ctr->driverdata;
	struct gigaset_capi_appl *ap;

	list_for_each_entry(ap, &iif->appls, ctrlist)
		if (ap->id == appl) {
			dev_notice(cs->dev,
				   "application %u already registered\n", appl);
			return;
		}

	ap = kzalloc(sizeof(*ap), GFP_KERNEL);
	if (!ap) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	ap->id = appl;
	ap->rp = *rp;

	list_add(&ap->ctrlist, &iif->appls);
	dev_info(cs->dev, "application %u registered\n", ap->id);
}

/*
 * remove CAPI application from channel
 * helper function to keep indentation levels down and stay in 80 columns
 */

static inline void remove_appl_from_channel(struct bc_state *bcs,
					    struct gigaset_capi_appl *ap)
{
	struct cardstate *cs = bcs->cs;
	struct gigaset_capi_appl *bcap;
	unsigned long flags;
	int prevconnstate;

	spin_lock_irqsave(&bcs->aplock, flags);
	bcap = bcs->ap;
	if (bcap == NULL) {
		spin_unlock_irqrestore(&bcs->aplock, flags);
		return;
	}

	/* check first application on channel */
	if (bcap == ap) {
		bcs->ap = ap->bcnext;
		if (bcs->ap != NULL) {
			spin_unlock_irqrestore(&bcs->aplock, flags);
			return;
		}

		/* none left, clear channel state */
		prevconnstate = bcs->apconnstate;
		bcs->apconnstate = APCONN_NONE;
		spin_unlock_irqrestore(&bcs->aplock, flags);

		if (prevconnstate == APCONN_ACTIVE) {
			dev_notice(cs->dev, "%s: hanging up channel %u\n",
				   __func__, bcs->channel);
			gigaset_add_event(cs, &bcs->at_state,
					  EV_HUP, NULL, 0, NULL);
			gigaset_schedule_event(cs);
		}
		return;
	}

	/* check remaining list */
	do {
		if (bcap->bcnext == ap) {
			bcap->bcnext = bcap->bcnext->bcnext;
			spin_unlock_irqrestore(&bcs->aplock, flags);
			return;
		}
		bcap = bcap->bcnext;
	} while (bcap != NULL);
	spin_unlock_irqrestore(&bcs->aplock, flags);
}

/*
 * release CAPI application
 */
static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
{
	struct gigaset_capi_ctr *iif
		= container_of(ctr, struct gigaset_capi_ctr, ctr);
	struct cardstate *cs = iif->ctr.driverdata;
	struct gigaset_capi_appl *ap, *tmp;
	unsigned ch;

	list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
		if (ap->id == appl) {
			/* remove from any channels */
			for (ch = 0; ch < cs->channels; ch++)
				remove_appl_from_channel(&cs->bcs[ch], ap);

			/* remove from registration list */
			list_del(&ap->ctrlist);
			kfree(ap);
			dev_info(cs->dev, "application %u released\n", appl);
		}
}

/*
 * =====================================================================
 * outgoing CAPI message handler
 * =====================================================================
 */

/*
 * helper function: emit reply message with given Info value
 */
static void send_conf(struct gigaset_capi_ctr *iif,
		      struct gigaset_capi_appl *ap,
		      struct sk_buff *skb,
		      u16 info)
{
	/*
	 * _CONF replies always only have NCCI and Info parameters
	 * so they'll fit into the _REQ message skb
	 */
	capi_cmsg_answer(&iif->acmsg);
	iif->acmsg.Info = info;
	capi_cmsg2message(&iif->acmsg, skb->data);
	__skb_trim(skb, CAPI_STDCONF_LEN);
	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}

/*
 * process FACILITY_REQ message
 */
static void do_facility_req(struct gigaset_capi_ctr *iif,
			    struct gigaset_capi_appl *ap,
			    struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct sk_buff *cskb;
	u8 *pparam;
	unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN;
	u16 function, info;
	static u8 confparam[10];	/* max. 9 octets + length byte */

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);

	/*
	 * Facility Request Parameter is not decoded by capi_message2cmsg()
	 * encoding depends on Facility Selector
	 */
	switch (cmsg->FacilitySelector) {
	case CAPI_FACILITY_DTMF:	/* ToDo */
		info = CapiFacilityNotSupported;
		confparam[0] = 2;	/* length */
		/* DTMF information: Unknown DTMF request */
		capimsg_setu16(confparam, 1, 2);
		break;

	case CAPI_FACILITY_V42BIS:	/* not supported */
		info = CapiFacilityNotSupported;
		confparam[0] = 2;	/* length */
		/* V.42 bis information: not available */
		capimsg_setu16(confparam, 1, 1);
		break;

	case CAPI_FACILITY_SUPPSVC:
		/* decode Function parameter */
		pparam = cmsg->FacilityRequestParameter;
		if (pparam == NULL || *pparam < 2) {
			dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
				   "Facility Request Parameter");
			send_conf(iif, ap, skb, CapiIllMessageParmCoding);
			return;
		}
		function = CAPIMSG_U16(pparam, 1);
		switch (function) {
		case CAPI_SUPPSVC_GETSUPPORTED:
			info = CapiSuccess;
			/* Supplementary Service specific parameter */
			confparam[3] = 6;	/* length */
			/* Supplementary services info: Success */
			capimsg_setu16(confparam, 4, CapiSuccess);
			/* Supported Services: none */
			capimsg_setu32(confparam, 6, 0);
			break;
		/* ToDo: add supported services */
		default:
			info = CapiFacilitySpecificFunctionNotSupported;
			/* Supplementary Service specific parameter */
			confparam[3] = 2;	/* length */
			/* Supplementary services info: not supported */
			capimsg_setu16(confparam, 4,
				       CapiSupplementaryServiceNotSupported);
		}

		/* Facility confirmation parameter */
		confparam[0] = confparam[3] + 3;	/* total length */
		/* Function: copy from _REQ message */
		capimsg_setu16(confparam, 1, function);
		/* Supplementary Service specific parameter already set above */
		break;

	case CAPI_FACILITY_WAKEUP:	/* ToDo */
		info = CapiFacilityNotSupported;
		confparam[0] = 2;	/* length */
		/* Number of accepted awake request parameters: 0 */
		capimsg_setu16(confparam, 1, 0);
		break;

	default:
		info = CapiFacilityNotSupported;
		confparam[0] = 0;	/* empty struct */
	}

	/* send FACILITY_CONF with given Info and confirmation parameter */
	capi_cmsg_answer(cmsg);
	cmsg->Info = info;
	cmsg->FacilityConfirmationParameter = confparam;
	msgsize += confparam[0];	/* length */
	cskb = alloc_skb(msgsize, GFP_ATOMIC);
	if (!cskb) {
		dev_err(cs->dev, "%s: out of memory\n", __func__);
		return;
	}
	capi_cmsg2message(cmsg, __skb_put(cskb, msgsize));
	dump_cmsg(DEBUG_CMD, __func__, cmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
}


/*
 * process LISTEN_REQ message
 * just store the masks in the application data structure
 */
static void do_listen_req(struct gigaset_capi_ctr *iif,
			  struct gigaset_capi_appl *ap,
			  struct sk_buff *skb)
{
	/* decode message */
	capi_message2cmsg(&iif->acmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);

	/* store listening parameters */
	ap->listenInfoMask = iif->acmsg.InfoMask;
	ap->listenCIPmask = iif->acmsg.CIPmask;
	send_conf(iif, ap, skb, CapiSuccess);
}

/*
 * process ALERT_REQ message
 * nothing to do, Gigaset always alerts anyway
 */
static void do_alert_req(struct gigaset_capi_ctr *iif,
			 struct gigaset_capi_appl *ap,
			 struct sk_buff *skb)
{
	/* decode message */
	capi_message2cmsg(&iif->acmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
	send_conf(iif, ap, skb, CapiAlertAlreadySent);
}

/*
 * process CONNECT_REQ message
 * allocate a B channel, prepare dial commands, queue a DIAL event,
 * emit CONNECT_CONF reply
 */
static void do_connect_req(struct gigaset_capi_ctr *iif,
			   struct gigaset_capi_appl *ap,
			   struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct bc_state *bcs;
	char **commands;
	char *s;
	u8 *pp;
	unsigned long flags;
	int i, l, lbc, lhlc;
	u16 info;

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);

	/* get free B channel & construct PLCI */
	bcs = gigaset_get_free_channel(cs);
	if (!bcs) {
		dev_notice(cs->dev, "%s: no B channel available\n",
			   "CONNECT_REQ");
		send_conf(iif, ap, skb, CapiNoPlciAvailable);
		return;
	}
	spin_lock_irqsave(&bcs->aplock, flags);
	if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE)
		dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n",
			 __func__, bcs->ap, bcs->apconnstate);
	ap->bcnext = NULL;
	bcs->ap = ap;
	bcs->apconnstate = APCONN_SETUP;
	spin_unlock_irqrestore(&bcs->aplock, flags);

	bcs->rx_bufsize = ap->rp.datablklen;
	dev_kfree_skb(bcs->rx_skb);
	gigaset_new_rx_skb(bcs);
	cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;

	/* build command table */
	commands = kzalloc(AT_NUM*(sizeof *commands), GFP_KERNEL);
	if (!commands)
		goto oom;

	/* encode parameter: Called party number */
	pp = cmsg->CalledPartyNumber;
	if (pp == NULL || *pp == 0) {
		dev_notice(cs->dev, "%s: %s missing\n",
			   "CONNECT_REQ", "Called party number");
		info = CapiIllMessageParmCoding;
		goto error;
	}
	l = *pp++;
	/* check type of number/numbering plan byte */
	switch (*pp) {
	case 0x80:	/* unknown type / unknown numbering plan */
	case 0x81:	/* unknown type / ISDN/Telephony numbering plan */
		break;
	default:	/* others: warn about potential misinterpretation */
		dev_notice(cs->dev, "%s: %s type/plan 0x%02x unsupported\n",
			   "CONNECT_REQ", "Called party number", *pp);
	}
	pp++;
	l--;
	/* translate "**" internal call prefix to CTP value */
	if (l >= 2 && pp[0] == '*' && pp[1] == '*') {
		s = "^SCTP=0\r";
		pp += 2;
		l -= 2;
	} else {
		s = "^SCTP=1\r";
	}
	commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
	if (!commands[AT_TYPE])
		goto oom;
	commands[AT_DIAL] = kmalloc(l+3, GFP_KERNEL);
	if (!commands[AT_DIAL])
		goto oom;
	snprintf(commands[AT_DIAL], l+3, "D%.*s\r", l, pp);

	/* encode parameter: Calling party number */
	pp = cmsg->CallingPartyNumber;
	if (pp != NULL && *pp > 0) {
		l = *pp++;

		/* check type of number/numbering plan byte */
		/* ToDo: allow for/handle Ext=1? */
		switch (*pp) {
		case 0x00:	/* unknown type / unknown numbering plan */
		case 0x01:	/* unknown type / ISDN/Telephony num. plan */
			break;
		default:
			dev_notice(cs->dev,
				   "%s: %s type/plan 0x%02x unsupported\n",
				   "CONNECT_REQ", "Calling party number", *pp);
		}
		pp++;
		l--;

		/* check presentation indicator */
		if (!l) {
			dev_notice(cs->dev, "%s: %s IE truncated\n",
				   "CONNECT_REQ", "Calling party number");
			info = CapiIllMessageParmCoding;
			goto error;
		}
		switch (*pp & 0xfc) { /* ignore Screening indicator */
		case 0x80:	/* Presentation allowed */
			s = "^SCLIP=1\r";
			break;
		case 0xa0:	/* Presentation restricted */
			s = "^SCLIP=0\r";
			break;
		default:
			dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
				   "CONNECT_REQ",
				   "Presentation/Screening indicator",
				   *pp);
			s = "^SCLIP=1\r";
		}
		commands[AT_CLIP] = kstrdup(s, GFP_KERNEL);
		if (!commands[AT_CLIP])
			goto oom;
		pp++;
		l--;

		if (l) {
			/* number */
			commands[AT_MSN] = kmalloc(l+8, GFP_KERNEL);
			if (!commands[AT_MSN])
				goto oom;
			snprintf(commands[AT_MSN], l+8, "^SMSN=%*s\r", l, pp);
		}
	}

	/* check parameter: CIP Value */
	if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
	    (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
		dev_notice(cs->dev, "%s: unknown CIP value %d\n",
			   "CONNECT_REQ", cmsg->CIPValue);
		info = CapiCipValueUnknown;
		goto error;
	}

	/*
	 * check/encode parameters: BC & HLC
	 * must be encoded together as device doesn't accept HLC separately
	 * explicit parameters override values derived from CIP
	 */

	/* determine lengths */
	if (cmsg->BC && cmsg->BC[0])		/* BC specified explicitly */
		lbc = 2*cmsg->BC[0];
	else if (cip2bchlc[cmsg->CIPValue].bc)	/* BC derived from CIP */
		lbc = strlen(cip2bchlc[cmsg->CIPValue].bc);
	else					/* no BC */
		lbc = 0;
	if (cmsg->HLC && cmsg->HLC[0])		/* HLC specified explicitly */
		lhlc = 2*cmsg->HLC[0];
	else if (cip2bchlc[cmsg->CIPValue].hlc)	/* HLC derived from CIP */
		lhlc = strlen(cip2bchlc[cmsg->CIPValue].hlc);
	else					/* no HLC */
		lhlc = 0;

	if (lbc) {
		/* have BC: allocate and assemble command string */
		l = lbc + 7;		/* "^SBC=" + value + "\r" + null byte */
		if (lhlc)
			l += lhlc + 7;	/* ";^SHLC=" + value */
		commands[AT_BC] = kmalloc(l, GFP_KERNEL);
		if (!commands[AT_BC])
			goto oom;
		strcpy(commands[AT_BC], "^SBC=");
		if (cmsg->BC && cmsg->BC[0])	/* BC specified explicitly */
			decode_ie(cmsg->BC, commands[AT_BC] + 5);
		else				/* BC derived from CIP */
			strcpy(commands[AT_BC] + 5,
			       cip2bchlc[cmsg->CIPValue].bc);
		if (lhlc) {
			strcpy(commands[AT_BC] + lbc + 5, ";^SHLC=");
			if (cmsg->HLC && cmsg->HLC[0])
				/* HLC specified explicitly */
				decode_ie(cmsg->HLC,
					  commands[AT_BC] + lbc + 12);
			else	/* HLC derived from CIP */
				strcpy(commands[AT_BC] + lbc + 12,
				       cip2bchlc[cmsg->CIPValue].hlc);
		}
		strcpy(commands[AT_BC] + l - 2, "\r");
	} else {
		/* no BC */
		if (lhlc) {
			dev_notice(cs->dev, "%s: cannot set HLC without BC\n",
				   "CONNECT_REQ");
			info = CapiIllMessageParmCoding; /* ? */
			goto error;
		}
	}

	/* check/encode parameter: B Protocol */
	if (cmsg->BProtocol == CAPI_DEFAULT) {
		bcs->proto2 = L2_HDLC;
		dev_warn(cs->dev,
		    "B2 Protocol X.75 SLP unsupported, using Transparent\n");
	} else {
		switch (cmsg->B1protocol) {
		case 0:
			bcs->proto2 = L2_HDLC;
			break;
		case 1:
			bcs->proto2 = L2_VOICE;
			break;
		default:
			dev_warn(cs->dev,
			    "B1 Protocol %u unsupported, using Transparent\n",
				 cmsg->B1protocol);
			bcs->proto2 = L2_VOICE;
		}
		if (cmsg->B2protocol != 1)
			dev_warn(cs->dev,
			    "B2 Protocol %u unsupported, using Transparent\n",
				 cmsg->B2protocol);
		if (cmsg->B3protocol != 0)
			dev_warn(cs->dev,
			    "B3 Protocol %u unsupported, using Transparent\n",
				 cmsg->B3protocol);
		ignore_cstruct_param(cs, cmsg->B1configuration,
					"CONNECT_REQ", "B1 Configuration");
		ignore_cstruct_param(cs, cmsg->B2configuration,
					"CONNECT_REQ", "B2 Configuration");
		ignore_cstruct_param(cs, cmsg->B3configuration,
					"CONNECT_REQ", "B3 Configuration");
	}
	commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
	if (!commands[AT_PROTO])
		goto oom;
	snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);

	/* ToDo: check/encode remaining parameters */
	ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
					"CONNECT_REQ", "Called pty subaddr");
	ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
					"CONNECT_REQ", "Calling pty subaddr");
	ignore_cstruct_param(cs, cmsg->LLC,
					"CONNECT_REQ", "LLC");
	if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
		ignore_cstruct_param(cs, cmsg->BChannelinformation,
					"CONNECT_REQ", "B Channel Information");
		ignore_cstruct_param(cs, cmsg->Keypadfacility,
					"CONNECT_REQ", "Keypad Facility");
		ignore_cstruct_param(cs, cmsg->Useruserdata,
					"CONNECT_REQ", "User-User Data");
		ignore_cstruct_param(cs, cmsg->Facilitydataarray,
					"CONNECT_REQ", "Facility Data Array");
	}

	/* encode parameter: B channel to use */
	commands[AT_ISO] = kmalloc(9, GFP_KERNEL);
	if (!commands[AT_ISO])
		goto oom;
	snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
		 (unsigned) bcs->channel + 1);

	/* queue & schedule EV_DIAL event */
	if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
			       bcs->at_state.seq_index, NULL)) {
		info = CAPI_MSGOSRESOURCEERR;
		goto error;
	}
	gigaset_schedule_event(cs);
	send_conf(iif, ap, skb, CapiSuccess);
	return;

oom:
	dev_err(cs->dev, "%s: out of memory\n", __func__);
	info = CAPI_MSGOSRESOURCEERR;
error:
	if (commands)
		for (i = 0; i < AT_NUM; i++)
			kfree(commands[i]);
	kfree(commands);
	gigaset_free_channel(bcs);
	send_conf(iif, ap, skb, info);
}

/*
 * process CONNECT_RESP message
 * checks protocol parameters and queues an ACCEPT or HUP event
 */
static void do_connect_resp(struct gigaset_capi_ctr *iif,
			    struct gigaset_capi_appl *ap,
			    struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct bc_state *bcs;
	struct gigaset_capi_appl *oap;
	unsigned long flags;
	int channel;

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);
	dev_kfree_skb_any(skb);

	/* extract and check channel number from PLCI */
	channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
	if (!channel || channel > cs->channels) {
		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
			   "CONNECT_RESP", "PLCI", cmsg->adr.adrPLCI);
		return;
	}
	bcs = cs->bcs + channel - 1;

	switch (cmsg->Reject) {
	case 0:		/* Accept */
		/* drop all competing applications, keep only this one */
		spin_lock_irqsave(&bcs->aplock, flags);
		while (bcs->ap != NULL) {
			oap = bcs->ap;
			bcs->ap = oap->bcnext;
			if (oap != ap) {
				spin_unlock_irqrestore(&bcs->aplock, flags);
				send_disconnect_ind(bcs, oap,
					CapiCallGivenToOtherApplication);
				spin_lock_irqsave(&bcs->aplock, flags);
			}
		}
		ap->bcnext = NULL;
		bcs->ap = ap;
		spin_unlock_irqrestore(&bcs->aplock, flags);

		bcs->rx_bufsize = ap->rp.datablklen;
		dev_kfree_skb(bcs->rx_skb);
		gigaset_new_rx_skb(bcs);
		bcs->chstate |= CHS_NOTIFY_LL;

		/* check/encode B channel protocol */
		if (cmsg->BProtocol == CAPI_DEFAULT) {
			bcs->proto2 = L2_HDLC;
			dev_warn(cs->dev,
		"B2 Protocol X.75 SLP unsupported, using Transparent\n");
		} else {
			switch (cmsg->B1protocol) {
			case 0:
				bcs->proto2 = L2_HDLC;
				break;
			case 1:
				bcs->proto2 = L2_VOICE;
				break;
			default:
				dev_warn(cs->dev,
			"B1 Protocol %u unsupported, using Transparent\n",
					 cmsg->B1protocol);
				bcs->proto2 = L2_VOICE;
			}
			if (cmsg->B2protocol != 1)
				dev_warn(cs->dev,
			"B2 Protocol %u unsupported, using Transparent\n",
					 cmsg->B2protocol);
			if (cmsg->B3protocol != 0)
				dev_warn(cs->dev,
			"B3 Protocol %u unsupported, using Transparent\n",
					 cmsg->B3protocol);
			ignore_cstruct_param(cs, cmsg->B1configuration,
					"CONNECT_RESP", "B1 Configuration");
			ignore_cstruct_param(cs, cmsg->B2configuration,
					"CONNECT_RESP", "B2 Configuration");
			ignore_cstruct_param(cs, cmsg->B3configuration,
					"CONNECT_RESP", "B3 Configuration");
		}

		/* ToDo: check/encode remaining parameters */
		ignore_cstruct_param(cs, cmsg->ConnectedNumber,
					"CONNECT_RESP", "Connected Number");
		ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
					"CONNECT_RESP", "Connected Subaddress");
		ignore_cstruct_param(cs, cmsg->LLC,
					"CONNECT_RESP", "LLC");
		if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
			ignore_cstruct_param(cs, cmsg->BChannelinformation,
					"CONNECT_RESP", "BChannel Information");
			ignore_cstruct_param(cs, cmsg->Keypadfacility,
					"CONNECT_RESP", "Keypad Facility");
			ignore_cstruct_param(cs, cmsg->Useruserdata,
					"CONNECT_RESP", "User-User Data");
			ignore_cstruct_param(cs, cmsg->Facilitydataarray,
					"CONNECT_RESP", "Facility Data Array");
		}

		/* Accept call */
		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
				       EV_ACCEPT, NULL, 0, NULL))
			return;
		gigaset_schedule_event(cs);
		return;

	case 1:			/* Ignore */
		/* send DISCONNECT_IND to this application */
		send_disconnect_ind(bcs, ap, 0);

		/* remove it from the list of listening apps */
		spin_lock_irqsave(&bcs->aplock, flags);
		if (bcs->ap == ap) {
			bcs->ap = ap->bcnext;
			if (bcs->ap == NULL) {
				/* last one: stop ev-layer hupD notifications */
				bcs->apconnstate = APCONN_NONE;
				bcs->chstate &= ~CHS_NOTIFY_LL;
			}
			spin_unlock_irqrestore(&bcs->aplock, flags);
			return;
		}
		for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) {
			if (oap->bcnext == ap) {
				oap->bcnext = oap->bcnext->bcnext;
				spin_unlock_irqrestore(&bcs->aplock, flags);
				return;
			}
		}
		spin_unlock_irqrestore(&bcs->aplock, flags);
		dev_err(cs->dev, "%s: application %u not found\n",
			__func__, ap->id);
		return;

	default:		/* Reject */
		/* drop all competing applications, keep only this one */
		spin_lock_irqsave(&bcs->aplock, flags);
		while (bcs->ap != NULL) {
			oap = bcs->ap;
			bcs->ap = oap->bcnext;
			if (oap != ap) {
				spin_unlock_irqrestore(&bcs->aplock, flags);
				send_disconnect_ind(bcs, oap,
					CapiCallGivenToOtherApplication);
				spin_lock_irqsave(&bcs->aplock, flags);
			}
		}
		ap->bcnext = NULL;
		bcs->ap = ap;
		spin_unlock_irqrestore(&bcs->aplock, flags);

		/* reject call - will trigger DISCONNECT_IND for this app */
		dev_info(cs->dev, "%s: Reject=%x\n",
			 "CONNECT_RESP", cmsg->Reject);
		if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
				       EV_HUP, NULL, 0, NULL))
			return;
		gigaset_schedule_event(cs);
		return;
	}
}

/*
 * process CONNECT_B3_REQ message
 * build NCCI and emit CONNECT_B3_CONF reply
 */
static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
			      struct gigaset_capi_appl *ap,
			      struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct bc_state *bcs;
	int channel;

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);

	/* extract and check channel number from PLCI */
	channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
	if (!channel || channel > cs->channels) {
		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
			   "CONNECT_B3_REQ", "PLCI", cmsg->adr.adrPLCI);
		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
		return;
	}
	bcs = &cs->bcs[channel-1];

	/* mark logical connection active */
	bcs->apconnstate = APCONN_ACTIVE;

	/* build NCCI: always 1 (one B3 connection only) */
	cmsg->adr.adrNCCI |= 1 << 16;

	/* NCPI parameter: not applicable for B3 Transparent */
	ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
	send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
				CapiNcpiNotSupportedByProtocol : CapiSuccess);
}

/*
 * process CONNECT_B3_RESP message
 * Depending on the Reject parameter, either emit CONNECT_B3_ACTIVE_IND
 * or queue EV_HUP and emit DISCONNECT_B3_IND.
 * The emitted message is always shorter than the received one,
 * allowing to reuse the skb.
 */
static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
			       struct gigaset_capi_appl *ap,
			       struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct bc_state *bcs;
	int channel;
	unsigned int msgsize;
	u8 command;

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);

	/* extract and check channel number and NCCI */
	channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
	if (!channel || channel > cs->channels ||
	    ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
			   "CONNECT_B3_RESP", "NCCI", cmsg->adr.adrNCCI);
		dev_kfree_skb_any(skb);
		return;
	}
	bcs = &cs->bcs[channel-1];

	if (cmsg->Reject) {
		/* Reject: clear B3 connect received flag */
		bcs->apconnstate = APCONN_SETUP;

		/* trigger hangup, causing eventual DISCONNECT_IND */
		if (!gigaset_add_event(cs, &bcs->at_state,
				       EV_HUP, NULL, 0, NULL)) {
			dev_kfree_skb_any(skb);
			return;
		}
		gigaset_schedule_event(cs);

		/* emit DISCONNECT_B3_IND */
		command = CAPI_DISCONNECT_B3;
		msgsize = CAPI_DISCONNECT_B3_IND_BASELEN;
	} else {
		/*
		 * Accept: emit CONNECT_B3_ACTIVE_IND immediately, as
		 * we only send CONNECT_B3_IND if the B channel is up
		 */
		command = CAPI_CONNECT_B3_ACTIVE;
		msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
	}
	capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
			 ap->nextMessageNumber++, cmsg->adr.adrNCCI);
	__skb_trim(skb, msgsize);
	capi_cmsg2message(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);
	capi_ctr_handle_message(&iif->ctr, ap->id, skb);
}

/*
 * process DISCONNECT_REQ message
 * schedule EV_HUP and emit DISCONNECT_B3_IND if necessary,
 * emit DISCONNECT_CONF reply
 */
static void do_disconnect_req(struct gigaset_capi_ctr *iif,
			      struct gigaset_capi_appl *ap,
			      struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct bc_state *bcs;
	_cmsg *b3cmsg;
	struct sk_buff *b3skb;
	int channel;

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);

	/* extract and check channel number from PLCI */
	channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
	if (!channel || channel > cs->channels) {
		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
			   "DISCONNECT_REQ", "PLCI", cmsg->adr.adrPLCI);
		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
		return;
	}
	bcs = cs->bcs + channel - 1;

	/* ToDo: process parameter: Additional info */
	if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
		ignore_cstruct_param(cs, cmsg->BChannelinformation,
				     "DISCONNECT_REQ", "B Channel Information");
		ignore_cstruct_param(cs, cmsg->Keypadfacility,
				     "DISCONNECT_REQ", "Keypad Facility");
		ignore_cstruct_param(cs, cmsg->Useruserdata,
				     "DISCONNECT_REQ", "User-User Data");
		ignore_cstruct_param(cs, cmsg->Facilitydataarray,
				     "DISCONNECT_REQ", "Facility Data Array");
	}

	/* skip if DISCONNECT_IND already sent */
	if (!bcs->apconnstate)
		return;

	/* check for active logical connection */
	if (bcs->apconnstate >= APCONN_ACTIVE) {
		/*
		 * emit DISCONNECT_B3_IND with cause 0x3301
		 * use separate cmsg structure, as the content of iif->acmsg
		 * is still needed for creating the _CONF message
		 */
		b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL);
		if (!b3cmsg) {
			dev_err(cs->dev, "%s: out of memory\n", __func__);
			send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
			return;
		}
		capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
				 ap->nextMessageNumber++,
				 cmsg->adr.adrPLCI | (1 << 16));
		b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
		b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
		if (b3skb == NULL) {
			dev_err(cs->dev, "%s: out of memory\n", __func__);
			send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
			return;
		}
		capi_cmsg2message(b3cmsg,
			__skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
		kfree(b3cmsg);
		capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
	}

	/* trigger hangup, causing eventual DISCONNECT_IND */
	if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
		return;
	}
	gigaset_schedule_event(cs);

	/* emit reply */
	send_conf(iif, ap, skb, CapiSuccess);
}

/*
 * process DISCONNECT_B3_REQ message
 * schedule EV_HUP and emit DISCONNECT_B3_CONF reply
 */
static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
				 struct gigaset_capi_appl *ap,
				 struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	_cmsg *cmsg = &iif->acmsg;
	struct bc_state *bcs;
	int channel;

	/* decode message */
	capi_message2cmsg(cmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, cmsg);

	/* extract and check channel number and NCCI */
	channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
	if (!channel || channel > cs->channels ||
	    ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
			   "DISCONNECT_B3_REQ", "NCCI", cmsg->adr.adrNCCI);
		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
		return;
	}
	bcs = &cs->bcs[channel-1];

	/* reject if logical connection not active */
	if (bcs->apconnstate < APCONN_ACTIVE) {
		send_conf(iif, ap, skb,
			  CapiMessageNotSupportedInCurrentState);
		return;
	}

	/* trigger hangup, causing eventual DISCONNECT_B3_IND */
	if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
		return;
	}
	gigaset_schedule_event(cs);

	/* NCPI parameter: not applicable for B3 Transparent */
	ignore_cstruct_param(cs, cmsg->NCPI,
				"DISCONNECT_B3_REQ", "NCPI");
	send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
				CapiNcpiNotSupportedByProtocol : CapiSuccess);
}

/*
 * process DATA_B3_REQ message
 */
static void do_data_b3_req(struct gigaset_capi_ctr *iif,
			   struct gigaset_capi_appl *ap,
			   struct sk_buff *skb)
{
	struct cardstate *cs = iif->ctr.driverdata;
	struct bc_state *bcs;
	int channel = CAPIMSG_PLCI_PART(skb->data);
	u16 ncci = CAPIMSG_NCCI_PART(skb->data);
	u16 msglen = CAPIMSG_LEN(skb->data);
	u16 datalen = CAPIMSG_DATALEN(skb->data);
	u16 flags = CAPIMSG_FLAGS(skb->data);
	u16 msgid = CAPIMSG_MSGID(skb->data);
	u16 handle = CAPIMSG_HANDLE_REQ(skb->data);

	/* frequent message, avoid _cmsg overhead */
	dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);

	gig_dbg(DEBUG_LLDATA,
		"Receiving data from LL (ch: %d, flg: %x, sz: %d|%d)",
		channel, flags, msglen, datalen);

	/* check parameters */
	if (channel == 0 || channel > cs->channels || ncci != 1) {
		dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
			   "DATA_B3_REQ", "NCCI", CAPIMSG_NCCI(skb->data));
		send_conf(iif, ap, skb, CapiIllContrPlciNcci);
		return;
	}
	bcs = &cs->bcs[channel-1];
	if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
		dev_notice(cs->dev, "%s: unexpected length %d\n",
			   "DATA_B3_REQ", msglen);
	if (msglen + datalen != skb->len)
		dev_notice(cs->dev, "%s: length mismatch (%d+%d!=%d)\n",
			   "DATA_B3_REQ", msglen, datalen, skb->len);
	if (msglen + datalen > skb->len) {
		/* message too short for announced data length */
		send_conf(iif, ap, skb, CapiIllMessageParmCoding); /* ? */
		return;
	}
	if (flags & CAPI_FLAGS_RESERVED) {
		dev_notice(cs->dev, "%s: reserved flags set (%x)\n",
			   "DATA_B3_REQ", flags);
		send_conf(iif, ap, skb, CapiIllMessageParmCoding);
		return;
	}

	/* reject if logical connection not active */
	if (bcs->apconnstate < APCONN_ACTIVE) {
		send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
		return;
	}

	/* pull CAPI message into link layer header */
	skb_reset_mac_header(skb);
	skb->mac_len = msglen;
	skb_pull(skb, msglen);

	/* pass to device-specific module */
	if (cs->ops->send_skb(bcs, skb) < 0) {
		send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
		return;
	}

	/*
	 * DATA_B3_CONF will be sent by gigaset_skb_sent() only if "delivery
	 * confirmation" bit is set; otherwise we have to send it now
	 */
	if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION))
		send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle,
				  flags ? CapiFlagsNotSupportedByProtocol
					: CAPI_NOERROR);
}

/*
 * process RESET_B3_REQ message
 * just always reply "not supported by current protocol"
 */
static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
			    struct gigaset_capi_appl *ap,
			    struct sk_buff *skb)
{
	/* decode message */
	capi_message2cmsg(&iif->acmsg, skb->data);
	dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
	send_conf(iif, ap, skb,
		  CapiResetProcedureNotSupportedByCurrentProtocol);
}

/*
 * dump unsupported/ignored messages at most twice per minute,
 * some apps send those very frequently
 */
static unsigned long ignored_msg_dump_time;

/*
 * unsupported CAPI message handler
 */
static void do_unsupported(struct gigaset_capi_ctr *iif,
			   struct gigaset_capi_appl *ap,
			   struct sk_buff *skb)
{
	/* decode message */
	capi_message2cmsg(&iif->acmsg, skb->data);
	if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000))
		dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
	send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
}

/*
 * CAPI message handler: no-op
 */
static void do_nothing(struct gigaset_capi_ctr *iif,
		       struct gigaset_capi_appl *ap,
		       struct sk_buff *skb)
{
	if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) {
		/* decode message */
		capi_message2cmsg(&iif->acmsg, skb->data);
		dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
	}
	dev_kfree_skb_any(skb);
}

static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
			    struct gigaset_capi_appl *ap,
			    struct sk_buff *skb)
{
	dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
	dev_kfree_skb_any(skb);
}

/* table of outgoing CAPI message handlers with lookup function */
typedef void (*capi_send_handler_t)(struct gigaset_capi_ctr *,
				    struct gigaset_capi_appl *,
				    struct sk_buff *);

static struct {
	u16 cmd;
	capi_send_handler_t handler;
} capi_send_handler_table[] = {
	/* most frequent messages first for faster lookup */
	{ CAPI_DATA_B3_REQ, do_data_b3_req },
	{ CAPI_DATA_B3_RESP, do_data_b3_resp },

	{ CAPI_ALERT_REQ, do_alert_req },
	{ CAPI_CONNECT_ACTIVE_RESP, do_nothing },
	{ CAPI_CONNECT_B3_ACTIVE_RESP, do_nothing },
	{ CAPI_CONNECT_B3_REQ, do_connect_b3_req },
	{ CAPI_CONNECT_B3_RESP, do_connect_b3_resp },
	{ CAPI_CONNECT_B3_T90_ACTIVE_RESP, do_nothing },
	{ CAPI_CONNECT_REQ, do_connect_req },
	{ CAPI_CONNECT_RESP, do_connect_resp },
	{ CAPI_DISCONNECT_B3_REQ, do_disconnect_b3_req },
	{ CAPI_DISCONNECT_B3_RESP, do_nothing },
	{ CAPI_DISCONNECT_REQ, do_disconnect_req },
	{ CAPI_DISCONNECT_RESP, do_nothing },
	{ CAPI_FACILITY_REQ, do_facility_req },
	{ CAPI_FACILITY_RESP, do_nothing },
	{ CAPI_LISTEN_REQ, do_listen_req },
	{ CAPI_SELECT_B_PROTOCOL_REQ, do_unsupported },
	{ CAPI_RESET_B3_REQ, do_reset_b3_req },
	{ CAPI_RESET_B3_RESP, do_nothing },

	/*
	 * ToDo: support overlap sending (requires ev-layer state
	 * machine extension to generate additional ATD commands)
	 */
	{ CAPI_INFO_REQ, do_unsupported },
	{ CAPI_INFO_RESP, do_nothing },

	/*
	 * ToDo: what's the proper response for these?
	 */
	{ CAPI_MANUFACTURER_REQ, do_nothing },
	{ CAPI_MANUFACTURER_RESP, do_nothing },
};

/* look up handler */
static inline capi_send_handler_t lookup_capi_send_handler(const u16 cmd)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(capi_send_handler_table); i++)
		if (capi_send_handler_table[i].cmd == cmd)
			return capi_send_handler_table[i].handler;
	return NULL;
}


/**
 * gigaset_send_message() - accept a CAPI message from an application
 * @ctr:	controller descriptor structure.
 * @skb:	CAPI message.
 *
 * Return value: CAPI error code
 * Note: capidrv (and probably others, too) only uses the return value to
 * decide whether it has to free the skb (only if result != CAPI_NOERROR (0))
 */
static u16 gigaset_send_message(struct capi_ctr *ctr, struct sk_buff *skb)
{
	struct gigaset_capi_ctr *iif
		= container_of(ctr, struct gigaset_capi_ctr, ctr);
	struct cardstate *cs = ctr->driverdata;
	struct gigaset_capi_appl *ap;
	capi_send_handler_t handler;

	/* can only handle linear sk_buffs */
	if (skb_linearize(skb) < 0) {
		dev_warn(cs->dev, "%s: skb_linearize failed\n", __func__);
		return CAPI_MSGOSRESOURCEERR;
	}

	/* retrieve application data structure */
	ap = get_appl(iif, CAPIMSG_APPID(skb->data));
	if (!ap) {
		dev_notice(cs->dev, "%s: application %u not registered\n",
			   __func__, CAPIMSG_APPID(skb->data));
		return CAPI_ILLAPPNR;
	}

	/* look up command */
	handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
	if (!handler) {
		/* unknown/unsupported message type */
		if (printk_ratelimit())
			dev_notice(cs->dev, "%s: unsupported message %u\n",
				   __func__, CAPIMSG_CMD(skb->data));
		return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
	}

	/* serialize */
	if (atomic_add_return(1, &iif->sendqlen) > 1) {
		/* queue behind other messages */
		skb_queue_tail(&iif->sendqueue, skb);
		return CAPI_NOERROR;
	}

	/* process message */
	handler(iif, ap, skb);

	/* process other messages arrived in the meantime */
	while (atomic_sub_return(1, &iif->sendqlen) > 0) {
		skb = skb_dequeue(&iif->sendqueue);
		if (!skb) {
			/* should never happen */
			dev_err(cs->dev, "%s: send queue empty\n", __func__);
			continue;
		}
		ap = get_appl(iif, CAPIMSG_APPID(skb->data));
		if (!ap) {
			/* could that happen? */
			dev_warn(cs->dev, "%s: application %u vanished\n",
				 __func__, CAPIMSG_APPID(skb->data));
			continue;
		}
		handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
		if (!handler) {
			/* should never happen */
			dev_err(cs->dev, "%s: handler %x vanished\n",
				__func__, CAPIMSG_CMD(skb->data));
			continue;
		}
		handler(iif, ap, skb);
	}

	return CAPI_NOERROR;
}

/**
 * gigaset_procinfo() - build single line description for controller
 * @ctr:	controller descriptor structure.
 *
 * Return value: pointer to generated string (null terminated)
 */
static char *gigaset_procinfo(struct capi_ctr *ctr)
{
	return ctr->name;	/* ToDo: more? */
}

static int gigaset_proc_show(struct seq_file *m, void *v)
{
	struct capi_ctr *ctr = m->private;
	struct cardstate *cs = ctr->driverdata;
	char *s;
	int i;

	seq_printf(m, "%-16s %s\n", "name", ctr->name);
	seq_printf(m, "%-16s %s %s\n", "dev",
			dev_driver_string(cs->dev), dev_name(cs->dev));
	seq_printf(m, "%-16s %d\n", "id", cs->myid);
	if (cs->gotfwver)
		seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
			cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
	seq_printf(m, "%-16s %d\n", "channels", cs->channels);
	seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");

	switch (cs->mode) {
	case M_UNKNOWN:
		s = "unknown";
		break;
	case M_CONFIG:
		s = "config";
		break;
	case M_UNIMODEM:
		s = "Unimodem";
		break;
	case M_CID:
		s = "CID";
		break;
	default:
		s = "??";
	}
	seq_printf(m, "%-16s %s\n", "mode", s);

	switch (cs->mstate) {
	case MS_UNINITIALIZED:
		s = "uninitialized";
		break;
	case MS_INIT:
		s = "init";
		break;
	case MS_LOCKED:
		s = "locked";
		break;
	case MS_SHUTDOWN:
		s = "shutdown";
		break;
	case MS_RECOVER:
		s = "recover";
		break;
	case MS_READY:
		s = "ready";
		break;
	default:
		s = "??";
	}
	seq_printf(m, "%-16s %s\n", "mstate", s);

	seq_printf(m, "%-16s %s\n", "running", cs->running ? "yes" : "no");
	seq_printf(m, "%-16s %s\n", "connected", cs->connected ? "yes" : "no");
	seq_printf(m, "%-16s %s\n", "isdn_up", cs->isdn_up ? "yes" : "no");
	seq_printf(m, "%-16s %s\n", "cidmode", cs->cidmode ? "yes" : "no");

	for (i = 0; i < cs->channels; i++) {
		seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
				cs->bcs[i].corrupted);
		seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
				cs->bcs[i].trans_down);
		seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
				cs->bcs[i].trans_up);
		seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
				cs->bcs[i].chstate);
		switch (cs->bcs[i].proto2) {
		case L2_BITSYNC:
			s = "bitsync";
			break;
		case L2_HDLC:
			s = "HDLC";
			break;
		case L2_VOICE:
			s = "voice";
			break;
		default:
			s = "??";
		}
		seq_printf(m, "[%d]%-13s %s\n", i, "proto2", s);
	}
	return 0;
}

static int gigaset_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, gigaset_proc_show, PDE(inode)->data);
}

static const struct file_operations gigaset_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= gigaset_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

/**
 * gigaset_isdn_regdev() - register device to LL
 * @cs:		device descriptor structure.
 * @isdnid:	device name.
 *
 * Return value: 1 for success, 0 for failure
 */
int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
{
	struct gigaset_capi_ctr *iif;
	int rc;

	iif = kmalloc(sizeof(*iif), GFP_KERNEL);
	if (!iif) {
		pr_err("%s: out of memory\n", __func__);
		return 0;
	}

	/* prepare controller structure */
	iif->ctr.owner         = THIS_MODULE;
	iif->ctr.driverdata    = cs;
	strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
	iif->ctr.driver_name   = "gigaset";
	iif->ctr.load_firmware = NULL;
	iif->ctr.reset_ctr     = NULL;
	iif->ctr.register_appl = gigaset_register_appl;
	iif->ctr.release_appl  = gigaset_release_appl;
	iif->ctr.send_message  = gigaset_send_message;
	iif->ctr.procinfo      = gigaset_procinfo;
	iif->ctr.proc_fops = &gigaset_proc_fops;
	INIT_LIST_HEAD(&iif->appls);
	skb_queue_head_init(&iif->sendqueue);
	atomic_set(&iif->sendqlen, 0);

	/* register controller with CAPI */
	rc = attach_capi_ctr(&iif->ctr);
	if (rc) {
		pr_err("attach_capi_ctr failed (%d)\n", rc);
		kfree(iif);
		return 0;
	}

	cs->iif = iif;
	cs->hw_hdr_len = CAPI_DATA_B3_REQ_LEN;
	return 1;
}

/**
 * gigaset_isdn_unregdev() - unregister device from LL
 * @cs:		device descriptor structure.
 */
void gigaset_isdn_unregdev(struct cardstate *cs)
{
	struct gigaset_capi_ctr *iif = cs->iif;

	detach_capi_ctr(&iif->ctr);
	kfree(iif);
	cs->iif = NULL;
}

static struct capi_driver capi_driver_gigaset = {
	.name		= "gigaset",
	.revision	= "1.0",
};

/**
 * gigaset_isdn_regdrv() - register driver to LL
 */
void gigaset_isdn_regdrv(void)
{
	pr_info("Kernel CAPI interface\n");
	register_capi_driver(&capi_driver_gigaset);
}

/**
 * gigaset_isdn_unregdrv() - unregister driver from LL
 */
void gigaset_isdn_unregdrv(void)
{
	unregister_capi_driver(&capi_driver_gigaset);
}
