/* $Id: isdnloop.c,v 1.11.6.7 2001/11/11 19:54:31 kai Exp $
 *
 * ISDN low-level module implementing a dummy loop driver.
 *
 * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de)
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/sched.h>
#include "isdnloop.h"

static char *isdnloop_id = "loop0";

MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card");
MODULE_AUTHOR("Fritz Elfert");
MODULE_LICENSE("GPL");
module_param(isdnloop_id, charp, 0);
MODULE_PARM_DESC(isdnloop_id, "ID-String of first card");

static int isdnloop_addcard(char *);

/*
 * Free queue completely.
 *
 * Parameter:
 *   card    = pointer to card struct
 *   channel = channel number
 */
static void
isdnloop_free_queue(isdnloop_card *card, int channel)
{
	struct sk_buff_head *queue = &card->bqueue[channel];

	skb_queue_purge(queue);
	card->sndcount[channel] = 0;
}

/*
 * Send B-Channel data to another virtual card.
 * This routine is called via timer-callback from isdnloop_pollbchan().
 *
 * Parameter:
 *   card = pointer to card struct.
 *   ch   = channel number (0-based)
 */
static void
isdnloop_bchan_send(isdnloop_card *card, int ch)
{
	isdnloop_card *rcard = card->rcard[ch];
	int rch = card->rch[ch], len, ack;
	struct sk_buff *skb;
	isdn_ctrl cmd;

	while (card->sndcount[ch]) {
		skb = skb_dequeue(&card->bqueue[ch]);
		if (skb) {
			len = skb->len;
			card->sndcount[ch] -= len;
			ack = *(skb->head); /* used as scratch area */
			cmd.driver = card->myid;
			cmd.arg = ch;
			if (rcard) {
				rcard->interface.rcvcallb_skb(rcard->myid, rch, skb);
			} else {
				printk(KERN_WARNING "isdnloop: no rcard, skb dropped\n");
				dev_kfree_skb(skb);

			};
			cmd.command = ISDN_STAT_BSENT;
			cmd.parm.length = len;
			card->interface.statcallb(&cmd);
		} else
			card->sndcount[ch] = 0;
	}
}

/*
 * Send/Receive Data to/from the B-Channel.
 * This routine is called via timer-callback.
 * It schedules itself while any B-Channel is open.
 *
 * Parameter:
 *   data = pointer to card struct, set by kernel timer.data
 */
static void
isdnloop_pollbchan(unsigned long data)
{
	isdnloop_card *card = (isdnloop_card *) data;
	unsigned long flags;

	if (card->flags & ISDNLOOP_FLAGS_B1ACTIVE)
		isdnloop_bchan_send(card, 0);
	if (card->flags & ISDNLOOP_FLAGS_B2ACTIVE)
		isdnloop_bchan_send(card, 1);
	if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE)) {
		/* schedule b-channel polling again */
		spin_lock_irqsave(&card->isdnloop_lock, flags);
		card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD;
		add_timer(&card->rb_timer);
		card->flags |= ISDNLOOP_FLAGS_RBTIMER;
		spin_unlock_irqrestore(&card->isdnloop_lock, flags);
	} else
		card->flags &= ~ISDNLOOP_FLAGS_RBTIMER;
}

/*
 * Parse ICN-type setup string and fill fields of setup-struct
 * with parsed data.
 *
 * Parameter:
 *   setup = setup string, format: [caller-id],si1,si2,[called-id]
 *   cmd   = pointer to struct to be filled.
 */
static void
isdnloop_parse_setup(char *setup, isdn_ctrl *cmd)
{
	char *t = setup;
	char *s = strchr(t, ',');

	*s++ = '\0';
	strlcpy(cmd->parm.setup.phone, t, sizeof(cmd->parm.setup.phone));
	s = strchr(t = s, ',');
	*s++ = '\0';
	if (!strlen(t))
		cmd->parm.setup.si1 = 0;
	else
		cmd->parm.setup.si1 = simple_strtoul(t, NULL, 10);
	s = strchr(t = s, ',');
	*s++ = '\0';
	if (!strlen(t))
		cmd->parm.setup.si2 = 0;
	else
		cmd->parm.setup.si2 =
			simple_strtoul(t, NULL, 10);
	strlcpy(cmd->parm.setup.eazmsn, s, sizeof(cmd->parm.setup.eazmsn));
	cmd->parm.setup.plan = 0;
	cmd->parm.setup.screen = 0;
}

typedef struct isdnloop_stat {
	char *statstr;
	int command;
	int action;
} isdnloop_stat;
/* *INDENT-OFF* */
static isdnloop_stat isdnloop_stat_table[] = {
	{"BCON_",          ISDN_STAT_BCONN, 1}, /* B-Channel connected        */
	{"BDIS_",          ISDN_STAT_BHUP,  2}, /* B-Channel disconnected     */
	{"DCON_",          ISDN_STAT_DCONN, 0}, /* D-Channel connected        */
	{"DDIS_",          ISDN_STAT_DHUP,  0}, /* D-Channel disconnected     */
	{"DCAL_I",         ISDN_STAT_ICALL, 3}, /* Incoming call dialup-line  */
	{"DSCA_I",         ISDN_STAT_ICALL, 3}, /* Incoming call 1TR6-SPV     */
	{"FCALL",          ISDN_STAT_ICALL, 4}, /* Leased line connection up  */
	{"CIF",            ISDN_STAT_CINF,  5}, /* Charge-info, 1TR6-type     */
	{"AOC",            ISDN_STAT_CINF,  6}, /* Charge-info, DSS1-type     */
	{"CAU",            ISDN_STAT_CAUSE, 7}, /* Cause code                 */
	{"TEI OK",         ISDN_STAT_RUN,   0}, /* Card connected to wallplug */
	{"E_L1: ACT FAIL", ISDN_STAT_BHUP,  8}, /* Layer-1 activation failed  */
	{"E_L2: DATA LIN", ISDN_STAT_BHUP,  8}, /* Layer-2 data link lost     */
	{"E_L1: ACTIVATION FAILED",
	 ISDN_STAT_BHUP,  8},         /* Layer-1 activation failed  */
	{NULL, 0, -1}
};
/* *INDENT-ON* */


/*
 * Parse Status message-strings from virtual card.
 * Depending on status, call statcallb for sending messages to upper
 * levels. Also set/reset B-Channel active-flags.
 *
 * Parameter:
 *   status  = status string to parse.
 *   channel = channel where message comes from.
 *   card    = card where message comes from.
 */
static void
isdnloop_parse_status(u_char *status, int channel, isdnloop_card *card)
{
	isdnloop_stat *s = isdnloop_stat_table;
	int action = -1;
	isdn_ctrl cmd;

	while (s->statstr) {
		if (!strncmp(status, s->statstr, strlen(s->statstr))) {
			cmd.command = s->command;
			action = s->action;
			break;
		}
		s++;
	}
	if (action == -1)
		return;
	cmd.driver = card->myid;
	cmd.arg = channel;
	switch (action) {
	case 1:
		/* BCON_x */
		card->flags |= (channel) ?
			ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE;
		break;
	case 2:
		/* BDIS_x */
		card->flags &= ~((channel) ?
				 ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE);
		isdnloop_free_queue(card, channel);
		break;
	case 3:
		/* DCAL_I and DSCA_I */
		isdnloop_parse_setup(status + 6, &cmd);
		break;
	case 4:
		/* FCALL */
		sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
		sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
		cmd.parm.setup.si1 = 7;
		cmd.parm.setup.si2 = 0;
		cmd.parm.setup.plan = 0;
		cmd.parm.setup.screen = 0;
		break;
	case 5:
		/* CIF */
		strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
		break;
	case 6:
		/* AOC */
		snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
			 (int) simple_strtoul(status + 7, NULL, 16));
		break;
	case 7:
		/* CAU */
		status += 3;
		if (strlen(status) == 4)
			snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
				 status + 2, *status, *(status + 1));
		else
			strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
		break;
	case 8:
		/* Misc Errors on L1 and L2 */
		card->flags &= ~ISDNLOOP_FLAGS_B1ACTIVE;
		isdnloop_free_queue(card, 0);
		cmd.arg = 0;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
		cmd.command = ISDN_STAT_DHUP;
		cmd.arg = 0;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
		cmd.command = ISDN_STAT_BHUP;
		card->flags &= ~ISDNLOOP_FLAGS_B2ACTIVE;
		isdnloop_free_queue(card, 1);
		cmd.arg = 1;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
		cmd.command = ISDN_STAT_DHUP;
		cmd.arg = 1;
		cmd.driver = card->myid;
		break;
	}
	card->interface.statcallb(&cmd);
}

/*
 * Store a cwcharacter into ringbuffer for reading from /dev/isdnctrl
 *
 * Parameter:
 *   card = pointer to card struct.
 *   c    = char to store.
 */
static void
isdnloop_putmsg(isdnloop_card *card, unsigned char c)
{
	ulong flags;

	spin_lock_irqsave(&card->isdnloop_lock, flags);
	*card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
	if (card->msg_buf_write == card->msg_buf_read) {
		if (++card->msg_buf_read > card->msg_buf_end)
			card->msg_buf_read = card->msg_buf;
	}
	if (card->msg_buf_write > card->msg_buf_end)
		card->msg_buf_write = card->msg_buf;
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
}

/*
 * Poll a virtual cards message queue.
 * If there are new status-replies from the card, copy them to
 * ringbuffer for reading on /dev/isdnctrl and call
 * isdnloop_parse_status() for processing them. Watch for special
 * Firmware bootmessage and parse it, to get the D-Channel protocol.
 * If there are B-Channels open, initiate a timer-callback to
 * isdnloop_pollbchan().
 * This routine is called periodically via timer interrupt.
 *
 * Parameter:
 *   data = pointer to card struct
 */
static void
isdnloop_polldchan(unsigned long data)
{
	isdnloop_card *card = (isdnloop_card *) data;
	struct sk_buff *skb;
	int avail;
	int left;
	u_char c;
	int ch;
	unsigned long flags;
	u_char *p;
	isdn_ctrl cmd;

	skb = skb_dequeue(&card->dqueue);
	if (skb)
		avail = skb->len;
	else
		avail = 0;
	for (left = avail; left > 0; left--) {
		c = *skb->data;
		skb_pull(skb, 1);
		isdnloop_putmsg(card, c);
		card->imsg[card->iptr] = c;
		if (card->iptr < 59)
			card->iptr++;
		if (!skb->len) {
			avail++;
			isdnloop_putmsg(card, '\n');
			card->imsg[card->iptr] = 0;
			card->iptr = 0;
			if (card->imsg[0] == '0' && card->imsg[1] >= '0' &&
			    card->imsg[1] <= '2' && card->imsg[2] == ';') {
				ch = (card->imsg[1] - '0') - 1;
				p = &card->imsg[3];
				isdnloop_parse_status(p, ch, card);
			} else {
				p = card->imsg;
				if (!strncmp(p, "DRV1.", 5)) {
					printk(KERN_INFO "isdnloop: (%s) %s\n", CID, p);
					if (!strncmp(p + 7, "TC", 2)) {
						card->ptype = ISDN_PTYPE_1TR6;
						card->interface.features |= ISDN_FEATURE_P_1TR6;
						printk(KERN_INFO
						       "isdnloop: (%s) 1TR6-Protocol loaded and running\n", CID);
					}
					if (!strncmp(p + 7, "EC", 2)) {
						card->ptype = ISDN_PTYPE_EURO;
						card->interface.features |= ISDN_FEATURE_P_EURO;
						printk(KERN_INFO
						       "isdnloop: (%s) Euro-Protocol loaded and running\n", CID);
					}
					continue;

				}
			}
		}
	}
	if (avail) {
		cmd.command = ISDN_STAT_STAVAIL;
		cmd.driver = card->myid;
		cmd.arg = avail;
		card->interface.statcallb(&cmd);
	}
	if (card->flags & (ISDNLOOP_FLAGS_B1ACTIVE | ISDNLOOP_FLAGS_B2ACTIVE))
		if (!(card->flags & ISDNLOOP_FLAGS_RBTIMER)) {
			/* schedule b-channel polling */
			card->flags |= ISDNLOOP_FLAGS_RBTIMER;
			spin_lock_irqsave(&card->isdnloop_lock, flags);
			del_timer(&card->rb_timer);
			card->rb_timer.function = isdnloop_pollbchan;
			card->rb_timer.data = (unsigned long) card;
			card->rb_timer.expires = jiffies + ISDNLOOP_TIMER_BCREAD;
			add_timer(&card->rb_timer);
			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
		}
	/* schedule again */
	spin_lock_irqsave(&card->isdnloop_lock, flags);
	card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD;
	add_timer(&card->st_timer);
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
}

/*
 * Append a packet to the transmit buffer-queue.
 *
 * Parameter:
 *   channel = Number of B-channel
 *   skb     = packet to send.
 *   card    = pointer to card-struct
 * Return:
 *   Number of bytes transferred, -E??? on error
 */
static int
isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card *card)
{
	int len = skb->len;
	unsigned long flags;
	struct sk_buff *nskb;

	if (len > 4000) {
		printk(KERN_WARNING
		       "isdnloop: Send packet too large\n");
		return -EINVAL;
	}
	if (len) {
		if (!(card->flags & (channel ? ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE)))
			return 0;
		if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE)
			return 0;
		spin_lock_irqsave(&card->isdnloop_lock, flags);
		nskb = dev_alloc_skb(skb->len);
		if (nskb) {
			skb_copy_from_linear_data(skb,
						  skb_put(nskb, len), len);
			skb_queue_tail(&card->bqueue[channel], nskb);
			dev_kfree_skb(skb);
		} else
			len = 0;
		card->sndcount[channel] += len;
		spin_unlock_irqrestore(&card->isdnloop_lock, flags);
	}
	return len;
}

/*
 * Read the messages from the card's ringbuffer
 *
 * Parameter:
 *   buf  = pointer to buffer.
 *   len  = number of bytes to read.
 *   user = flag, 1: called from userlevel 0: called from kernel.
 *   card = pointer to card struct.
 * Return:
 *   number of bytes actually transferred.
 */
static int
isdnloop_readstatus(u_char __user *buf, int len, isdnloop_card *card)
{
	int count;
	u_char __user *p;

	for (p = buf, count = 0; count < len; p++, count++) {
		if (card->msg_buf_read == card->msg_buf_write)
			return count;
		if (put_user(*card->msg_buf_read++, p))
			return -EFAULT;
		if (card->msg_buf_read > card->msg_buf_end)
			card->msg_buf_read = card->msg_buf;
	}
	return count;
}

/*
 * Simulate a card's response by appending it to the cards
 * message queue.
 *
 * Parameter:
 *   card = pointer to card struct.
 *   s    = pointer to message-string.
 *   ch   = channel: 0 = generic messages, 1 and 2 = D-channel messages.
 * Return:
 *   0 on success, 1 on memory squeeze.
 */
static int
isdnloop_fake(isdnloop_card *card, char *s, int ch)
{
	struct sk_buff *skb;
	int len = strlen(s) + ((ch >= 0) ? 3 : 0);
	skb = dev_alloc_skb(len);
	if (!skb) {
		printk(KERN_WARNING "isdnloop: Out of memory in isdnloop_fake\n");
		return 1;
	}
	if (ch >= 0)
		sprintf(skb_put(skb, 3), "%02d;", ch);
	skb_put_data(skb, s, strlen(s));
	skb_queue_tail(&card->dqueue, skb);
	return 0;
}
/* *INDENT-OFF* */
static isdnloop_stat isdnloop_cmd_table[] = {
	{"BCON_R",         0,  1},	/* B-Channel connect        */
	{"BCON_I",         0, 17},	/* B-Channel connect ind    */
	{"BDIS_R",         0,  2},	/* B-Channel disconnect     */
	{"DDIS_R",         0,  3},	/* D-Channel disconnect     */
	{"DCON_R",         0, 16},	/* D-Channel connect        */
	{"DSCA_R",         0,  4},	/* Dial 1TR6-SPV     */
	{"DCAL_R",         0,  5},	/* Dial */
	{"EAZC",           0,  6},	/* Clear EAZ listener */
	{"EAZ",            0,  7},	/* Set EAZ listener */
	{"SEEAZ",          0,  8},	/* Get EAZ listener */
	{"MSN",            0,  9},	/* Set/Clear MSN listener */
	{"MSALL",          0, 10},	/* Set multi MSN listeners */
	{"SETSIL",         0, 11},	/* Set SI list     */
	{"SEESIL",         0, 12},	/* Get SI list     */
	{"SILC",           0, 13},	/* Clear SI list     */
	{"LOCK",           0, -1},	/* LOCK channel     */
	{"UNLOCK",         0, -1},	/* UNLOCK channel     */
	{"FV2ON",          1, 14},	/* Leased mode on               */
	{"FV2OFF",         1, 15},	/* Leased mode off              */
	{NULL, 0, -1}
};
/* *INDENT-ON* */


/*
 * Simulate an error-response from a card.
 *
 * Parameter:
 *   card = pointer to card struct.
 */
static void
isdnloop_fake_err(isdnloop_card *card)
{
	char buf[64];

	snprintf(buf, sizeof(buf), "E%s", card->omsg);
	isdnloop_fake(card, buf, -1);
	isdnloop_fake(card, "NAK", -1);
}

static u_char ctable_eu[] = {0x00, 0x11, 0x01, 0x12};
static u_char ctable_1t[] = {0x00, 0x3b, 0x01, 0x3a};

/*
 * Assemble a simplified cause message depending on the
 * D-channel protocol used.
 *
 * Parameter:
 *   card = pointer to card struct.
 *   loc  = location: 0 = local, 1 = remote.
 *   cau  = cause: 1 = busy, 2 = nonexistent callerid, 3 = no user responding.
 * Return:
 *   Pointer to buffer containing the assembled message.
 */
static char *
isdnloop_unicause(isdnloop_card *card, int loc, int cau)
{
	static char buf[6];

	switch (card->ptype) {
	case ISDN_PTYPE_EURO:
		sprintf(buf, "E%02X%02X", (loc) ? 4 : 2, ctable_eu[cau]);
		break;
	case ISDN_PTYPE_1TR6:
		sprintf(buf, "%02X44", ctable_1t[cau]);
		break;
	default:
		return "0000";
	}
	return buf;
}

/*
 * Release a virtual connection. Called from timer interrupt, when
 * called party did not respond.
 *
 * Parameter:
 *   card = pointer to card struct.
 *   ch   = channel (0-based)
 */
static void
isdnloop_atimeout(isdnloop_card *card, int ch)
{
	unsigned long flags;
	char buf[60];

	spin_lock_irqsave(&card->isdnloop_lock, flags);
	if (card->rcard) {
		isdnloop_fake(card->rcard[ch], "DDIS_I", card->rch[ch] + 1);
		card->rcard[ch]->rcard[card->rch[ch]] = NULL;
		card->rcard[ch] = NULL;
	}
	isdnloop_fake(card, "DDIS_I", ch + 1);
	/* No user responding */
	sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 3));
	isdnloop_fake(card, buf, ch + 1);
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
}

/*
 * Wrapper for isdnloop_atimeout().
 */
static void
isdnloop_atimeout0(unsigned long data)
{
	isdnloop_card *card = (isdnloop_card *) data;
	isdnloop_atimeout(card, 0);
}

/*
 * Wrapper for isdnloop_atimeout().
 */
static void
isdnloop_atimeout1(unsigned long data)
{
	isdnloop_card *card = (isdnloop_card *) data;
	isdnloop_atimeout(card, 1);
}

/*
 * Install a watchdog for a user, not responding.
 *
 * Parameter:
 *   card = pointer to card struct.
 *   ch   = channel to watch for.
 */
static void
isdnloop_start_ctimer(isdnloop_card *card, int ch)
{
	unsigned long flags;

	spin_lock_irqsave(&card->isdnloop_lock, flags);
	init_timer(&card->c_timer[ch]);
	card->c_timer[ch].expires = jiffies + ISDNLOOP_TIMER_ALERTWAIT;
	if (ch)
		card->c_timer[ch].function = isdnloop_atimeout1;
	else
		card->c_timer[ch].function = isdnloop_atimeout0;
	card->c_timer[ch].data = (unsigned long) card;
	add_timer(&card->c_timer[ch]);
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
}

/*
 * Kill a pending channel watchdog.
 *
 * Parameter:
 *   card = pointer to card struct.
 *   ch   = channel (0-based).
 */
static void
isdnloop_kill_ctimer(isdnloop_card *card, int ch)
{
	unsigned long flags;

	spin_lock_irqsave(&card->isdnloop_lock, flags);
	del_timer(&card->c_timer[ch]);
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
}

static u_char si2bit[] = {0, 1, 0, 0, 0, 2, 0, 4, 0, 0};
static u_char bit2si[] = {1, 5, 7};

/*
 * Try finding a listener for an outgoing call.
 *
 * Parameter:
 *   card = pointer to calling card.
 *   p    = pointer to ICN-type setup-string.
 *   lch  = channel of calling card.
 *   cmd  = pointer to struct to be filled when parsing setup.
 * Return:
 *   0 = found match, alerting should happen.
 *   1 = found matching number but it is busy.
 *   2 = no matching listener.
 *   3 = found matching number but SI does not match.
 */
static int
isdnloop_try_call(isdnloop_card *card, char *p, int lch, isdn_ctrl *cmd)
{
	isdnloop_card *cc = cards;
	unsigned long flags;
	int ch;
	int num_match;
	int i;
	char *e;
	char nbuf[32];

	isdnloop_parse_setup(p, cmd);
	while (cc) {
		for (ch = 0; ch < 2; ch++) {
			/* Exclude ourself */
			if ((cc == card) && (ch == lch))
				continue;
			num_match = 0;
			switch (cc->ptype) {
			case ISDN_PTYPE_EURO:
				for (i = 0; i < 3; i++)
					if (!(strcmp(cc->s0num[i], cmd->parm.setup.phone)))
						num_match = 1;
				break;
			case ISDN_PTYPE_1TR6:
				e = cc->eazlist[ch];
				while (*e) {
					sprintf(nbuf, "%s%c", cc->s0num[0], *e);
					if (!(strcmp(nbuf, cmd->parm.setup.phone)))
						num_match = 1;
					e++;
				}
			}
			if (num_match) {
				spin_lock_irqsave(&card->isdnloop_lock, flags);
				/* channel idle? */
				if (!(cc->rcard[ch])) {
					/* Check SI */
					if (!(si2bit[cmd->parm.setup.si1] & cc->sil[ch])) {
						spin_unlock_irqrestore(&card->isdnloop_lock, flags);
						return 3;
					}
					/* ch is idle, si and number matches */
					cc->rcard[ch] = card;
					cc->rch[ch] = lch;
					card->rcard[lch] = cc;
					card->rch[lch] = ch;
					spin_unlock_irqrestore(&card->isdnloop_lock, flags);
					return 0;
				} else {
					spin_unlock_irqrestore(&card->isdnloop_lock, flags);
					/* num matches, but busy */
					if (ch == 1)
						return 1;
				}
			}
		}
		cc = cc->next;
	}
	return 2;
}

/*
 * Depending on D-channel protocol and caller/called, modify
 * phone number.
 *
 * Parameter:
 *   card   = pointer to card struct.
 *   phone  = pointer phone number.
 *   caller = flag: 1 = caller, 0 = called.
 * Return:
 *   pointer to new phone number.
 */
static char *
isdnloop_vstphone(isdnloop_card *card, char *phone, int caller)
{
	int i;
	static char nphone[30];

	if (!card) {
		printk("BUG!!!\n");
		return "";
	}
	switch (card->ptype) {
	case ISDN_PTYPE_EURO:
		if (caller) {
			for (i = 0; i < 2; i++)
				if (!(strcmp(card->s0num[i], phone)))
					return phone;
			return card->s0num[0];
		}
		return phone;
		break;
	case ISDN_PTYPE_1TR6:
		if (caller) {
			sprintf(nphone, "%s%c", card->s0num[0], phone[0]);
			return nphone;
		} else
			return &phone[strlen(phone) - 1];
		break;
	}
	return "";
}

/*
 * Parse an ICN-type command string sent to the 'card'.
 * Perform misc. actions depending on the command.
 *
 * Parameter:
 *   card = pointer to card struct.
 */
static void
isdnloop_parse_cmd(isdnloop_card *card)
{
	char *p = card->omsg;
	isdn_ctrl cmd;
	char buf[60];
	isdnloop_stat *s = isdnloop_cmd_table;
	int action = -1;
	int i;
	int ch;

	if ((card->omsg[0] != '0') && (card->omsg[2] != ';')) {
		isdnloop_fake_err(card);
		return;
	}
	ch = card->omsg[1] - '0';
	if ((ch < 0) || (ch > 2)) {
		isdnloop_fake_err(card);
		return;
	}
	p += 3;
	while (s->statstr) {
		if (!strncmp(p, s->statstr, strlen(s->statstr))) {
			action = s->action;
			if (s->command && (ch != 0)) {
				isdnloop_fake_err(card);
				return;
			}
			break;
		}
		s++;
	}
	if (action == -1)
		return;
	switch (action) {
	case 1:
		/* 0x;BCON_R */
		if (card->rcard[ch - 1]) {
			isdnloop_fake(card->rcard[ch - 1], "BCON_I",
				      card->rch[ch - 1] + 1);
			isdnloop_fake(card, "BCON_C", ch);
		}
		break;
	case 17:
		/* 0x;BCON_I */
		if (card->rcard[ch - 1]) {
			isdnloop_fake(card->rcard[ch - 1], "BCON_C",
				      card->rch[ch - 1] + 1);
		}
		break;
	case 2:
		/* 0x;BDIS_R */
		isdnloop_fake(card, "BDIS_C", ch);
		if (card->rcard[ch - 1]) {
			isdnloop_fake(card->rcard[ch - 1], "BDIS_I",
				      card->rch[ch - 1] + 1);
		}
		break;
	case 16:
		/* 0x;DCON_R */
		isdnloop_kill_ctimer(card, ch - 1);
		if (card->rcard[ch - 1]) {
			isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
			isdnloop_fake(card->rcard[ch - 1], "DCON_C",
				      card->rch[ch - 1] + 1);
			isdnloop_fake(card, "DCON_C", ch);
		}
		break;
	case 3:
		/* 0x;DDIS_R */
		isdnloop_kill_ctimer(card, ch - 1);
		if (card->rcard[ch - 1]) {
			isdnloop_kill_ctimer(card->rcard[ch - 1], card->rch[ch - 1]);
			isdnloop_fake(card->rcard[ch - 1], "DDIS_I",
				      card->rch[ch - 1] + 1);
			card->rcard[ch - 1] = NULL;
		}
		isdnloop_fake(card, "DDIS_C", ch);
		break;
	case 4:
		/* 0x;DSCA_Rdd,yy,zz,oo */
		if (card->ptype != ISDN_PTYPE_1TR6) {
			isdnloop_fake_err(card);
			return;
		}
		/* Fall through */
	case 5:
		/* 0x;DCAL_Rdd,yy,zz,oo */
		p += 6;
		switch (isdnloop_try_call(card, p, ch - 1, &cmd)) {
		case 0:
			/* Alerting */
			sprintf(buf, "D%s_I%s,%02d,%02d,%s",
				(action == 4) ? "SCA" : "CAL",
				isdnloop_vstphone(card, cmd.parm.setup.eazmsn, 1),
				cmd.parm.setup.si1,
				cmd.parm.setup.si2,
				isdnloop_vstphone(card->rcard[ch - 1],
						  cmd.parm.setup.phone, 0));
			isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
			/* Fall through */
		case 3:
			/* si1 does not match, don't alert but start timer */
			isdnloop_start_ctimer(card, ch - 1);
			break;
		case 1:
			/* Remote busy */
			isdnloop_fake(card, "DDIS_I", ch);
			sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 1));
			isdnloop_fake(card, buf, ch);
			break;
		case 2:
			/* No such user */
			isdnloop_fake(card, "DDIS_I", ch);
			sprintf(buf, "CAU%s", isdnloop_unicause(card, 1, 2));
			isdnloop_fake(card, buf, ch);
			break;
		}
		break;
	case 6:
		/* 0x;EAZC */
		card->eazlist[ch - 1][0] = '\0';
		break;
	case 7:
		/* 0x;EAZ */
		p += 3;
		if (strlen(p) >= sizeof(card->eazlist[0]))
			break;
		strcpy(card->eazlist[ch - 1], p);
		break;
	case 8:
		/* 0x;SEEAZ */
		sprintf(buf, "EAZ-LIST: %s", card->eazlist[ch - 1]);
		isdnloop_fake(card, buf, ch + 1);
		break;
	case 9:
		/* 0x;MSN */
		break;
	case 10:
		/* 0x;MSNALL */
		break;
	case 11:
		/* 0x;SETSIL */
		p += 6;
		i = 0;
		while (strchr("0157", *p)) {
			if (i)
				card->sil[ch - 1] |= si2bit[*p - '0'];
			i = (*p++ == '0');
		}
		if (*p)
			isdnloop_fake_err(card);
		break;
	case 12:
		/* 0x;SEESIL */
		sprintf(buf, "SIN-LIST: ");
		p = buf + 10;
		for (i = 0; i < 3; i++)
			if (card->sil[ch - 1] & (1 << i))
				p += sprintf(p, "%02d", bit2si[i]);
		isdnloop_fake(card, buf, ch + 1);
		break;
	case 13:
		/* 0x;SILC */
		card->sil[ch - 1] = 0;
		break;
	case 14:
		/* 00;FV2ON */
		break;
	case 15:
		/* 00;FV2OFF */
		break;
	}
}

/*
 * Put command-strings into the of the 'card'. In reality, execute them
 * right in place by calling isdnloop_parse_cmd(). Also copy every
 * command to the read message ringbuffer, preceding it with a '>'.
 * These mesagges can be read at /dev/isdnctrl.
 *
 * Parameter:
 *   buf  = pointer to command buffer.
 *   len  = length of buffer data.
 *   user = flag: 1 = called form userlevel, 0 called from kernel.
 *   card = pointer to card struct.
 * Return:
 *   number of bytes transferred (currently always equals len).
 */
static int
isdnloop_writecmd(const u_char *buf, int len, int user, isdnloop_card *card)
{
	int xcount = 0;
	int ocount = 1;
	isdn_ctrl cmd;

	while (len) {
		int count = len;
		u_char *p;
		u_char msg[0x100];

		if (count > 255)
			count = 255;
		if (user) {
			if (copy_from_user(msg, buf, count))
				return -EFAULT;
		} else
			memcpy(msg, buf, count);
		isdnloop_putmsg(card, '>');
		for (p = msg; count > 0; count--, p++) {
			len--;
			xcount++;
			isdnloop_putmsg(card, *p);
			card->omsg[card->optr] = *p;
			if (*p == '\n') {
				card->omsg[card->optr] = '\0';
				card->optr = 0;
				isdnloop_parse_cmd(card);
				if (len) {
					isdnloop_putmsg(card, '>');
					ocount++;
				}
			} else {
				if (card->optr < 59)
					card->optr++;
			}
			ocount++;
		}
	}
	cmd.command = ISDN_STAT_STAVAIL;
	cmd.driver = card->myid;
	cmd.arg = ocount;
	card->interface.statcallb(&cmd);
	return xcount;
}

/*
 * Delete card's pending timers, send STOP to linklevel
 */
static void
isdnloop_stopcard(isdnloop_card *card)
{
	unsigned long flags;
	isdn_ctrl cmd;

	spin_lock_irqsave(&card->isdnloop_lock, flags);
	if (card->flags & ISDNLOOP_FLAGS_RUNNING) {
		card->flags &= ~ISDNLOOP_FLAGS_RUNNING;
		del_timer(&card->st_timer);
		del_timer(&card->rb_timer);
		del_timer(&card->c_timer[0]);
		del_timer(&card->c_timer[1]);
		cmd.command = ISDN_STAT_STOP;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
	}
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
}

/*
 * Stop all cards before unload.
 */
static void
isdnloop_stopallcards(void)
{
	isdnloop_card *p = cards;

	while (p) {
		isdnloop_stopcard(p);
		p = p->next;
	}
}

/*
 * Start a 'card'. Simulate card's boot message and set the phone
 * number(s) of the virtual 'S0-Interface'. Install D-channel
 * poll timer.
 *
 * Parameter:
 *   card  = pointer to card struct.
 *   sdefp = pointer to struct holding ioctl parameters.
 * Return:
 *   0 on success, -E??? otherwise.
 */
static int
isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp)
{
	unsigned long flags;
	isdnloop_sdef sdef;
	int i;

	if (card->flags & ISDNLOOP_FLAGS_RUNNING)
		return -EBUSY;
	if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef)))
		return -EFAULT;

	for (i = 0; i < 3; i++) {
		if (!memchr(sdef.num[i], 0, sizeof(sdef.num[i])))
			return -EINVAL;
	}

	spin_lock_irqsave(&card->isdnloop_lock, flags);
	switch (sdef.ptype) {
	case ISDN_PTYPE_EURO:
		if (isdnloop_fake(card, "DRV1.23EC-Q.931-CAPI-CNS-BASIS-20.02.96",
				  -1)) {
			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
			return -ENOMEM;
		}
		card->sil[0] = card->sil[1] = 4;
		if (isdnloop_fake(card, "TEI OK", 0)) {
			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
			return -ENOMEM;
		}
		for (i = 0; i < 3; i++) {
			strlcpy(card->s0num[i], sdef.num[i],
				sizeof(card->s0num[0]));
		}
		break;
	case ISDN_PTYPE_1TR6:
		if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
				  -1)) {
			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
			return -ENOMEM;
		}
		card->sil[0] = card->sil[1] = 4;
		if (isdnloop_fake(card, "TEI OK", 0)) {
			spin_unlock_irqrestore(&card->isdnloop_lock, flags);
			return -ENOMEM;
		}
		strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0]));
		card->s0num[1][0] = '\0';
		card->s0num[2][0] = '\0';
		break;
	default:
		spin_unlock_irqrestore(&card->isdnloop_lock, flags);
		printk(KERN_WARNING "isdnloop: Illegal D-channel protocol %d\n",
		       sdef.ptype);
		return -EINVAL;
	}
	init_timer(&card->st_timer);
	card->st_timer.expires = jiffies + ISDNLOOP_TIMER_DCREAD;
	card->st_timer.function = isdnloop_polldchan;
	card->st_timer.data = (unsigned long) card;
	add_timer(&card->st_timer);
	card->flags |= ISDNLOOP_FLAGS_RUNNING;
	spin_unlock_irqrestore(&card->isdnloop_lock, flags);
	return 0;
}

/*
 * Main handler for commands sent by linklevel.
 */
static int
isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
{
	ulong a;
	int i;
	char cbuf[80];
	isdn_ctrl cmd;
	isdnloop_cdef cdef;

	switch (c->command) {
	case ISDN_CMD_IOCTL:
		memcpy(&a, c->parm.num, sizeof(ulong));
		switch (c->arg) {
		case ISDNLOOP_IOCTL_DEBUGVAR:
			return (ulong) card;
		case ISDNLOOP_IOCTL_STARTUP:
			return isdnloop_start(card, (isdnloop_sdef *) a);
			break;
		case ISDNLOOP_IOCTL_ADDCARD:
			if (copy_from_user((char *)&cdef,
					   (char *)a,
					   sizeof(cdef)))
				return -EFAULT;
			return isdnloop_addcard(cdef.id1);
			break;
		case ISDNLOOP_IOCTL_LEASEDCFG:
			if (a) {
				if (!card->leased) {
					card->leased = 1;
					while (card->ptype == ISDN_PTYPE_UNKNOWN)
						schedule_timeout_interruptible(10);
					schedule_timeout_interruptible(10);
					sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
					printk(KERN_INFO
					       "isdnloop: (%s) Leased-line mode enabled\n",
					       CID);
					cmd.command = ISDN_STAT_RUN;
					cmd.driver = card->myid;
					cmd.arg = 0;
					card->interface.statcallb(&cmd);
				}
			} else {
				if (card->leased) {
					card->leased = 0;
					sprintf(cbuf, "00;FV2OFF\n");
					i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
					printk(KERN_INFO
					       "isdnloop: (%s) Leased-line mode disabled\n",
					       CID);
					cmd.command = ISDN_STAT_RUN;
					cmd.driver = card->myid;
					cmd.arg = 0;
					card->interface.statcallb(&cmd);
				}
			}
			return 0;
		default:
			return -EINVAL;
		}
		break;
	case ISDN_CMD_DIAL:
		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
			return -ENODEV;
		if (card->leased)
			break;
		if ((c->arg & 255) < ISDNLOOP_BCH) {
			char *p;
			char dcode[4];

			a = c->arg;
			p = c->parm.setup.phone;
			if (*p == 's' || *p == 'S') {
				/* Dial for SPV */
				p++;
				strcpy(dcode, "SCA");
			} else
				/* Normal Dial */
				strcpy(dcode, "CAL");
			snprintf(cbuf, sizeof(cbuf),
				 "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
				 dcode, p, c->parm.setup.si1,
				 c->parm.setup.si2, c->parm.setup.eazmsn);
			i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_ACCEPTD:
		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
			return -ENODEV;
		if (c->arg < ISDNLOOP_BCH) {
			a = c->arg + 1;
			cbuf[0] = 0;
			switch (card->l2_proto[a - 1]) {
			case ISDN_PROTO_L2_X75I:
				sprintf(cbuf, "%02d;BX75\n", (int) a);
				break;
#ifdef CONFIG_ISDN_X25
			case ISDN_PROTO_L2_X25DTE:
				sprintf(cbuf, "%02d;BX2T\n", (int) a);
				break;
			case ISDN_PROTO_L2_X25DCE:
				sprintf(cbuf, "%02d;BX2C\n", (int) a);
				break;
#endif
			case ISDN_PROTO_L2_HDLC:
				sprintf(cbuf, "%02d;BTRA\n", (int) a);
				break;
			}
			if (strlen(cbuf))
				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
			sprintf(cbuf, "%02d;DCON_R\n", (int) a);
			i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_ACCEPTB:
		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
			return -ENODEV;
		if (c->arg < ISDNLOOP_BCH) {
			a = c->arg + 1;
			switch (card->l2_proto[a - 1]) {
			case ISDN_PROTO_L2_X75I:
				sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
				break;
#ifdef CONFIG_ISDN_X25
			case ISDN_PROTO_L2_X25DTE:
				sprintf(cbuf, "%02d;BCON_R,BX2T\n", (int) a);
				break;
			case ISDN_PROTO_L2_X25DCE:
				sprintf(cbuf, "%02d;BCON_R,BX2C\n", (int) a);
				break;
#endif
			case ISDN_PROTO_L2_HDLC:
				sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
				break;
			default:
				sprintf(cbuf, "%02d;BCON_R\n", (int) a);
			}
			printk(KERN_DEBUG "isdnloop writecmd '%s'\n", cbuf);
			i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
			break;
		case ISDN_CMD_HANGUP:
			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
				return -ENODEV;
			if (c->arg < ISDNLOOP_BCH) {
				a = c->arg + 1;
				sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_SETEAZ:
			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
				return -ENODEV;
			if (card->leased)
				break;
			if (c->arg < ISDNLOOP_BCH) {
				a = c->arg + 1;
				if (card->ptype == ISDN_PTYPE_EURO) {
					sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
						c->parm.num[0] ? "N" : "ALL", c->parm.num);
				} else
					sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
						c->parm.num[0] ? c->parm.num : (u_char *) "0123456789");
				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_CLREAZ:
			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
				return -ENODEV;
			if (card->leased)
				break;
			if (c->arg < ISDNLOOP_BCH) {
				a = c->arg + 1;
				if (card->ptype == ISDN_PTYPE_EURO)
					sprintf(cbuf, "%02d;MSNC\n", (int) a);
				else
					sprintf(cbuf, "%02d;EAZC\n", (int) a);
				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			break;
		case ISDN_CMD_SETL2:
			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
				return -ENODEV;
			if ((c->arg & 255) < ISDNLOOP_BCH) {
				a = c->arg;
				switch (a >> 8) {
				case ISDN_PROTO_L2_X75I:
					sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
					break;
#ifdef CONFIG_ISDN_X25
				case ISDN_PROTO_L2_X25DTE:
					sprintf(cbuf, "%02d;BX2T\n", (int) (a & 255) + 1);
					break;
				case ISDN_PROTO_L2_X25DCE:
					sprintf(cbuf, "%02d;BX2C\n", (int) (a & 255) + 1);
					break;
#endif
				case ISDN_PROTO_L2_HDLC:
					sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
					break;
				case ISDN_PROTO_L2_TRANS:
					sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
					break;
				default:
					return -EINVAL;
				}
				i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
				card->l2_proto[a & 255] = (a >> 8);
			}
			break;
		case ISDN_CMD_SETL3:
			if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
				return -ENODEV;
			return 0;
		default:
			return -EINVAL;
		}
	}
	return 0;
}

/*
 * Find card with given driverId
 */
static inline isdnloop_card *
isdnloop_findcard(int driverid)
{
	isdnloop_card *p = cards;

	while (p) {
		if (p->myid == driverid)
			return p;
		p = p->next;
	}
	return (isdnloop_card *) 0;
}

/*
 * Wrapper functions for interface to linklevel
 */
static int
if_command(isdn_ctrl *c)
{
	isdnloop_card *card = isdnloop_findcard(c->driver);

	if (card)
		return isdnloop_command(c, card);
	printk(KERN_ERR
	       "isdnloop: if_command called with invalid driverId!\n");
	return -ENODEV;
}

static int
if_writecmd(const u_char __user *buf, int len, int id, int channel)
{
	isdnloop_card *card = isdnloop_findcard(id);

	if (card) {
		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
			return -ENODEV;
		return isdnloop_writecmd(buf, len, 1, card);
	}
	printk(KERN_ERR
	       "isdnloop: if_writecmd called with invalid driverId!\n");
	return -ENODEV;
}

static int
if_readstatus(u_char __user *buf, int len, int id, int channel)
{
	isdnloop_card *card = isdnloop_findcard(id);

	if (card) {
		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
			return -ENODEV;
		return isdnloop_readstatus(buf, len, card);
	}
	printk(KERN_ERR
	       "isdnloop: if_readstatus called with invalid driverId!\n");
	return -ENODEV;
}

static int
if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
{
	isdnloop_card *card = isdnloop_findcard(id);

	if (card) {
		if (!(card->flags & ISDNLOOP_FLAGS_RUNNING))
			return -ENODEV;
		/* ack request stored in skb scratch area */
		*(skb->head) = ack;
		return isdnloop_sendbuf(channel, skb, card);
	}
	printk(KERN_ERR
	       "isdnloop: if_sendbuf called with invalid driverId!\n");
	return -ENODEV;
}

/*
 * Allocate a new card-struct, initialize it
 * link it into cards-list and register it at linklevel.
 */
static isdnloop_card *
isdnloop_initcard(char *id)
{
	isdnloop_card *card;
	int i;
	card = kzalloc(sizeof(isdnloop_card), GFP_KERNEL);
	if (!card) {
		printk(KERN_WARNING
		       "isdnloop: (%s) Could not allocate card-struct.\n", id);
		return (isdnloop_card *) 0;
	}
	card->interface.owner = THIS_MODULE;
	card->interface.channels = ISDNLOOP_BCH;
	card->interface.hl_hdrlen  = 1; /* scratch area for storing ack flag*/
	card->interface.maxbufsize = 4000;
	card->interface.command = if_command;
	card->interface.writebuf_skb = if_sendbuf;
	card->interface.writecmd = if_writecmd;
	card->interface.readstat = if_readstatus;
	card->interface.features = ISDN_FEATURE_L2_X75I |
#ifdef CONFIG_ISDN_X25
		ISDN_FEATURE_L2_X25DTE |
		ISDN_FEATURE_L2_X25DCE |
#endif
		ISDN_FEATURE_L2_HDLC |
		ISDN_FEATURE_L3_TRANS |
		ISDN_FEATURE_P_UNKNOWN;
	card->ptype = ISDN_PTYPE_UNKNOWN;
	strlcpy(card->interface.id, id, sizeof(card->interface.id));
	card->msg_buf_write = card->msg_buf;
	card->msg_buf_read = card->msg_buf;
	card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1];
	for (i = 0; i < ISDNLOOP_BCH; i++) {
		card->l2_proto[i] = ISDN_PROTO_L2_X75I;
		skb_queue_head_init(&card->bqueue[i]);
	}
	skb_queue_head_init(&card->dqueue);
	spin_lock_init(&card->isdnloop_lock);
	card->next = cards;
	cards = card;
	if (!register_isdn(&card->interface)) {
		cards = cards->next;
		printk(KERN_WARNING
		       "isdnloop: Unable to register %s\n", id);
		kfree(card);
		return (isdnloop_card *) 0;
	}
	card->myid = card->interface.channels;
	return card;
}

static int
isdnloop_addcard(char *id1)
{
	isdnloop_card *card;
	card = isdnloop_initcard(id1);
	if (!card) {
		return -EIO;
	}
	printk(KERN_INFO
	       "isdnloop: (%s) virtual card added\n",
	       card->interface.id);
	return 0;
}

static int __init
isdnloop_init(void)
{
	if (isdnloop_id)
		return isdnloop_addcard(isdnloop_id);

	return 0;
}

static void __exit
isdnloop_exit(void)
{
	isdn_ctrl cmd;
	isdnloop_card *card = cards;
	isdnloop_card *last;
	int i;

	isdnloop_stopallcards();
	while (card) {
		cmd.command = ISDN_STAT_UNLOAD;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
		for (i = 0; i < ISDNLOOP_BCH; i++)
			isdnloop_free_queue(card, i);
		card = card->next;
	}
	card = cards;
	while (card) {
		last = card;
		skb_queue_purge(&card->dqueue);
		card = card->next;
		kfree(last);
	}
	printk(KERN_NOTICE "isdnloop-ISDN-driver unloaded\n");
}

module_init(isdnloop_init);
module_exit(isdnloop_exit);
