diff options
author | Arnd Bergmann <arnd@arndb.de> | 2016-03-02 20:06:46 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-03-05 15:00:38 -0800 |
commit | a921e9bd4e22a792279e46f97a85891a3d5f1b7d (patch) | |
tree | fe4192cf75e8705272729a611f4bc71146f5f8f3 /drivers/isdn | |
parent | 01ed1e1504ac83a8b0b365c9f55d3427babbd7d9 (diff) |
isdn: i4l: move active-isdn drivers to staging
The icn, act2000 and pcbit drivers are all for very old hardware,
and it is highly unlikely that anyone is actually still using them
on modern kernels, if at all.
All three drivers apparently are for hardware that predates PCI
being the common connector, as they are ISA-only and active
PCI ISDN cards were widely available in the 1990s.
Looking through the git logs, it I cannot find any indication of a
patch to any of these drivers that has been tested on real hardware,
only cleanups or global API changes.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Karsten Keil <isdn@linux-pingi.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/isdn')
27 files changed, 0 insertions, 9055 deletions
diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile index 91c81965e7ca..c32e45826c2c 100644 --- a/drivers/isdn/Makefile +++ b/drivers/isdn/Makefile @@ -8,9 +8,6 @@ obj-$(CONFIG_MISDN) += mISDN/ obj-$(CONFIG_ISDN) += hardware/ obj-$(CONFIG_ISDN_DIVERSION) += divert/ obj-$(CONFIG_ISDN_DRV_HISAX) += hisax/ -obj-$(CONFIG_ISDN_DRV_ICN) += icn/ -obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit/ obj-$(CONFIG_ISDN_DRV_LOOP) += isdnloop/ -obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000/ obj-$(CONFIG_HYSDN) += hysdn/ obj-$(CONFIG_ISDN_DRV_GIGASET) += gigaset/ diff --git a/drivers/isdn/act2000/Kconfig b/drivers/isdn/act2000/Kconfig deleted file mode 100644 index fa2673fc69c2..000000000000 --- a/drivers/isdn/act2000/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -config ISDN_DRV_ACT2000 - tristate "IBM Active 2000 support" - depends on ISA - help - Say Y here if you have an IBM Active 2000 ISDN card. In order to use - this card, additional firmware is necessary, which has to be loaded - into the card using a utility which is part of the latest - isdn4k-utils package. Please read the file - <file:Documentation/isdn/README.act2000> for more information. diff --git a/drivers/isdn/act2000/Makefile b/drivers/isdn/act2000/Makefile deleted file mode 100644 index 05e582fb5c00..000000000000 --- a/drivers/isdn/act2000/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile for the act2000 ISDN device driver - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000.o - -# Multipart objects. - -act2000-y := module.o capi.o act2000_isa.o diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h deleted file mode 100644 index 321d437f579e..000000000000 --- a/drivers/isdn/act2000/act2000.h +++ /dev/null @@ -1,202 +0,0 @@ -/* $Id: act2000.h,v 1.8.6.3 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * - * Author Fritz Elfert - * Copyright 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. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#ifndef act2000_h -#define act2000_h - -#include <linux/compiler.h> - -#define ACT2000_IOCTL_SETPORT 1 -#define ACT2000_IOCTL_GETPORT 2 -#define ACT2000_IOCTL_SETIRQ 3 -#define ACT2000_IOCTL_GETIRQ 4 -#define ACT2000_IOCTL_SETBUS 5 -#define ACT2000_IOCTL_GETBUS 6 -#define ACT2000_IOCTL_SETPROTO 7 -#define ACT2000_IOCTL_GETPROTO 8 -#define ACT2000_IOCTL_SETMSN 9 -#define ACT2000_IOCTL_GETMSN 10 -#define ACT2000_IOCTL_LOADBOOT 11 -#define ACT2000_IOCTL_ADDCARD 12 - -#define ACT2000_IOCTL_TEST 98 -#define ACT2000_IOCTL_DEBUGVAR 99 - -#define ACT2000_BUS_ISA 1 -#define ACT2000_BUS_MCA 2 -#define ACT2000_BUS_PCMCIA 3 - -/* Struct for adding new cards */ -typedef struct act2000_cdef { - int bus; - int port; - int irq; - char id[10]; -} act2000_cdef; - -/* Struct for downloading firmware */ -typedef struct act2000_ddef { - int length; /* Length of code */ - char __user *buffer; /* Ptr. to code */ -} act2000_ddef; - -typedef struct act2000_fwid { - char isdn[4]; - char revlen[2]; - char revision[504]; -} act2000_fwid; - -#if defined(__KERNEL__) || defined(__DEBUGVAR__) - -#ifdef __KERNEL__ -/* Kernel includes */ - -#include <linux/sched.h> -#include <linux/string.h> -#include <linux/workqueue.h> -#include <linux/interrupt.h> -#include <linux/skbuff.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/major.h> -#include <asm/io.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/ioport.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/delay.h> -#include <linux/ctype.h> -#include <linux/isdnif.h> - -#endif /* __KERNEL__ */ - -#define ACT2000_PORTLEN 8 - -#define ACT2000_FLAGS_RUNNING 1 /* Cards driver activated */ -#define ACT2000_FLAGS_PVALID 2 /* Cards port is valid */ -#define ACT2000_FLAGS_IVALID 4 /* Cards irq is valid */ -#define ACT2000_FLAGS_LOADED 8 /* Firmware loaded */ - -#define ACT2000_BCH 2 /* # of channels per card */ - -/* D-Channel states */ -#define ACT2000_STATE_NULL 0 -#define ACT2000_STATE_ICALL 1 -#define ACT2000_STATE_OCALL 2 -#define ACT2000_STATE_IWAIT 3 -#define ACT2000_STATE_OWAIT 4 -#define ACT2000_STATE_IBWAIT 5 -#define ACT2000_STATE_OBWAIT 6 -#define ACT2000_STATE_BWAIT 7 -#define ACT2000_STATE_BHWAIT 8 -#define ACT2000_STATE_BHWAIT2 9 -#define ACT2000_STATE_DHWAIT 10 -#define ACT2000_STATE_DHWAIT2 11 -#define ACT2000_STATE_BSETUP 12 -#define ACT2000_STATE_ACTIVE 13 - -#define ACT2000_MAX_QUEUED 8000 /* 2 * maxbuff */ - -#define ACT2000_LOCK_TX 0 -#define ACT2000_LOCK_RX 1 - -typedef struct act2000_chan { - unsigned short callref; /* Call Reference */ - unsigned short fsm_state; /* Current D-Channel state */ - unsigned short eazmask; /* EAZ-Mask for this Channel */ - short queued; /* User-Data Bytes in TX queue */ - unsigned short plci; - unsigned short ncci; - unsigned char l2prot; /* Layer 2 protocol */ - unsigned char l3prot; /* Layer 3 protocol */ -} act2000_chan; - -typedef struct msn_entry { - char eaz; - char msn[16]; - struct msn_entry *next; -} msn_entry; - -typedef struct irq_data_isa { - __u8 *rcvptr; - __u16 rcvidx; - __u16 rcvlen; - struct sk_buff *rcvskb; - __u8 rcvignore; - __u8 rcvhdr[8]; -} irq_data_isa; - -typedef union act2000_irq_data { - irq_data_isa isa; -} act2000_irq_data; - -/* - * Per card driver data - */ -typedef struct act2000_card { - unsigned short port; /* Base-port-address */ - unsigned short irq; /* Interrupt */ - u_char ptype; /* Protocol type (1TR6 or Euro) */ - u_char bus; /* Cardtype (ISA, MCA, PCMCIA) */ - struct act2000_card *next; /* Pointer to next device struct */ - spinlock_t lock; /* protect critical operations */ - int myid; /* Driver-Nr. assigned by linklevel */ - unsigned long flags; /* Statusflags */ - unsigned long ilock; /* Semaphores for IRQ-Routines */ - struct sk_buff_head rcvq; /* Receive-Message queue */ - struct sk_buff_head sndq; /* Send-Message queue */ - struct sk_buff_head ackq; /* Data-Ack-Message queue */ - u_char *ack_msg; /* Ptr to User Data in User skb */ - __u16 need_b3ack; /* Flag: Need ACK for current skb */ - struct sk_buff *sbuf; /* skb which is currently sent */ - struct timer_list ptimer; /* Poll timer */ - struct work_struct snd_tq; /* Task struct for xmit bh */ - struct work_struct rcv_tq; /* Task struct for rcv bh */ - struct work_struct poll_tq; /* Task struct for polled rcv bh */ - msn_entry *msn_list; - unsigned short msgnum; /* Message number for sending */ - spinlock_t mnlock; /* lock for msgnum */ - act2000_chan bch[ACT2000_BCH]; /* B-Channel status/control */ - char status_buf[256]; /* Buffer for status messages */ - char *status_buf_read; - char *status_buf_write; - char *status_buf_end; - act2000_irq_data idat; /* Data used for IRQ handler */ - isdn_if interface; /* Interface to upper layer */ - char regname[35]; /* Name used for request_region */ -} act2000_card; - -static inline void act2000_schedule_tx(act2000_card *card) -{ - schedule_work(&card->snd_tq); -} - -static inline void act2000_schedule_rx(act2000_card *card) -{ - schedule_work(&card->rcv_tq); -} - -static inline void act2000_schedule_poll(act2000_card *card) -{ - schedule_work(&card->poll_tq); -} - -extern char *act2000_find_eaz(act2000_card *, char); - -#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */ -#endif /* act2000_h */ diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c deleted file mode 100644 index b5fad29a9ba6..000000000000 --- a/drivers/isdn/act2000/act2000_isa.c +++ /dev/null @@ -1,443 +0,0 @@ -/* $Id: act2000_isa.c,v 1.11.6.3 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). - * - * Author Fritz Elfert - * Copyright 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. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#include "act2000.h" -#include "act2000_isa.h" -#include "capi.h" - -/* - * Reset Controller, then try to read the Card's signature. - + Return: - * 1 = Signature found. - * 0 = Signature not found. - */ -static int -act2000_isa_reset(unsigned short portbase) -{ - unsigned char reg; - int i; - int found; - int serial = 0; - - found = 0; - if ((reg = inb(portbase + ISA_COR)) != 0xff) { - outb(reg | ISA_COR_RESET, portbase + ISA_COR); - mdelay(10); - outb(reg, portbase + ISA_COR); - mdelay(10); - - for (i = 0; i < 16; i++) { - if (inb(portbase + ISA_ISR) & ISA_ISR_SERIAL) - serial |= 0x10000; - serial >>= 1; - } - if (serial == ISA_SER_ID) - found++; - } - return found; -} - -int -act2000_isa_detect(unsigned short portbase) -{ - int ret = 0; - - if (request_region(portbase, ACT2000_PORTLEN, "act2000isa")) { - ret = act2000_isa_reset(portbase); - release_region(portbase, ISA_REGION); - } - return ret; -} - -static irqreturn_t -act2000_isa_interrupt(int dummy, void *dev_id) -{ - act2000_card *card = dev_id; - u_char istatus; - - istatus = (inb(ISA_PORT_ISR) & 0x07); - if (istatus & ISA_ISR_OUT) { - /* RX fifo has data */ - istatus &= ISA_ISR_OUT_MASK; - outb(0, ISA_PORT_SIS); - act2000_isa_receive(card); - outb(ISA_SIS_INT, ISA_PORT_SIS); - } - if (istatus & ISA_ISR_ERR) { - /* Error Interrupt */ - istatus &= ISA_ISR_ERR_MASK; - printk(KERN_WARNING "act2000: errIRQ\n"); - } - if (istatus) - printk(KERN_DEBUG "act2000: ?IRQ %d %02x\n", card->irq, istatus); - return IRQ_HANDLED; -} - -static void -act2000_isa_select_irq(act2000_card *card) -{ - unsigned char reg; - - reg = (inb(ISA_PORT_COR) & ~ISA_COR_IRQOFF) | ISA_COR_PERR; - switch (card->irq) { - case 3: - reg = ISA_COR_IRQ03; - break; - case 5: - reg = ISA_COR_IRQ05; - break; - case 7: - reg = ISA_COR_IRQ07; - break; - case 10: - reg = ISA_COR_IRQ10; - break; - case 11: - reg = ISA_COR_IRQ11; - break; - case 12: - reg = ISA_COR_IRQ12; - break; - case 15: - reg = ISA_COR_IRQ15; - break; - } - outb(reg, ISA_PORT_COR); -} - -static void -act2000_isa_enable_irq(act2000_card *card) -{ - act2000_isa_select_irq(card); - /* Enable READ irq */ - outb(ISA_SIS_INT, ISA_PORT_SIS); -} - -/* - * Install interrupt handler, enable irq on card. - * If irq is -1, choose next free irq, else irq is given explicitly. - */ -int -act2000_isa_config_irq(act2000_card *card, short irq) -{ - int old_irq; - - if (card->flags & ACT2000_FLAGS_IVALID) { - free_irq(card->irq, card); - } - card->flags &= ~ACT2000_FLAGS_IVALID; - outb(ISA_COR_IRQOFF, ISA_PORT_COR); - if (!irq) - return 0; - - old_irq = card->irq; - card->irq = irq; - if (request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) { - card->irq = old_irq; - card->flags |= ACT2000_FLAGS_IVALID; - printk(KERN_WARNING - "act2000: Could not request irq %d\n", irq); - return -EBUSY; - } else { - act2000_isa_select_irq(card); - /* Disable READ and WRITE irq */ - outb(0, ISA_PORT_SIS); - outb(0, ISA_PORT_SOS); - } - return 0; -} - -int -act2000_isa_config_port(act2000_card *card, unsigned short portbase) -{ - if (card->flags & ACT2000_FLAGS_PVALID) { - release_region(card->port, ISA_REGION); - card->flags &= ~ACT2000_FLAGS_PVALID; - } - if (request_region(portbase, ACT2000_PORTLEN, card->regname) == NULL) - return -EBUSY; - else { - card->port = portbase; - card->flags |= ACT2000_FLAGS_PVALID; - return 0; - } -} - -/* - * Release ressources, used by an adaptor. - */ -void -act2000_isa_release(act2000_card *card) -{ - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - if (card->flags & ACT2000_FLAGS_IVALID) - free_irq(card->irq, card); - - card->flags &= ~ACT2000_FLAGS_IVALID; - if (card->flags & ACT2000_FLAGS_PVALID) - release_region(card->port, ISA_REGION); - card->flags &= ~ACT2000_FLAGS_PVALID; - spin_unlock_irqrestore(&card->lock, flags); -} - -static int -act2000_isa_writeb(act2000_card *card, u_char data) -{ - u_char timeout = 40; - - while (timeout) { - if (inb(ISA_PORT_SOS) & ISA_SOS_READY) { - outb(data, ISA_PORT_SDO); - return 0; - } else { - timeout--; - udelay(10); - } - } - return 1; -} - -static int -act2000_isa_readb(act2000_card *card, u_char *data) -{ - u_char timeout = 40; - - while (timeout) { - if (inb(ISA_PORT_SIS) & ISA_SIS_READY) { - *data = inb(ISA_PORT_SDI); - return 0; - } else { - timeout--; - udelay(10); - } - } - return 1; -} - -void -act2000_isa_receive(act2000_card *card) -{ - u_char c; - - if (test_and_set_bit(ACT2000_LOCK_RX, (void *) &card->ilock) != 0) - return; - while (!act2000_isa_readb(card, &c)) { - if (card->idat.isa.rcvidx < 8) { - card->idat.isa.rcvhdr[card->idat.isa.rcvidx++] = c; - if (card->idat.isa.rcvidx == 8) { - int valid = actcapi_chkhdr(card, (actcapi_msghdr *)&card->idat.isa.rcvhdr); - - if (valid) { - card->idat.isa.rcvlen = ((actcapi_msghdr *)&card->idat.isa.rcvhdr)->len; - card->idat.isa.rcvskb = dev_alloc_skb(card->idat.isa.rcvlen); - if (card->idat.isa.rcvskb == NULL) { - card->idat.isa.rcvignore = 1; - printk(KERN_WARNING - "act2000_isa_receive: no memory\n"); - test_and_clear_bit(ACT2000_LOCK_RX, (void *) &card->ilock); - return; - } - memcpy(skb_put(card->idat.isa.rcvskb, 8), card->idat.isa.rcvhdr, 8); - card->idat.isa.rcvptr = skb_put(card->idat.isa.rcvskb, card->idat.isa.rcvlen - 8); - } else { - card->idat.isa.rcvidx = 0; - printk(KERN_WARNING - "act2000_isa_receive: Invalid CAPI msg\n"); - { - int i; __u8 *p; __u8 *t; __u8 tmp[30]; - for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++) - t += sprintf(t, "%02x ", *(p++)); - printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp); - } - } - } - } else { - if (!card->idat.isa.rcvignore) - *card->idat.isa.rcvptr++ = c; - if (++card->idat.isa.rcvidx >= card->idat.isa.rcvlen) { - if (!card->idat.isa.rcvignore) { - skb_queue_tail(&card->rcvq, card->idat.isa.rcvskb); - act2000_schedule_rx(card); - } - card->idat.isa.rcvidx = 0; - card->idat.isa.rcvlen = 8; - card->idat.isa.rcvignore = 0; - card->idat.isa.rcvskb = NULL; - card->idat.isa.rcvptr = card->idat.isa.rcvhdr; - } - } - } - if (!(card->flags & ACT2000_FLAGS_IVALID)) { - /* In polling mode, schedule myself */ - if ((card->idat.isa.rcvidx) && - (card->idat.isa.rcvignore || - (card->idat.isa.rcvidx < card->idat.isa.rcvlen))) - act2000_schedule_poll(card); - } - test_and_clear_bit(ACT2000_LOCK_RX, (void *) &card->ilock); -} - -void -act2000_isa_send(act2000_card *card) -{ - unsigned long flags; - struct sk_buff *skb; - actcapi_msg *msg; - int l; - - if (test_and_set_bit(ACT2000_LOCK_TX, (void *) &card->ilock) != 0) - return; - while (1) { - spin_lock_irqsave(&card->lock, flags); - if (!(card->sbuf)) { - if ((card->sbuf = skb_dequeue(&card->sndq))) { - card->ack_msg = card->sbuf->data; - msg = (actcapi_msg *)card->sbuf->data; - if ((msg->hdr.cmd.cmd == 0x86) && - (msg->hdr.cmd.subcmd == 0)) { - /* Save flags in message */ - card->need_b3ack = msg->msg.data_b3_req.flags; - msg->msg.data_b3_req.flags = 0; - } - } - } - spin_unlock_irqrestore(&card->lock, flags); - if (!(card->sbuf)) { - /* No more data to send */ - test_and_clear_bit(ACT2000_LOCK_TX, (void *) &card->ilock); - return; - } - skb = card->sbuf; - l = 0; - while (skb->len) { - if (act2000_isa_writeb(card, *(skb->data))) { - /* Fifo is full, but more data to send */ - test_and_clear_bit(ACT2000_LOCK_TX, (void *) &card->ilock); - /* Schedule myself */ - act2000_schedule_tx(card); - return; - } - skb_pull(skb, 1); - l++; - } - msg = (actcapi_msg *)card->ack_msg; - if ((msg->hdr.cmd.cmd == 0x86) && - (msg->hdr.cmd.subcmd == 0)) { - /* - * If it's user data, reset data-ptr - * and put skb into ackq. - */ - skb->data = card->ack_msg; - /* Restore flags in message */ - msg->msg.data_b3_req.flags = card->need_b3ack; - skb_queue_tail(&card->ackq, skb); - } else - dev_kfree_skb(skb); - card->sbuf = NULL; - } -} - -/* - * Get firmware ID, check for 'ISDN' signature. - */ -static int -act2000_isa_getid(act2000_card *card) -{ - - act2000_fwid fid; - u_char *p = (u_char *)&fid; - int count = 0; - - while (1) { - if (count > 510) - return -EPROTO; - if (act2000_isa_readb(card, p++)) - break; - count++; - } - if (count <= 20) { - printk(KERN_WARNING "act2000: No Firmware-ID!\n"); - return -ETIME; - } - *p = '\0'; - fid.revlen[0] = '\0'; - if (strcmp(fid.isdn, "ISDN")) { - printk(KERN_WARNING "act2000: Wrong Firmware-ID!\n"); - return -EPROTO; - } - if ((p = strchr(fid.revision, '\n'))) - *p = '\0'; - printk(KERN_INFO "act2000: Firmware-ID: %s\n", fid.revision); - if (card->flags & ACT2000_FLAGS_IVALID) { - printk(KERN_DEBUG "Enabling Interrupts ...\n"); - act2000_isa_enable_irq(card); - } - return 0; -} - -/* - * Download microcode into card, check Firmware signature. - */ -int -act2000_isa_download(act2000_card *card, act2000_ddef __user *cb) -{ - unsigned int length; - int l; - int c; - long timeout; - u_char *b; - u_char __user *p; - u_char *buf; - act2000_ddef cblock; - - if (!act2000_isa_reset(card->port)) - return -ENXIO; - msleep_interruptible(500); - if (copy_from_user(&cblock, cb, sizeof(cblock))) - return -EFAULT; - length = cblock.length; - p = cblock.buffer; - if (!access_ok(VERIFY_READ, p, length)) - return -EFAULT; - buf = kmalloc(1024, GFP_KERNEL); - if (!buf) - return -ENOMEM; - timeout = 0; - while (length) { - l = (length > 1024) ? 1024 : length; - c = 0; - b = buf; - if (copy_from_user(buf, p, l)) { - kfree(buf); - return -EFAULT; - } - while (c < l) { - if (act2000_isa_writeb(card, *b++)) { - printk(KERN_WARNING - "act2000: loader timed out" - " len=%d c=%d\n", length, c); - kfree(buf); - return -ETIME; - } - c++; - } - length -= l; - p += l; - } - kfree(buf); - msleep_interruptible(500); - return (act2000_isa_getid(card)); -} diff --git a/drivers/isdn/act2000/act2000_isa.h b/drivers/isdn/act2000/act2000_isa.h deleted file mode 100644 index 1a728984ede1..000000000000 --- a/drivers/isdn/act2000/act2000_isa.h +++ /dev/null @@ -1,136 +0,0 @@ -/* $Id: act2000_isa.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). - * - * Author Fritz Elfert - * Copyright 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. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#ifndef act2000_isa_h -#define act2000_isa_h - -#define ISA_POLL_LOOP 40 /* Try to read-write before give up */ - -typedef enum { - INT_NO_CHANGE = 0, /* Do not change the Mask */ - INT_ON = 1, /* Set to Enable */ - INT_OFF = 2, /* Set to Disable */ -} ISA_INT_T; - -/**************************************************************************/ -/* Configuration Register COR (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* Soft Res| IRQM | IRQ Select | N/A | WAIT |Proc err */ -/**************************************************************************/ -#define ISA_COR 0 /* Offset for ISA config register */ -#define ISA_COR_PERR 0x01 /* Processor Error Enabled */ -#define ISA_COR_WS 0x02 /* Insert Wait State if 1 */ -#define ISA_COR_IRQOFF 0x38 /* No Interrupt */ -#define ISA_COR_IRQ07 0x30 /* IRQ 7 Enable */ -#define ISA_COR_IRQ05 0x28 /* IRQ 5 Enable */ -#define ISA_COR_IRQ03 0x20 /* IRQ 3 Enable */ -#define ISA_COR_IRQ10 0x18 /* IRQ 10 Enable */ -#define ISA_COR_IRQ11 0x10 /* IRQ 11 Enable */ -#define ISA_COR_IRQ12 0x08 /* IRQ 12 Enable */ -#define ISA_COR_IRQ15 0x00 /* IRQ 15 Enable */ -#define ISA_COR_IRQPULSE 0x40 /* 0 = Level 1 = Pulse Interrupt */ -#define ISA_COR_RESET 0x80 /* Soft Reset for Transputer */ - -/**************************************************************************/ -/* Interrupt Source Register ISR (RO) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A |Err sig |Ser ID |IN Intr |Out Intr| Error */ -/**************************************************************************/ -#define ISA_ISR 1 /* Offset for Interrupt Register */ -#define ISA_ISR_ERR 0x01 /* Error Interrupt */ -#define ISA_ISR_OUT 0x02 /* Output Interrupt */ -#define ISA_ISR_INP 0x04 /* Input Interrupt */ -#define ISA_ISR_SERIAL 0x08 /* Read out Serial ID after Reset */ -#define ISA_ISR_ERRSIG 0x10 /* Error Signal Input */ -#define ISA_ISR_ERR_MASK 0xfe /* Mask Error Interrupt */ -#define ISA_ISR_OUT_MASK 0xfd /* Mask Output Interrupt */ -#define ISA_ISR_INP_MASK 0xfb /* Mask Input Interrupt */ - -/* Signature delivered after Reset at ISA_ISR_SERIAL (LSB first) */ -#define ISA_SER_ID 0x0201 /* ID for ISA Card */ - -/**************************************************************************/ -/* EEPROM Register EPR (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A |ROM Hold| ROM CS |ROM CLK | ROM IN |ROM Out */ -/**************************************************************************/ -#define ISA_EPR 2 /* Offset for this Register */ -#define ISA_EPR_OUT 0x01 /* Rome Register Out (RO) */ -#define ISA_EPR_IN 0x02 /* Rom Register In (WR) */ -#define ISA_EPR_CLK 0x04 /* Rom Clock (WR) */ -#define ISA_EPR_CS 0x08 /* Rom Cip Select (WR) */ -#define ISA_EPR_HOLD 0x10 /* Rom Hold Signal (WR) */ - -/**************************************************************************/ -/* EEPROM enable Register EER (unused) */ -/**************************************************************************/ -#define ISA_EER 3 /* Offset for this Register */ - -/**************************************************************************/ -/* SLC Data Input SDI (RO) */ -/**************************************************************************/ -#define ISA_SDI 4 /* Offset for this Register */ - -/**************************************************************************/ -/* SLC Data Output SDO (WO) */ -/**************************************************************************/ -#define ISA_SDO 5 /* Offset for this Register */ - -/**************************************************************************/ -/* IMS C011 Mode 2 Input Status Register for INMOS CPU SIS (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A | N/A | N/A | N/A |Int Ena |Data Pre */ -/**************************************************************************/ -#define ISA_SIS 6 /* Offset for this Register */ -#define ISA_SIS_READY 0x01 /* If 1 : data is available */ -#define ISA_SIS_INT 0x02 /* Enable Interrupt for READ */ - -/**************************************************************************/ -/* IMS C011 Mode 2 Output Status Register from INMOS CPU SOS (RW) */ -/**************************************************************************/ -/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */ -/* N/A | N/A | N/A | N/A | N/A | N/A |Int Ena |Out Rdy */ -/**************************************************************************/ -#define ISA_SOS 7 /* Offset for this Register */ -#define ISA_SOS_READY 0x01 /* If 1 : we can write Data */ -#define ISA_SOS_INT 0x02 /* Enable Interrupt for WRITE */ - -#define ISA_REGION 8 /* Number of Registers */ - - -/* Macros for accessing ports */ -#define ISA_PORT_COR (card->port + ISA_COR) -#define ISA_PORT_ISR (card->port + ISA_ISR) -#define ISA_PORT_EPR (card->port + ISA_EPR) -#define ISA_PORT_EER (card->port + ISA_EER) -#define ISA_PORT_SDI (card->port + ISA_SDI) -#define ISA_PORT_SDO (card->port + ISA_SDO) -#define ISA_PORT_SIS (card->port + ISA_SIS) -#define ISA_PORT_SOS (card->port + ISA_SOS) - -/* Prototypes */ - -extern int act2000_isa_detect(unsigned short portbase); -extern int act2000_isa_config_irq(act2000_card *card, short irq); -extern int act2000_isa_config_port(act2000_card *card, unsigned short portbase); -extern int act2000_isa_download(act2000_card *card, act2000_ddef __user *cb); -extern void act2000_isa_release(act2000_card *card); -extern void act2000_isa_receive(act2000_card *card); -extern void act2000_isa_send(act2000_card *card); - -#endif /* act2000_isa_h */ diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c deleted file mode 100644 index 3f66ca20b5e5..000000000000 --- a/drivers/isdn/act2000/capi.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * CAPI encoder/decoder - * - * Author Fritz Elfert - * Copyright 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. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#include "act2000.h" -#include "capi.h" - -static actcapi_msgdsc valid_msg[] = { - {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */ - {{ 0x86, 0x01}, "DATA_B3_CONF"}, - {{ 0x02, 0x01}, "CONNECT_CONF"}, - {{ 0x02, 0x02}, "CONNECT_IND"}, - {{ 0x09, 0x01}, "CONNECT_INFO_CONF"}, - {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"}, - {{ 0x04, 0x01}, "DISCONNECT_CONF"}, - {{ 0x04, 0x02}, "DISCONNECT_IND"}, - {{ 0x05, 0x01}, "LISTEN_CONF"}, - {{ 0x06, 0x01}, "GET_PARAMS_CONF"}, - {{ 0x07, 0x01}, "INFO_CONF"}, - {{ 0x07, 0x02}, "INFO_IND"}, - {{ 0x08, 0x01}, "DATA_CONF"}, - {{ 0x08, 0x02}, "DATA_IND"}, - {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"}, - {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"}, - {{ 0x81, 0x01}, "LISTEN_B3_CONF"}, - {{ 0x82, 0x01}, "CONNECT_B3_CONF"}, - {{ 0x82, 0x02}, "CONNECT_B3_IND"}, - {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"}, - {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"}, - {{ 0x84, 0x02}, "DISCONNECT_B3_IND"}, - {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"}, - {{ 0x01, 0x01}, "RESET_B3_CONF"}, - {{ 0x01, 0x02}, "RESET_B3_IND"}, - /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */ - {{ 0xff, 0x01}, "MANUFACTURER_CONF"}, - {{ 0xff, 0x02}, "MANUFACTURER_IND"}, -#ifdef DEBUG_MSG - /* Requests */ - {{ 0x01, 0x00}, "RESET_B3_REQ"}, - {{ 0x02, 0x00}, "CONNECT_REQ"}, - {{ 0x04, 0x00}, "DISCONNECT_REQ"}, - {{ 0x05, 0x00}, "LISTEN_REQ"}, - {{ 0x06, 0x00}, "GET_PARAMS_REQ"}, - {{ 0x07, 0x00}, "INFO_REQ"}, - {{ 0x08, 0x00}, "DATA_REQ"}, - {{ 0x09, 0x00}, "CONNECT_INFO_REQ"}, - {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"}, - {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"}, - {{ 0x81, 0x00}, "LISTEN_B3_REQ"}, - {{ 0x82, 0x00}, "CONNECT_B3_REQ"}, - {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"}, - {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"}, - {{ 0x86, 0x00}, "DATA_B3_REQ"}, - {{ 0xff, 0x00}, "MANUFACTURER_REQ"}, - /* Responses */ - {{ 0x01, 0x03}, "RESET_B3_RESP"}, - {{ 0x02, 0x03}, "CONNECT_RESP"}, - {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"}, - {{ 0x04, 0x03}, "DISCONNECT_RESP"}, - {{ 0x07, 0x03}, "INFO_RESP"}, - {{ 0x08, 0x03}, "DATA_RESP"}, - {{ 0x82, 0x03}, "CONNECT_B3_RESP"}, - {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"}, - {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"}, - {{ 0x86, 0x03}, "DATA_B3_RESP"}, - {{ 0xff, 0x03}, "MANUFACTURER_RESP"}, -#endif - {{ 0x00, 0x00}, NULL}, -}; -#define num_valid_imsg 27 /* MANUFACTURER_IND */ - -/* - * Check for a valid incoming CAPI message. - * Return: - * 0 = Invalid message - * 1 = Valid message, no B-Channel-data - * 2 = Valid message, B-Channel-data - */ -int -actcapi_chkhdr(act2000_card *card, actcapi_msghdr *hdr) -{ - int i; - - if (hdr->applicationID != 1) - return 0; - if (hdr->len < 9) - return 0; - for (i = 0; i < num_valid_imsg; i++) - if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) && - (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) { - return (i ? 1 : 2); - } - return 0; -} - -#define ACTCAPI_MKHDR(l, c, s) { \ - skb = alloc_skb(l + 8, GFP_ATOMIC); \ - if (skb) { \ - m = (actcapi_msg *)skb_put(skb, l + 8); \ - m->hdr.len = l + 8; \ - m->hdr.applicationID = 1; \ - m->hdr.cmd.cmd = c; \ - m->hdr.cmd.subcmd = s; \ - m->hdr.msgnum = actcapi_nextsmsg(card); \ - } else m = NULL; \ - } - -#define ACTCAPI_CHKSKB if (!skb) { \ - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \ - return; \ - } - -#define ACTCAPI_QUEUE_TX { \ - actcapi_debug_msg(skb, 1); \ - skb_queue_tail(&card->sndq, skb); \ - act2000_schedule_tx(card); \ - } - -int -actcapi_listen_req(act2000_card *card) -{ - __u16 eazmask = 0; - int i; - actcapi_msg *m; - struct sk_buff *skb; - - for (i = 0; i < ACT2000_BCH; i++) - eazmask |= card->bch[i].eazmask; - ACTCAPI_MKHDR(9, 0x05, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.listen_req.controller = 0; - m->msg.listen_req.infomask = 0x3f; /* All information */ - m->msg.listen_req.eazmask = eazmask; - m->msg.listen_req.simask = (eazmask) ? 0x86 : 0; /* All SI's */ - ACTCAPI_QUEUE_TX; - return 0; -} - -int -actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone, - char eaz, int si1, int si2) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - chan->fsm_state = ACT2000_STATE_NULL; - return -ENOMEM; - } - m->msg.connect_req.controller = 0; - m->msg.connect_req.bchan = 0x83; - m->msg.connect_req.infomask = 0x3f; - m->msg.connect_req.si1 = si1; - m->msg.connect_req.si2 = si2; - m->msg.connect_req.eaz = eaz ? eaz : '0'; - m->msg.connect_req.addr.len = strlen(phone) + 1; - m->msg.connect_req.addr.tnp = 0x81; - memcpy(m->msg.connect_req.addr.num, phone, strlen(phone)); - chan->callref = m->hdr.msgnum; - ACTCAPI_QUEUE_TX; - return 0; -} - -static void -actcapi_connect_b3_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(17, 0x82, 0x00); - ACTCAPI_CHKSKB; - m->msg.connect_b3_req.plci = chan->plci; - memset(&m->msg.connect_b3_req.ncpi, 0, - sizeof(m->msg.connect_b3_req.ncpi)); - m->msg.connect_b3_req.ncpi.len = 13; - m->msg.connect_b3_req.ncpi.modulo = 8; - ACTCAPI_QUEUE_TX; -} - -/* - * Set net type (1TR6) or (EDSS1) - */ -int -actcapi_manufacturer_req_net(act2000_card *card) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(5, 0xff, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_net.manuf_msg = 0x11; - m->msg.manufacturer_req_net.controller = 1; - m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO) ? 1 : 0; - ACTCAPI_QUEUE_TX; - printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n", - card->interface.id, (card->ptype == ISDN_PTYPE_EURO) ? "euro" : "1tr6"); - card->interface.features &= - ~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6); - card->interface.features |= - ((card->ptype == ISDN_PTYPE_EURO) ? ISDN_FEATURE_P_EURO : ISDN_FEATURE_P_1TR6); - return 0; -} - -/* - * Switch V.42 on or off - */ -#if 0 -int -actcapi_manufacturer_req_v42(act2000_card *card, ulong arg) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(8, 0xff, 0x00); - if (!skb) { - - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_v42.manuf_msg = 0x10; - m->msg.manufacturer_req_v42.controller = 0; - m->msg.manufacturer_req_v42.v42control = (arg ? 1 : 0); - ACTCAPI_QUEUE_TX; - return 0; -} -#endif /* 0 */ - -/* - * Set error-handler - */ -int -actcapi_manufacturer_req_errh(act2000_card *card) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(4, 0xff, 0x00); - if (!skb) { - - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_err.manuf_msg = 0x03; - m->msg.manufacturer_req_err.controller = 0; - ACTCAPI_QUEUE_TX; - return 0; -} - -/* - * Set MSN-Mapping. - */ -int -actcapi_manufacturer_req_msn(act2000_card *card) -{ - msn_entry *p = card->msn_list; - actcapi_msg *m; - struct sk_buff *skb; - int len; - - while (p) { - int i; - - len = strlen(p->msn); - for (i = 0; i < 2; i++) { - ACTCAPI_MKHDR(6 + len, 0xff, 0x00); - if (!skb) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return -ENOMEM; - } - m->msg.manufacturer_req_msn.manuf_msg = 0x13 + i; - m->msg.manufacturer_req_msn.controller = 0; - m->msg.manufacturer_req_msn.msnmap.eaz = p->eaz; - m->msg.manufacturer_req_msn.msnmap.len = len; - memcpy(m->msg.manufacturer_req_msn.msnmap.msn, p->msn, len); - ACTCAPI_QUEUE_TX; - } - p = p->next; - } - return 0; -} - -void -actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(10, 0x40, 0x00); - ACTCAPI_CHKSKB; - m->msg.select_b2_protocol_req.plci = chan->plci; - memset(&m->msg.select_b2_protocol_req.dlpd, 0, - sizeof(m->msg.select_b2_protocol_req.dlpd)); - m->msg.select_b2_protocol_req.dlpd.len = 6; - switch (chan->l2prot) { - case ISDN_PROTO_L2_TRANS: - m->msg.select_b2_protocol_req.protocol = 0x03; - m->msg.select_b2_protocol_req.dlpd.dlen = 4000; - break; - case ISDN_PROTO_L2_HDLC: - m->msg.select_b2_protocol_req.protocol = 0x02; - m->msg.select_b2_protocol_req.dlpd.dlen = 4000; - break; - case ISDN_PROTO_L2_X75I: - case ISDN_PROTO_L2_X75UI: - case ISDN_PROTO_L2_X75BUI: - m->msg.select_b2_protocol_req.protocol = 0x01; - m->msg.select_b2_protocol_req.dlpd.dlen = 4000; - m->msg.select_b2_protocol_req.dlpd.laa = 3; - m->msg.select_b2_protocol_req.dlpd.lab = 1; - m->msg.select_b2_protocol_req.dlpd.win = 7; - m->msg.select_b2_protocol_req.dlpd.modulo = 8; - break; - } - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(17, 0x80, 0x00); - ACTCAPI_CHKSKB; - m->msg.select_b3_protocol_req.plci = chan->plci; - memset(&m->msg.select_b3_protocol_req.ncpd, 0, - sizeof(m->msg.select_b3_protocol_req.ncpd)); - switch (chan->l3prot) { - case ISDN_PROTO_L3_TRANS: - m->msg.select_b3_protocol_req.protocol = 0x04; - m->msg.select_b3_protocol_req.ncpd.len = 13; - m->msg.select_b3_protocol_req.ncpd.modulo = 8; - break; - } - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_listen_b3_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x81, 0x00); - ACTCAPI_CHKSKB; - m->msg.listen_b3_req.plci = chan->plci; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_disconnect_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(3, 0x04, 0x00); - ACTCAPI_CHKSKB; - m->msg.disconnect_req.plci = chan->plci; - m->msg.disconnect_req.cause = 0; - ACTCAPI_QUEUE_TX; -} - -void -actcapi_disconnect_b3_req(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(17, 0x84, 0x00); - ACTCAPI_CHKSKB; - m->msg.disconnect_b3_req.ncci = chan->ncci; - memset(&m->msg.disconnect_b3_req.ncpi, 0, - sizeof(m->msg.disconnect_b3_req.ncpi)); - m->msg.disconnect_b3_req.ncpi.len = 13; - m->msg.disconnect_b3_req.ncpi.modulo = 8; - chan->fsm_state = ACT2000_STATE_BHWAIT; - ACTCAPI_QUEUE_TX; -} - -void -actcapi_connect_resp(act2000_card *card, act2000_chan *chan, __u8 cause) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(3, 0x02, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_resp.plci = chan->plci; - m->msg.connect_resp.rejectcause = cause; - if (cause) { - chan->fsm_state = ACT2000_STATE_NULL; - chan->plci = 0x8000; - } else - chan->fsm_state = ACT2000_STATE_IWAIT; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_connect_active_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x03, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_resp.plci = chan->plci; - if (chan->fsm_state == ACT2000_STATE_IWAIT) - chan->fsm_state = ACT2000_STATE_IBWAIT; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR((rejectcause ? 3 : 17), 0x82, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_b3_resp.ncci = chan->ncci; - m->msg.connect_b3_resp.rejectcause = rejectcause; - if (!rejectcause) { - memset(&m->msg.connect_b3_resp.ncpi, 0, - sizeof(m->msg.connect_b3_resp.ncpi)); - m->msg.connect_b3_resp.ncpi.len = 13; - m->msg.connect_b3_resp.ncpi.modulo = 8; - chan->fsm_state = ACT2000_STATE_BWAIT; - } - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_connect_b3_active_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x83, 0x03); - ACTCAPI_CHKSKB; - m->msg.connect_b3_active_resp.ncci = chan->ncci; - chan->fsm_state = ACT2000_STATE_ACTIVE; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_info_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x07, 0x03); - ACTCAPI_CHKSKB; - m->msg.info_resp.plci = chan->plci; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_disconnect_b3_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x84, 0x03); - ACTCAPI_CHKSKB; - m->msg.disconnect_b3_resp.ncci = chan->ncci; - chan->ncci = 0x8000; - chan->queued = 0; - ACTCAPI_QUEUE_TX; -} - -static void -actcapi_disconnect_resp(act2000_card *card, act2000_chan *chan) -{ - actcapi_msg *m; - struct sk_buff *skb; - - ACTCAPI_MKHDR(2, 0x04, 0x03); - ACTCAPI_CHKSKB; - m->msg.disconnect_resp.plci = chan->plci; - chan->plci = 0x8000; - ACTCAPI_QUEUE_TX; -} - -static int -new_plci(act2000_card *card, __u16 plci) -{ - int i; - for (i = 0; i < ACT2000_BCH; i++) - if (card->bch[i].plci == 0x8000) { - card->bch[i].plci = plci; - return i; - } - return -1; -} - -static int -find_plci(act2000_card *card, __u16 plci) -{ - int i; - for (i = 0; i < ACT2000_BCH; i++) - if (card->bch[i].plci == plci) - return i; - return -1; -} - -static int -find_ncci(act2000_card *card, __u16 ncci) -{ - int i; - for (i = 0; i < ACT2000_BCH; i++) - if (card->bch[i].ncci == ncci) - return i; - return -1; -} - -static int -find_dialing(act2000_card *card, __u16 callref) -{ - int i; - for (i = 0; i < ACT2000_BCH; i++) - if ((card->bch[i].callref == callref) && - (card->bch[i].fsm_state == ACT2000_STATE_OCALL)) - return i; - return -1; -} - -static int -actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) { - __u16 plci; - __u16 ncci; - __u16 controller; - __u8 blocknr; - int chan; - actcapi_msg *msg = (actcapi_msg *)skb->data; - - EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, controller, ncci); - chan = find_ncci(card, ncci); - if (chan < 0) - return 0; - if (card->bch[chan].fsm_state != ACT2000_STATE_ACTIVE) - return 0; - if (card->bch[chan].plci != plci) - return 0; - blocknr = msg->msg.data_b3_ind.blocknr; - skb_pull(skb, 19); - card->interface.rcvcallb_skb(card->myid, chan, skb); - if (!(skb = alloc_skb(11, GFP_ATOMIC))) { - printk(KERN_WARNING "actcapi: alloc_skb failed\n"); - return 1; - } - msg = (actcapi_msg *)skb_put(skb, 11); - msg->hdr.len = 11; - msg->hdr.applicationID = 1; - msg->hdr.cmd.cmd = 0x86; - msg->hdr.cmd.subcmd = 0x03; - msg->hdr.msgnum = actcapi_nextsmsg(card); - msg->msg.data_b3_resp.ncci = ncci; - msg->msg.data_b3_resp.blocknr = blocknr; - ACTCAPI_QUEUE_TX; - return 1; -} - -/* - * Walk over ackq, unlink DATA_B3_REQ from it, if - * ncci and blocknr are matching. - * Decrement queued-bytes counter. - */ -static int -handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) { - unsigned long flags; - struct sk_buff *skb; - struct sk_buff *tmp; - struct actcapi_msg *m; - int ret = 0; - - spin_lock_irqsave(&card->lock, flags); - skb = skb_peek(&card->ackq); - spin_unlock_irqrestore(&card->lock, flags); - if (!skb) { - printk(KERN_WARNING "act2000: handle_ack nothing found!\n"); - return 0; - } - tmp = skb; - while (1) { - m = (actcapi_msg *)tmp->data; - if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) && - (m->msg.data_b3_req.blocknr == blocknr)) { - /* found corresponding DATA_B3_REQ */ - skb_unlink(tmp, &card->ackq); - chan->queued -= m->msg.data_b3_req.datalen; - if (m->msg.data_b3_req.flags) - ret = m->msg.data_b3_req.datalen; - dev_kfree_skb(tmp); - if (chan->queued < 0) - chan->queued = 0; - return ret; - } - spin_lock_irqsave(&card->lock, flags); - tmp = skb_peek((struct sk_buff_head *)tmp); - spin_unlock_irqrestore(&card->lock, flags); - if ((tmp == skb) || (tmp == NULL)) { - /* reached end of queue */ - printk(KERN_WARNING "act2000: handle_ack nothing found!\n"); - return 0; - } - } -} - -void -actcapi_dispatch(struct work_struct *work) -{ - struct act2000_card *card = - container_of(work, struct act2000_card, rcv_tq); - struct sk_buff *skb; - actcapi_msg *msg; - __u16 ccmd; - int chan; - int len; - act2000_chan *ctmp; - isdn_ctrl cmd; - char tmp[170]; - - while ((skb = skb_dequeue(&card->rcvq))) { - actcapi_debug_msg(skb, 0); - msg = (actcapi_msg *)skb->data; - ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd); - switch (ccmd) { - case 0x8602: - /* DATA_B3_IND */ - if (actcapi_data_b3_ind(card, skb)) - return; - break; - case 0x8601: - /* DATA_B3_CONF */ - chan = find_ncci(card, msg->msg.data_b3_conf.ncci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) { - if (msg->msg.data_b3_conf.info != 0) - printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n", - msg->msg.data_b3_conf.info); - len = handle_ack(card, &card->bch[chan], - msg->msg.data_b3_conf.blocknr); - if (len) { - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BSENT; - cmd.arg = chan; - cmd.parm.length = len; - card->interface.statcallb(&cmd); - } - } - break; - case 0x0201: - /* CONNECT_CONF */ - chan = find_dialing(card, msg->hdr.msgnum); - if (chan >= 0) { - if (msg->msg.connect_conf.info) { - card->bch[chan].fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - card->bch[chan].fsm_state = ACT2000_STATE_OWAIT; - card->bch[chan].plci = msg->msg.connect_conf.plci; - } - } - break; - case 0x0202: - /* CONNECT_IND */ - chan = new_plci(card, msg->msg.connect_ind.plci); - if (chan < 0) { - ctmp = (act2000_chan *)tmp; - ctmp->plci = msg->msg.connect_ind.plci; - actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */ - } else { - card->bch[chan].fsm_state = ACT2000_STATE_ICALL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_ICALL; - cmd.arg = chan; - cmd.parm.setup.si1 = msg->msg.connect_ind.si1; - cmd.parm.setup.si2 = msg->msg.connect_ind.si2; - if (card->ptype == ISDN_PTYPE_EURO) - strcpy(cmd.parm.setup.eazmsn, - act2000_find_eaz(card, msg->msg.connect_ind.eaz)); - else { - cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz; - cmd.parm.setup.eazmsn[1] = 0; - } - memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone)); - memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num, - msg->msg.connect_ind.addr.len - 1); - cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp; - cmd.parm.setup.screen = 0; - if (card->interface.statcallb(&cmd) == 2) - actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */ - } - break; - case 0x0302: - /* CONNECT_ACTIVE_IND */ - chan = find_plci(card, msg->msg.connect_active_ind.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_IWAIT: - actcapi_connect_active_resp(card, &card->bch[chan]); - break; - case ACT2000_STATE_OWAIT: - actcapi_connect_active_resp(card, &card->bch[chan]); - actcapi_select_b2_protocol_req(card, &card->bch[chan]); - break; - } - break; - case 0x8202: - /* CONNECT_B3_IND */ - chan = find_plci(card, msg->msg.connect_b3_ind.plci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) { - card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci; - actcapi_connect_b3_resp(card, &card->bch[chan], 0); - } else { - ctmp = (act2000_chan *)tmp; - ctmp->ncci = msg->msg.connect_b3_ind.ncci; - actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */ - } - break; - case 0x8302: - /* CONNECT_B3_ACTIVE_IND */ - chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) { - actcapi_connect_b3_active_resp(card, &card->bch[chan]); - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BCONN; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - case 0x8402: - /* DISCONNECT_B3_IND */ - chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci); - if (chan >= 0) { - ctmp = &card->bch[chan]; - actcapi_disconnect_b3_resp(card, ctmp); - switch (ctmp->fsm_state) { - case ACT2000_STATE_ACTIVE: - ctmp->fsm_state = ACT2000_STATE_DHWAIT2; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - break; - case ACT2000_STATE_BHWAIT2: - actcapi_disconnect_req(card, ctmp); - ctmp->fsm_state = ACT2000_STATE_DHWAIT; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_BHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - break; - } - } - break; - case 0x0402: - /* DISCONNECT_IND */ - chan = find_plci(card, msg->msg.disconnect_ind.plci); - if (chan >= 0) { - ctmp = &card->bch[chan]; - actcapi_disconnect_resp(card, ctmp); - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - ctmp = (act2000_chan *)tmp; - ctmp->plci = msg->msg.disconnect_ind.plci; - actcapi_disconnect_resp(card, ctmp); - } - break; - case 0x4001: - /* SELECT_B2_PROTOCOL_CONF */ - chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_ICALL: - case ACT2000_STATE_OWAIT: - ctmp = &card->bch[chan]; - if (msg->msg.select_b2_protocol_conf.info == 0) - actcapi_select_b3_protocol_req(card, ctmp); - else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - } - break; - case 0x8001: - /* SELECT_B3_PROTOCOL_CONF */ - chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_ICALL: - case ACT2000_STATE_OWAIT: - ctmp = &card->bch[chan]; - if (msg->msg.select_b3_protocol_conf.info == 0) - actcapi_listen_b3_req(card, ctmp); - else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - } - break; - case 0x8101: - /* LISTEN_B3_CONF */ - chan = find_plci(card, msg->msg.listen_b3_conf.plci); - if (chan >= 0) - switch (card->bch[chan].fsm_state) { - case ACT2000_STATE_ICALL: - ctmp = &card->bch[chan]; - if (msg->msg.listen_b3_conf.info == 0) - actcapi_connect_resp(card, ctmp, 0); - else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - case ACT2000_STATE_OWAIT: - ctmp = &card->bch[chan]; - if (msg->msg.listen_b3_conf.info == 0) { - actcapi_connect_b3_req(card, ctmp); - ctmp->fsm_state = ACT2000_STATE_OBWAIT; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DCONN; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } - break; - } - break; - case 0x8201: - /* CONNECT_B3_CONF */ - chan = find_plci(card, msg->msg.connect_b3_conf.plci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) { - ctmp = &card->bch[chan]; - if (msg->msg.connect_b3_conf.info) { - ctmp->fsm_state = ACT2000_STATE_NULL; - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg = chan; - card->interface.statcallb(&cmd); - } else { - ctmp->ncci = msg->msg.connect_b3_conf.ncci; - ctmp->fsm_state = ACT2000_STATE_BWAIT; - } - } - break; - case 0x8401: - /* DISCONNECT_B3_CONF */ - chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci); - if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT)) - card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2; - break; - case 0x0702: - /* INFO_IND */ - chan = find_plci(card, msg->msg.info_ind.plci); - if (chan >= 0) - /* TODO: Eval Charging info / cause */ - actcapi_info_resp(card, &card->bch[chan]); - break; - case 0x0401: - /* LISTEN_CONF */ - case 0x0501: - /* LISTEN_CONF */ - case 0xff01: - /* MANUFACTURER_CONF */ - break; - case 0xff02: - /* MANUFACTURER_IND */ - if (msg->msg.manuf_msg == 3) { - memset(tmp, 0, sizeof(tmp)); - strncpy(tmp, - &msg->msg.manufacturer_ind_err.errstring, - msg->hdr.len - 16); - if (msg->msg.manufacturer_ind_err.errcode) - printk(KERN_WARNING "act2000: %s\n", tmp); - else { - printk(KERN_DEBUG "act2000: %s\n", tmp); - if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) || - (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) { - card->flags |= ACT2000_FLAGS_RUNNING; - cmd.command = ISDN_STAT_RUN; - cmd.driver = card->myid; - cmd.arg = 0; - actcapi_manufacturer_req_net(card); - actcapi_manufacturer_req_msn(card); - actcapi_listen_req(card); - card->interface.statcallb(&cmd); - } - } - } - break; - default: - printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd); - break; - } - dev_kfree_skb(skb); - } -} - -#ifdef DEBUG_MSG -static void -actcapi_debug_caddr(actcapi_addr *addr) -{ - char tmp[30]; - - printk(KERN_DEBUG " Alen = %d\n", addr->len); - if (addr->len > 0) - printk(KERN_DEBUG " Atnp = 0x%02x\n", addr->tnp); - if (addr->len > 1) { - memset(tmp, 0, 30); - memcpy(tmp, addr->num, addr->len - 1); - printk(KERN_DEBUG " Anum = '%s'\n", tmp); - } -} - -static void -actcapi_debug_ncpi(actcapi_ncpi *ncpi) -{ - printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len); - if (ncpi->len >= 2) - printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic); - if (ncpi->len >= 4) - printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic); - if (ncpi->len >= 6) - printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc); - if (ncpi->len >= 8) - printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc); - if (ncpi->len >= 10) - printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc); - if (ncpi->len >= 12) - printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc); - if (ncpi->len >= 13) - printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo); -} - -static void -actcapi_debug_dlpd(actcapi_dlpd *dlpd) -{ - printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len); - if (dlpd->len >= 2) - printk(KERN_DEBUG " dlpd.dlen = 0x%04x\n", dlpd->dlen); - if (dlpd->len >= 3) - printk(KERN_DEBUG " dlpd.laa = 0x%02x\n", dlpd->laa); - if (dlpd->len >= 4) - printk(KERN_DEBUG " dlpd.lab = 0x%02x\n", dlpd->lab); - if (dlpd->len >= 5) - printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo); - if (dlpd->len >= 6) - printk(KERN_DEBUG " dlpd.win = %d\n", dlpd->win); -} - -#ifdef DEBUG_DUMP_SKB -static void dump_skb(struct sk_buff *skb) { - char tmp[80]; - char *p = skb->data; - char *t = tmp; - int i; - - for (i = 0; i < skb->len; i++) { - t += sprintf(t, "%02x ", *p++ & 0xff); - if ((i & 0x0f) == 8) { - printk(KERN_DEBUG "dump: %s\n", tmp); - t = tmp; - } - } - if (i & 0x07) - printk(KERN_DEBUG "dump: %s\n", tmp); -} -#endif - -void -actcapi_debug_msg(struct sk_buff *skb, int direction) -{ - actcapi_msg *msg = (actcapi_msg *)skb->data; - char *descr; - int i; - char tmp[170]; - -#ifndef DEBUG_DATA_MSG - if (msg->hdr.cmd.cmd == 0x86) - return; -#endif - descr = "INVALID"; -#ifdef DEBUG_DUMP_SKB - dump_skb(skb); -#endif - for (i = 0; i < ARRAY_SIZE(valid_msg); i++) - if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) && - (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) { - descr = valid_msg[i].description; - break; - } - printk(KERN_DEBUG "%s %s msg\n", direction ? "Outgoing" : "Incoming", descr); - printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID); - printk(KERN_DEBUG " Len = %d\n", msg->hdr.len); - printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum); - printk(KERN_DEBUG " Cmd = 0x%02x\n", msg->hdr.cmd.cmd); - printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd); - switch (i) { - case 0: - /* DATA B3 IND */ - printk(KERN_DEBUG " BLOCK = 0x%02x\n", - msg->msg.data_b3_ind.blocknr); - break; - case 2: - /* CONNECT CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.connect_conf.info); - break; - case 3: - /* CONNECT IND */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_ind.plci); - printk(KERN_DEBUG " Contr = %d\n", - msg->msg.connect_ind.controller); - printk(KERN_DEBUG " SI1 = %d\n", - msg->msg.connect_ind.si1); - printk(KERN_DEBUG " SI2 = %d\n", - msg->msg.connect_ind.si2); - printk(KERN_DEBUG " EAZ = '%c'\n", - msg->msg.connect_ind.eaz); - actcapi_debug_caddr(&msg->msg.connect_ind.addr); - break; - case 5: - /* CONNECT ACTIVE IND */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_active_ind.plci); - actcapi_debug_caddr(&msg->msg.connect_active_ind.addr); - break; - case 8: - /* LISTEN CONF */ - printk(KERN_DEBUG " Contr = %d\n", - msg->msg.listen_conf.controller); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.listen_conf.info); - break; - case 11: - /* INFO IND */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.info_ind.plci); - printk(KERN_DEBUG " Imsk = 0x%04x\n", - msg->msg.info_ind.nr.mask); - if (msg->hdr.len > 12) { - int l = msg->hdr.len - 12; - int j; - char *p = tmp; - for (j = 0; j < l; j++) - p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]); - printk(KERN_DEBUG " D = '%s'\n", tmp); - } - break; - case 14: - /* SELECT B2 PROTOCOL CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.select_b2_protocol_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.select_b2_protocol_conf.info); - break; - case 15: - /* SELECT B3 PROTOCOL CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.select_b3_protocol_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.select_b3_protocol_conf.info); - break; - case 16: - /* LISTEN B3 CONF */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.listen_b3_conf.plci); - printk(KERN_DEBUG " Info = 0x%04x\n", - msg->msg.listen_b3_conf.info); - break; - case 18: - /* CONNECT B3 IND */ - printk(KERN_DEBUG " NCCI = 0x%04x\n", - msg->msg.connect_b3_ind.ncci); - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_b3_ind.plci); - actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi); - break; - case 19: - /* CONNECT B3 ACTIVE IND */ - printk(KERN_DEBUG " NCCI = 0x%04x\n", - msg->msg.connect_b3_active_ind.ncci); - actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi); - break; - case 26: - /* MANUFACTURER IND */ - printk(KERN_DEBUG " Mmsg = 0x%02x\n", - msg->msg.manufacturer_ind_err.manuf_msg); - switch (msg->msg.manufacturer_ind_err.manuf_msg) { - case 3: - printk(KERN_DEBUG " Contr = %d\n", - msg->msg.manufacturer_ind_err.controller); - printk(KERN_DEBUG " Code = 0x%08x\n", - msg->msg.manufacturer_ind_err.errcode); - memset(tmp, 0, sizeof(tmp)); - strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring, - msg->hdr.len - 16); - printk(KERN_DEBUG " Emsg = '%s'\n", tmp); - break; - } - break; - case 30: - /* LISTEN REQ */ - printk(KERN_DEBUG " Imsk = 0x%08x\n", - msg->msg.listen_req.infomask); - printk(KERN_DEBUG " Emsk = 0x%04x\n", - msg->msg.listen_req.eazmask); - printk(KERN_DEBUG " Smsk = 0x%04x\n", - msg->msg.listen_req.simask); - break; - case 35: - /* SELECT_B2_PROTOCOL_REQ */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.select_b2_protocol_req.plci); - printk(KERN_DEBUG " prot = 0x%02x\n", - msg->msg.select_b2_protocol_req.protocol); - if (msg->hdr.len >= 11) - printk(KERN_DEBUG "No dlpd\n"); - else - actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd); - break; - case 44: - /* CONNECT RESP */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_resp.plci); - printk(KERN_DEBUG " CAUSE = 0x%02x\n", - msg->msg.connect_resp.rejectcause); - break; - case 45: - /* CONNECT ACTIVE RESP */ - printk(KERN_DEBUG " PLCI = 0x%04x\n", - msg->msg.connect_active_resp.plci); - break; - } -} -#endif diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h deleted file mode 100644 index 01ccdecd43f7..000000000000 --- a/drivers/isdn/act2000/capi.h +++ /dev/null @@ -1,365 +0,0 @@ -/* $Id: capi.h,v 1.6.6.2 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * - * Author Fritz Elfert - * Copyright 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. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#ifndef CAPI_H -#define CAPI_H - -/* Command-part of a CAPI message */ -typedef struct actcapi_msgcmd { - __u8 cmd; - __u8 subcmd; -} actcapi_msgcmd; - -/* CAPI message header */ -typedef struct actcapi_msghdr { - __u16 len; - __u16 applicationID; - actcapi_msgcmd cmd; - __u16 msgnum; -} actcapi_msghdr; - -/* CAPI message description (for debugging) */ -typedef struct actcapi_msgdsc { - actcapi_msgcmd cmd; - char *description; -} actcapi_msgdsc; - -/* CAPI Address */ -typedef struct actcapi_addr { - __u8 len; /* Length of element */ - __u8 tnp; /* Type/Numbering Plan */ - __u8 num[20]; /* Caller ID */ -} actcapi_addr; - -/* CAPI INFO element mask */ -typedef union actcapi_infonr { /* info number */ - __u16 mask; /* info-mask field */ - struct bmask { /* bit definitions */ - unsigned codes:3; /* code set */ - unsigned rsvd:5; /* reserved */ - unsigned svind:1; /* single, variable length ind. */ - unsigned wtype:7; /* W-element type */ - } bmask; -} actcapi_infonr; - -/* CAPI INFO element */ -typedef union actcapi_infoel { /* info element */ - __u8 len; /* length of info element */ - __u8 display[40]; /* display contents */ - __u8 uuinfo[40]; /* User-user info field */ - struct cause { /* Cause information */ - unsigned ext2:1; /* extension */ - unsigned cod:2; /* coding standard */ - unsigned spare:1; /* spare */ - unsigned loc:4; /* location */ - unsigned ext1:1; /* extension */ - unsigned cval:7; /* Cause value */ - } cause; - struct charge { /* Charging information */ - __u8 toc; /* type of charging info */ - __u8 unit[10]; /* charging units */ - } charge; - __u8 date[20]; /* date fields */ - __u8 stat; /* state of remote party */ -} actcapi_infoel; - -/* Message for EAZ<->MSN Mapping */ -typedef struct actcapi_msn { - __u8 eaz; - __u8 len; /* Length of MSN */ - __u8 msn[15]; -} __attribute__((packed)) actcapi_msn; - -typedef struct actcapi_dlpd { - __u8 len; /* Length of structure */ - __u16 dlen; /* Data Length */ - __u8 laa; /* Link Address A */ - __u8 lab; /* Link Address B */ - __u8 modulo; /* Modulo Mode */ - __u8 win; /* Window size */ - __u8 xid[100]; /* XID Information */ -} __attribute__((packed)) actcapi_dlpd; - -typedef struct actcapi_ncpd { - __u8 len; /* Length of structure */ - __u16 lic; - __u16 hic; - __u16 ltc; - __u16 htc; - __u16 loc; - __u16 hoc; - __u8 modulo; -} __attribute__((packed)) actcapi_ncpd; -#define actcapi_ncpi actcapi_ncpd - -/* - * Layout of NCCI field in a B3 DATA CAPI message is different from - * standard at act2000: - * - * Bit 0-4 = PLCI - * Bit 5-7 = Controller - * Bit 8-15 = NCCI - */ -#define MAKE_NCCI(plci, contr, ncci) \ - ((plci & 0x1f) | ((contr & 0x7) << 5) | ((ncci & 0xff) << 8)) - -#define EVAL_NCCI(fakencci, plci, contr, ncci) { \ - plci = fakencci & 0x1f; \ - contr = (fakencci >> 5) & 0x7; \ - ncci = (fakencci >> 8) & 0xff; \ - } - -/* - * Layout of PLCI field in a B3 DATA CAPI message is different from - * standard at act2000: - * - * Bit 0-4 = PLCI - * Bit 5-7 = Controller - * Bit 8-15 = reserved (must be 0) - */ -#define MAKE_PLCI(plci, contr) \ - ((plci & 0x1f) | ((contr & 0x7) << 5)) - -#define EVAL_PLCI(fakeplci, plci, contr) { \ - plci = fakeplci & 0x1f; \ - contr = (fakeplci >> 5) & 0x7; \ - } - -typedef struct actcapi_msg { - actcapi_msghdr hdr; - union { - __u16 manuf_msg; - struct manufacturer_req_net { - __u16 manuf_msg; - __u16 controller; - __u8 nettype; - } manufacturer_req_net; - struct manufacturer_req_v42 { - __u16 manuf_msg; - __u16 controller; - __u32 v42control; - } manufacturer_req_v42; - struct manufacturer_conf_v42 { - __u16 manuf_msg; - __u16 controller; - } manufacturer_conf_v42; - struct manufacturer_req_err { - __u16 manuf_msg; - __u16 controller; - } manufacturer_req_err; - struct manufacturer_ind_err { - __u16 manuf_msg; - __u16 controller; - __u32 errcode; - __u8 errstring; /* actually up to 160 */ - } manufacturer_ind_err; - struct manufacturer_req_msn { - __u16 manuf_msg; - __u16 controller; - actcapi_msn msnmap; - } __attribute ((packed)) manufacturer_req_msn; - /* TODO: TraceInit-req/conf/ind/resp and - * TraceDump-req/conf/ind/resp - */ - struct connect_req { - __u8 controller; - __u8 bchan; - __u32 infomask; - __u8 si1; - __u8 si2; - __u8 eaz; - actcapi_addr addr; - } __attribute__ ((packed)) connect_req; - struct connect_conf { - __u16 plci; - __u16 info; - } connect_conf; - struct connect_ind { - __u16 plci; - __u8 controller; - __u8 si1; - __u8 si2; - __u8 eaz; - actcapi_addr addr; - } __attribute__ ((packed)) connect_ind; - struct connect_resp { - __u16 plci; - __u8 rejectcause; - } connect_resp; - struct connect_active_ind { - __u16 plci; - actcapi_addr addr; - } __attribute__ ((packed)) connect_active_ind; - struct connect_active_resp { - __u16 plci; - } connect_active_resp; - struct connect_b3_req { - __u16 plci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_req; - struct connect_b3_conf { - __u16 plci; - __u16 ncci; - __u16 info; - } connect_b3_conf; - struct connect_b3_ind { - __u16 ncci; - __u16 plci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_ind; - struct connect_b3_resp { - __u16 ncci; - __u8 rejectcause; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_resp; - struct disconnect_req { - __u16 plci; - __u8 cause; - } disconnect_req; - struct disconnect_conf { - __u16 plci; - __u16 info; - } disconnect_conf; - struct disconnect_ind { - __u16 plci; - __u16 info; - } disconnect_ind; - struct disconnect_resp { - __u16 plci; - } disconnect_resp; - struct connect_b3_active_ind { - __u16 ncci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_active_ind; - struct connect_b3_active_resp { - __u16 ncci; - } connect_b3_active_resp; - struct disconnect_b3_req { - __u16 ncci; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) disconnect_b3_req; - struct disconnect_b3_conf { - __u16 ncci; - __u16 info; - } disconnect_b3_conf; - struct disconnect_b3_ind { - __u16 ncci; - __u16 info; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) disconnect_b3_ind; - struct disconnect_b3_resp { - __u16 ncci; - } disconnect_b3_resp; - struct info_ind { - __u16 plci; - actcapi_infonr nr; - actcapi_infoel el; - } __attribute__ ((packed)) info_ind; - struct info_resp { - __u16 plci; - } info_resp; - struct listen_b3_req { - __u16 plci; - } listen_b3_req; - struct listen_b3_conf { - __u16 plci; - __u16 info; - } listen_b3_conf; - struct select_b2_protocol_req { - __u16 plci; - __u8 protocol; - actcapi_dlpd dlpd; - } __attribute__ ((packed)) select_b2_protocol_req; - struct select_b2_protocol_conf { - __u16 plci; - __u16 info; - } select_b2_protocol_conf; - struct select_b3_protocol_req { - __u16 plci; - __u8 protocol; - actcapi_ncpd ncpd; - } __attribute__ ((packed)) select_b3_protocol_req; - struct select_b3_protocol_conf { - __u16 plci; - __u16 info; - } select_b3_protocol_conf; - struct listen_req { - __u8 controller; - __u32 infomask; - __u16 eazmask; - __u16 simask; - } __attribute__ ((packed)) listen_req; - struct listen_conf { - __u8 controller; - __u16 info; - } __attribute__ ((packed)) listen_conf; - struct data_b3_req { - __u16 fakencci; - __u16 datalen; - __u32 unused; - __u8 blocknr; - __u16 flags; - } __attribute ((packed)) data_b3_req; - struct data_b3_ind { - __u16 fakencci; - __u16 datalen; - __u32 unused; - __u8 blocknr; - __u16 flags; - } __attribute__ ((packed)) data_b3_ind; - struct data_b3_resp { - __u16 ncci; - __u8 blocknr; - } __attribute__ ((packed)) data_b3_resp; - struct data_b3_conf { - __u16 ncci; - __u8 blocknr; - __u16 info; - } __attribute__ ((packed)) data_b3_conf; - } msg; -} __attribute__ ((packed)) actcapi_msg; - -static inline unsigned short -actcapi_nextsmsg(act2000_card *card) -{ - unsigned long flags; - unsigned short n; - - spin_lock_irqsave(&card->mnlock, flags); - n = card->msgnum; - card->msgnum++; - card->msgnum &= 0x7fff; - spin_unlock_irqrestore(&card->mnlock, flags); - return n; -} -#define DEBUG_MSG -#undef DEBUG_DATA_MSG -#undef DEBUG_DUMP_SKB - -extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *); -extern int actcapi_listen_req(act2000_card *); -extern int actcapi_manufacturer_req_net(act2000_card *); -extern int actcapi_manufacturer_req_errh(act2000_card *); -extern int actcapi_manufacturer_req_msn(act2000_card *); -extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int); -extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *); -extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *); -extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8); -extern void actcapi_dispatch(struct work_struct *); -#ifdef DEBUG_MSG -extern void actcapi_debug_msg(struct sk_buff *skb, int); -#else -#define actcapi_debug_msg(skb, len) -#endif -#endif diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c deleted file mode 100644 index 68073d0da0e3..000000000000 --- a/drivers/isdn/act2000/module.c +++ /dev/null @@ -1,813 +0,0 @@ -/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $ - * - * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. - * - * Author Fritz Elfert - * Copyright 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. - * - * Thanks to Friedemann Baitinger and IBM Germany - * - */ - -#include "act2000.h" -#include "act2000_isa.h" -#include "capi.h" -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> - -static unsigned short act2000_isa_ports[] = -{ - 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, - 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60, -}; - -static act2000_card *cards = (act2000_card *) NULL; - -/* Parameters to be set by insmod */ -static int act_bus = 0; -static int act_port = -1; /* -1 = Autoprobe */ -static int act_irq = -1; -static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - -MODULE_DESCRIPTION("ISDN4Linux: Driver for IBM Active 2000 ISDN card"); -MODULE_AUTHOR("Fritz Elfert"); -MODULE_LICENSE("GPL"); -MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA"); -MODULE_PARM_DESC(act_port, "Base port address of first card"); -MODULE_PARM_DESC(act_irq, "IRQ of first card"); -MODULE_PARM_DESC(act_id, "ID-String of first card"); -module_param(act_bus, int, 0); -module_param(act_port, int, 0); -module_param(act_irq, int, 0); -module_param(act_id, charp, 0); - -static int act2000_addcard(int, int, int, char *); - -static act2000_chan * -find_channel(act2000_card *card, int channel) -{ - if ((channel >= 0) && (channel < ACT2000_BCH)) - return &(card->bch[channel]); - printk(KERN_WARNING "act2000: Invalid channel %d\n", channel); - return NULL; -} - -/* - * Free MSN list - */ -static void -act2000_clear_msn(act2000_card *card) -{ - struct msn_entry *p = card->msn_list; - struct msn_entry *q; - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); - card->msn_list = NULL; - spin_unlock_irqrestore(&card->lock, flags); - while (p) { - q = p->next; - kfree(p); - p = q; - } -} - -/* - * Find an MSN entry in the list. - * If ia5 != 0, return IA5-encoded EAZ, else - * return a bitmask with corresponding bit set. - */ -static __u16 -act2000_find_msn(act2000_card *card, char *msn, int ia5) -{ - struct msn_entry *p = card->msn_list; - __u8 eaz = '0'; - - while (p) { - if (!strcmp(p->msn, msn)) { - eaz = p->eaz; - break; - } - p = p->next; - } - if (!ia5) - return (1 << (eaz - '0')); - else - return eaz; -} - -/* - * Find an EAZ entry in the list. - * return a string with corresponding msn. - */ -char * -act2000_find_eaz(act2000_card *card, char eaz) -{ - struct msn_entry *p = card->msn_list; - - while (p) { - if (p->eaz == eaz) - return (p->msn); - p = p->next; - } - return ("\0"); -} - -/* - * Add or delete an MSN to the MSN list - * - * First character of msneaz is EAZ, rest is MSN. - * If length of eazmsn is 1, delete that entry. - */ -static int -act2000_set_msn(act2000_card *card, char *eazmsn) -{ - struct msn_entry *p = card->msn_list; - struct msn_entry *q = NULL; - unsigned long flags; - int i; - - if (!strlen(eazmsn)) - return 0; - if (strlen(eazmsn) > 16) - return -EINVAL; - for (i = 0; i < strlen(eazmsn); i++) - if (!isdigit(eazmsn[i])) - return -EINVAL; - if (strlen(eazmsn) == 1) { - /* Delete a single MSN */ - while (p) { - if (p->eaz == eazmsn[0]) { - spin_lock_irqsave(&card->lock, flags); - if (q) - q->next = p->next; - else - card->msn_list = p->next; - spin_unlock_irqrestore(&card->lock, flags); - kfree(p); - printk(KERN_DEBUG - "Mapping for EAZ %c deleted\n", - eazmsn[0]); - return 0; - } - q = p; - p = p->next; - } - return 0; - } - /* Add a single MSN */ - while (p) { - /* Found in list, replace MSN */ - if (p->eaz == eazmsn[0]) { - spin_lock_irqsave(&card->lock, flags); - strcpy(p->msn, &eazmsn[1]); - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_DEBUG - "Mapping for EAZ %c changed to %s\n", - eazmsn[0], - &eazmsn[1]); - return 0; - } - p = p->next; - } - /* Not found in list, add new entry */ - p = kmalloc(sizeof(msn_entry), GFP_KERNEL); - if (!p) - return -ENOMEM; - p->eaz = eazmsn[0]; - strcpy(p->msn, &eazmsn[1]); - p->next = card->msn_list; - spin_lock_irqsave(&card->lock, flags); - card->msn_list = p; - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_DEBUG - "Mapping %c -> %s added\n", - eazmsn[0], - &eazmsn[1]); - return 0; -} - -static void -act2000_transmit(struct work_struct *work) -{ - struct act2000_card *card = - container_of(work, struct act2000_card, snd_tq); - - switch (card->bus) { - case ACT2000_BUS_ISA: - act2000_isa_send(card); - break; - case ACT2000_BUS_PCMCIA: - case ACT2000_BUS_MCA: - default: - printk(KERN_WARNING - "act2000_transmit: Illegal bustype %d\n", card->bus); - } -} - -static void -act2000_receive(struct work_struct *work) -{ - struct act2000_card *card = - container_of(work, struct act2000_card, poll_tq); - - switch (card->bus) { - case ACT2000_BUS_ISA: - act2000_isa_receive(card); - break; - case ACT2000_BUS_PCMCIA: - case ACT2000_BUS_MCA: - default: - printk(KERN_WARNING - "act2000_receive: Illegal bustype %d\n", card->bus); - } -} - -static void -act2000_poll(unsigned long data) -{ - act2000_card *card = (act2000_card *)data; - unsigned long flags; - - act2000_receive(&card->poll_tq); - spin_lock_irqsave(&card->lock, flags); - mod_timer(&card->ptimer, jiffies + 3); - spin_unlock_irqrestore(&card->lock, flags); -} - -static int -act2000_command(act2000_card *card, isdn_ctrl *c) -{ - ulong a; - act2000_chan *chan; - act2000_cdef cdef; - isdn_ctrl cmd; - char tmp[17]; - int ret; - unsigned long flags; - void __user *arg; - - switch (c->command) { - case ISDN_CMD_IOCTL: - memcpy(&a, c->parm.num, sizeof(ulong)); - arg = (void __user *)a; - switch (c->arg) { - case ACT2000_IOCTL_LOADBOOT: - switch (card->bus) { - case ACT2000_BUS_ISA: - ret = act2000_isa_download(card, - arg); - if (!ret) { - card->flags |= ACT2000_FLAGS_LOADED; - if (!(card->flags & ACT2000_FLAGS_IVALID)) { - card->ptimer.expires = jiffies + 3; - card->ptimer.function = act2000_poll; - card->ptimer.data = (unsigned long)card; - add_timer(&card->ptimer); - } - actcapi_manufacturer_req_errh(card); - } - break; - default: - printk(KERN_WARNING - "act2000: Illegal BUS type %d\n", - card->bus); - ret = -EIO; - } - return ret; - case ACT2000_IOCTL_SETPROTO: - card->ptype = a ? ISDN_PTYPE_EURO : ISDN_PTYPE_1TR6; - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return 0; - actcapi_manufacturer_req_net(card); - return 0; - case ACT2000_IOCTL_SETMSN: - if (copy_from_user(tmp, arg, - sizeof(tmp))) - return -EFAULT; - if ((ret = act2000_set_msn(card, tmp))) - return ret; - if (card->flags & ACT2000_FLAGS_RUNNING) - return (actcapi_manufacturer_req_msn(card)); - return 0; - case ACT2000_IOCTL_ADDCARD: - if (copy_from_user(&cdef, arg, - sizeof(cdef))) - return -EFAULT; - if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id)) - return -EIO; - return 0; - case ACT2000_IOCTL_TEST: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return 0; - default: - return -EINVAL; - } - break; - case ISDN_CMD_DIAL: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - spin_lock_irqsave(&card->lock, flags); - if (chan->fsm_state != ACT2000_STATE_NULL) { - spin_unlock_irqrestore(&card->lock, flags); - printk(KERN_WARNING "Dial on channel with state %d\n", - chan->fsm_state); - return -EBUSY; - } - if (card->ptype == ISDN_PTYPE_EURO) - tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1); - else - tmp[0] = c->parm.setup.eazmsn[0]; - chan->fsm_state = ACT2000_STATE_OCALL; - chan->callref = 0xffff; - spin_unlock_irqrestore(&card->lock, flags); - ret = actcapi_connect_req(card, chan, c->parm.setup.phone, - tmp[0], c->parm.setup.si1, - c->parm.setup.si2); - if (ret) { - cmd.driver = card->myid; - cmd.command = ISDN_STAT_DHUP; - cmd.arg &= 0x0f; - card->interface.statcallb(&cmd); - } - return ret; - case ISDN_CMD_ACCEPTD: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - if (chan->fsm_state == ACT2000_STATE_ICALL) - actcapi_select_b2_protocol_req(card, chan); - return 0; - case ISDN_CMD_ACCEPTB: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return 0; - case ISDN_CMD_HANGUP: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - switch (chan->fsm_state) { - case ACT2000_STATE_ICALL: - case ACT2000_STATE_BSETUP: - actcapi_connect_resp(card, chan, 0x15); - break; - case ACT2000_STATE_ACTIVE: - actcapi_disconnect_b3_req(card, chan); - break; - } - return 0; - case ISDN_CMD_SETEAZ: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - if (strlen(c->parm.num)) { - if (card->ptype == ISDN_PTYPE_EURO) { - chan->eazmask = act2000_find_msn(card, c->parm.num, 0); - } - if (card->ptype == ISDN_PTYPE_1TR6) { - int i; - chan->eazmask = 0; - for (i = 0; i < strlen(c->parm.num); i++) - if (isdigit(c->parm.num[i])) - chan->eazmask |= (1 << (c->parm.num[i] - '0')); - } - } else - chan->eazmask = 0x3ff; - actcapi_listen_req(card); - return 0; - case ISDN_CMD_CLREAZ: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - chan->eazmask = 0; - actcapi_listen_req(card); - return 0; - case ISDN_CMD_SETL2: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - chan->l2prot = (c->arg >> 8); - return 0; - case ISDN_CMD_SETL3: - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) { - printk(KERN_WARNING "L3 protocol unknown\n"); - return -1; - } - if (!(chan = find_channel(card, c->arg & 0x0f))) - break; - chan->l3prot = (c->arg >> 8); - return 0; - } - - return -EINVAL; -} - -static int -act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb) -{ - struct sk_buff *xmit_skb; - int len; - act2000_chan *chan; - actcapi_msg *msg; - - if (!(chan = find_channel(card, channel))) - return -1; - if (chan->fsm_state != ACT2000_STATE_ACTIVE) - return -1; - len = skb->len; - if ((chan->queued + len) >= ACT2000_MAX_QUEUED) - return 0; - if (!len) - return 0; - if (skb_headroom(skb) < 19) { - printk(KERN_WARNING "act2000_sendbuf: Headroom only %d\n", - skb_headroom(skb)); - xmit_skb = alloc_skb(len + 19, GFP_ATOMIC); - if (!xmit_skb) { - printk(KERN_WARNING "act2000_sendbuf: Out of memory\n"); - return 0; - } - skb_reserve(xmit_skb, 19); - skb_copy_from_linear_data(skb, skb_put(xmit_skb, len), len); - } else { - xmit_skb = skb_clone(skb, GFP_ATOMIC); - if (!xmit_skb) { - printk(KERN_WARNING "act2000_sendbuf: Out of memory\n"); - return 0; - } - } - dev_kfree_skb(skb); - msg = (actcapi_msg *)skb_push(xmit_skb, 19); - msg->hdr.len = 19 + len; - msg->hdr.applicationID = 1; - msg->hdr.cmd.cmd = 0x86; - msg->hdr.cmd.subcmd = 0x00; - msg->hdr.msgnum = actcapi_nextsmsg(card); - msg->msg.data_b3_req.datalen = len; - msg->msg.data_b3_req.blocknr = (msg->hdr.msgnum & 0xff); - msg->msg.data_b3_req.fakencci = MAKE_NCCI(chan->plci, 0, chan->ncci); - msg->msg.data_b3_req.flags = ack; /* Will be set to 0 on actual sending */ - actcapi_debug_msg(xmit_skb, 1); - chan->queued += len; - skb_queue_tail(&card->sndq, xmit_skb); - act2000_schedule_tx(card); - return len; -} - - -/* Read the Status-replies from the Interface */ -static int -act2000_readstatus(u_char __user *buf, int len, act2000_card *card) -{ - int count; - u_char __user *p; - - for (p = buf, count = 0; count < len; p++, count++) { - if (card->status_buf_read == card->status_buf_write) - return count; - put_user(*card->status_buf_read++, p); - if (card->status_buf_read > card->status_buf_end) - card->status_buf_read = card->status_buf; - } - return count; -} - -/* - * Find card with given driverId - */ -static inline act2000_card * -act2000_findcard(int driverid) -{ - act2000_card *p = cards; - - while (p) { - if (p->myid == driverid) - return p; - p = p->next; - } - return (act2000_card *) 0; -} - -/* - * Wrapper functions for interface to linklevel - */ -static int -if_command(isdn_ctrl *c) -{ - act2000_card *card = act2000_findcard(c->driver); - - if (card) - return (act2000_command(card, c)); - printk(KERN_ERR - "act2000: 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) -{ - act2000_card *card = act2000_findcard(id); - - if (card) { - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return (len); - } - printk(KERN_ERR - "act2000: if_writecmd called with invalid driverId!\n"); - return -ENODEV; -} - -static int -if_readstatus(u_char __user *buf, int len, int id, int channel) -{ - act2000_card *card = act2000_findcard(id); - - if (card) { - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return (act2000_readstatus(buf, len, card)); - } - printk(KERN_ERR - "act2000: if_readstatus called with invalid driverId!\n"); - return -ENODEV; -} - -static int -if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) -{ - act2000_card *card = act2000_findcard(id); - - if (card) { - if (!(card->flags & ACT2000_FLAGS_RUNNING)) - return -ENODEV; - return (act2000_sendbuf(card, channel, ack, skb)); - } - printk(KERN_ERR - "act2000: if_sendbuf called with invalid driverId!\n"); - return -ENODEV; -} - - -/* - * Allocate a new card-struct, initialize it - * link it into cards-list. - */ -static void -act2000_alloccard(int bus, int port, int irq, char *id) -{ - int i; - act2000_card *card; - if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) { - printk(KERN_WARNING - "act2000: (%s) Could not allocate card-struct.\n", id); - return; - } - spin_lock_init(&card->lock); - spin_lock_init(&card->mnlock); - skb_queue_head_init(&card->sndq); - skb_queue_head_init(&card->rcvq); - skb_queue_head_init(&card->ackq); - INIT_WORK(&card->snd_tq, act2000_transmit); - INIT_WORK(&card->rcv_tq, actcapi_dispatch); - INIT_WORK(&card->poll_tq, act2000_receive); - init_timer(&card->ptimer); - card->interface.owner = THIS_MODULE; - card->interface.channels = ACT2000_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->interface.hl_hdrlen = 20; - card->ptype = ISDN_PTYPE_EURO; - strlcpy(card->interface.id, id, sizeof(card->interface.id)); - for (i = 0; i < ACT2000_BCH; i++) { - card->bch[i].plci = 0x8000; - card->bch[i].ncci = 0x8000; - card->bch[i].l2prot = ISDN_PROTO_L2_X75I; - card->bch[i].l3prot = ISDN_PROTO_L3_TRANS; - } - card->myid = -1; - card->bus = bus; - card->port = port; - card->irq = irq; - card->next = cards; - cards = card; -} - -/* - * register card at linklevel - */ -static int -act2000_registercard(act2000_card *card) -{ - switch (card->bus) { - case ACT2000_BUS_ISA: - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: Illegal BUS type %d\n", - card->bus); - return -1; - } - if (!register_isdn(&card->interface)) { - printk(KERN_WARNING - "act2000: Unable to register %s\n", - card->interface.id); - return -1; - } - card->myid = card->interface.channels; - sprintf(card->regname, "act2000-isdn (%s)", card->interface.id); - return 0; -} - -static void -unregister_card(act2000_card *card) -{ - isdn_ctrl cmd; - - cmd.command = ISDN_STAT_UNLOAD; - cmd.driver = card->myid; - card->interface.statcallb(&cmd); - switch (card->bus) { - case ACT2000_BUS_ISA: - act2000_isa_release(card); - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: Invalid BUS type %d\n", - card->bus); - break; - } -} - -static int -act2000_addcard(int bus, int port, int irq, char *id) -{ - act2000_card *p; - act2000_card *q = NULL; - int initialized; - int added = 0; - int failed = 0; - int i; - - if (!bus) - bus = ACT2000_BUS_ISA; - if (port != -1) { - /* Port defined, do fixed setup */ - act2000_alloccard(bus, port, irq, id); - } else { - /* No port defined, perform autoprobing. - * This may result in more than one card detected. - */ - switch (bus) { - case ACT2000_BUS_ISA: - for (i = 0; i < ARRAY_SIZE(act2000_isa_ports); i++) - if (act2000_isa_detect(act2000_isa_ports[i])) { - printk(KERN_INFO "act2000: Detected " - "ISA card at port 0x%x\n", - act2000_isa_ports[i]); - act2000_alloccard(bus, - act2000_isa_ports[i], irq, id); - } - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: addcard: Invalid BUS type %d\n", bus); - } - } - if (!cards) - return 1; - p = cards; - while (p) { - initialized = 0; - if (!p->interface.statcallb) { - /* Not yet registered. - * Try to register and activate it. - */ - added++; - switch (p->bus) { - case ACT2000_BUS_ISA: - if (act2000_isa_detect(p->port)) { - if (act2000_registercard(p)) - break; - if (act2000_isa_config_port(p, p->port)) { - printk(KERN_WARNING - "act2000: Could not request port 0x%04x\n", - p->port); - unregister_card(p); - p->interface.statcallb = NULL; - break; - } - if (act2000_isa_config_irq(p, p->irq)) { - printk(KERN_INFO - "act2000: No IRQ available, fallback to polling\n"); - /* Fall back to polled operation */ - p->irq = 0; - } - printk(KERN_INFO - "act2000: ISA" - "-type card at port " - "0x%04x ", - p->port); - if (p->irq) - printk("irq %d\n", p->irq); - else - printk("polled\n"); - initialized = 1; - } - break; - case ACT2000_BUS_MCA: - case ACT2000_BUS_PCMCIA: - default: - printk(KERN_WARNING - "act2000: addcard: Invalid BUS type %d\n", - p->bus); - } - } else - /* Card already initialized */ - initialized = 1; - if (initialized) { - /* Init OK, next card ... */ - q = p; - p = p->next; - } else { - /* Init failed, remove card from list, free memory */ - printk(KERN_WARNING - "act2000: Initialization of %s failed\n", - p->interface.id); - if (q) { - q->next = p->next; - kfree(p); - p = q->next; - } else { - cards = p->next; - kfree(p); - p = cards; - } - failed++; - } - } - return (added - failed); -} - -#define DRIVERNAME "IBM Active 2000 ISDN driver" - -static int __init act2000_init(void) -{ - printk(KERN_INFO "%s\n", DRIVERNAME); - if (!cards) - act2000_addcard(act_bus, act_port, act_irq, act_id); - if (!cards) - printk(KERN_INFO "act2000: No cards defined yet\n"); - return 0; -} - -static void __exit act2000_exit(void) -{ - act2000_card *card = cards; - act2000_card *last; - while (card) { - unregister_card(card); - del_timer_sync(&card->ptimer); - card = card->next; - } - card = cards; - while (card) { - last = card; - card = card->next; - act2000_clear_msn(last); - kfree(last); - } - printk(KERN_INFO "%s unloaded\n", DRIVERNAME); -} - -module_init(act2000_init); -module_exit(act2000_exit); diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index f5b714cd7618..68e54d9f2f53 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig @@ -123,16 +123,6 @@ comment "ISDN4Linux hardware drivers" source "drivers/isdn/hisax/Kconfig" - -menu "Active cards" - -source "drivers/isdn/icn/Kconfig" - -source "drivers/isdn/pcbit/Kconfig" - -source "drivers/isdn/act2000/Kconfig" - -endmenu # end ISDN_I4L endif diff --git a/drivers/isdn/icn/Kconfig b/drivers/isdn/icn/Kconfig deleted file mode 100644 index 4534f21a1852..000000000000 --- a/drivers/isdn/icn/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -config ISDN_DRV_ICN - tristate "ICN 2B and 4B support" - depends on ISA - help - This enables support for two kinds of ISDN-cards made by a German - company called ICN. 2B is the standard version for a single ISDN - line with two B-channels, 4B supports two ISDN lines. For running - this card, additional firmware is necessary, which has to be - downloaded into the card using a utility which is distributed - separately. See <file:Documentation/isdn/README> and - <file:Documentation/isdn/README.icn> for more - information. diff --git a/drivers/isdn/icn/Makefile b/drivers/isdn/icn/Makefile deleted file mode 100644 index d9b476fcf384..000000000000 --- a/drivers/isdn/icn/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# Makefile for the icn ISDN device driver - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_ICN) += icn.o diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c deleted file mode 100644 index 46d957c34be1..000000000000 --- a/drivers/isdn/icn/icn.c +++ /dev/null @@ -1,1693 +0,0 @@ -/* $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; - /* 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); diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h deleted file mode 100644 index f8f2e76d34bf..000000000000 --- a/drivers/isdn/icn/icn.h +++ /dev/null @@ -1,253 +0,0 @@ -/* $Id: icn.h,v 1.30.6.5 2001/09/23 22:24:55 kai Exp $ - * - * ISDN lowlevel-module for the ICN active ISDN-Card. - * - * Copyright 1994 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. - * - */ - -#ifndef icn_h -#define icn_h - -#define ICN_IOCTL_SETMMIO 0 -#define ICN_IOCTL_GETMMIO 1 -#define ICN_IOCTL_SETPORT 2 -#define ICN_IOCTL_GETPORT 3 -#define ICN_IOCTL_LOADBOOT 4 -#define ICN_IOCTL_LOADPROTO 5 -#define ICN_IOCTL_LEASEDCFG 6 -#define ICN_IOCTL_GETDOUBLE 7 -#define ICN_IOCTL_DEBUGVAR 8 -#define ICN_IOCTL_ADDCARD 9 - -/* Struct for adding new cards */ -typedef struct icn_cdef { - int port; - char id1[10]; - char id2[10]; -} icn_cdef; - -#if defined(__KERNEL__) || defined(__DEBUGVAR__) - -#ifdef __KERNEL__ -/* Kernel includes */ - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/major.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/signal.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/ioport.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/delay.h> -#include <linux/isdnif.h> - -#endif /* __KERNEL__ */ - -/* some useful macros for debugging */ -#ifdef ICN_DEBUG_PORT -#define OUTB_P(v, p) {printk(KERN_DEBUG "icn: outb_p(0x%02x,0x%03x)\n", v, p); outb_p(v, p);} -#else -#define OUTB_P outb -#endif - -/* Defaults for Port-Address and shared-memory */ -#define ICN_BASEADDR 0x320 -#define ICN_PORTLEN (0x04) -#define ICN_MEMADDR 0x0d0000 - -#define ICN_FLAGS_B1ACTIVE 1 /* B-Channel-1 is open */ -#define ICN_FLAGS_B2ACTIVE 2 /* B-Channel-2 is open */ -#define ICN_FLAGS_RUNNING 4 /* Cards driver activated */ -#define ICN_FLAGS_RBTIMER 8 /* cyclic scheduling of B-Channel-poll */ - -#define ICN_BOOT_TIMEOUT1 1000 /* Delay for Boot-download (msecs) */ - -#define ICN_TIMER_BCREAD (HZ / 100) /* B-Channel poll-cycle */ -#define ICN_TIMER_DCREAD (HZ / 2) /* D-Channel poll-cycle */ - -#define ICN_CODE_STAGE1 4096 /* Size of bootcode */ -#define ICN_CODE_STAGE2 65536 /* Size of protocol-code */ - -#define ICN_MAX_SQUEUE 8000 /* Max. outstanding send-data (2* hw-buf.) */ -#define ICN_FRAGSIZE (250) /* Max. size of send-fragments */ -#define ICN_BCH 2 /* Number of supported channels per card */ - -/* type-definitions for accessing the mmap-io-areas */ - -#define SHM_DCTL_OFFSET (0) /* Offset to data-controlstructures in shm */ -#define SHM_CCTL_OFFSET (0x1d2) /* Offset to comm-controlstructures in shm */ -#define SHM_CBUF_OFFSET (0x200) /* Offset to comm-buffers in shm */ -#define SHM_DBUF_OFFSET (0x2000) /* Offset to data-buffers in shm */ - -/* - * Layout of card's data buffers - */ -typedef struct { - unsigned char length; /* Bytecount of fragment (max 250) */ - unsigned char endflag; /* 0=last frag., 0xff=frag. continued */ - unsigned char data[ICN_FRAGSIZE]; /* The data */ - /* Fill to 256 bytes */ - char unused[0x100 - ICN_FRAGSIZE - 2]; -} frag_buf; - -/* - * Layout of card's shared memory - */ -typedef union { - struct { - unsigned char scns; /* Index to free SendFrag. */ - unsigned char scnr; /* Index to active SendFrag READONLY */ - unsigned char ecns; /* Index to free RcvFrag. READONLY */ - unsigned char ecnr; /* Index to valid RcvFrag */ - char unused[6]; - unsigned short fuell1; /* Internal Buf Bytecount */ - } data_control; - struct { - char unused[SHM_CCTL_OFFSET]; - unsigned char iopc_i; /* Read-Ptr Status-Queue READONLY */ - unsigned char iopc_o; /* Write-Ptr Status-Queue */ - unsigned char pcio_i; /* Write-Ptr Command-Queue */ - unsigned char pcio_o; /* Read-Ptr Command Queue READONLY */ - } comm_control; - struct { - char unused[SHM_CBUF_OFFSET]; - unsigned char pcio_buf[0x100]; /* Ring-Buffer Command-Queue */ - unsigned char iopc_buf[0x100]; /* Ring-Buffer Status-Queue */ - } comm_buffers; - struct { - char unused[SHM_DBUF_OFFSET]; - frag_buf receive_buf[0x10]; - frag_buf send_buf[0x10]; - } data_buffers; -} icn_shmem; - -/* - * Per card driver data - */ -typedef struct icn_card { - struct icn_card *next; /* Pointer to next device struct */ - struct icn_card *other; /* Pointer to other card for ICN4B */ - unsigned short port; /* Base-port-address */ - int myid; /* Driver-Nr. assigned by linklevel */ - int rvalid; /* IO-portregion has been requested */ - int leased; /* Flag: This Adapter is connected */ - /* to a leased line */ - unsigned short flags; /* Statusflags */ - int doubleS0; /* Flag: ICN4B */ - int secondhalf; /* Flag: Second half of a doubleS0 */ - int fw_rev; /* Firmware revision loaded */ - int ptype; /* Protocol type (1TR6 or Euro) */ - struct timer_list st_timer; /* Timer for Status-Polls */ - struct timer_list rb_timer; /* Timer for B-Channel-Polls */ - u_char rcvbuf[ICN_BCH][4096]; /* B-Channel-Receive-Buffers */ - int rcvidx[ICN_BCH]; /* Index for above buffers */ - int l2_proto[ICN_BCH]; /* Current layer-2-protocol */ - isdn_if interface; /* Interface to upper layer */ - int iptr; /* Index to imsg-buffer */ - char imsg[60]; /* Internal buf for status-parsing */ - char msg_buf[2048]; /* Buffer for status-messages */ - char *msg_buf_write; /* Writepointer for statusbuffer */ - char *msg_buf_read; /* Readpointer for statusbuffer */ - char *msg_buf_end; /* Pointer to end of statusbuffer */ - int sndcount[ICN_BCH]; /* Byte-counters for B-Ch.-send */ - int xlen[ICN_BCH]; /* Byte-counters/Flags for sent-ACK */ - struct sk_buff *xskb[ICN_BCH]; /* Current transmitted skb */ - struct sk_buff_head spqueue[ICN_BCH]; /* Sendqueue */ - char regname[35]; /* Name used for request_region */ - u_char xmit_lock[ICN_BCH]; /* Semaphore for pollbchan_send()*/ - spinlock_t lock; /* protect critical operations */ -} icn_card; - -/* - * Main driver data - */ -typedef struct icn_dev { - spinlock_t devlock; /* spinlock to protect this struct */ - unsigned long memaddr; /* Address of memory mapped buffers */ - icn_shmem __iomem *shmem; /* Pointer to memory-mapped-buffers */ - int mvalid; /* IO-shmem has been requested */ - int channel; /* Currently mapped channel */ - struct icn_card *mcard; /* Currently mapped card */ - int chanlock; /* Semaphore for channel-mapping */ - int firstload; /* Flag: firmware never loaded */ -} icn_dev; - -typedef icn_dev *icn_devptr; - -#ifdef __KERNEL__ - -static icn_card *cards = (icn_card *) 0; -static u_char chan2bank[] = -{0, 4, 8, 12}; /* for icn_map_channel() */ - -static icn_dev dev; - -#endif /* __KERNEL__ */ - -/* Utility-Macros */ - -/* Macros for accessing ports */ -#define ICN_CFG (card->port) -#define ICN_MAPRAM (card->port + 1) -#define ICN_RUN (card->port + 2) -#define ICN_BANK (card->port + 3) - -/* Return true, if there is a free transmit-buffer */ -#define sbfree (((readb(&dev.shmem->data_control.scns) + 1) & 0xf) != \ - readb(&dev.shmem->data_control.scnr)) - -/* Switch to next transmit-buffer */ -#define sbnext (writeb((readb(&dev.shmem->data_control.scns) + 1) & 0xf, \ - &dev.shmem->data_control.scns)) - -/* Shortcuts for transmit-buffer-access */ -#define sbuf_n dev.shmem->data_control.scns -#define sbuf_d dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].data -#define sbuf_l dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].length -#define sbuf_f dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].endflag - -/* Return true, if there is receive-data is available */ -#define rbavl (readb(&dev.shmem->data_control.ecnr) != \ - readb(&dev.shmem->data_control.ecns)) - -/* Switch to next receive-buffer */ -#define rbnext (writeb((readb(&dev.shmem->data_control.ecnr) + 1) & 0xf, \ - &dev.shmem->data_control.ecnr)) - -/* Shortcuts for receive-buffer-access */ -#define rbuf_n dev.shmem->data_control.ecnr -#define rbuf_d dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].data -#define rbuf_l dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].length -#define rbuf_f dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].endflag - -/* Shortcuts for command-buffer-access */ -#define cmd_o (dev.shmem->comm_control.pcio_o) -#define cmd_i (dev.shmem->comm_control.pcio_i) - -/* Return free space in command-buffer */ -#define cmd_free ((readb(&cmd_i) >= readb(&cmd_o)) ? \ - 0x100 - readb(&cmd_i) + readb(&cmd_o) : \ - readb(&cmd_o) - readb(&cmd_i)) - -/* Shortcuts for message-buffer-access */ -#define msg_o (dev.shmem->comm_control.iopc_o) -#define msg_i (dev.shmem->comm_control.iopc_i) - -/* Return length of Message, if avail. */ -#define msg_avail ((readb(&msg_o) > readb(&msg_i)) ? \ - 0x100 - readb(&msg_o) + readb(&msg_i) : \ - readb(&msg_i) - readb(&msg_o)) - -#define CID (card->interface.id) - -#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */ -#endif /* icn_h */ diff --git a/drivers/isdn/pcbit/Kconfig b/drivers/isdn/pcbit/Kconfig deleted file mode 100644 index e9b2dd85d410..000000000000 --- a/drivers/isdn/pcbit/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config ISDN_DRV_PCBIT - tristate "PCBIT-D support" - depends on ISA && (BROKEN || X86) - help - This enables support for the PCBIT ISDN-card. This card is - manufactured in Portugal by Octal. For running this card, - additional firmware is necessary, which has to be downloaded into - the card using a utility which is distributed separately. See - <file:Documentation/isdn/README> and - <file:Documentation/isdn/README.pcbit> for more information. diff --git a/drivers/isdn/pcbit/Makefile b/drivers/isdn/pcbit/Makefile deleted file mode 100644 index 2d026c3242e8..000000000000 --- a/drivers/isdn/pcbit/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile for the pcbit ISDN device driver - -# Each configuration option enables a list of files. - -obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit.o - -# Multipart objects. - -pcbit-y := module.o edss1.o drv.o layer2.o capi.o callbacks.o diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c deleted file mode 100644 index efb6d6a3639a..000000000000 --- a/drivers/isdn/pcbit/callbacks.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Callbacks for the FSM - * - * 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. - */ - -/* - * Fix: 19981230 - Carlos Morgado <chbm@techie.com> - * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN - * NULL pointer dereference in cb_in_1 (originally fixed in 2.0) - */ - -#include <linux/string.h> -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/skbuff.h> - -#include <asm/io.h> - -#include <linux/isdnif.h> - -#include "pcbit.h" -#include "layer2.h" -#include "edss1.h" -#include "callbacks.h" -#include "capi.h" - -ushort last_ref_num = 1; - -/* - * send_conn_req - * - */ - -void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *cbdata) -{ - struct sk_buff *skb; - int len; - ushort refnum; - - -#ifdef DEBUG - printk(KERN_DEBUG "Called Party Number: %s\n", - cbdata->data.setup.CalledPN); -#endif - /* - * hdr - kmalloc in capi_conn_req - * - kfree when msg has been sent - */ - - if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb, - chan->proto)) < 0) - { - printk("capi_conn_req failed\n"); - return; - } - - - refnum = last_ref_num++ & 0x7fffU; - - chan->callref = 0; - chan->layer2link = 0; - chan->snum = 0; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len); -} - -/* - * rcv CONNECT - * will go into ACTIVE state - * send CONN_ACTIVE_RESP - * send Select protocol request - */ - -void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - isdn_ctrl ictl; - struct sk_buff *skb; - int len; - ushort refnum; - - if ((len = capi_conn_active_resp(chan, &skb)) < 0) - { - printk("capi_conn_active_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len); - - - ictl.command = ISDN_STAT_DCONN; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); - - /* ACTIVE D-channel */ - - /* Select protocol */ - - if ((len = capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) { - printk("capi_select_proto_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len); -} - - -/* - * Incoming call received - * inform user - */ - -void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *cbdata) -{ - isdn_ctrl ictl; - unsigned short refnum; - struct sk_buff *skb; - int len; - - - ictl.command = ISDN_STAT_ICALL; - ictl.driver = dev->id; - ictl.arg = chan->id; - - /* - * ictl.num >= strlen() + strlen() + 5 - */ - - if (cbdata->data.setup.CallingPN == NULL) { - printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n"); - strcpy(ictl.parm.setup.phone, "0"); - } - else { - strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN); - } - if (cbdata->data.setup.CalledPN == NULL) { - printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n"); - strcpy(ictl.parm.setup.eazmsn, "0"); - } - else { - strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN); - } - ictl.parm.setup.si1 = 7; - ictl.parm.setup.si2 = 0; - ictl.parm.setup.plan = 0; - ictl.parm.setup.screen = 0; - -#ifdef DEBUG - printk(KERN_DEBUG "statstr: %s\n", ictl.num); -#endif - - dev->dev_if->statcallb(&ictl); - - - if ((len = capi_conn_resp(chan, &skb)) < 0) { - printk(KERN_DEBUG "capi_conn_resp failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len); -} - -/* - * user has replied - * open the channel - * send CONNECT message CONNECT_ACTIVE_REQ in CAPI - */ - -void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - unsigned short refnum; - struct sk_buff *skb; - int len; - - if ((len = capi_conn_active_req(chan, &skb)) < 0) { - printk(KERN_DEBUG "capi_conn_active_req failed\n"); - return; - } - - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n"); - pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len); -} - -/* - * CONN_ACK arrived - * start b-proto selection - * - */ - -void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - unsigned short refnum; - struct sk_buff *skb; - int len; - - if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0) - { - printk("capi_select_proto_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len); - -} - - -/* - * Received disconnect ind on active state - * send disconnect resp - * send msg to user - */ -void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - struct sk_buff *skb; - int len; - ushort refnum; - isdn_ctrl ictl; - - if ((len = capi_disc_resp(chan, &skb)) < 0) { - printk("capi_disc_resp failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len); - - ictl.command = ISDN_STAT_BHUP; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} - - -/* - * User HANGUP on active/call proceeding state - * send disc.req - */ -void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - struct sk_buff *skb; - int len; - ushort refnum; - - if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0) - { - printk("capi_disc_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len); -} - -/* - * Disc confirm received send BHUP - * Problem: when the HL driver sends the disc req itself - * LL receives BHUP - */ -void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - isdn_ctrl ictl; - - ictl.command = ISDN_STAT_BHUP; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} - -void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ -} - -/* - * send activate b-chan protocol - */ -void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - struct sk_buff *skb; - int len; - ushort refnum; - - if ((len = capi_activate_transp_req(chan, &skb)) < 0) - { - printk("capi_conn_activate_transp_req failed\n"); - return; - } - - refnum = last_ref_num++ & 0x7fffU; - chan->s_refnum = refnum; - - pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len); -} - -/* - * Inform User that the B-channel is available - */ -void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data) -{ - isdn_ctrl ictl; - - ictl.command = ISDN_STAT_BCONN; - ictl.driver = dev->id; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); -} diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h deleted file mode 100644 index a036b4a7ffad..000000000000 --- a/drivers/isdn/pcbit/callbacks.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Callbacks prototypes for FSM - * - * 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. - */ - -#ifndef CALLBACKS_H -#define CALLBACKS_H - - -extern void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -extern void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); -extern void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan, - struct callb_data *data); - -#endif diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c deleted file mode 100644 index 4e3cbf857d60..000000000000 --- a/drivers/isdn/pcbit/capi.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * CAPI encoder/decoder for - * Portugal Telecom CAPI 2.0 - * - * 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. - * - * Not compatible with the AVM Gmbh. CAPI 2.0 - * - */ - -/* - * Documentation: - * - "Common ISDN API - Perfil Português - Versão 2.1", - * Telecom Portugal, Fev 1992. - * - "Common ISDN API - Especificação de protocolos para - * acesso aos canais B", Inesc, Jan 1994. - */ - -/* - * TODO: better decoding of Information Elements - * for debug purposes mainly - * encode our number in CallerPN and ConnectedPN - */ - -#include <linux/string.h> -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/mm.h> - -#include <linux/skbuff.h> - -#include <asm/io.h> -#include <asm/string.h> - -#include <linux/isdnif.h> - -#include "pcbit.h" -#include "edss1.h" -#include "capi.h" - - -/* - * Encoding of CAPI messages - * - */ - -int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto) -{ - ushort len; - - /* - * length - * AppInfoMask - 2 - * BC0 - 3 - * BC1 - 1 - * Chan - 2 - * Keypad - 1 - * CPN - 1 - * CPSA - 1 - * CalledPN - 2 + strlen - * CalledPSA - 1 - * rest... - 4 - * ---------------- - * Total 18 + strlen - */ - - len = 18 + strlen(calledPN); - - if (proto == ISDN_PROTO_L2_TRANS) - len++; - - if ((*skb = dev_alloc_skb(len)) == NULL) { - - printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n"); - return -1; - } - - /* InfoElmMask */ - *((ushort *)skb_put(*skb, 2)) = AppInfoMask; - - if (proto == ISDN_PROTO_L2_TRANS) - { - /* Bearer Capability - Mandatory*/ - *(skb_put(*skb, 1)) = 3; /* BC0.Length */ - *(skb_put(*skb, 1)) = 0x80; /* Speech */ - *(skb_put(*skb, 1)) = 0x10; /* Circuit Mode */ - *(skb_put(*skb, 1)) = 0x23; /* A-law */ - } - else - { - /* Bearer Capability - Mandatory*/ - *(skb_put(*skb, 1)) = 2; /* BC0.Length */ - *(skb_put(*skb, 1)) = 0x88; /* Digital Information */ - *(skb_put(*skb, 1)) = 0x90; /* BC0.Octect4 */ - } - - /* Bearer Capability - Optional*/ - *(skb_put(*skb, 1)) = 0; /* BC1.Length = 0 */ - - *(skb_put(*skb, 1)) = 1; /* ChannelID.Length = 1 */ - *(skb_put(*skb, 1)) = 0x83; /* Basic Interface - Any Channel */ - - *(skb_put(*skb, 1)) = 0; /* Keypad.Length = 0 */ - - - *(skb_put(*skb, 1)) = 0; /* CallingPN.Length = 0 */ - *(skb_put(*skb, 1)) = 0; /* CallingPSA.Length = 0 */ - - /* Called Party Number */ - *(skb_put(*skb, 1)) = strlen(calledPN) + 1; - *(skb_put(*skb, 1)) = 0x81; - memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN)); - - /* '#' */ - - *(skb_put(*skb, 1)) = 0; /* CalledPSA.Length = 0 */ - - /* LLC.Length = 0; */ - /* HLC0.Length = 0; */ - /* HLC1.Length = 0; */ - /* UTUS.Length = 0; */ - memset(skb_put(*skb, 4), 0, 4); - - return len; -} - -int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb) -{ - - if ((*skb = dev_alloc_skb(5)) == NULL) { - - printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - *(skb_put(*skb, 1)) = 0x01; /* ACCEPT_CALL */ - *(skb_put(*skb, 1)) = 0; - *(skb_put(*skb, 1)) = 0; - - return 5; -} - -int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb) -{ - /* - * 8 bytes - */ - - if ((*skb = dev_alloc_skb(8)) == NULL) { - - printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - -#ifdef DEBUG - printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); -#endif - - *(skb_put(*skb, 1)) = 0; /* BC.Length = 0; */ - *(skb_put(*skb, 1)) = 0; /* ConnectedPN.Length = 0 */ - *(skb_put(*skb, 1)) = 0; /* PSA.Length */ - *(skb_put(*skb, 1)) = 0; /* LLC.Length = 0; */ - *(skb_put(*skb, 1)) = 0; /* HLC.Length = 0; */ - *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */ - - return 8; -} - -int capi_conn_active_resp(struct pcbit_chan *chan, struct sk_buff **skb) -{ - /* - * 2 bytes - */ - - if ((*skb = dev_alloc_skb(2)) == NULL) { - - printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - return 2; -} - - -int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, - int outgoing) -{ - - /* - * 18 bytes - */ - - if ((*skb = dev_alloc_skb(18)) == NULL) { - - printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - /* Layer2 protocol */ - - switch (chan->proto) { - case ISDN_PROTO_L2_X75I: - *(skb_put(*skb, 1)) = 0x05; /* LAPB */ - break; - case ISDN_PROTO_L2_HDLC: - *(skb_put(*skb, 1)) = 0x02; - break; - case ISDN_PROTO_L2_TRANS: - /* - * Voice (a-law) - */ - *(skb_put(*skb, 1)) = 0x06; - break; - default: -#ifdef DEBUG - printk(KERN_DEBUG "Transparent\n"); -#endif - *(skb_put(*skb, 1)) = 0x03; - break; - } - - *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42); /* Don't ask */ - *(skb_put(*skb, 1)) = 0x00; - - *((ushort *) skb_put(*skb, 2)) = MRU; - - - *(skb_put(*skb, 1)) = 0x08; /* Modulo */ - *(skb_put(*skb, 1)) = 0x07; /* Max Window */ - - *(skb_put(*skb, 1)) = 0x01; /* No Layer3 Protocol */ - - /* - * 2 - layer3 MTU [10] - * - Modulo [12] - * - Window - * - layer1 proto [14] - * - bitrate - * - sub-channel [16] - * - layer1dataformat [17] - */ - - memset(skb_put(*skb, 8), 0, 8); - - return 18; -} - - -int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb) -{ - - if ((*skb = dev_alloc_skb(7)) == NULL) { - - printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - - *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */ - *(skb_put(*skb, 1)) = 0x00; /* Transmit by default */ - - *((ushort *) skb_put(*skb, 2)) = MRU; - - *(skb_put(*skb, 1)) = 0x01; /* Enables reception*/ - - return 7; -} - -int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort data_len; - - - /* - * callref - 2 - * layer2link - 1 - * wBlockLength - 2 - * data - 4 - * sernum - 1 - */ - - data_len = skb->len; - - if (skb_headroom(skb) < 10) - { - printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb); - } - else - { - skb_push(skb, 10); - } - - *((u16 *) (skb->data)) = chan->callref; - skb->data[2] = chan->layer2link; - *((u16 *) (skb->data + 3)) = data_len; - - chan->s_refnum = (chan->s_refnum + 1) % 8; - *((u32 *) (skb->data + 5)) = chan->s_refnum; - - skb->data[9] = 0; /* HDLC frame number */ - - return 10; -} - -int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb) - -{ - if ((*skb = dev_alloc_skb(4)) == NULL) { - - printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - *(skb_put(*skb, 1)) = chan->layer2link; - *(skb_put(*skb, 1)) = chan->r_refnum; - - return (*skb)->len; -} - -int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause) -{ - - if ((*skb = dev_alloc_skb(6)) == NULL) { - - printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = callref; - - *(skb_put(*skb, 1)) = 2; /* Cause.Length = 2; */ - *(skb_put(*skb, 1)) = 0x80; - *(skb_put(*skb, 1)) = 0x80 | cause; - - /* - * Change it: we should send 'Sic transit gloria Mundi' here ;-) - */ - - *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */ - - return 6; -} - -int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb) -{ - if ((*skb = dev_alloc_skb(2)) == NULL) { - - printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n"); - return -1; - } - - *((ushort *)skb_put(*skb, 2)) = chan->callref; - - return 2; -} - - -/* - * Decoding of CAPI messages - * - */ - -int capi_decode_conn_ind(struct pcbit_chan *chan, - struct sk_buff *skb, - struct callb_data *info) -{ - int CIlen, len; - - /* Call Reference [CAPI] */ - chan->callref = *((ushort *)skb->data); - skb_pull(skb, 2); - -#ifdef DEBUG - printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); -#endif - - /* Channel Identification */ - - /* Expect - Len = 1 - Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ] - */ - - CIlen = skb->data[0]; -#ifdef DEBUG - if (CIlen == 1) { - - if (((skb->data[1]) & 0xFC) == 0x48) - printk(KERN_DEBUG "decode_conn_ind: chan ok\n"); - printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03); - } - else - printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen); -#endif - skb_pull(skb, CIlen + 1); - - /* Calling Party Number */ - /* An "additional service" as far as Portugal Telecom is concerned */ - - len = skb->data[0]; - - if (len > 0) { - int count = 1; - -#ifdef DEBUG - printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]); -#endif - if ((skb->data[1] & 0x80) == 0) - count = 2; - - if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC))) - return -1; - - skb_copy_from_linear_data_offset(skb, count + 1, - info->data.setup.CallingPN, - len - count); - info->data.setup.CallingPN[len - count] = 0; - - } - else { - info->data.setup.CallingPN = NULL; - printk(KERN_DEBUG "NULL CallingPN\n"); - } - - skb_pull(skb, len + 1); - - /* Calling Party Subaddress */ - skb_pull(skb, skb->data[0] + 1); - - /* Called Party Number */ - - len = skb->data[0]; - - if (len > 0) { - int count = 1; - - if ((skb->data[1] & 0x80) == 0) - count = 2; - - if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC))) - return -1; - - skb_copy_from_linear_data_offset(skb, count + 1, - info->data.setup.CalledPN, - len - count); - info->data.setup.CalledPN[len - count] = 0; - - } - else { - info->data.setup.CalledPN = NULL; - printk(KERN_DEBUG "NULL CalledPN\n"); - } - - skb_pull(skb, len + 1); - - /* Called Party Subaddress */ - skb_pull(skb, skb->data[0] + 1); - - /* LLC */ - skb_pull(skb, skb->data[0] + 1); - - /* HLC */ - skb_pull(skb, skb->data[0] + 1); - - /* U2U */ - skb_pull(skb, skb->data[0] + 1); - - return 0; -} - -/* - * returns errcode - */ - -int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb, - int *complete) -{ - int errcode; - - chan->callref = *((ushort *)skb->data); /* Update CallReference */ - skb_pull(skb, 2); - - errcode = *((ushort *) skb->data); /* read errcode */ - skb_pull(skb, 2); - - *complete = *(skb->data); - skb_pull(skb, 1); - - /* FIX ME */ - /* This is actually a firmware bug */ - if (!*complete) - { - printk(KERN_DEBUG "complete=%02x\n", *complete); - *complete = 1; - } - - - /* Optional Bearer Capability */ - skb_pull(skb, *(skb->data) + 1); - - /* Channel Identification */ - skb_pull(skb, *(skb->data) + 1); - - /* High Layer Compatibility follows */ - skb_pull(skb, *(skb->data) + 1); - - return errcode; -} - -int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort len; -#ifdef DEBUG - char str[32]; -#endif - - /* Yet Another Bearer Capability */ - skb_pull(skb, *(skb->data) + 1); - - - /* Connected Party Number */ - len = *(skb->data); - -#ifdef DEBUG - if (len > 1 && len < 31) { - skb_copy_from_linear_data_offset(skb, 2, str, len - 1); - str[len] = 0; - printk(KERN_DEBUG "Connected Party Number: %s\n", str); - } - else - printk(KERN_DEBUG "actv_ind CPN len = %d\n", len); -#endif - - skb_pull(skb, len + 1); - - /* Connected Subaddress */ - skb_pull(skb, *(skb->data) + 1); - - /* Low Layer Capability */ - skb_pull(skb, *(skb->data) + 1); - - /* High Layer Capability */ - skb_pull(skb, *(skb->data) + 1); - - return 0; -} - -int capi_decode_conn_actv_conf(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort errcode; - - errcode = *((ushort *)skb->data); - skb_pull(skb, 2); - - /* Channel Identification - skb_pull(skb, skb->data[0] + 1); - */ - return errcode; -} - - -int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort errcode; - - chan->layer2link = *(skb->data); - skb_pull(skb, 1); - - errcode = *((ushort *)skb->data); - skb_pull(skb, 2); - - return errcode; -} - -int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort errcode; - - if (chan->layer2link != *(skb->data)) - printk("capi_decode_actv_trans_conf: layer2link doesn't match\n"); - - skb_pull(skb, 1); - - errcode = *((ushort *)skb->data); - skb_pull(skb, 2); - - return errcode; -} - -int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb) -{ - ushort len; -#ifdef DEBUG - int i; -#endif - /* Cause */ - - len = *(skb->data); - skb_pull(skb, 1); - -#ifdef DEBUG - - for (i = 0; i < len; i++) - printk(KERN_DEBUG "Cause Octect %d: %02x\n", i + 3, - *(skb->data + i)); -#endif - - skb_pull(skb, len); - - return 0; -} - -#ifdef DEBUG -int capi_decode_debug_188(u_char *hdr, ushort hdrlen) -{ - char str[64]; - int len; - - len = hdr[0]; - - if (len < 64 && len == hdrlen - 1) { - memcpy(str, hdr + 1, hdrlen - 1); - str[hdrlen - 1] = 0; - printk("%s\n", str); - } - else - printk("debug message incorrect\n"); - - return 0; -} -#endif diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h deleted file mode 100644 index 635f63476944..000000000000 --- a/drivers/isdn/pcbit/capi.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * CAPI encode/decode prototypes and defines - * - * 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. - */ - -#ifndef CAPI_H -#define CAPI_H - - -#define REQ_CAUSE 0x01 -#define REQ_DISPLAY 0x04 -#define REQ_USER_TO_USER 0x08 - -#define AppInfoMask REQ_CAUSE | REQ_DISPLAY | REQ_USER_TO_USER - -/* Connection Setup */ -extern int capi_conn_req(const char *calledPN, struct sk_buff **buf, - int proto); -extern int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb, - int *complete); - -extern int capi_decode_conn_ind(struct pcbit_chan *chan, struct sk_buff *skb, - struct callb_data *info); -extern int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb); - -extern int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb); -extern int capi_decode_conn_actv_conf(struct pcbit_chan *chan, - struct sk_buff *skb); - -extern int capi_decode_conn_actv_ind(struct pcbit_chan *chan, - struct sk_buff *skb); -extern int capi_conn_active_resp(struct pcbit_chan *chan, - struct sk_buff **skb); - -/* Data */ -extern int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, - int outgoing); -extern int capi_decode_sel_proto_conf(struct pcbit_chan *chan, - struct sk_buff *skb); - -extern int capi_activate_transp_req(struct pcbit_chan *chan, - struct sk_buff **skb); -extern int capi_decode_actv_trans_conf(struct pcbit_chan *chan, - struct sk_buff *skb); - -extern int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb); -extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb); - -/* Connection Termination */ -extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause); - -extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb); -extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb); - -#ifdef DEBUG -extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen); -#endif - -static inline struct pcbit_chan * -capi_channel(struct pcbit_dev *dev, struct sk_buff *skb) -{ - ushort callref; - - callref = *((ushort *)skb->data); - skb_pull(skb, 2); - - if (dev->b1->callref == callref) - return dev->b1; - else if (dev->b2->callref == callref) - return dev->b2; - - return NULL; -} - -#endif diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c deleted file mode 100644 index 4172e22ae7ed..000000000000 --- a/drivers/isdn/pcbit/drv.c +++ /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; -} diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c deleted file mode 100644 index b2262ba6f0c9..000000000000 --- a/drivers/isdn/pcbit/edss1.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * DSS.1 Finite State Machine - * base: ITU-T Rec Q.931 - * - * 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. - */ - -/* - * TODO: complete the FSM - * move state/event descriptions to a user space logger - */ - -#include <linux/string.h> -#include <linux/kernel.h> - -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/skbuff.h> - -#include <linux/timer.h> -#include <asm/io.h> - -#include <linux/isdnif.h> - -#include "pcbit.h" -#include "edss1.h" -#include "layer2.h" -#include "callbacks.h" - - -const char * const isdn_state_table[] = { - "Closed", - "Call initiated", - "Overlap sending", - "Outgoing call proceeding", - "NOT DEFINED", - "Call delivered", - "Call present", - "Call received", - "Connect request", - "Incoming call proceeding", - "Active", - "Disconnect request", - "Disconnect indication", - "NOT DEFINED", - "NOT DEFINED", - "Suspend request", - "NOT DEFINED", - "Resume request", - "NOT DEFINED", - "Release Request", - "NOT DEFINED", - "NOT DEFINED", - "NOT DEFINED", - "NOT DEFINED", - "NOT DEFINED", - "Overlap receiving", - "Select protocol on B-Channel", - "Activate B-channel protocol" -}; - -#ifdef DEBUG_ERRS -static -struct CauseValue { - byte nr; - char *descr; -} cvlist[] = { - {0x01, "Unallocated (unassigned) number"}, - {0x02, "No route to specified transit network"}, - {0x03, "No route to destination"}, - {0x04, "Send special information tone"}, - {0x05, "Misdialled trunk prefix"}, - {0x06, "Channel unacceptable"}, - {0x07, "Channel awarded and being delivered in an established channel"}, - {0x08, "Preemption"}, - {0x09, "Preemption - circuit reserved for reuse"}, - {0x10, "Normal call clearing"}, - {0x11, "User busy"}, - {0x12, "No user responding"}, - {0x13, "No answer from user (user alerted)"}, - {0x14, "Subscriber absent"}, - {0x15, "Call rejected"}, - {0x16, "Number changed"}, - {0x1a, "non-selected user clearing"}, - {0x1b, "Destination out of order"}, - {0x1c, "Invalid number format (address incomplete)"}, - {0x1d, "Facility rejected"}, - {0x1e, "Response to Status enquiry"}, - {0x1f, "Normal, unspecified"}, - {0x22, "No circuit/channel available"}, - {0x26, "Network out of order"}, - {0x27, "Permanent frame mode connection out-of-service"}, - {0x28, "Permanent frame mode connection operational"}, - {0x29, "Temporary failure"}, - {0x2a, "Switching equipment congestion"}, - {0x2b, "Access information discarded"}, - {0x2c, "Requested circuit/channel not available"}, - {0x2e, "Precedence call blocked"}, - {0x2f, "Resource unavailable, unspecified"}, - {0x31, "Quality of service unavailable"}, - {0x32, "Requested facility not subscribed"}, - {0x35, "Outgoing calls barred within CUG"}, - {0x37, "Incoming calls barred within CUG"}, - {0x39, "Bearer capability not authorized"}, - {0x3a, "Bearer capability not presently available"}, - {0x3e, "Inconsistency in designated outgoing access information and subscriber class"}, - {0x3f, "Service or option not available, unspecified"}, - {0x41, "Bearer capability not implemented"}, - {0x42, "Channel type not implemented"}, - {0x43, "Requested facility not implemented"}, - {0x44, "Only restricted digital information bearer capability is available"}, - {0x4f, "Service or option not implemented"}, - {0x51, "Invalid call reference value"}, - {0x52, "Identified channel does not exist"}, - {0x53, "A suspended call exists, but this call identity does not"}, - {0x54, "Call identity in use"}, - {0x55, "No call suspended"}, - {0x56, "Call having the requested call identity has been cleared"}, - {0x57, "User not member of CUG"}, - {0x58, "Incompatible destination"}, - {0x5a, "Non-existent CUG"}, - {0x5b, "Invalid transit network selection"}, - {0x5f, "Invalid message, unspecified"}, - {0x60, "Mandatory information element is missing"}, - {0x61, "Message type non-existent or not implemented"}, - {0x62, "Message not compatible with call state or message type non-existent or not implemented"}, - {0x63, "Information element/parameter non-existent or not implemented"}, - {0x64, "Invalid information element contents"}, - {0x65, "Message not compatible with call state"}, - {0x66, "Recovery on timer expiry"}, - {0x67, "Parameter non-existent or not implemented - passed on"}, - {0x6e, "Message with unrecognized parameter discarded"}, - {0x6f, "Protocol error, unspecified"}, - {0x7f, "Interworking, unspecified"} -}; - -#endif - -static struct isdn_event_desc { - unsigned short ev; - char *desc; -} isdn_event_table[] = { - {EV_USR_SETUP_REQ, "CC->L3: Setup Request"}, - {EV_USR_SETUP_RESP, "CC->L3: Setup Response"}, - {EV_USR_PROCED_REQ, "CC->L3: Proceeding Request"}, - {EV_USR_RELEASE_REQ, "CC->L3: Release Request"}, - - {EV_NET_SETUP, "NET->TE: setup "}, - {EV_NET_CALL_PROC, "NET->TE: call proceeding"}, - {EV_NET_SETUP_ACK, "NET->TE: setup acknowledge (more info needed)"}, - {EV_NET_CONN, "NET->TE: connect"}, - {EV_NET_CONN_ACK, "NET->TE: connect acknowledge"}, - {EV_NET_DISC, "NET->TE: disconnect indication"}, - {EV_NET_RELEASE, "NET->TE: release"}, - {EV_NET_RELEASE_COMP, "NET->TE: release complete"}, - {EV_NET_SELP_RESP, "Board: Select B-channel protocol ack"}, - {EV_NET_ACTV_RESP, "Board: Activate B-channel protocol ack"}, - {EV_TIMER, "Timeout"}, - {0, "NULL"} -}; - -char *strisdnevent(ushort ev) -{ - struct isdn_event_desc *entry; - - for (entry = isdn_event_table; entry->ev; entry++) - if (entry->ev == ev) - break; - - return entry->desc; -} - -/* - * Euro ISDN finite state machine - */ - -static struct fsm_timer_entry fsm_timers[] = { - {ST_CALL_PROC, 10}, - {ST_DISC_REQ, 2}, - {ST_ACTIVE_SELP, 5}, - {ST_ACTIVE_ACTV, 5}, - {ST_INCM_PROC, 10}, - {ST_CONN_REQ, 2}, - {0xff, 0} -}; - -static struct fsm_entry fsm_table[] = { -/* Connect Phase */ - /* Outgoing */ - {ST_NULL, ST_CALL_INIT, EV_USR_SETUP_REQ, cb_out_1}, - - {ST_CALL_INIT, ST_OVER_SEND, EV_NET_SETUP_ACK, cb_notdone}, - {ST_CALL_INIT, ST_CALL_PROC, EV_NET_CALL_PROC, NULL}, - {ST_CALL_INIT, ST_NULL, EV_NET_DISC, cb_out_2}, - - {ST_CALL_PROC, ST_ACTIVE_SELP, EV_NET_CONN, cb_out_2}, - {ST_CALL_PROC, ST_NULL, EV_NET_DISC, cb_disc_1}, - {ST_CALL_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - /* Incoming */ - {ST_NULL, ST_CALL_PRES, EV_NET_SETUP, NULL}, - - {ST_CALL_PRES, ST_INCM_PROC, EV_USR_PROCED_REQ, cb_in_1}, - {ST_CALL_PRES, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - {ST_INCM_PROC, ST_CONN_REQ, EV_USR_SETUP_RESP, cb_in_2}, - {ST_INCM_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - {ST_CONN_REQ, ST_ACTIVE_SELP, EV_NET_CONN_ACK, cb_in_3}, - - /* Active */ - {ST_ACTIVE, ST_NULL, EV_NET_DISC, cb_disc_1}, - {ST_ACTIVE, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - {ST_ACTIVE, ST_NULL, EV_NET_RELEASE, cb_disc_3}, - - /* Disconnect */ - - {ST_DISC_REQ, ST_NULL, EV_NET_DISC, cb_disc_1}, - {ST_DISC_REQ, ST_NULL, EV_NET_RELEASE, cb_disc_3}, - - /* protocol selection */ - {ST_ACTIVE_SELP, ST_ACTIVE_ACTV, EV_NET_SELP_RESP, cb_selp_1}, - {ST_ACTIVE_SELP, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - {ST_ACTIVE_ACTV, ST_ACTIVE, EV_NET_ACTV_RESP, cb_open}, - {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2}, - - /* Timers */ - {ST_CALL_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_DISC_REQ, ST_NULL, EV_TIMER, cb_disc_3}, - {ST_ACTIVE_SELP, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_INCM_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2}, - {ST_CONN_REQ, ST_CONN_REQ, EV_TIMER, cb_in_2}, - - {0xff, 0, 0, NULL} -}; - - -static void pcbit_fsm_timer(unsigned long data) -{ - struct pcbit_dev *dev; - struct pcbit_chan *chan; - - chan = (struct pcbit_chan *) data; - - del_timer(&chan->fsm_timer); - chan->fsm_timer.function = NULL; - - dev = chan2dev(chan); - - if (dev == NULL) { - printk(KERN_WARNING "pcbit: timer for unknown device\n"); - return; - } - - pcbit_fsm_event(dev, chan, EV_TIMER, NULL); -} - - -void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan, - unsigned short event, struct callb_data *data) -{ - struct fsm_entry *action; - struct fsm_timer_entry *tentry; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - for (action = fsm_table; action->init != 0xff; action++) - if (action->init == chan->fsm_state && action->event == event) - break; - - if (action->init == 0xff) { - - spin_unlock_irqrestore(&dev->lock, flags); - printk(KERN_DEBUG "fsm error: event %x on state %x\n", - event, chan->fsm_state); - return; - } - - if (chan->fsm_timer.function) { - del_timer(&chan->fsm_timer); - chan->fsm_timer.function = NULL; - } - - chan->fsm_state = action->final; - - pcbit_state_change(dev, chan, action->init, event, action->final); - - for (tentry = fsm_timers; tentry->init != 0xff; tentry++) - if (tentry->init == chan->fsm_state) - break; - - if (tentry->init != 0xff) { - init_timer(&chan->fsm_timer); - chan->fsm_timer.function = &pcbit_fsm_timer; - chan->fsm_timer.data = (ulong) chan; - chan->fsm_timer.expires = jiffies + tentry->timeout * HZ; - add_timer(&chan->fsm_timer); - } - - spin_unlock_irqrestore(&dev->lock, flags); - - if (action->callb) - action->callb(dev, chan, data); - -} diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h deleted file mode 100644 index 2f6b3a8edfba..000000000000 --- a/drivers/isdn/pcbit/edss1.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * DSS.1 module definitions - * - * 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. - */ - -#ifndef EDSS1_H -#define EDSS1_H - -/* ISDN states */ - -#define ST_NULL 0 -#define ST_CALL_INIT 1 /* Call initiated */ -#define ST_OVER_SEND 2 /* Overlap sending - Requests More Info 4 call */ -#define ST_CALL_PROC 3 /* Call Proceeding */ -#define ST_CALL_DELV 4 -#define ST_CALL_PRES 6 /* Call Present - Received CONN.IND */ -#define ST_CALL_RECV 7 /* Alerting sent */ -#define ST_CONN_REQ 8 /* Answered - waiting 4 CONN.CONF */ -#define ST_INCM_PROC 9 -#define ST_ACTIVE 10 -#define ST_DISC_REQ 11 -#define ST_DISC_IND 12 -#define ST_SUSP_REQ 15 -#define ST_RESM_REQ 17 -#define ST_RELS_REQ 19 -#define ST_OVER_RECV 25 - -#define ST_ACTIVE_SELP 26 /* Select protocol on B-Channel */ -#define ST_ACTIVE_ACTV 27 /* Activate B-channel protocol */ - -#define MAX_STATE ST_ACTIVE_ACTV - -#define EV_NULL 0 -#define EV_USR_SETUP_REQ 1 -#define EV_USR_SETUP_RESP 2 -#define EV_USR_PROCED_REQ 3 -#define EV_USR_RELEASE_REQ 4 -#define EV_USR_REJECT_REQ 4 - -#define EV_NET_SETUP 16 -#define EV_NET_CALL_PROC 17 -#define EV_NET_SETUP_ACK 18 -#define EV_NET_CONN 19 -#define EV_NET_CONN_ACK 20 - -#define EV_NET_SELP_RESP 21 -#define EV_NET_ACTV_RESP 22 - -#define EV_NET_DISC 23 -#define EV_NET_RELEASE 24 -#define EV_NET_RELEASE_COMP 25 - -#define EV_TIMER 26 -#define EV_ERROR 32 - -/* - * Cause values - * only the ones we use - */ - -#define CAUSE_NORMAL 0x10U -#define CAUSE_NOCHAN 0x22U - -struct callb_data { - unsigned short type; - union { - struct ConnInfo { - char *CalledPN; - char *CallingPN; - } setup; - unsigned short cause; - } data; -}; - -struct fsm_entry { - unsigned short init; - unsigned short final; - unsigned short event; - void (*callb)(struct pcbit_dev *, struct pcbit_chan *, struct callb_data*); -}; - -struct fsm_timer_entry { - unsigned short init; - unsigned long timeout; /* in seconds */ -}; - -extern const char * const isdn_state_table[]; - -void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *, - unsigned short event, struct callb_data *); -char *strisdnevent(ushort ev); - -#endif diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c deleted file mode 100644 index 46e1240ae074..000000000000 --- a/drivers/isdn/pcbit/layer2.c +++ /dev/null @@ -1,712 +0,0 @@ -/* - * PCBIT-D low-layer interface - * - * 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. - */ - -/* - * 19991203 - Fernando Carvalho - takion@superbofh.org - * Hacked to compile with egcs and run with current version of isdn modules - */ - -/* - * Based on documentation provided by Inesc: - * - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93 - */ - -/* - * TODO: better handling of errors - * re-write/remove debug printks - */ - -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/workqueue.h> -#include <linux/mm.h> -#include <linux/skbuff.h> - -#include <linux/isdnif.h> - -#include <asm/io.h> - - -#include "pcbit.h" -#include "layer2.h" -#include "edss1.h" - -#undef DEBUG_FRAG - - -/* - * Prototypes - */ - -static void pcbit_transmit(struct pcbit_dev *dev); - -static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack); - -static void pcbit_l2_error(struct pcbit_dev *dev); -static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info); -static void pcbit_l2_err_recover(unsigned long data); - -static void pcbit_firmware_bug(struct pcbit_dev *dev); - -static __inline__ void -pcbit_sched_delivery(struct pcbit_dev *dev) -{ - schedule_work(&dev->qdelivery); -} - - -/* - * Called from layer3 - */ - -int -pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum, - struct sk_buff *skb, unsigned short hdr_len) -{ - struct frame_buf *frame, - *ptr; - unsigned long flags; - - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) { - dev_kfree_skb(skb); - return -1; - } - if ((frame = kmalloc(sizeof(struct frame_buf), - GFP_ATOMIC)) == NULL) { - dev_kfree_skb(skb); - return -1; - } - frame->msg = msg; - frame->refnum = refnum; - frame->copied = 0; - frame->hdr_len = hdr_len; - - if (skb) - frame->dt_len = skb->len - hdr_len; - else - frame->dt_len = 0; - - frame->skb = skb; - - frame->next = NULL; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->write_queue == NULL) { - dev->write_queue = frame; - spin_unlock_irqrestore(&dev->lock, flags); - pcbit_transmit(dev); - } else { - for (ptr = dev->write_queue; ptr->next; ptr = ptr->next); - ptr->next = frame; - - spin_unlock_irqrestore(&dev->lock, flags); - } - return 0; -} - -static __inline__ void -pcbit_tx_update(struct pcbit_dev *dev, ushort len) -{ - u_char info; - - dev->send_seq = (dev->send_seq + 1) % 8; - - dev->fsize[dev->send_seq] = len; - info = 0; - info |= dev->rcv_seq << 3; - info |= dev->send_seq; - - writeb(info, dev->sh_mem + BANK4); - -} - -/* - * called by interrupt service routine or by write_2 - */ - -static void -pcbit_transmit(struct pcbit_dev *dev) -{ - struct frame_buf *frame = NULL; - unsigned char unacked; - int flen; /* fragment frame length including all headers */ - int free; - int count, - cp_len; - unsigned long flags; - unsigned short tt; - - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) - return; - - unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->free > 16 && dev->write_queue && unacked < 7) { - - if (!dev->w_busy) - dev->w_busy = 1; - else { - spin_unlock_irqrestore(&dev->lock, flags); - return; - } - - - frame = dev->write_queue; - free = dev->free; - - spin_unlock_irqrestore(&dev->lock, flags); - - if (frame->copied == 0) { - - /* Type 0 frame */ - - ulong msg; - - if (frame->skb) - flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len; - else - flen = FRAME_HDR_LEN + PREHDR_LEN; - - if (flen > free) - flen = free; - - msg = frame->msg; - - /* - * Board level 2 header - */ - - pcbit_writew(dev, flen - FRAME_HDR_LEN); - - pcbit_writeb(dev, GET_MSG_CPU(msg)); - - pcbit_writeb(dev, GET_MSG_PROC(msg)); - - /* TH */ - pcbit_writew(dev, frame->hdr_len + PREHDR_LEN); - - /* TD */ - pcbit_writew(dev, frame->dt_len); - - - /* - * Board level 3 fixed-header - */ - - /* LEN = TH */ - pcbit_writew(dev, frame->hdr_len + PREHDR_LEN); - - /* XX */ - pcbit_writew(dev, 0); - - /* C + S */ - pcbit_writeb(dev, GET_MSG_CMD(msg)); - pcbit_writeb(dev, GET_MSG_SCMD(msg)); - - /* NUM */ - pcbit_writew(dev, frame->refnum); - - count = FRAME_HDR_LEN + PREHDR_LEN; - } else { - /* Type 1 frame */ - - flen = 2 + (frame->skb->len - frame->copied); - - if (flen > free) - flen = free; - - /* TT */ - tt = ((ushort) (flen - 2)) | 0x8000U; /* Type 1 */ - pcbit_writew(dev, tt); - - count = 2; - } - - if (frame->skb) { - cp_len = frame->skb->len - frame->copied; - if (cp_len > flen - count) - cp_len = flen - count; - - memcpy_topcbit(dev, frame->skb->data + frame->copied, - cp_len); - frame->copied += cp_len; - } - /* bookkeeping */ - dev->free -= flen; - pcbit_tx_update(dev, flen); - - spin_lock_irqsave(&dev->lock, flags); - - if (frame->skb == NULL || frame->copied == frame->skb->len) { - - dev->write_queue = frame->next; - - if (frame->skb != NULL) { - /* free frame */ - dev_kfree_skb(frame->skb); - } - kfree(frame); - } - dev->w_busy = 0; - spin_unlock_irqrestore(&dev->lock, flags); - } else { - spin_unlock_irqrestore(&dev->lock, flags); -#ifdef DEBUG - printk(KERN_DEBUG "unacked %d free %d write_queue %s\n", - unacked, dev->free, dev->write_queue ? "not empty" : - "empty"); -#endif - } -} - - -/* - * deliver a queued frame to the upper layer - */ - -void -pcbit_deliver(struct work_struct *work) -{ - struct frame_buf *frame; - unsigned long flags, msg; - struct pcbit_dev *dev = - container_of(work, struct pcbit_dev, qdelivery); - - spin_lock_irqsave(&dev->lock, flags); - - while ((frame = dev->read_queue)) { - dev->read_queue = frame->next; - spin_unlock_irqrestore(&dev->lock, flags); - - msg = 0; - SET_MSG_CPU(msg, 0); - SET_MSG_PROC(msg, 0); - SET_MSG_CMD(msg, frame->skb->data[2]); - SET_MSG_SCMD(msg, frame->skb->data[3]); - - frame->refnum = *((ushort *)frame->skb->data + 4); - frame->msg = *((ulong *)&msg); - - skb_pull(frame->skb, 6); - - pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len, - frame->refnum); - - kfree(frame); - - spin_lock_irqsave(&dev->lock, flags); - } - - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* - * Reads BANK 2 & Reassembles - */ - -static void -pcbit_receive(struct pcbit_dev *dev) -{ - unsigned short tt; - u_char cpu, - proc; - struct frame_buf *frame = NULL; - unsigned long flags; - u_char type1; - - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) - return; - - tt = pcbit_readw(dev); - - if ((tt & 0x7fffU) > 511) { - printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n", - tt); - pcbit_l2_error(dev); - return; - } - if (!(tt & 0x8000U)) { /* Type 0 */ - type1 = 0; - - if (dev->read_frame) { - printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n"); - /* discard previous queued frame */ - kfree_skb(dev->read_frame->skb); - kfree(dev->read_frame); - dev->read_frame = NULL; - } - frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC); - - if (frame == NULL) { - printk(KERN_WARNING "kmalloc failed\n"); - return; - } - - cpu = pcbit_readb(dev); - proc = pcbit_readb(dev); - - - if (cpu != 0x06 && cpu != 0x02) { - printk(KERN_DEBUG "pcbit: invalid cpu value\n"); - kfree(frame); - pcbit_l2_error(dev); - return; - } - /* - * we discard cpu & proc on receiving - * but we read it to update the pointer - */ - - frame->hdr_len = pcbit_readw(dev); - frame->dt_len = pcbit_readw(dev); - - /* - * 0 sized packet - * I don't know if they are an error or not... - * But they are very frequent - * Not documented - */ - - if (frame->hdr_len == 0) { - kfree(frame); -#ifdef DEBUG - printk(KERN_DEBUG "0 sized frame\n"); -#endif - pcbit_firmware_bug(dev); - return; - } - /* sanity check the length values */ - if (frame->hdr_len > 1024 || frame->dt_len > 2048) { -#ifdef DEBUG - printk(KERN_DEBUG "length problem: "); - printk(KERN_DEBUG "TH=%04x TD=%04x\n", - frame->hdr_len, - frame->dt_len); -#endif - pcbit_l2_error(dev); - kfree(frame); - return; - } - /* minimum frame read */ - - frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len + - ((frame->hdr_len + 15) & ~15)); - - if (!frame->skb) { - printk(KERN_DEBUG "pcbit_receive: out of memory\n"); - kfree(frame); - return; - } - /* 16 byte alignment for IP */ - if (frame->dt_len) - skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15); - - } else { - /* Type 1 */ - type1 = 1; - tt &= 0x7fffU; - - if (!(frame = dev->read_frame)) { - printk("Type 1 frame and no frame queued\n"); - /* usually after an error: toss frame */ - dev->readptr += tt; - if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN) - dev->readptr -= BANKLEN; - return; - - } - } - - memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt); - - frame->copied += tt; - spin_lock_irqsave(&dev->lock, flags); - if (frame->copied == frame->hdr_len + frame->dt_len) { - - if (type1) { - dev->read_frame = NULL; - } - if (dev->read_queue) { - struct frame_buf *ptr; - for (ptr = dev->read_queue; ptr->next; ptr = ptr->next); - ptr->next = frame; - } else - dev->read_queue = frame; - - } else { - dev->read_frame = frame; - } - spin_unlock_irqrestore(&dev->lock, flags); -} - -/* - * The board sends 0 sized frames - * They are TDATA_CONFs that get messed up somehow - * gotta send a fake acknowledgment to the upper layer somehow - */ - -static __inline__ void -pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan *chan) -{ - isdn_ctrl ictl; - - if (chan->queued) { - chan->queued--; - - ictl.driver = dev->id; - ictl.command = ISDN_STAT_BSENT; - ictl.arg = chan->id; - dev->dev_if->statcallb(&ictl); - } -} - -static void -pcbit_firmware_bug(struct pcbit_dev *dev) -{ - struct pcbit_chan *chan; - - chan = dev->b1; - - if (chan->fsm_state == ST_ACTIVE) { - pcbit_fake_conf(dev, chan); - } - chan = dev->b2; - - if (chan->fsm_state == ST_ACTIVE) { - pcbit_fake_conf(dev, chan); - } -} - -irqreturn_t -pcbit_irq_handler(int interrupt, void *devptr) -{ - struct pcbit_dev *dev; - u_char info, - ack_seq, - read_seq; - - dev = (struct pcbit_dev *) devptr; - - if (!dev) { - printk(KERN_WARNING "pcbit_irq_handler: wrong device\n"); - return IRQ_NONE; - } - if (dev->interrupt) { - printk(KERN_DEBUG "pcbit: reentering interrupt handler\n"); - return IRQ_HANDLED; - } - dev->interrupt = 1; - - info = readb(dev->sh_mem + BANK3); - - if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR) { - pcbit_l2_active_conf(dev, info); - dev->interrupt = 0; - return IRQ_HANDLED; - } - if (info & 0x40U) { /* E bit set */ -#ifdef DEBUG - printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n"); -#endif - pcbit_l2_error(dev); - dev->interrupt = 0; - return IRQ_HANDLED; - } - if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) { - dev->interrupt = 0; - return IRQ_HANDLED; - } - ack_seq = (info >> 3) & 0x07U; - read_seq = (info & 0x07U); - - dev->interrupt = 0; - - if (read_seq != dev->rcv_seq) { - while (read_seq != dev->rcv_seq) { - pcbit_receive(dev); - dev->rcv_seq = (dev->rcv_seq + 1) % 8; - } - pcbit_sched_delivery(dev); - } - if (ack_seq != dev->unack_seq) { - pcbit_recv_ack(dev, ack_seq); - } - info = dev->rcv_seq << 3; - info |= dev->send_seq; - - writeb(info, dev->sh_mem + BANK4); - return IRQ_HANDLED; -} - - -static void -pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info) -{ - u_char state; - - state = dev->l2_state; - -#ifdef DEBUG - printk(KERN_DEBUG "layer2_active_confirm\n"); -#endif - - - if (info & 0x80U) { - dev->rcv_seq = info & 0x07U; - dev->l2_state = L2_RUNNING; - } else - dev->l2_state = L2_DOWN; - - if (state == L2_STARTING) - wake_up_interruptible(&dev->set_running_wq); - - if (state == L2_ERROR && dev->l2_state == L2_RUNNING) { - pcbit_transmit(dev); - } -} - -static void -pcbit_l2_err_recover(unsigned long data) -{ - - struct pcbit_dev *dev; - struct frame_buf *frame; - - dev = (struct pcbit_dev *) data; - - del_timer(&dev->error_recover_timer); - if (dev->w_busy || dev->r_busy) { - init_timer(&dev->error_recover_timer); - dev->error_recover_timer.expires = jiffies + ERRTIME; - add_timer(&dev->error_recover_timer); - return; - } - dev->w_busy = dev->r_busy = 1; - - if (dev->read_frame) { - kfree_skb(dev->read_frame->skb); - kfree(dev->read_frame); - dev->read_frame = NULL; - } - if (dev->write_queue) { - frame = dev->write_queue; -#ifdef FREE_ON_ERROR - dev->write_queue = dev->write_queue->next; - - if (frame->skb) { - dev_kfree_skb(frame->skb); - } - kfree(frame); -#else - frame->copied = 0; -#endif - } - dev->rcv_seq = dev->send_seq = dev->unack_seq = 0; - dev->free = 511; - dev->l2_state = L2_ERROR; - - /* this is an hack... */ - pcbit_firmware_bug(dev); - - dev->writeptr = dev->sh_mem; - dev->readptr = dev->sh_mem + BANK2; - - writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)), - dev->sh_mem + BANK4); - dev->w_busy = dev->r_busy = 0; - -} - -static void -pcbit_l2_error(struct pcbit_dev *dev) -{ - if (dev->l2_state == L2_RUNNING) { - - printk(KERN_INFO "pcbit: layer 2 error\n"); - -#ifdef DEBUG - log_state(dev); -#endif - - dev->l2_state = L2_DOWN; - - init_timer(&dev->error_recover_timer); - dev->error_recover_timer.function = &pcbit_l2_err_recover; - dev->error_recover_timer.data = (ulong) dev; - dev->error_recover_timer.expires = jiffies + ERRTIME; - add_timer(&dev->error_recover_timer); - } -} - -/* - * Description: - * if board acks frames - * update dev->free - * call pcbit_transmit to write possible queued frames - */ - -static void -pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack) -{ - int i, - count; - int unacked; - - unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07; - - /* dev->unack_seq < ack <= dev->send_seq; */ - - if (unacked) { - - if (dev->send_seq > dev->unack_seq) { - if (ack <= dev->unack_seq || ack > dev->send_seq) { - printk(KERN_DEBUG - "layer 2 ack unacceptable - dev %d", - dev->id); - - pcbit_l2_error(dev); - } else if (ack > dev->send_seq && ack <= dev->unack_seq) { - printk(KERN_DEBUG - "layer 2 ack unacceptable - dev %d", - dev->id); - pcbit_l2_error(dev); - } - } - /* ack is acceptable */ - - - i = dev->unack_seq; - - do { - dev->unack_seq = i = (i + 1) % 8; - dev->free += dev->fsize[i]; - } while (i != ack); - - count = 0; - while (count < 7 && dev->write_queue) { - u8 lsend_seq = dev->send_seq; - - pcbit_transmit(dev); - - if (dev->send_seq == lsend_seq) - break; - count++; - } - } else - printk(KERN_DEBUG "recv_ack: unacked = 0\n"); -} diff --git a/drivers/isdn/pcbit/layer2.h b/drivers/isdn/pcbit/layer2.h deleted file mode 100644 index be1327bc162a..000000000000 --- a/drivers/isdn/pcbit/layer2.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * PCBIT-D low-layer interface definitions - * - * 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. - */ - -/* - * 19991203 - Fernando Carvalho - takion@superbofh.org - * Hacked to compile with egcs and run with current version of isdn modules - */ - -#ifndef LAYER2_H -#define LAYER2_H - -#include <linux/interrupt.h> - -#include <asm/byteorder.h> - -#define BANK1 0x0000U /* PC -> Board */ -#define BANK2 0x01ffU /* Board -> PC */ -#define BANK3 0x03feU /* Att Board */ -#define BANK4 0x03ffU /* Att PC */ - -#define BANKLEN 0x01FFU - -#define LOAD_ZONE_START 0x03f8U -#define LOAD_ZONE_END 0x03fdU - -#define LOAD_RETRY 18000000 - - - -/* TAM - XX - C - S - NUM */ -#define PREHDR_LEN 8 -/* TT - M - I - TH - TD */ -#define FRAME_HDR_LEN 8 - -#define MSG_CONN_REQ 0x08000100 -#define MSG_CONN_CONF 0x00000101 -#define MSG_CONN_IND 0x00000102 -#define MSG_CONN_RESP 0x08000103 - -#define MSG_CONN_ACTV_REQ 0x08000300 -#define MSG_CONN_ACTV_CONF 0x00000301 -#define MSG_CONN_ACTV_IND 0x00000302 -#define MSG_CONN_ACTV_RESP 0x08000303 - -#define MSG_DISC_REQ 0x08000400 -#define MSG_DISC_CONF 0x00000401 -#define MSG_DISC_IND 0x00000402 -#define MSG_DISC_RESP 0x08000403 - -#define MSG_TDATA_REQ 0x0908E200 -#define MSG_TDATA_CONF 0x0000E201 -#define MSG_TDATA_IND 0x0000E202 -#define MSG_TDATA_RESP 0x0908E203 - -#define MSG_SELP_REQ 0x09004000 -#define MSG_SELP_CONF 0x00004001 - -#define MSG_ACT_TRANSP_REQ 0x0908E000 -#define MSG_ACT_TRANSP_CONF 0x0000E001 - -#define MSG_STPROT_REQ 0x09004100 -#define MSG_STPROT_CONF 0x00004101 - -#define MSG_PING188_REQ 0x09030500 -#define MSG_PING188_CONF 0x000005bc - -#define MSG_WATCH188 0x09030400 - -#define MSG_API_ON 0x08020102 -#define MSG_POOL_PCBIT 0x08020400 -#define MSG_POOL_PCBIT_CONF 0x00000401 - -#define MSG_INFO_IND 0x00002602 -#define MSG_INFO_RESP 0x08002603 - -#define MSG_DEBUG_188 0x0000ff00 - -/* - - long 4 3 2 1 - Intel 1 2 3 4 -*/ - -#ifdef __LITTLE_ENDIAN -#define SET_MSG_SCMD(msg, ch) (msg = (msg & 0xffffff00) | (((ch) & 0xff))) -#define SET_MSG_CMD(msg, ch) (msg = (msg & 0xffff00ff) | (((ch) & 0xff) << 8)) -#define SET_MSG_PROC(msg, ch) (msg = (msg & 0xff00ffff) | (((ch) & 0xff) << 16)) -#define SET_MSG_CPU(msg, ch) (msg = (msg & 0x00ffffff) | (((ch) & 0xff) << 24)) - -#define GET_MSG_SCMD(msg) ((msg) & 0xFF) -#define GET_MSG_CMD(msg) ((msg) >> 8 & 0xFF) -#define GET_MSG_PROC(msg) ((msg) >> 16 & 0xFF) -#define GET_MSG_CPU(msg) ((msg) >> 24) - -#else -#error "Non-Intel CPU" -#endif - -#define MAX_QUEUED 7 - -#define SCHED_READ 0x01 -#define SCHED_WRITE 0x02 - -#define SET_RUN_TIMEOUT 2 * HZ /* 2 seconds */ - -struct frame_buf { - ulong msg; - unsigned int refnum; - unsigned int dt_len; - unsigned int hdr_len; - struct sk_buff *skb; - unsigned int copied; - struct frame_buf *next; -}; - -extern int pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum, - struct sk_buff *skb, unsigned short hdr_len); - -extern irqreturn_t pcbit_irq_handler(int interrupt, void *); - -extern struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS]; - -#ifdef DEBUG -static __inline__ void log_state(struct pcbit_dev *dev) { - printk(KERN_DEBUG "writeptr = %ld\n", - (ulong) (dev->writeptr - dev->sh_mem)); - printk(KERN_DEBUG "readptr = %ld\n", - (ulong) (dev->readptr - (dev->sh_mem + BANK2))); - printk(KERN_DEBUG "{rcv_seq=%01x, send_seq=%01x, unack_seq=%01x}\n", - dev->rcv_seq, dev->send_seq, dev->unack_seq); -} -#endif - -static __inline__ struct pcbit_dev *chan2dev(struct pcbit_chan *chan) -{ - struct pcbit_dev *dev; - int i; - - - for (i = 0; i < MAX_PCBIT_CARDS; i++) - if ((dev = dev_pcbit[i])) - if (dev->b1 == chan || dev->b2 == chan) - return dev; - return NULL; - -} - -static __inline__ struct pcbit_dev *finddev(int id) -{ - struct pcbit_dev *dev; - int i; - - for (i = 0; i < MAX_PCBIT_CARDS; i++) - if ((dev = dev_pcbit[i])) - if (dev->id == id) - return dev; - return NULL; -} - - -/* - * Support routines for reading and writing in the board - */ - -static __inline__ void pcbit_writeb(struct pcbit_dev *dev, unsigned char dt) -{ - writeb(dt, dev->writeptr++); - if (dev->writeptr == dev->sh_mem + BANKLEN) - dev->writeptr = dev->sh_mem; -} - -static __inline__ void pcbit_writew(struct pcbit_dev *dev, unsigned short dt) -{ - int dist; - - dist = BANKLEN - (dev->writeptr - dev->sh_mem); - switch (dist) { - case 2: - writew(dt, dev->writeptr); - dev->writeptr = dev->sh_mem; - break; - case 1: - writeb((u_char) (dt & 0x00ffU), dev->writeptr); - dev->writeptr = dev->sh_mem; - writeb((u_char) (dt >> 8), dev->writeptr++); - break; - default: - writew(dt, dev->writeptr); - dev->writeptr += 2; - break; - }; -} - -static __inline__ void memcpy_topcbit(struct pcbit_dev *dev, u_char *data, - int len) -{ - int diff; - - diff = len - (BANKLEN - (dev->writeptr - dev->sh_mem)); - - if (diff > 0) - { - memcpy_toio(dev->writeptr, data, len - diff); - memcpy_toio(dev->sh_mem, data + (len - diff), diff); - dev->writeptr = dev->sh_mem + diff; - } - else - { - memcpy_toio(dev->writeptr, data, len); - - dev->writeptr += len; - if (diff == 0) - dev->writeptr = dev->sh_mem; - } -} - -static __inline__ unsigned char pcbit_readb(struct pcbit_dev *dev) -{ - unsigned char val; - - val = readb(dev->readptr++); - if (dev->readptr == dev->sh_mem + BANK2 + BANKLEN) - dev->readptr = dev->sh_mem + BANK2; - - return val; -} - -static __inline__ unsigned short pcbit_readw(struct pcbit_dev *dev) -{ - int dist; - unsigned short val; - - dist = BANKLEN - (dev->readptr - (dev->sh_mem + BANK2)); - switch (dist) { - case 2: - val = readw(dev->readptr); - dev->readptr = dev->sh_mem + BANK2; - break; - case 1: - val = readb(dev->readptr); - dev->readptr = dev->sh_mem + BANK2; - val = (readb(dev->readptr++) << 8) | val; - break; - default: - val = readw(dev->readptr); - dev->readptr += 2; - break; - }; - return val; -} - -static __inline__ void memcpy_frompcbit(struct pcbit_dev *dev, u_char *data, int len) -{ - int diff; - - diff = len - (BANKLEN - (dev->readptr - (dev->sh_mem + BANK2))); - if (diff > 0) - { - memcpy_fromio(data, dev->readptr, len - diff); - memcpy_fromio(data + (len - diff), dev->sh_mem + BANK2 , diff); - dev->readptr = dev->sh_mem + BANK2 + diff; - } - else - { - memcpy_fromio(data, dev->readptr, len); - dev->readptr += len; - if (diff == 0) - dev->readptr = dev->sh_mem + BANK2; - } -} - - -#endif diff --git a/drivers/isdn/pcbit/module.c b/drivers/isdn/pcbit/module.c deleted file mode 100644 index 0a59bd0b8210..000000000000 --- a/drivers/isdn/pcbit/module.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * PCBIT-D module support - * - * 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. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/skbuff.h> - -#include <linux/isdnif.h> -#include "pcbit.h" - -MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card"); -MODULE_AUTHOR("Pedro Roque Marques"); -MODULE_LICENSE("GPL"); - -static int mem[MAX_PCBIT_CARDS]; -static int irq[MAX_PCBIT_CARDS]; - -module_param_array(mem, int, NULL, 0); -module_param_array(irq, int, NULL, 0); - -static int num_boards; -struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS]; - -static int __init pcbit_init(void) -{ - int board; - - num_boards = 0; - - printk(KERN_NOTICE - "PCBIT-D device driver v 0.5-fjpc0 19991204 - " - "Copyright (C) 1996 Universidade de Lisboa\n"); - - if (mem[0] || irq[0]) - { - for (board = 0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++) - { - if (!mem[board]) - mem[board] = 0xD0000; - if (!irq[board]) - irq[board] = 5; - - if (pcbit_init_dev(board, mem[board], irq[board]) == 0) - num_boards++; - - else - { - printk(KERN_WARNING - "pcbit_init failed for dev %d", - board + 1); - return -EIO; - } - } - } - - /* Hardcoded default settings detection */ - - if (!num_boards) - { - printk(KERN_INFO - "Trying to detect board using default settings\n"); - if (pcbit_init_dev(0, 0xD0000, 5) == 0) - num_boards++; - else - return -EIO; - } - return 0; -} - -static void __exit pcbit_exit(void) -{ -#ifdef MODULE - int board; - - for (board = 0; board < num_boards; board++) - pcbit_terminate(board); - printk(KERN_NOTICE - "PCBIT-D module unloaded\n"); -#endif -} - -#ifndef MODULE -#define MAX_PARA (MAX_PCBIT_CARDS * 2) -static int __init pcbit_setup(char *line) -{ - int i, j, argc; - char *str; - int ints[MAX_PARA + 1]; - - str = get_options(line, MAX_PARA, ints); - argc = ints[0]; - i = 0; - j = 1; - - while (argc && (i < MAX_PCBIT_CARDS)) { - - if (argc) { - mem[i] = ints[j]; - j++; argc--; - } - - if (argc) { - irq[i] = ints[j]; - j++; argc--; - } - - i++; - } - return (1); -} -__setup("pcbit=", pcbit_setup); -#endif - -module_init(pcbit_init); -module_exit(pcbit_exit); diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h deleted file mode 100644 index 0a5a99440a80..000000000000 --- a/drivers/isdn/pcbit/pcbit.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * PCBIT-D device driver definitions - * - * 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. - */ - -#ifndef PCBIT_H -#define PCBIT_H - -#include <linux/workqueue.h> - -#define MAX_PCBIT_CARDS 4 - - -#define BLOCK_TIMER - -#ifdef __KERNEL__ - -struct pcbit_chan { - unsigned short id; - unsigned short callref; /* Call Reference */ - unsigned char proto; /* layer2protocol */ - unsigned char queued; /* unacked data messages */ - unsigned char layer2link; /* used in TData */ - unsigned char snum; /* used in TData */ - unsigned short s_refnum; - unsigned short r_refnum; - unsigned short fsm_state; - struct timer_list fsm_timer; -#ifdef BLOCK_TIMER - struct timer_list block_timer; -#endif -}; - -struct msn_entry { - char *msn; - struct msn_entry *next; -}; - -struct pcbit_dev { - /* board */ - - volatile unsigned char __iomem *sh_mem; /* RDP address */ - unsigned long ph_mem; - unsigned int irq; - unsigned int id; - unsigned int interrupt; /* set during interrupt - processing */ - spinlock_t lock; - /* isdn4linux */ - - struct msn_entry *msn_list; /* ISDN address list */ - - isdn_if *dev_if; - - ushort ll_hdrlen; - ushort hl_hdrlen; - - /* link layer */ - unsigned char l2_state; - - struct frame_buf *read_queue; - struct frame_buf *read_frame; - struct frame_buf *write_queue; - - /* Protocol start */ - wait_queue_head_t set_running_wq; - struct timer_list set_running_timer; - - struct timer_list error_recover_timer; - - struct work_struct qdelivery; - - u_char w_busy; - u_char r_busy; - - volatile unsigned char __iomem *readptr; - volatile unsigned char __iomem *writeptr; - - ushort loadptr; - - unsigned short fsize[8]; /* sent layer2 frames size */ - - unsigned char send_seq; - unsigned char rcv_seq; - unsigned char unack_seq; - - unsigned short free; - - /* channels */ - - struct pcbit_chan *b1; - struct pcbit_chan *b2; -}; - -#define STATS_TIMER (10 * HZ) -#define ERRTIME (HZ / 10) - -/* MRU */ -#define MAXBUFSIZE 1534 -#define MRU MAXBUFSIZE - -#define STATBUF_LEN 2048 -/* - * - */ - -#endif /* __KERNEL__ */ - -/* isdn_ctrl only allows a long sized argument */ - -struct pcbit_ioctl { - union { - struct byte_op { - ushort addr; - ushort value; - } rdp_byte; - unsigned long l2_status; - } info; -}; - - - -#define PCBIT_IOCTL_GETSTAT 0x01 /* layer2 status */ -#define PCBIT_IOCTL_LWMODE 0x02 /* linear write mode */ -#define PCBIT_IOCTL_STRLOAD 0x03 /* start load mode */ -#define PCBIT_IOCTL_ENDLOAD 0x04 /* end load mode */ -#define PCBIT_IOCTL_SETBYTE 0x05 /* set byte */ -#define PCBIT_IOCTL_GETBYTE 0x06 /* get byte */ -#define PCBIT_IOCTL_RUNNING 0x07 /* set protocol running */ -#define PCBIT_IOCTL_WATCH188 0x08 /* set watch 188 */ -#define PCBIT_IOCTL_PING188 0x09 /* ping 188 */ -#define PCBIT_IOCTL_FWMODE 0x0A /* firmware write mode */ -#define PCBIT_IOCTL_STOP 0x0B /* stop protocol */ -#define PCBIT_IOCTL_APION 0x0C /* issue API_ON */ - -#ifndef __KERNEL__ - -#define PCBIT_GETSTAT (PCBIT_IOCTL_GETSTAT + IIOCDRVCTL) -#define PCBIT_LWMODE (PCBIT_IOCTL_LWMODE + IIOCDRVCTL) -#define PCBIT_STRLOAD (PCBIT_IOCTL_STRLOAD + IIOCDRVCTL) -#define PCBIT_ENDLOAD (PCBIT_IOCTL_ENDLOAD + IIOCDRVCTL) -#define PCBIT_SETBYTE (PCBIT_IOCTL_SETBYTE + IIOCDRVCTL) -#define PCBIT_GETBYTE (PCBIT_IOCTL_GETBYTE + IIOCDRVCTL) -#define PCBIT_RUNNING (PCBIT_IOCTL_RUNNING + IIOCDRVCTL) -#define PCBIT_WATCH188 (PCBIT_IOCTL_WATCH188 + IIOCDRVCTL) -#define PCBIT_PING188 (PCBIT_IOCTL_PING188 + IIOCDRVCTL) -#define PCBIT_FWMODE (PCBIT_IOCTL_FWMODE + IIOCDRVCTL) -#define PCBIT_STOP (PCBIT_IOCTL_STOP + IIOCDRVCTL) -#define PCBIT_APION (PCBIT_IOCTL_APION + IIOCDRVCTL) - -#define MAXSUPERLINE 3000 - -#endif - -#define L2_DOWN 0 -#define L2_LOADING 1 -#define L2_LWMODE 2 -#define L2_FWMODE 3 -#define L2_STARTING 4 -#define L2_RUNNING 5 -#define L2_ERROR 6 - -void pcbit_deliver(struct work_struct *work); -int pcbit_init_dev(int board, int mem_base, int irq); -void pcbit_terminate(int board); -void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, struct sk_buff *skb, - ushort hdr_len, ushort refnum); -void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan, - unsigned short i, unsigned short ev, unsigned short f); - -#endif |