/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $
 *
 * ISDN low-level module for the ICN active ISDN-Card.
 *
 * Copyright 1994,95,96 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 "icn.h"
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched.h>

static int portbase = ICN_BASEADDR;
static unsigned long membase = ICN_MEMADDR;
static char *icn_id = "\0";
static char *icn_id2 = "\0";

MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
MODULE_AUTHOR("Fritz Elfert");
MODULE_LICENSE("GPL");
module_param(portbase, int, 0);
MODULE_PARM_DESC(portbase, "Port address of first card");
module_param(membase, ulong, 0);
MODULE_PARM_DESC(membase, "Shared memory address of all cards");
module_param(icn_id, charp, 0);
MODULE_PARM_DESC(icn_id, "ID-String of first card");
module_param(icn_id2, charp, 0);
MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");

/*
 * Verbose bootcode- and protocol-downloading.
 */
#undef BOOT_DEBUG

/*
 * Verbose Shmem-Mapping.
 */
#undef MAP_DEBUG

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

static int icn_addcard(int, char *, char *);

/*
 * Free send-queue completely.
 * Parameter:
 *   card   = pointer to card struct
 *   channel = channel number
 */
static void
icn_free_queue(icn_card *card, int channel)
{
	struct sk_buff_head *queue = &card->spqueue[channel];
	struct sk_buff *skb;

	skb_queue_purge(queue);
	card->xlen[channel] = 0;
	card->sndcount[channel] = 0;
	if ((skb = card->xskb[channel])) {
		card->xskb[channel] = NULL;
		dev_kfree_skb(skb);
	}
}

/* Put a value into a shift-register, highest bit first.
 * Parameters:
 *            port     = port for output (bit 0 is significant)
 *            val      = value to be output
 *            firstbit = Bit-Number of highest bit
 *            bitcount = Number of bits to output
 */
static inline void
icn_shiftout(unsigned short port,
	     unsigned long val,
	     int firstbit,
	     int bitcount)
{

	register u_char s;
	register u_char c;

	for (s = firstbit, c = bitcount; c > 0; s--, c--)
		OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
}

/*
 * disable a cards shared memory
 */
static inline void
icn_disable_ram(icn_card *card)
{
	OUTB_P(0, ICN_MAPRAM);
}

/*
 * enable a cards shared memory
 */
static inline void
icn_enable_ram(icn_card *card)
{
	OUTB_P(0xff, ICN_MAPRAM);
}

/*
 * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
 *
 * must called with holding the devlock
 */
static inline void
icn_map_channel(icn_card *card, int channel)
{
#ifdef MAP_DEBUG
	printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);
#endif
	if ((channel == dev.channel) && (card == dev.mcard))
		return;
	if (dev.mcard)
		icn_disable_ram(dev.mcard);
	icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4);	/* Select Bank          */
	icn_enable_ram(card);
	dev.mcard = card;
	dev.channel = channel;
#ifdef MAP_DEBUG
	printk(KERN_DEBUG "icn_map_channel done\n");
#endif
}

/*
 * Lock a cards channel.
 * Return 0 if requested card/channel is unmapped (failure).
 * Return 1 on success.
 *
 * must called with holding the devlock
 */
static inline int
icn_lock_channel(icn_card *card, int channel)
{
	register int retval;

#ifdef MAP_DEBUG
	printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
#endif
	if ((dev.channel == channel) && (card == dev.mcard)) {
		dev.chanlock++;
		retval = 1;
#ifdef MAP_DEBUG
		printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);
#endif
	} else {
		retval = 0;
#ifdef MAP_DEBUG
		printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
#endif
	}
	return retval;
}

/*
 * Release current card/channel lock
 *
 * must called with holding the devlock
 */
static inline void
__icn_release_channel(void)
{
#ifdef MAP_DEBUG
	printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
#endif
	if (dev.chanlock > 0)
		dev.chanlock--;
}

/*
 * Release current card/channel lock
 */
static inline void
icn_release_channel(void)
{
	ulong flags;

	spin_lock_irqsave(&dev.devlock, flags);
	__icn_release_channel();
	spin_unlock_irqrestore(&dev.devlock, flags);
}

/*
 * Try to map and lock a cards channel.
 * Return 1 on success, 0 on failure.
 */
static inline int
icn_trymaplock_channel(icn_card *card, int channel)
{
	ulong flags;

#ifdef MAP_DEBUG
	printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
	       dev.chanlock);
#endif
	spin_lock_irqsave(&dev.devlock, flags);
	if ((!dev.chanlock) ||
	    ((dev.channel == channel) && (dev.mcard == card))) {
		dev.chanlock++;
		icn_map_channel(card, channel);
		spin_unlock_irqrestore(&dev.devlock, flags);
#ifdef MAP_DEBUG
		printk(KERN_DEBUG "trymaplock %d OK\n", channel);
#endif
		return 1;
	}
	spin_unlock_irqrestore(&dev.devlock, flags);
#ifdef MAP_DEBUG
	printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
#endif
	return 0;
}

/*
 * Release current card/channel lock,
 * then map same or other channel without locking.
 */
static inline void
icn_maprelease_channel(icn_card *card, int channel)
{
	ulong flags;

#ifdef MAP_DEBUG
	printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
#endif
	spin_lock_irqsave(&dev.devlock, flags);
	if (dev.chanlock > 0)
		dev.chanlock--;
	if (!dev.chanlock)
		icn_map_channel(card, channel);
	spin_unlock_irqrestore(&dev.devlock, flags);
}

/* Get Data from the B-Channel, assemble fragmented packets and put them
 * into receive-queue. Wake up any B-Channel-reading processes.
 * This routine is called via timer-callback from icn_pollbchan().
 */

static void
icn_pollbchan_receive(int channel, icn_card *card)
{
	int mch = channel + ((card->secondhalf) ? 2 : 0);
	int eflag;
	int cnt;
	struct sk_buff *skb;

	if (icn_trymaplock_channel(card, mch)) {
		while (rbavl) {
			cnt = readb(&rbuf_l);
			if ((card->rcvidx[channel] + cnt) > 4000) {
				printk(KERN_WARNING
				       "icn: (%s) bogus packet on ch%d, dropping.\n",
				       CID,
				       channel + 1);
				card->rcvidx[channel] = 0;
				eflag = 0;
			} else {
				memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
					      &rbuf_d, cnt);
				card->rcvidx[channel] += cnt;
				eflag = readb(&rbuf_f);
			}
			rbnext;
			icn_maprelease_channel(card, mch & 2);
			if (!eflag) {
				if ((cnt = card->rcvidx[channel])) {
					if (!(skb = dev_alloc_skb(cnt))) {
						printk(KERN_WARNING "icn: receive out of memory\n");
						break;
					}
					memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);
					card->rcvidx[channel] = 0;
					card->interface.rcvcallb_skb(card->myid, channel, skb);
				}
			}
			if (!icn_trymaplock_channel(card, mch))
				break;
		}
		icn_maprelease_channel(card, mch & 2);
	}
}

/* Send data-packet to B-Channel, split it up into fragments of
 * ICN_FRAGSIZE length. If last fragment is sent out, signal
 * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
 * This routine is called via timer-callback from icn_pollbchan() or
 * directly from icn_sendbuf().
 */

static void
icn_pollbchan_send(int channel, icn_card *card)
{
	int mch = channel + ((card->secondhalf) ? 2 : 0);
	int cnt;
	unsigned long flags;
	struct sk_buff *skb;
	isdn_ctrl cmd;

	if (!(card->sndcount[channel] || card->xskb[channel] ||
	      !skb_queue_empty(&card->spqueue[channel])))
		return;
	if (icn_trymaplock_channel(card, mch)) {
		while (sbfree &&
		       (card->sndcount[channel] ||
			!skb_queue_empty(&card->spqueue[channel]) ||
			card->xskb[channel])) {
			spin_lock_irqsave(&card->lock, flags);
			if (card->xmit_lock[channel]) {
				spin_unlock_irqrestore(&card->lock, flags);
				break;
			}
			card->xmit_lock[channel]++;
			spin_unlock_irqrestore(&card->lock, flags);
			skb = card->xskb[channel];
			if (!skb) {
				skb = skb_dequeue(&card->spqueue[channel]);
				if (skb) {
					/* Pop ACK-flag off skb.
					 * Store length to xlen.
					 */
					if (*(skb_pull(skb, 1)))
						card->xlen[channel] = skb->len;
					else
						card->xlen[channel] = 0;
				}
			}
			if (!skb)
				break;
			if (skb->len > ICN_FRAGSIZE) {
				writeb(0xff, &sbuf_f);
				cnt = ICN_FRAGSIZE;
			} else {
				writeb(0x0, &sbuf_f);
				cnt = skb->len;
			}
			writeb(cnt, &sbuf_l);
			memcpy_toio(&sbuf_d, skb->data, cnt);
			skb_pull(skb, cnt);
			sbnext; /* switch to next buffer        */
			icn_maprelease_channel(card, mch & 2);
			spin_lock_irqsave(&card->lock, flags);
			card->sndcount[channel] -= cnt;
			if (!skb->len) {
				if (card->xskb[channel])
					card->xskb[channel] = NULL;
				card->xmit_lock[channel] = 0;
				spin_unlock_irqrestore(&card->lock, flags);
				dev_kfree_skb(skb);
				if (card->xlen[channel]) {
					cmd.command = ISDN_STAT_BSENT;
					cmd.driver = card->myid;
					cmd.arg = channel;
					cmd.parm.length = card->xlen[channel];
					card->interface.statcallb(&cmd);
				}
			} else {
				card->xskb[channel] = skb;
				card->xmit_lock[channel] = 0;
				spin_unlock_irqrestore(&card->lock, flags);
			}
			if (!icn_trymaplock_channel(card, mch))
				break;
		}
		icn_maprelease_channel(card, mch & 2);
	}
}

/* Send/Receive Data to/from the B-Channel.
 * This routine is called via timer-callback.
 * It schedules itself while any B-Channel is open.
 */

static void
icn_pollbchan(unsigned long data)
{
	icn_card *card = (icn_card *) data;
	unsigned long flags;

	if (card->flags & ICN_FLAGS_B1ACTIVE) {
		icn_pollbchan_receive(0, card);
		icn_pollbchan_send(0, card);
	}
	if (card->flags & ICN_FLAGS_B2ACTIVE) {
		icn_pollbchan_receive(1, card);
		icn_pollbchan_send(1, card);
	}
	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
		/* schedule b-channel polling again */
		spin_lock_irqsave(&card->lock, flags);
		mod_timer(&card->rb_timer, jiffies + ICN_TIMER_BCREAD);
		card->flags |= ICN_FLAGS_RBTIMER;
		spin_unlock_irqrestore(&card->lock, flags);
	} else
		card->flags &= ~ICN_FLAGS_RBTIMER;
}

typedef struct icn_stat {
	char *statstr;
	int command;
	int action;
} icn_stat;
/* *INDENT-OFF* */
static icn_stat icn_stat_table[] =
{
	{"BCON_",          ISDN_STAT_BCONN, 1},	/* B-Channel connected        */
	{"BDIS_",          ISDN_STAT_BHUP,  2},	/* B-Channel disconnected     */
	/*
	** add d-channel connect and disconnect support to link-level
	*/
	{"DCON_",          ISDN_STAT_DCONN, 10},	/* D-Channel connected        */
	{"DDIS_",          ISDN_STAT_DHUP,  11},	/* 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* */


/*
 * Check Statusqueue-Pointer from isdn-cards.
 * If there are new status-replies from the interface, check
 * them against B-Channel-connects/disconnects and set flags accordingly.
 * Wake-Up any processes, who are reading the status-device.
 * If there are B-Channels open, initiate a timer-callback to
 * icn_pollbchan().
 * This routine is called periodically via timer.
 */

static void
icn_parse_status(u_char *status, int channel, icn_card *card)
{
	icn_stat *s = icn_stat_table;
	int action = -1;
	unsigned long flags;
	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 11:
		spin_lock_irqsave(&card->lock, flags);
		icn_free_queue(card, channel);
		card->rcvidx[channel] = 0;

		if (card->flags &
		    ((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) {

			isdn_ctrl ncmd;

			card->flags &= ~((channel) ?
					 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);

			memset(&ncmd, 0, sizeof(ncmd));

			ncmd.driver = card->myid;
			ncmd.arg = channel;
			ncmd.command = ISDN_STAT_BHUP;
			spin_unlock_irqrestore(&card->lock, flags);
			card->interface.statcallb(&cmd);
		} else
			spin_unlock_irqrestore(&card->lock, flags);
		break;
	case 1:
		spin_lock_irqsave(&card->lock, flags);
		icn_free_queue(card, channel);
		card->flags |= (channel) ?
			ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
		spin_unlock_irqrestore(&card->lock, flags);
		break;
	case 2:
		spin_lock_irqsave(&card->lock, flags);
		card->flags &= ~((channel) ?
				 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
		icn_free_queue(card, channel);
		card->rcvidx[channel] = 0;
		spin_unlock_irqrestore(&card->lock, flags);
		break;
	case 3:
	{
		char *t = status + 6;
		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;
	break;
	case 4:
		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:
		strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
		break;
	case 6:
		snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
			 (int) simple_strtoul(status + 7, NULL, 16));
		break;
	case 7:
		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:
		spin_lock_irqsave(&card->lock, flags);
		card->flags &= ~ICN_FLAGS_B1ACTIVE;
		icn_free_queue(card, 0);
		card->rcvidx[0] = 0;
		spin_unlock_irqrestore(&card->lock, flags);
		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;
		spin_lock_irqsave(&card->lock, flags);
		card->flags &= ~ICN_FLAGS_B2ACTIVE;
		icn_free_queue(card, 1);
		card->rcvidx[1] = 0;
		spin_unlock_irqrestore(&card->lock, flags);
		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);
	return;
}

static void
icn_putmsg(icn_card *card, unsigned char c)
{
	ulong flags;

	spin_lock_irqsave(&card->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->lock, flags);
}

static void
icn_polldchan(unsigned long data)
{
	icn_card *card = (icn_card *) data;
	int mch = card->secondhalf ? 2 : 0;
	int avail = 0;
	int left;
	u_char c;
	int ch;
	unsigned long flags;
	int i;
	u_char *p;
	isdn_ctrl cmd;

	if (icn_trymaplock_channel(card, mch)) {
		avail = msg_avail;
		for (left = avail, i = readb(&msg_o); left > 0; i++, left--) {
			c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]);
			icn_putmsg(card, c);
			if (c == 0xff) {
				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];
					icn_parse_status(p, ch, card);
				} else {
					p = card->imsg;
					if (!strncmp(p, "DRV1.", 5)) {
						u_char vstr[10];
						u_char *q = vstr;

						printk(KERN_INFO "icn: (%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
							       "icn: (%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
							       "icn: (%s) Euro-Protocol loaded and running\n", CID);
						}
						p = strstr(card->imsg, "BRV") + 3;
						while (*p) {
							if (*p >= '0' && *p <= '9')
								*q++ = *p;
							p++;
						}
						*q = '\0';
						strcat(vstr, "000");
						vstr[3] = '\0';
						card->fw_rev = (int) simple_strtoul(vstr, NULL, 10);
						continue;

					}
				}
			} else {
				card->imsg[card->iptr] = c;
				if (card->iptr < 59)
					card->iptr++;
			}
		}
		writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
		icn_release_channel();
	}
	if (avail) {
		cmd.command = ISDN_STAT_STAVAIL;
		cmd.driver = card->myid;
		cmd.arg = avail;
		card->interface.statcallb(&cmd);
	}
	spin_lock_irqsave(&card->lock, flags);
	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
		if (!(card->flags & ICN_FLAGS_RBTIMER)) {
			/* schedule b-channel polling */
			card->flags |= ICN_FLAGS_RBTIMER;
			del_timer(&card->rb_timer);
			card->rb_timer.function = icn_pollbchan;
			card->rb_timer.data = (unsigned long) card;
			card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
			add_timer(&card->rb_timer);
		}
	/* schedule again */
	mod_timer(&card->st_timer, jiffies + ICN_TIMER_DCREAD);
	spin_unlock_irqrestore(&card->lock, flags);
}

/* Append a packet to the transmit buffer-queue.
 * Parameters:
 *   channel = Number of B-channel
 *   skb     = pointer to sk_buff
 *   card    = pointer to card-struct
 * Return:
 *   Number of bytes transferred, -E??? on error
 */

static int
icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card)
{
	int len = skb->len;
	unsigned long flags;
	struct sk_buff *nskb;

	if (len > 4000) {
		printk(KERN_WARNING
		       "icn: Send packet too large\n");
		return -EINVAL;
	}
	if (len) {
		if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE))
			return 0;
		if (card->sndcount[channel] > ICN_MAX_SQUEUE)
			return 0;
#warning TODO test headroom or use skb->nb to flag ACK
		nskb = skb_clone(skb, GFP_ATOMIC);
		if (nskb) {
			/* Push ACK flag as one
			 * byte in front of data.
			 */
			*(skb_push(nskb, 1)) = ack ? 1 : 0;
			skb_queue_tail(&card->spqueue[channel], nskb);
			dev_kfree_skb(skb);
		} else
			len = 0;
		spin_lock_irqsave(&card->lock, flags);
		card->sndcount[channel] += len;
		spin_unlock_irqrestore(&card->lock, flags);
	}
	return len;
}

/*
 * Check card's status after starting the bootstrap loader.
 * On entry, the card's shared memory has already to be mapped.
 * Return:
 *   0 on success (Boot loader ready)
 *   -EIO on failure (timeout)
 */
static int
icn_check_loader(int cardnumber)
{
	int timer = 0;

	while (1) {
#ifdef BOOT_DEBUG
		printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
#endif
		if (readb(&dev.shmem->data_control.scns) ||
		    readb(&dev.shmem->data_control.scnr)) {
			if (timer++ > 5) {
				printk(KERN_WARNING
				       "icn: Boot-Loader %d timed out.\n",
				       cardnumber);
				icn_release_channel();
				return -EIO;
			}
#ifdef BOOT_DEBUG
			printk(KERN_DEBUG "Loader %d TO?\n", cardnumber);
#endif
			msleep_interruptible(ICN_BOOT_TIMEOUT1);
		} else {
#ifdef BOOT_DEBUG
			printk(KERN_DEBUG "Loader %d OK\n", cardnumber);
#endif
			icn_release_channel();
			return 0;
		}
	}
}

/* Load the boot-code into the interface-card's memory and start it.
 * Always called from user-process.
 *
 * Parameters:
 *            buffer = pointer to packet
 * Return:
 *        0 if successfully loaded
 */

#ifdef BOOT_DEBUG
#define SLEEP(sec) {						\
		int slsec = sec;				\
		printk(KERN_DEBUG "SLEEP(%d)\n", slsec);	\
		while (slsec) {					\
			msleep_interruptible(1000);		\
			slsec--;				\
		}						\
	}
#else
#define SLEEP(sec)
#endif

static int
icn_loadboot(u_char __user *buffer, icn_card *card)
{
	int ret;
	u_char *codebuf;
	unsigned long flags;

#ifdef BOOT_DEBUG
	printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
#endif
	if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
		printk(KERN_WARNING "icn: Could not allocate code buffer\n");
		ret = -ENOMEM;
		goto out;
	}
	if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) {
		ret = -EFAULT;
		goto out_kfree;
	}
	if (!card->rvalid) {
		if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
			printk(KERN_WARNING
			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
			       CID,
			       card->port,
			       card->port + ICN_PORTLEN);
			ret = -EBUSY;
			goto out_kfree;
		}
		card->rvalid = 1;
		if (card->doubleS0)
			card->other->rvalid = 1;
	}
	if (!dev.mvalid) {
		if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) {
			printk(KERN_WARNING
			       "icn: memory at 0x%08lx in use.\n", dev.memaddr);
			ret = -EBUSY;
			goto out_kfree;
		}
		dev.shmem = ioremap(dev.memaddr, 0x4000);
		dev.mvalid = 1;
	}
	OUTB_P(0, ICN_RUN);     /* Reset Controller */
	OUTB_P(0, ICN_MAPRAM);  /* Disable RAM      */
	icn_shiftout(ICN_CFG, 0x0f, 3, 4);	/* Windowsize= 16k  */
	icn_shiftout(ICN_CFG, dev.memaddr, 23, 10);	/* Set RAM-Addr.    */
#ifdef BOOT_DEBUG
	printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr);
#endif
	SLEEP(1);
#ifdef BOOT_DEBUG
	printk(KERN_DEBUG "Map Bank 0\n");
#endif
	spin_lock_irqsave(&dev.devlock, flags);
	icn_map_channel(card, 0);	/* Select Bank 0    */
	icn_lock_channel(card, 0);	/* Lock Bank 0      */
	spin_unlock_irqrestore(&dev.devlock, flags);
	SLEEP(1);
	memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */
#ifdef BOOT_DEBUG
	printk(KERN_DEBUG "Bootloader transferred\n");
#endif
	if (card->doubleS0) {
		SLEEP(1);
#ifdef BOOT_DEBUG
		printk(KERN_DEBUG "Map Bank 8\n");
#endif
		spin_lock_irqsave(&dev.devlock, flags);
		__icn_release_channel();
		icn_map_channel(card, 2);	/* Select Bank 8   */
		icn_lock_channel(card, 2);	/* Lock Bank 8     */
		spin_unlock_irqrestore(&dev.devlock, flags);
		SLEEP(1);
		memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */
#ifdef BOOT_DEBUG
		printk(KERN_DEBUG "Bootloader transferred\n");
#endif
	}
	SLEEP(1);
	OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */
	if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) {
		goto out_kfree;
	}
	if (!card->doubleS0) {
		ret = 0;
		goto out_kfree;
	}
	/* reached only, if we have a Double-S0-Card */
#ifdef BOOT_DEBUG
	printk(KERN_DEBUG "Map Bank 0\n");
#endif
	spin_lock_irqsave(&dev.devlock, flags);
	icn_map_channel(card, 0);	/* Select Bank 0   */
	icn_lock_channel(card, 0);	/* Lock Bank 0     */
	spin_unlock_irqrestore(&dev.devlock, flags);
	SLEEP(1);
	ret = (icn_check_loader(1));

out_kfree:
	kfree(codebuf);
out:
	return ret;
}

static int
icn_loadproto(u_char __user *buffer, icn_card *card)
{
	register u_char __user *p = buffer;
	u_char codebuf[256];
	uint left = ICN_CODE_STAGE2;
	uint cnt;
	int timer;
	unsigned long flags;

#ifdef BOOT_DEBUG
	printk(KERN_DEBUG "icn_loadproto called\n");
#endif
	if (!access_ok(VERIFY_READ, buffer, ICN_CODE_STAGE2))
		return -EFAULT;
	timer = 0;
	spin_lock_irqsave(&dev.devlock, flags);
	if (card->secondhalf) {
		icn_map_channel(card, 2);
		icn_lock_channel(card, 2);
	} else {
		icn_map_channel(card, 0);
		icn_lock_channel(card, 0);
	}
	spin_unlock_irqrestore(&dev.devlock, flags);
	while (left) {
		if (sbfree) {   /* If there is a free buffer...  */
			cnt = left;
			if (cnt > 256)
				cnt = 256;
			if (copy_from_user(codebuf, p, cnt)) {
				icn_maprelease_channel(card, 0);
				return -EFAULT;
			}
			memcpy_toio(&sbuf_l, codebuf, cnt);	/* copy data                     */
			sbnext; /* switch to next buffer         */
			p += cnt;
			left -= cnt;
			timer = 0;
		} else {
#ifdef BOOT_DEBUG
			printk(KERN_DEBUG "boot 2 !sbfree\n");
#endif
			if (timer++ > 5) {
				icn_maprelease_channel(card, 0);
				return -EIO;
			}
			schedule_timeout_interruptible(10);
		}
	}
	writeb(0x20, &sbuf_n);
	timer = 0;
	while (1) {
		if (readb(&cmd_o) || readb(&cmd_i)) {
#ifdef BOOT_DEBUG
			printk(KERN_DEBUG "Proto?\n");
#endif
			if (timer++ > 5) {
				printk(KERN_WARNING
				       "icn: (%s) Protocol timed out.\n",
				       CID);
#ifdef BOOT_DEBUG
				printk(KERN_DEBUG "Proto TO!\n");
#endif
				icn_maprelease_channel(card, 0);
				return -EIO;
			}
#ifdef BOOT_DEBUG
			printk(KERN_DEBUG "Proto TO?\n");
#endif
			msleep_interruptible(ICN_BOOT_TIMEOUT1);
		} else {
			if ((card->secondhalf) || (!card->doubleS0)) {
#ifdef BOOT_DEBUG
				printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
				       card->secondhalf);
#endif
				spin_lock_irqsave(&card->lock, flags);
				init_timer(&card->st_timer);
				card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
				card->st_timer.function = icn_polldchan;
				card->st_timer.data = (unsigned long) card;
				add_timer(&card->st_timer);
				card->flags |= ICN_FLAGS_RUNNING;
				if (card->doubleS0) {
					init_timer(&card->other->st_timer);
					card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
					card->other->st_timer.function = icn_polldchan;
					card->other->st_timer.data = (unsigned long) card->other;
					add_timer(&card->other->st_timer);
					card->other->flags |= ICN_FLAGS_RUNNING;
				}
				spin_unlock_irqrestore(&card->lock, flags);
			}
			icn_maprelease_channel(card, 0);
			return 0;
		}
	}
}

/* Read the Status-replies from the Interface */
static int
icn_readstatus(u_char __user *buf, int len, icn_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;
}

/* Put command-strings into the command-queue of the Interface */
static int
icn_writecmd(const u_char *buf, int len, int user, icn_card *card)
{
	int mch = card->secondhalf ? 2 : 0;
	int pp;
	int i;
	int count;
	int xcount;
	int ocount;
	int loop;
	unsigned long flags;
	int lastmap_channel;
	struct icn_card *lastmap_card;
	u_char *p;
	isdn_ctrl cmd;
	u_char msg[0x100];

	ocount = 1;
	xcount = loop = 0;
	while (len) {
		count = cmd_free;
		if (count > len)
			count = len;
		if (user) {
			if (copy_from_user(msg, buf, count))
				return -EFAULT;
		} else
			memcpy(msg, buf, count);

		spin_lock_irqsave(&dev.devlock, flags);
		lastmap_card = dev.mcard;
		lastmap_channel = dev.channel;
		icn_map_channel(card, mch);

		icn_putmsg(card, '>');
		for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp
			     ++) {
			writeb((*p == '\n') ? 0xff : *p,
			       &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
			len--;
			xcount++;
			icn_putmsg(card, *p);
			if ((*p == '\n') && (i > 1)) {
				icn_putmsg(card, '>');
				ocount++;
			}
			ocount++;
		}
		writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
		if (lastmap_card)
			icn_map_channel(lastmap_card, lastmap_channel);
		spin_unlock_irqrestore(&dev.devlock, flags);
		if (len) {
			mdelay(1);
			if (loop++ > 20)
				break;
		} else
			break;
	}
	if (len && (!user))
		printk(KERN_WARNING "icn: writemsg incomplete!\n");
	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
icn_stopcard(icn_card *card)
{
	unsigned long flags;
	isdn_ctrl cmd;

	spin_lock_irqsave(&card->lock, flags);
	if (card->flags & ICN_FLAGS_RUNNING) {
		card->flags &= ~ICN_FLAGS_RUNNING;
		del_timer(&card->st_timer);
		del_timer(&card->rb_timer);
		spin_unlock_irqrestore(&card->lock, flags);
		cmd.command = ISDN_STAT_STOP;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
		if (card->doubleS0)
			icn_stopcard(card->other);
	} else
		spin_unlock_irqrestore(&card->lock, flags);
}

static void
icn_stopallcards(void)
{
	icn_card *p = cards;

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

/*
 * Unmap all cards, because some of them may be mapped accidetly during
 * autoprobing of some network drivers (SMC-driver?)
 */
static void
icn_disable_cards(void)
{
	icn_card *card = cards;

	while (card) {
		if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) {
			printk(KERN_WARNING
			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
			       CID,
			       card->port,
			       card->port + ICN_PORTLEN);
		} else {
			OUTB_P(0, ICN_RUN);	/* Reset Controller     */
			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */
			release_region(card->port, ICN_PORTLEN);
		}
		card = card->next;
	}
}

static int
icn_command(isdn_ctrl *c, icn_card *card)
{
	ulong a;
	ulong flags;
	int i;
	char cbuf[80];
	isdn_ctrl cmd;
	icn_cdef cdef;
	char __user *arg;

	switch (c->command) {
	case ISDN_CMD_IOCTL:
		memcpy(&a, c->parm.num, sizeof(ulong));
		arg = (char __user *)a;
		switch (c->arg) {
		case ICN_IOCTL_SETMMIO:
			if (dev.memaddr != (a & 0x0ffc000)) {
				if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) {
					printk(KERN_WARNING
					       "icn: memory at 0x%08lx in use.\n",
					       a & 0x0ffc000);
					return -EINVAL;
				}
				release_mem_region(a & 0x0ffc000, 0x4000);
				icn_stopallcards();
				spin_lock_irqsave(&card->lock, flags);
				if (dev.mvalid) {
					iounmap(dev.shmem);
					release_mem_region(dev.memaddr, 0x4000);
				}
				dev.mvalid = 0;
				dev.memaddr = a & 0x0ffc000;
				spin_unlock_irqrestore(&card->lock, flags);
				printk(KERN_INFO
				       "icn: (%s) mmio set to 0x%08lx\n",
				       CID,
				       dev.memaddr);
			}
			break;
		case ICN_IOCTL_GETMMIO:
			return (long) dev.memaddr;
		case ICN_IOCTL_SETPORT:
			if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
			    || a == 0x340 || a == 0x350 || a == 0x360 ||
			    a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
			    || a == 0x348 || a == 0x358 || a == 0x368) {
				if (card->port != (unsigned short) a) {
					if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) {
						printk(KERN_WARNING
						       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
						       CID, (int) a, (int) a + ICN_PORTLEN);
						return -EINVAL;
					}
					release_region((unsigned short) a, ICN_PORTLEN);
					icn_stopcard(card);
					spin_lock_irqsave(&card->lock, flags);
					if (card->rvalid)
						release_region(card->port, ICN_PORTLEN);
					card->port = (unsigned short) a;
					card->rvalid = 0;
					if (card->doubleS0) {
						card->other->port = (unsigned short) a;
						card->other->rvalid = 0;
					}
					spin_unlock_irqrestore(&card->lock, flags);
					printk(KERN_INFO
					       "icn: (%s) port set to 0x%03x\n",
					       CID, card->port);
				}
			} else
				return -EINVAL;
			break;
		case ICN_IOCTL_GETPORT:
			return (int) card->port;
		case ICN_IOCTL_GETDOUBLE:
			return (int) card->doubleS0;
		case ICN_IOCTL_DEBUGVAR:
			if (copy_to_user(arg,
					 &card,
					 sizeof(ulong)))
				return -EFAULT;
			a += sizeof(ulong);
			{
				ulong l = (ulong)&dev;
				if (copy_to_user(arg,
						 &l,
						 sizeof(ulong)))
					return -EFAULT;
			}
			return 0;
		case ICN_IOCTL_LOADBOOT:
			if (dev.firstload) {
				icn_disable_cards();
				dev.firstload = 0;
			}
			icn_stopcard(card);
			return (icn_loadboot(arg, card));
		case ICN_IOCTL_LOADPROTO:
			icn_stopcard(card);
			if ((i = (icn_loadproto(arg, card))))
				return i;
			if (card->doubleS0)
				i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other);
			return i;
			break;
		case ICN_IOCTL_ADDCARD:
			if (!dev.firstload)
				return -EBUSY;
			if (copy_from_user(&cdef,
					   arg,
					   sizeof(cdef)))
				return -EFAULT;
			return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
			break;
		case ICN_IOCTL_LEASEDCFG:
			if (a) {
				if (!card->leased) {
					card->leased = 1;
					while (card->ptype == ISDN_PTYPE_UNKNOWN) {
						msleep_interruptible(ICN_BOOT_TIMEOUT1);
					}
					msleep_interruptible(ICN_BOOT_TIMEOUT1);
					sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
						(a & 1) ? '1' : 'C', (a & 2) ? '2' : 'C');
					i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
					printk(KERN_INFO
					       "icn: (%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 = icn_writecmd(cbuf, strlen(cbuf), 0, card);
					printk(KERN_INFO
					       "icn: (%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 & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if (card->leased)
			break;
		if ((c->arg & 255) < ICN_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 = icn_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_ACCEPTD:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if (c->arg < ICN_BCH) {
			a = c->arg + 1;
			if (card->fw_rev >= 300) {
				switch (card->l2_proto[a - 1]) {
				case ISDN_PROTO_L2_X75I:
					sprintf(cbuf, "%02d;BX75\n", (int) a);
					break;
				case ISDN_PROTO_L2_HDLC:
					sprintf(cbuf, "%02d;BTRA\n", (int) a);
					break;
				}
				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			}
			sprintf(cbuf, "%02d;DCON_R\n", (int) a);
			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_ACCEPTB:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if (c->arg < ICN_BCH) {
			a = c->arg + 1;
			if (card->fw_rev >= 300)
				switch (card->l2_proto[a - 1]) {
				case ISDN_PROTO_L2_X75I:
					sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
					break;
				case ISDN_PROTO_L2_HDLC:
					sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
					break;
				} else
				sprintf(cbuf, "%02d;BCON_R\n", (int) a);
			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_HANGUP:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if (c->arg < ICN_BCH) {
			a = c->arg + 1;
			sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_SETEAZ:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if (card->leased)
			break;
		if (c->arg < ICN_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] ? (char *)(c->parm.num) : "0123456789");
			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_CLREAZ:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if (card->leased)
			break;
		if (c->arg < ICN_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 = icn_writecmd(cbuf, strlen(cbuf), 0, card);
		}
		break;
	case ISDN_CMD_SETL2:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		if ((c->arg & 255) < ICN_BCH) {
			a = c->arg;
			switch (a >> 8) {
			case ISDN_PROTO_L2_X75I:
				sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
				break;
			case ISDN_PROTO_L2_HDLC:
				sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
				break;
			default:
				return -EINVAL;
			}
			i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
			card->l2_proto[a & 255] = (a >> 8);
		}
		break;
	case ISDN_CMD_SETL3:
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		return 0;
	default:
		return -EINVAL;
	}
	return 0;
}

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

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

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

	if (card)
		return (icn_command(c, card));
	printk(KERN_ERR
	       "icn: if_command %d called with invalid driverId %d!\n",
	       c->command, c->driver);
	return -ENODEV;
}

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

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

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

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

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

	if (card) {
		if (!(card->flags & ICN_FLAGS_RUNNING))
			return -ENODEV;
		return (icn_sendbuf(channel, ack, skb, card));
	}
	printk(KERN_ERR
	       "icn: 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 icn_card *
icn_initcard(int port, char *id)
{
	icn_card *card;
	int i;

	if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) {
		printk(KERN_WARNING
		       "icn: (%s) Could not allocate card-struct.\n", id);
		return (icn_card *) 0;
	}
	spin_lock_init(&card->lock);
	card->port = port;
	card->interface.owner = THIS_MODULE;
	card->interface.hl_hdrlen = 1;
	card->interface.channels = ICN_BCH;
	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 |
		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 < ICN_BCH; i++) {
		card->l2_proto[i] = ISDN_PROTO_L2_X75I;
		skb_queue_head_init(&card->spqueue[i]);
	}
	card->next = cards;
	cards = card;
	if (!register_isdn(&card->interface)) {
		cards = cards->next;
		printk(KERN_WARNING
		       "icn: Unable to register %s\n", id);
		kfree(card);
		return (icn_card *) 0;
	}
	card->myid = card->interface.channels;
	sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
	return card;
}

static int
icn_addcard(int port, char *id1, char *id2)
{
	icn_card *card;
	icn_card *card2;

	if (!(card = icn_initcard(port, id1))) {
		return -EIO;
	}
	if (!strlen(id2)) {
		printk(KERN_INFO
		       "icn: (%s) ICN-2B, port 0x%x added\n",
		       card->interface.id, port);
		return 0;
	}
	if (!(card2 = icn_initcard(port, id2))) {
		printk(KERN_INFO
		       "icn: (%s) half ICN-4B, port 0x%x added\n", id2, port);
		return 0;
	}
	card->doubleS0 = 1;
	card->secondhalf = 0;
	card->other = card2;
	card2->doubleS0 = 1;
	card2->secondhalf = 1;
	card2->other = card;
	printk(KERN_INFO
	       "icn: (%s and %s) ICN-4B, port 0x%x added\n",
	       card->interface.id, card2->interface.id, port);
	return 0;
}

#ifndef MODULE
static int __init
icn_setup(char *line)
{
	char *p, *str;
	int	ints[3];
	static char sid[20];
	static char sid2[20];

	str = get_options(line, 2, ints);
	if (ints[0])
		portbase = ints[1];
	if (ints[0] > 1)
		membase = (unsigned long)ints[2];
	if (str && *str) {
		strlcpy(sid, str, sizeof(sid));
		icn_id = sid;
		if ((p = strchr(sid, ','))) {
			*p++ = 0;
			strcpy(sid2, p);
			icn_id2 = sid2;
		}
	}
	return (1);
}
__setup("icn=", icn_setup);
#endif /* MODULE */

static int __init icn_init(void)
{
	char *p;
	char rev[21];

	memset(&dev, 0, sizeof(icn_dev));
	dev.memaddr = (membase & 0x0ffc000);
	dev.channel = -1;
	dev.mcard = NULL;
	dev.firstload = 1;
	spin_lock_init(&dev.devlock);

	if ((p = strchr(revision, ':'))) {
		strncpy(rev, p + 1, 20);
		rev[20] = '\0';
		p = strchr(rev, '$');
		if (p)
			*p = 0;
	} else
		strcpy(rev, " ??? ");
	printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
	       dev.memaddr);
	return (icn_addcard(portbase, icn_id, icn_id2));
}

static void __exit icn_exit(void)
{
	isdn_ctrl cmd;
	icn_card *card = cards;
	icn_card *last, *tmpcard;
	int i;
	unsigned long flags;

	icn_stopallcards();
	while (card) {
		cmd.command = ISDN_STAT_UNLOAD;
		cmd.driver = card->myid;
		card->interface.statcallb(&cmd);
		spin_lock_irqsave(&card->lock, flags);
		if (card->rvalid) {
			OUTB_P(0, ICN_RUN);	/* Reset Controller     */
			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */
			if (card->secondhalf || (!card->doubleS0)) {
				release_region(card->port, ICN_PORTLEN);
				card->rvalid = 0;
			}
			for (i = 0; i < ICN_BCH; i++)
				icn_free_queue(card, i);
		}
		tmpcard = card->next;
		spin_unlock_irqrestore(&card->lock, flags);
		card = tmpcard;
	}
	card = cards;
	cards = NULL;
	while (card) {
		last = card;
		card = card->next;
		kfree(last);
	}
	if (dev.mvalid) {
		iounmap(dev.shmem);
		release_mem_region(dev.memaddr, 0x4000);
	}
	printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
}

module_init(icn_init);
module_exit(icn_exit);
