/* $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]) {
		if ((skb = skb_dequeue(&card->bqueue[ch]))) {
			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;

	if ((skb = skb_dequeue(&card->dqueue)))
		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);

	if (!(skb = dev_alloc_skb(len))) {
		printk(KERN_WARNING "isdnloop: Out of memory in isdnloop_fake\n");
		return 1;
	}
	if (ch >= 0)
		sprintf(skb_put(skb, 3), "%02d;", ch);
	memcpy(skb_put(skb, strlen(s)), 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:
			if (!access_ok(VERIFY_READ, (void *) a, sizeof(isdnloop_sdef)))
				return -EFAULT;
			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;

	if (!(card = kzalloc(sizeof(isdnloop_card), GFP_KERNEL))) {
		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;

	if (!(card = isdnloop_initcard(id1))) {
		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);
