diff options
Diffstat (limited to 'drivers/isdn/pcbit')
-rw-r--r-- | drivers/isdn/pcbit/Kconfig | 10 | ||||
-rw-r--r-- | drivers/isdn/pcbit/Makefile | 9 | ||||
-rw-r--r-- | drivers/isdn/pcbit/callbacks.c | 345 | ||||
-rw-r--r-- | drivers/isdn/pcbit/callbacks.h | 44 | ||||
-rw-r--r-- | drivers/isdn/pcbit/capi.c | 649 | ||||
-rw-r--r-- | drivers/isdn/pcbit/capi.h | 81 | ||||
-rw-r--r-- | drivers/isdn/pcbit/drv.c | 1077 | ||||
-rw-r--r-- | drivers/isdn/pcbit/edss1.c | 313 | ||||
-rw-r--r-- | drivers/isdn/pcbit/edss1.h | 99 | ||||
-rw-r--r-- | drivers/isdn/pcbit/layer2.c | 712 | ||||
-rw-r--r-- | drivers/isdn/pcbit/layer2.h | 281 | ||||
-rw-r--r-- | drivers/isdn/pcbit/module.c | 125 | ||||
-rw-r--r-- | drivers/isdn/pcbit/pcbit.h | 177 |
13 files changed, 0 insertions, 3922 deletions
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 |