/*
 * PCBIT-D interface with isdn4linux
 *
 * Copyright (C) 1996 Universidade de Lisboa
 * 
 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
 *
 * This software may be used and distributed according to the terms of 
 * the GNU General Public License, incorporated herein by reference.
 */

/*
 *	Fixes:
 *
 *	Nuno Grilo	<l38486@alfa.ist.utl.pt>
 *      fixed msn_list NULL pointer dereference.
 *		
 */

#include <linux/module.h>

#include <linux/sched.h>

#include <linux/kernel.h>

#include <linux/types.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/skbuff.h>

#include <linux/isdnif.h>
#include <asm/string.h>
#include <asm/io.h>
#include <linux/ioport.h>

#include "pcbit.h"
#include "edss1.h"
#include "layer2.h"
#include "capi.h"


extern ushort last_ref_num;

static int pcbit_ioctl(isdn_ctrl* ctl);

static char* pcbit_devname[MAX_PCBIT_CARDS] = {
	"pcbit0",
	"pcbit1",
	"pcbit2",
	"pcbit3"
};

/*
 * prototypes
 */

static int pcbit_command(isdn_ctrl* ctl);
static int pcbit_stat(u_char __user * buf, int len, int, int);
static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
static int pcbit_writecmd(const u_char __user *, int, int, int);

static int set_protocol_running(struct pcbit_dev * dev);

static void pcbit_clear_msn(struct pcbit_dev *dev);
static void pcbit_set_msn(struct pcbit_dev *dev, char *list);
static int pcbit_check_msn(struct pcbit_dev *dev, char *msn);


extern void pcbit_deliver(void * data);

int pcbit_init_dev(int board, int mem_base, int irq)
{
	struct pcbit_dev *dev;
	isdn_if *dev_if;

	if ((dev=kmalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
	{
		printk("pcbit_init: couldn't malloc pcbit_dev struct\n");
		return -ENOMEM;
	}

	dev_pcbit[board] = dev;
	memset(dev, 0, sizeof(struct pcbit_dev));
	init_waitqueue_head(&dev->set_running_wq);
	spin_lock_init(&dev->lock);

	if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) {
		dev->ph_mem = mem_base;
		if (!request_mem_region(dev->ph_mem, 4096, "PCBIT mem")) {
			printk(KERN_WARNING
				"PCBIT: memory region %lx-%lx already in use\n",
				dev->ph_mem, dev->ph_mem + 4096);
			kfree(dev);
			dev_pcbit[board] = NULL;
			return -EACCES;
		}
		dev->sh_mem = ioremap(dev->ph_mem, 4096);
	}
	else 
	{
		printk("memory address invalid");
		kfree(dev);
		dev_pcbit[board] = NULL;
		return -EACCES;
	}

	dev->b1 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
	if (!dev->b1) {
		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
		iounmap(dev->sh_mem);
		release_mem_region(dev->ph_mem, 4096);
		kfree(dev);
		return -ENOMEM;
	}
    
	dev->b2 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
	if (!dev->b2) {
		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
		kfree(dev->b1);
		iounmap(dev->sh_mem);
		release_mem_region(dev->ph_mem, 4096);
		kfree(dev);
		return -ENOMEM;
	}

	memset(dev->b1, 0, sizeof(struct pcbit_chan));
	memset(dev->b2, 0, sizeof(struct pcbit_chan));
	dev->b2->id = 1;

	INIT_WORK(&dev->qdelivery, pcbit_deliver, dev);

	/*
	 *  interrupts
	 */

	if (request_irq(irq, &pcbit_irq_handler, 0, pcbit_devname[board], dev) != 0) 
	{
		kfree(dev->b1);
		kfree(dev->b2);
		iounmap(dev->sh_mem);
		release_mem_region(dev->ph_mem, 4096);
		kfree(dev);
		dev_pcbit[board] = NULL;
		return -EIO;
	}

	dev->irq = irq;

	/* next frame to be received */
	dev->rcv_seq = 0;
	dev->send_seq = 0;
	dev->unack_seq = 0;

	dev->hl_hdrlen = 16;

	dev_if = kmalloc(sizeof(isdn_if), GFP_KERNEL);

	if (!dev_if) {
		free_irq(irq, dev);
		kfree(dev->b1);
		kfree(dev->b2);
		iounmap(dev->sh_mem);
		release_mem_region(dev->ph_mem, 4096);
		kfree(dev);
		dev_pcbit[board] = NULL;
		return -EIO;
	}

	dev->dev_if = dev_if;

	dev_if->owner = THIS_MODULE;

	dev_if->channels = 2;
	
	dev_if->features = (ISDN_FEATURE_P_EURO  | ISDN_FEATURE_L3_TRANS | 
			    ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS );

	dev_if->writebuf_skb = pcbit_xmit;
	dev_if->hl_hdrlen = 16;

	dev_if->maxbufsize = MAXBUFSIZE;
	dev_if->command  = pcbit_command;
	
	dev_if->writecmd = pcbit_writecmd;
	dev_if->readstat = pcbit_stat;


	strcpy(dev_if->id, pcbit_devname[board]);

	if (!register_isdn(dev_if)) {
		free_irq(irq, dev);
		kfree(dev->b1);
		kfree(dev->b2);
		iounmap(dev->sh_mem);
		release_mem_region(dev->ph_mem, 4096);
		kfree(dev);
		dev_pcbit[board] = NULL;
		return -EIO;
	}

	dev->id = dev_if->channels;


	dev->l2_state = L2_DOWN;
	dev->free = 511;

	/*
	 * set_protocol_running(dev);
	 */

	return 0;
}

#ifdef MODULE
void pcbit_terminate(int board)
{
	struct pcbit_dev * dev;

	dev = dev_pcbit[board];

	if (dev) {
	     /* unregister_isdn(dev->dev_if); */
		free_irq(dev->irq, dev);
		pcbit_clear_msn(dev);
		kfree(dev->dev_if);
		if (dev->b1->fsm_timer.function)
			del_timer(&dev->b1->fsm_timer);
		if (dev->b2->fsm_timer.function)
			del_timer(&dev->b2->fsm_timer);
		kfree(dev->b1);
		kfree(dev->b2);
		iounmap(dev->sh_mem);
		release_mem_region(dev->ph_mem, 4096);
		kfree(dev);
	}
}
#endif

static int pcbit_command(isdn_ctrl* ctl)
{
	struct pcbit_dev  *dev;
	struct pcbit_chan *chan;
	struct callb_data info;

	dev = finddev(ctl->driver);

	if (!dev)
	{
		printk("pcbit_command: unknown device\n");
		return -1;
	}

	chan = (ctl->arg & 0x0F) ? dev->b2 : dev->b1;


	switch(ctl->command) {
	case ISDN_CMD_IOCTL:
		return pcbit_ioctl(ctl);
		break;
	case ISDN_CMD_DIAL:
		info.type = EV_USR_SETUP_REQ;
		info.data.setup.CalledPN = (char *) &ctl->parm.setup.phone;
		pcbit_fsm_event(dev, chan, EV_USR_SETUP_REQ, &info);
		break;
	case ISDN_CMD_ACCEPTD:
		pcbit_fsm_event(dev, chan, EV_USR_SETUP_RESP, NULL);
		break;
	case ISDN_CMD_ACCEPTB:
		printk("ISDN_CMD_ACCEPTB - not really needed\n");
		break;
	case ISDN_CMD_HANGUP:
		pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
		break;
	case ISDN_CMD_SETL2:
		chan->proto = (ctl->arg >> 8);
		break;
	case ISDN_CMD_CLREAZ:
		pcbit_clear_msn(dev);
		break;
	case ISDN_CMD_SETEAZ:
		pcbit_set_msn(dev, ctl->parm.num);
		break;
	case ISDN_CMD_SETL3:
		if ((ctl->arg >> 8) != ISDN_PROTO_L3_TRANS)
			printk(KERN_DEBUG "L3 protocol unknown\n");
		break;
	default:
		printk(KERN_DEBUG "pcbit_command: unknown command\n");
		break;
	};

	return 0;
}

/*
 * Another Hack :-(
 * on some conditions the board stops sending TDATA_CONFs
 * let's see if we can turn around the problem
 */

#ifdef BLOCK_TIMER
static void pcbit_block_timer(unsigned long data)
{
	struct pcbit_chan *chan;
	struct pcbit_dev * dev;
	isdn_ctrl ictl;

	chan = (struct pcbit_chan *) data;

	dev = chan2dev(chan);

	if (dev == NULL) {
		printk(KERN_DEBUG "pcbit: chan2dev failed\n");
		return;
	}

	del_timer(&chan->block_timer);
	chan->block_timer.function = NULL;

#ifdef DEBUG
	printk(KERN_DEBUG "pcbit_block_timer\n");
#endif	
	chan->queued = 0;
	ictl.driver = dev->id;
	ictl.command = ISDN_STAT_BSENT;
	ictl.arg = chan->id;
	dev->dev_if->statcallb(&ictl);     
}
#endif

static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
{
	ushort hdrlen;
	int refnum, len;
	struct pcbit_chan * chan;
	struct pcbit_dev *dev;

	dev = finddev(driver);
	if (dev == NULL)
	{
		printk("finddev returned NULL");
		return -1;
	}

	chan = chnum ? dev->b2 : dev->b1;


	if (chan->fsm_state != ST_ACTIVE)
		return -1;

	if (chan->queued >= MAX_QUEUED )
	{
#ifdef DEBUG_QUEUE
		printk(KERN_DEBUG 
		       "pcbit: %d packets already in queue - write fails\n",
		       chan->queued);
#endif
		/*
		 * packet stays on the head of the device queue
		 * since dev_start_xmit will fail
		 * see net/core/dev.c
		 */
#ifdef BLOCK_TIMER
		if (chan->block_timer.function == NULL) {
			init_timer(&chan->block_timer);
			chan->block_timer.function =  &pcbit_block_timer;
			chan->block_timer.data = (long) chan;
			chan->block_timer.expires = jiffies + 1 * HZ;
			add_timer(&chan->block_timer);
		}
#endif		
		return 0;	                 
	}


	chan->queued++;
	
        len = skb->len;

	hdrlen = capi_tdata_req(chan, skb);

	refnum = last_ref_num++ & 0x7fffU;
	chan->s_refnum = refnum;

	pcbit_l2_write(dev, MSG_TDATA_REQ, refnum, skb, hdrlen);

	return len;
}

static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
{
	struct pcbit_dev * dev;
	int i, j;
	const u_char * loadbuf;
	u_char * ptr = NULL;
	u_char *cbuf;

	int errstat;

	dev = finddev(driver);

	if (!dev)
	{
		printk("pcbit_writecmd: couldn't find device");
		return -ENODEV;
	}

	switch(dev->l2_state) {
	case L2_LWMODE:
		/* check (size <= rdp_size); write buf into board */
		if (len < 0 || len > BANK4 + 1 || len > 1024)
		{
			printk("pcbit_writecmd: invalid length %d\n", len);
			return -EINVAL;
		}

		cbuf = kmalloc(len, GFP_KERNEL);
		if (!cbuf)
			return -ENOMEM;

		if (copy_from_user(cbuf, buf, len)) {
			kfree(cbuf);
			return -EFAULT;
		}
		memcpy_toio(dev->sh_mem, cbuf, len);
		kfree(cbuf);
		return len;
	case L2_FWMODE:
		/* this is the hard part */
		/* dumb board */
		/* get it into kernel space */
		if ((ptr = kmalloc(len, GFP_KERNEL))==NULL)
			return -ENOMEM;
		if (copy_from_user(ptr, buf, len)) {
			kfree(ptr);
			return -EFAULT;
		}
		loadbuf = ptr;
    
		errstat = 0;

		for (i=0; i < len; i++)
		{
			for(j=0; j < LOAD_RETRY; j++)
				if (!(readb(dev->sh_mem + dev->loadptr)))
					break;

			if (j == LOAD_RETRY)
			{
				errstat = -ETIME;
				printk("TIMEOUT i=%d\n", i);
				break;
			}
			writeb(loadbuf[i], dev->sh_mem + dev->loadptr + 1);
			writeb(0x01, dev->sh_mem + dev->loadptr);

			dev->loadptr += 2;
			if (dev->loadptr > LOAD_ZONE_END)
				dev->loadptr = LOAD_ZONE_START;
		}
		kfree(ptr);

		return errstat ? errstat : len;
	default:
		return -EBUSY;
	}
}

/*
 *  demultiplexing of messages
 *
 */

void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg, 
			     struct sk_buff * skb,
			     ushort hdr_len, ushort refnum)
{
	struct pcbit_chan *chan;
	struct sk_buff *skb2;
	unsigned short len;
	struct callb_data cbdata;
	int complete, err;
	isdn_ctrl ictl;

	switch(msg) {

	case MSG_TDATA_IND:
		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}
		chan->r_refnum = skb->data[7];
		skb_pull(skb, 8);

		dev->dev_if->rcvcallb_skb(dev->id, chan->id, skb);

		if (capi_tdata_resp(chan, &skb2) > 0) 
			pcbit_l2_write(dev, MSG_TDATA_RESP, refnum, 
				       skb2, skb2->len);
		return;
		break;  
	case MSG_TDATA_CONF:
		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}

#ifdef DEBUG
		if ( (*((ushort *) (skb->data + 2) )) != 0) {
                        printk(KERN_DEBUG "TDATA_CONF error\n");
		}
#endif
#ifdef BLOCK_TIMER
                if (chan->queued == MAX_QUEUED) {
                        del_timer(&chan->block_timer);
			chan->block_timer.function = NULL;
		}
                
#endif		
		chan->queued--;

		ictl.driver = dev->id;
		ictl.command = ISDN_STAT_BSENT;
		ictl.arg = chan->id;
		dev->dev_if->statcallb(&ictl);
		break;

	case MSG_CONN_IND:
		/*
		 *  channel: 1st not used will do
		 *           if both are used we're in trouble 
		 */

		if (!dev->b1->fsm_state)
			chan = dev->b1;
		else if (!dev->b2->fsm_state)
			chan = dev->b2;
		else {
			printk(KERN_INFO 
			       "Incoming connection: no channels available");

			if ((len = capi_disc_req(*(ushort*)(skb->data), &skb2, CAUSE_NOCHAN)) > 0)
				pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb2, len);
			break;  
		}

		cbdata.data.setup.CalledPN = NULL;
		cbdata.data.setup.CallingPN = NULL;

		capi_decode_conn_ind(chan, skb, &cbdata);
		cbdata.type = EV_NET_SETUP;

		pcbit_fsm_event(dev, chan, EV_NET_SETUP, NULL);

		if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN)) 
			pcbit_fsm_event(dev, chan, EV_USR_PROCED_REQ, &cbdata);
		else
			pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);

		if (cbdata.data.setup.CalledPN)
			kfree(cbdata.data.setup.CalledPN);
		if (cbdata.data.setup.CallingPN)
			kfree(cbdata.data.setup.CallingPN);
		break;
    
	case MSG_CONN_CONF:
		/* 
		 * We should be able to find the channel by the message
		 * reference number. The current version of the firmware
		 * doesn't sent the ref number correctly.
		 */
#ifdef DEBUG
		printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum, 
		       dev->b1->s_refnum, 
		       dev->b2->s_refnum);
#endif
		/* We just try to find a channel in the right state */

		if (dev->b1->fsm_state == ST_CALL_INIT)
			chan = dev->b1;
		else { 		   
			if (dev->b2->s_refnum == ST_CALL_INIT)
				chan = dev->b2;
			else {			
				chan = NULL;
				printk(KERN_WARNING "Connection Confirm - no channel in Call Init state\n");
				break;
			}
		}
		if (capi_decode_conn_conf(chan, skb, &complete)) {
			printk(KERN_DEBUG "conn_conf indicates error\n");
			pcbit_fsm_event(dev, chan, EV_ERROR, NULL);
		}
		else
			if (complete)
				pcbit_fsm_event(dev, chan, EV_NET_CALL_PROC, NULL);
			else
				pcbit_fsm_event(dev, chan, EV_NET_SETUP_ACK, NULL);
		break; 
	case MSG_CONN_ACTV_IND:

		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}
		
		if (capi_decode_conn_actv_ind(chan, skb)) {
			printk("error in capi_decode_conn_actv_ind\n");
		     /* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */
			break;
		}
		chan->r_refnum = refnum;
		pcbit_fsm_event(dev, chan, EV_NET_CONN, NULL);
		break;
	case MSG_CONN_ACTV_CONF:

		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}

		if (capi_decode_conn_actv_conf(chan, skb) == 0)
			pcbit_fsm_event(dev, chan, EV_NET_CONN_ACK, NULL);
		
		else
			printk(KERN_DEBUG "decode_conn_actv_conf failed\n");
		break;

	case  MSG_SELP_CONF:

		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}

		if (!(err = capi_decode_sel_proto_conf(chan, skb)))
			pcbit_fsm_event(dev, chan, EV_NET_SELP_RESP, NULL);
		else {
			/* Error */
			printk("error %d - capi_decode_sel_proto_conf\n", err);
		}
		break;
	case MSG_ACT_TRANSP_CONF:
		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}

		if (!capi_decode_actv_trans_conf(chan, skb))
			pcbit_fsm_event(dev, chan, EV_NET_ACTV_RESP, NULL);
		break;

	case MSG_DISC_IND:

		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}

		if (!capi_decode_disc_ind(chan, skb))
			pcbit_fsm_event(dev, chan, EV_NET_DISC, NULL);
		else
			printk(KERN_WARNING "capi_decode_disc_ind - error\n");
		break;
	case MSG_DISC_CONF:
		if (!(chan = capi_channel(dev, skb))) {
			printk(KERN_WARNING 
			       "CAPI header: unknown channel id\n");
			break;
		}

		if (!capi_decode_disc_ind(chan, skb))
			pcbit_fsm_event(dev, chan, EV_NET_RELEASE, NULL);
		else
			printk(KERN_WARNING "capi_decode_disc_conf - error\n");
		break;
	case MSG_INFO_IND:
#ifdef DEBUG
		printk(KERN_DEBUG "received Info Indication - discarded\n");
#endif
		break;
#ifdef DEBUG
	case MSG_DEBUG_188:
		capi_decode_debug_188(skb->data, skb->len);
		break;

	default:
		printk(KERN_DEBUG "pcbit_l3_receive: unknown message %08lx\n",
		       msg);
		break;
#endif
	}

	kfree_skb(skb);

}

/*
 *   Single statbuf
 *   should be a statbuf per device
 */

static char statbuf[STATBUF_LEN];
static int stat_st = 0;
static int stat_end = 0;

static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
{
	int stat_count;
	stat_count = stat_end - stat_st;

	if (stat_count < 0)
		stat_count = STATBUF_LEN - stat_st + stat_end;

	/* FIXME: should we sleep and wait for more cookies ? */
	if (len > stat_count)            
		len = stat_count;

	if (stat_st < stat_end)
	{
		copy_to_user(buf, statbuf + stat_st, len);
		stat_st += len;	   
	}
	else
	{
		if (len > STATBUF_LEN - stat_st)
		{
			copy_to_user(buf, statbuf + stat_st, 
				       STATBUF_LEN - stat_st);
			copy_to_user(buf, statbuf, 
				       len - (STATBUF_LEN - stat_st));

			stat_st = len - (STATBUF_LEN - stat_st);
		}
		else
		{
			copy_to_user(buf, statbuf + stat_st, len);

			stat_st += len;
			
			if (stat_st == STATBUF_LEN)
				stat_st = 0;
		}
	}

	if (stat_st == stat_end)
		stat_st = stat_end = 0;

	return len;
}

static void pcbit_logstat(struct pcbit_dev *dev, char *str)
{
	int i;
	isdn_ctrl ictl;

	for (i=stat_end; i<strlen(str); i++)
	{
		statbuf[i]=str[i];
		stat_end = (stat_end + 1) % STATBUF_LEN;
		if (stat_end == stat_st)
			stat_st = (stat_st + 1) % STATBUF_LEN;
	}

	ictl.command=ISDN_STAT_STAVAIL;
	ictl.driver=dev->id;
	ictl.arg=strlen(str);
	dev->dev_if->statcallb(&ictl);
}
	
extern char * isdn_state_table[];
extern char * strisdnevent(unsigned short);


void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan, 
			unsigned short i, unsigned short ev, unsigned short f)
{
	char buf[256];
  
	sprintf(buf, "change on device: %d channel:%d\n%s -> %s -> %s\n",
		dev->id, chan->id, 
		isdn_state_table[i], strisdnevent(ev), isdn_state_table[f]
		);

#ifdef DEBUG
	printk("%s", buf);
#endif

	pcbit_logstat(dev, buf);
}

static void set_running_timeout(unsigned long ptr)
{
	struct pcbit_dev * dev;

#ifdef DEBUG
	printk(KERN_DEBUG "set_running_timeout\n");
#endif
	dev = (struct pcbit_dev *) ptr;

	wake_up_interruptible(&dev->set_running_wq);
}

static int set_protocol_running(struct pcbit_dev * dev)
{
	isdn_ctrl ctl;

	init_timer(&dev->set_running_timer);

	dev->set_running_timer.function = &set_running_timeout;
	dev->set_running_timer.data = (ulong) dev;
	dev->set_running_timer.expires = jiffies + SET_RUN_TIMEOUT;

	/* kick it */

	dev->l2_state = L2_STARTING;

	writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)), 
	       dev->sh_mem + BANK4);

	add_timer(&dev->set_running_timer);

	interruptible_sleep_on(&dev->set_running_wq);

	del_timer(&dev->set_running_timer);

	if (dev->l2_state == L2_RUNNING)
	{
		printk(KERN_DEBUG "pcbit: running\n");

		dev->unack_seq = dev->send_seq;

		dev->writeptr = dev->sh_mem;
		dev->readptr = dev->sh_mem + BANK2;
    
		/* tell the good news to the upper layer */  
		ctl.driver = dev->id;
		ctl.command = ISDN_STAT_RUN;

		dev->dev_if->statcallb(&ctl);
	}
	else
	{
		printk(KERN_DEBUG "pcbit: initialization failed\n");
		printk(KERN_DEBUG "pcbit: firmware not loaded\n");

		dev->l2_state = L2_DOWN;

#ifdef DEBUG
		printk(KERN_DEBUG "Bank3 = %02x\n", 
		       readb(dev->sh_mem + BANK3));
#endif
		writeb(0x40, dev->sh_mem + BANK4);

		/* warn the upper layer */
		ctl.driver = dev->id;
		ctl.command = ISDN_STAT_STOP;

		dev->dev_if->statcallb(&ctl);

		return -EL2HLT;	/* Level 2 halted */
	}

	return 0;
}

static int pcbit_ioctl(isdn_ctrl* ctl)
{
	struct pcbit_dev * dev;
	struct pcbit_ioctl *cmd;

	dev = finddev(ctl->driver);
  
	if (!dev)
	{
		printk(KERN_DEBUG "pcbit_ioctl: unknown device\n");
		return -ENODEV;
	}

	cmd = (struct pcbit_ioctl *) ctl->parm.num;

	switch(ctl->arg) {
	case PCBIT_IOCTL_GETSTAT:
		cmd->info.l2_status = dev->l2_state;
		break;

	case PCBIT_IOCTL_STRLOAD:
		if (dev->l2_state == L2_RUNNING)
			return -EBUSY;

		dev->unack_seq = dev->send_seq = dev->rcv_seq = 0;

		dev->writeptr = dev->sh_mem;
		dev->readptr = dev->sh_mem + BANK2;
    
		dev->l2_state = L2_LOADING;
		break;

	case PCBIT_IOCTL_LWMODE:
		if (dev->l2_state != L2_LOADING)
			return -EINVAL;

		dev->l2_state = L2_LWMODE;
		break;

	case PCBIT_IOCTL_FWMODE:
		if (dev->l2_state == L2_RUNNING)
			return -EBUSY;
		dev->loadptr = LOAD_ZONE_START;
		dev->l2_state = L2_FWMODE;

		break; 
	case PCBIT_IOCTL_ENDLOAD:
		if (dev->l2_state == L2_RUNNING)
			return -EBUSY;
		dev->l2_state = L2_DOWN;
		break; 

	case PCBIT_IOCTL_SETBYTE: 
		if (dev->l2_state == L2_RUNNING)
			return -EBUSY;

		/* check addr */
		if (cmd->info.rdp_byte.addr > BANK4)
			return -EFAULT;
		
		writeb(cmd->info.rdp_byte.value, dev->sh_mem + cmd->info.rdp_byte.addr);
		break;
	case PCBIT_IOCTL_GETBYTE:
		if (dev->l2_state == L2_RUNNING)
			return -EBUSY;

		/* check addr */

		if (cmd->info.rdp_byte.addr > BANK4)
		{
			printk("getbyte: invalid addr %04x\n", cmd->info.rdp_byte.addr);
			return -EFAULT;
		}
		
		cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr); 
		break;
	case PCBIT_IOCTL_RUNNING: 
		if (dev->l2_state == L2_RUNNING)
			return -EBUSY;
		return set_protocol_running(dev);
		break;
	case PCBIT_IOCTL_WATCH188:
		if (dev->l2_state != L2_LOADING)
			return -EINVAL;
		pcbit_l2_write(dev, MSG_WATCH188, 0x0001, NULL, 0);
		break;
	case PCBIT_IOCTL_PING188:
		if (dev->l2_state != L2_LOADING)
			return -EINVAL;
		pcbit_l2_write(dev, MSG_PING188_REQ, 0x0001, NULL, 0);
		break;
	case PCBIT_IOCTL_APION:
		if (dev->l2_state != L2_LOADING)
			return -EINVAL;
		pcbit_l2_write(dev, MSG_API_ON, 0x0001, NULL, 0);
		break;
	case PCBIT_IOCTL_STOP:
		dev->l2_state = L2_DOWN;
		writeb(0x40, dev->sh_mem + BANK4);
		dev->rcv_seq = 0;
		dev->send_seq = 0;
		dev->unack_seq = 0;
		break;
	default:
		printk("error: unknown ioctl\n");
		break;
	};
	return 0;
}

/* 
 *        MSN list handling
 *
 *        if null reject all calls
 *        if first entry has null MSN accept all calls 
 */

static void pcbit_clear_msn(struct pcbit_dev *dev)
{
	struct msn_entry *ptr, *back;

	for (ptr=dev->msn_list; ptr; )
	{
		back = ptr->next;
		kfree(ptr);
		ptr = back;
	}

	dev->msn_list = NULL; 
}

static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
{
	struct msn_entry *ptr;
	struct msn_entry *back = NULL;
	char *cp, *sp;
	int len;

	if (strlen(list) == 0) {
		ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);
		if (!ptr) {
			printk(KERN_WARNING "kmalloc failed\n");
			return;
		}

		ptr->msn = NULL;

		ptr->next = dev->msn_list;
		dev->msn_list = ptr;

		return;
	}

	if (dev->msn_list)
		for (back=dev->msn_list; back->next; back=back->next);
	
	sp = list;

	do {
		cp=strchr(sp, ',');
		if (cp)
			len = cp - sp;
		else
			len = strlen(sp);

		ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);

		if (!ptr) {
			printk(KERN_WARNING "kmalloc failed\n");
			return;
		}
		ptr->next = NULL;
		
		ptr->msn = kmalloc(len, GFP_ATOMIC);
		if (!ptr->msn) {
			printk(KERN_WARNING "kmalloc failed\n");
			kfree(ptr);
			return;
		}

		memcpy(ptr->msn, sp, len - 1);
		ptr->msn[len] = 0;

#ifdef DEBUG
		printk(KERN_DEBUG "msn: %s\n", ptr->msn);
#endif
		if (dev->msn_list == NULL)
			dev->msn_list = ptr;
		else
			back->next = ptr;
		back = ptr;
		sp += len;
	} while(cp);
}

/*
 *  check if we do signal or reject an incoming call
 */
static int pcbit_check_msn(struct pcbit_dev *dev, char *msn)
{
	struct msn_entry *ptr;
	
	for (ptr=dev->msn_list; ptr; ptr=ptr->next) {

		if (ptr->msn == NULL) 
			return 1;
		
		if (strcmp(ptr->msn, msn) == 0)
			return 1;
	}

	return 0;
}
