isdn: i4l: move active-isdn drivers to staging
[cascardo/linux.git] / drivers / isdn / pcbit / drv.c
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
deleted file mode 100644 (file)
index 4172e22..0000000
+++ /dev/null
@@ -1,1077 +0,0 @@
-/*
- * 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/kernel.h>
-
-#include <linux/types.h>
-#include <linux/sched.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);
-
-
-int pcbit_init_dev(int board, int mem_base, int irq)
-{
-       struct pcbit_dev *dev;
-       isdn_if *dev_if;
-
-       if ((dev = kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
-       {
-               printk("pcbit_init: couldn't malloc pcbit_dev struct\n");
-               return -ENOMEM;
-       }
-
-       dev_pcbit[board] = 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 = kzalloc(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 = kzalloc(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;
-       }
-
-       dev->b2->id = 1;
-
-       INIT_WORK(&dev->qdelivery, pcbit_deliver);
-
-       /*
-        *  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 = memdup_user(buf, len);
-               if (IS_ERR(cbuf))
-                       return PTR_ERR(cbuf);
-
-               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);
-
-               kfree(cbdata.data.setup.CalledPN);
-               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)
-       {
-               if (copy_to_user(buf, statbuf + stat_st, len))
-                       return -EFAULT;
-               stat_st += len;
-       }
-       else
-       {
-               if (len > STATBUF_LEN - stat_st)
-               {
-                       if (copy_to_user(buf, statbuf + stat_st,
-                                        STATBUF_LEN - stat_st))
-                               return -EFAULT;
-                       if (copy_to_user(buf, statbuf,
-                                        len - (STATBUF_LEN - stat_st)))
-                               return -EFAULT;
-
-                       stat_st = len - (STATBUF_LEN - stat_st);
-               }
-               else
-               {
-                       if (copy_to_user(buf, statbuf + stat_st, len))
-                               return -EFAULT;
-
-                       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);
-}
-
-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;
-
-       dev->l2_state = L2_DOWN;
-       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);
-
-       wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING ||
-                                       dev->l2_state == L2_DOWN);
-
-       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");
-
-#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 + 1, GFP_ATOMIC);
-               if (!ptr->msn) {
-                       printk(KERN_WARNING "kmalloc failed\n");
-                       kfree(ptr);
-                       return;
-               }
-
-               memcpy(ptr->msn, sp, len);
-               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;
-}