summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-21 04:26:39 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-21 04:26:39 -0800
commited407526409355987fadaeaaba75149d1bac88bc (patch)
tree4ad351152e7d39584120d734ea4f55049b287487
parent756ee81990fdeb9f662c20296a797dfd44481579 (diff)
Remove stale legacy ISDN files.
From Armin Schindler <armin@melware.de>: "These files were added in the first place for the compat driver to the legacy isdn4linux module. Since the Eicon driver now uses CAPI only, these files are obsolete."
-rw-r--r--drivers/isdn/hardware/eicon/i4l_idi.c3135
-rw-r--r--drivers/isdn/hardware/eicon/i4l_idi.h381
-rw-r--r--drivers/isdn/hardware/eicon/i4lididrv.c1418
-rw-r--r--drivers/isdn/hardware/eicon/i4lididrv.h272
4 files changed, 0 insertions, 5206 deletions
diff --git a/drivers/isdn/hardware/eicon/i4l_idi.c b/drivers/isdn/hardware/eicon/i4l_idi.c
deleted file mode 100644
index 02457b2f9d4d..000000000000
--- a/drivers/isdn/hardware/eicon/i4l_idi.c
+++ /dev/null
@@ -1,3135 +0,0 @@
-/* $Id: i4l_idi.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
- *
- * ISDN interface module for Eicon active cards.
- * I4L - IDI Interface
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999-2002 Cytronics & Melware (info@melware.de)
- *
- * Thanks to Deutsche Mailbox Saar-Lor-Lux GmbH
- * for sponsoring and testing fax
- * capabilities with Diva Server cards.
- * (dor@deutschemailbox.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#include <linux/config.h>
-#include "i4lididrv.h"
-
-#undef EICON_FULL_SERVICE_OKTETT
-
-char *eicon_idi_revision = "$Revision: 1.1.2.2 $";
-
-eicon_manifbuf *manbuf;
-
-static int eicon_idi_manage_assign(eicon_card *card);
-static int idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer);
-
-static int
-idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan)
-{
- int l = 0;
- int tmp;
-
- tmp = 0;
- if (!signet) {
- /* Signal Layer */
- reqbuf->XBuffer.P[l++] = CAI;
- reqbuf->XBuffer.P[l++] = 1;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = KEY;
- reqbuf->XBuffer.P[l++] = 3;
- reqbuf->XBuffer.P[l++] = 'I';
- reqbuf->XBuffer.P[l++] = '4';
- reqbuf->XBuffer.P[l++] = 'L';
- reqbuf->XBuffer.P[l++] = SHIFT|6;
- reqbuf->XBuffer.P[l++] = SIN;
- reqbuf->XBuffer.P[l++] = 2;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0; /* end */
- reqbuf->Req = ASSIGN;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = DSIG_ID;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 0; /* Sig Entity */
- }
- else {
- /* Network Layer */
- reqbuf->XBuffer.P[l++] = CAI;
- reqbuf->XBuffer.P[l++] = 1;
- reqbuf->XBuffer.P[l++] = chan->e.D3Id;
- reqbuf->XBuffer.P[l++] = LLC;
- reqbuf->XBuffer.P[l++] = 2;
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_V11096:
- case ISDN_PROTO_L2_V11019:
- case ISDN_PROTO_L2_V11038:
- case ISDN_PROTO_L2_TRANS:
- reqbuf->XBuffer.P[l++] = 2; /* transparent */
- break;
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- reqbuf->XBuffer.P[l++] = 5; /* X.75 */
- break;
- case ISDN_PROTO_L2_MODEM:
- if (chan->fsm_state == EICON_STATE_IWAIT)
- reqbuf->XBuffer.P[l++] = 9; /* V.42 incoming */
- else
- reqbuf->XBuffer.P[l++] = 10; /* V.42 */
- break;
- case ISDN_PROTO_L2_HDLC:
- case ISDN_PROTO_L2_FAX:
- if (chan->fsm_state == EICON_STATE_IWAIT)
- reqbuf->XBuffer.P[l++] = 3; /* autoconnect on incoming */
- else
- reqbuf->XBuffer.P[l++] = 2; /* transparent */
- break;
- default:
- reqbuf->XBuffer.P[l++] = 1;
- }
- switch(chan->l3prot) {
- case ISDN_PROTO_L3_FCLASS2:
-#ifdef CONFIG_ISDN_TTY_FAX
- reqbuf->XBuffer.P[l++] = 6;
- reqbuf->XBuffer.P[l++] = NLC;
- tmp = idi_fill_in_T30(chan, &reqbuf->XBuffer.P[l+1]);
- reqbuf->XBuffer.P[l++] = tmp;
- l += tmp;
- break;
-#endif
- case ISDN_PROTO_L3_TRANS:
- default:
- reqbuf->XBuffer.P[l++] = 4;
- }
- /* Additional DLC element */
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- case ISDN_PROTO_L2_FAX:
- reqbuf->XBuffer.P[l++] = DLC;
- reqbuf->XBuffer.P[l++] = 2;
- reqbuf->XBuffer.P[l++] = (2138 % 256); /* max. info (lo byte) */
- reqbuf->XBuffer.P[l++] = (2138 / 256); /* max. info (hi byte) */
- break;
- }
- reqbuf->XBuffer.P[l++] = 0; /* end */
- reqbuf->Req = ASSIGN;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = NL_ID;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 1; /* Net Entity */
- }
- return(0);
-}
-
-static int
-idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
-{
- reqbuf->Req = rq;
- reqbuf->ReqCh = Ch;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.length = 1;
- reqbuf->XBuffer.P[0] = 0;
- reqbuf->Reference = signet;
- return(0);
-}
-
-static int
-idi_put_suspend_req(eicon_REQ *reqbuf, eicon_chan *chan)
-{
- reqbuf->Req = SUSPEND;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.P[0] = CAI;
- reqbuf->XBuffer.P[1] = 1;
- reqbuf->XBuffer.P[2] = chan->No;
- reqbuf->XBuffer.P[3] = 0;
- reqbuf->XBuffer.length = 4;
- reqbuf->Reference = 0; /* Sig Entity */
- return(0);
-}
-
-static int
-idi_call_res_req(eicon_REQ *reqbuf, eicon_chan *chan)
-{
- int l = 9;
- reqbuf->Req = CALL_RES;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.P[0] = CAI;
- reqbuf->XBuffer.P[1] = 6;
- reqbuf->XBuffer.P[2] = 9;
- reqbuf->XBuffer.P[3] = 0;
- reqbuf->XBuffer.P[4] = 0;
- reqbuf->XBuffer.P[5] = 0;
- reqbuf->XBuffer.P[6] = 32;
- reqbuf->XBuffer.P[7] = 0;
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- case ISDN_PROTO_L2_HDLC:
- reqbuf->XBuffer.P[1] = 1;
- reqbuf->XBuffer.P[2] = 0x05;
- l = 4;
- break;
- case ISDN_PROTO_L2_V11096:
- reqbuf->XBuffer.P[2] = 0x0d;
- reqbuf->XBuffer.P[3] = 5;
- reqbuf->XBuffer.P[4] = 0;
- break;
- case ISDN_PROTO_L2_V11019:
- reqbuf->XBuffer.P[2] = 0x0d;
- reqbuf->XBuffer.P[3] = 6;
- reqbuf->XBuffer.P[4] = 0;
- break;
- case ISDN_PROTO_L2_V11038:
- reqbuf->XBuffer.P[2] = 0x0d;
- reqbuf->XBuffer.P[3] = 7;
- reqbuf->XBuffer.P[4] = 0;
- break;
- case ISDN_PROTO_L2_MODEM:
- /* reqbuf->XBuffer.P[1] = 12; */
- reqbuf->XBuffer.P[2] = 0x11;
- reqbuf->XBuffer.P[3] = 9;
- reqbuf->XBuffer.P[4] = 0;
- reqbuf->XBuffer.P[5] = 0;
- reqbuf->XBuffer.P[6] = 32;
- reqbuf->XBuffer.P[7] = 0;
- break;
- case ISDN_PROTO_L2_FAX:
- reqbuf->XBuffer.P[2] = 0x10;
- reqbuf->XBuffer.P[3] = 0;
- reqbuf->XBuffer.P[4] = 0;
- reqbuf->XBuffer.P[5] = 0;
- reqbuf->XBuffer.P[6] = 32;
- reqbuf->XBuffer.P[7] = 0;
- break;
- case ISDN_PROTO_L2_TRANS:
- switch(chan->l3prot) {
- case ISDN_PROTO_L3_TRANSDSP:
- reqbuf->XBuffer.P[2] = 22; /* DTMF, audio events on */
- }
- break;
- }
- reqbuf->XBuffer.P[l-1] = 0;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 0; /* Sig Entity */
- eicon_log(NULL, 8, "idi_req: Ch%d: Call_Res\n", chan->No);
- return(0);
-}
-
-int
-idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
- eicon_log(card, 8, "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig");
- if (layer) cmd |= 0x700;
- switch(cmd) {
- case ASSIGN:
- case ASSIGN|0x700:
- idi_assign_req(reqbuf, layer, chan);
- break;
- case REMOVE:
- case REMOVE|0x700:
- idi_put_req(reqbuf, REMOVE, layer, 0);
- break;
- case INDICATE_REQ:
- idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
- break;
- case HANGUP:
- idi_put_req(reqbuf, HANGUP, 0, 0);
- break;
- case SUSPEND:
- idi_put_suspend_req(reqbuf, chan);
- break;
- case RESUME:
- idi_put_req(reqbuf, RESUME, 0 ,0);
- break;
- case REJECT:
- idi_put_req(reqbuf, REJECT, 0 ,0);
- break;
- case CALL_ALERT:
- idi_put_req(reqbuf, CALL_ALERT, 0, 0);
- break;
- case CALL_RES:
- idi_call_res_req(reqbuf, chan);
- break;
- case CALL_HOLD:
- idi_put_req(reqbuf, CALL_HOLD, 0, 0);
- break;
- case N_CONNECT|0x700:
- idi_put_req(reqbuf, N_CONNECT, 1, 0);
- break;
- case N_CONNECT_ACK|0x700:
- idi_put_req(reqbuf, N_CONNECT_ACK, 1, 0);
- break;
- case N_DISC|0x700:
- idi_put_req(reqbuf, N_DISC, 1, chan->e.IndCh);
- break;
- case N_DISC_ACK|0x700:
- idi_put_req(reqbuf, N_DISC_ACK, 1, chan->e.IndCh);
- break;
- default:
- eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
- dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
- return(-1);
- }
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_tx_request(card);
- return(0);
-}
-
-int
-eicon_idi_listen_req(eicon_card *card, eicon_chan *chan)
-{
- if ((!card) || (!chan))
- return 1;
-
- eicon_log(card, 16, "idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask);
- if (!chan->e.D3Id) {
- idi_do_req(card, chan, ASSIGN, 0);
- }
- if (chan->fsm_state == EICON_STATE_NULL) {
- if (!(chan->statectrl & HAVE_CONN_REQ)) {
- idi_do_req(card, chan, INDICATE_REQ, 0);
- chan->fsm_state = EICON_STATE_LISTEN;
- }
- }
- return(0);
-}
-
-static unsigned char
-idi_si2bc(int si1, int si2, char *bc, char *hlc)
-{
- hlc[0] = 0;
- switch(si1) {
- case 1:
- bc[0] = 0x90; /* 3,1 kHz audio */
- bc[1] = 0x90; /* 64 kbit/s */
- bc[2] = 0xa3; /* G.711 A-law */
-#ifdef EICON_FULL_SERVICE_OKTETT
- if (si2 == 1) {
- bc[0] = 0x80; /* Speech */
- hlc[0] = 0x02; /* hlc len */
- hlc[1] = 0x91; /* first hic */
- hlc[2] = 0x81; /* Telephony */
- }
-#endif
- return(3);
- case 2:
- bc[0] = 0x90; /* 3,1 kHz audio */
- bc[1] = 0x90; /* 64 kbit/s */
- bc[2] = 0xa3; /* G.711 A-law */
-#ifdef EICON_FULL_SERVICE_OKTETT
- if (si2 == 2) {
- hlc[0] = 0x02; /* hlc len */
- hlc[1] = 0x91; /* first hic */
- hlc[2] = 0x84; /* Fax Gr.2/3 */
- }
-#endif
- return(3);
- case 5:
- case 7:
- default:
- bc[0] = 0x88;
- bc[1] = 0x90;
- return(2);
- }
- return (0);
-}
-
-int
-idi_hangup(eicon_card *card, eicon_chan *chan)
-{
- if ((!card) || (!chan))
- return 1;
-
- if ((chan->fsm_state == EICON_STATE_ACTIVE) ||
- (chan->fsm_state == EICON_STATE_WMCONN)) {
- if (chan->e.B2Id) idi_do_req(card, chan, N_DISC, 1);
- }
- if (chan->e.B2Id) idi_do_req(card, chan, REMOVE, 1);
- if (chan->fsm_state != EICON_STATE_NULL) {
- chan->statectrl |= WAITING_FOR_HANGUP;
- idi_do_req(card, chan, HANGUP, 0);
- chan->fsm_state = EICON_STATE_NULL;
- }
- eicon_log(card, 8, "idi_req: Ch%d: Hangup\n", chan->No);
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fax = 0;
-#endif
- return(0);
-}
-
-int
-capipmsg(eicon_card *card, eicon_chan *chan, capi_msg *cm)
-{
- if ((cm->para[0] != 3) || (cm->para[1] != 0))
- return -1;
- if (cm->para[2] < 3)
- return -1;
- if (cm->para[4] != 0)
- return -1;
- switch(cm->para[3]) {
- case 4: /* Suspend */
- eicon_log(card, 8, "idi_req: Ch%d: Call Suspend\n", chan->No);
- if (cm->para[5]) {
- idi_do_req(card, chan, SUSPEND, 0);
- } else {
- idi_do_req(card, chan, CALL_HOLD, 0);
- }
- break;
- case 5: /* Resume */
- eicon_log(card, 8, "idi_req: Ch%d: Call Resume\n", chan->No);
- idi_do_req(card, chan, RESUME, 0);
- break;
- }
- return 0;
-}
-
-int
-idi_connect_res(eicon_card *card, eicon_chan *chan)
-{
- if ((!card) || (!chan))
- return 1;
-
- chan->fsm_state = EICON_STATE_IWAIT;
-
- /* check if old NetID has been removed */
- if (chan->e.B2Id) {
- eicon_log(card, 1, "idi_conn_res: Ch%d: old net_id %x still exist, removing.\n",
- chan->No, chan->e.B2Id);
- idi_do_req(card, chan, REMOVE, 1);
- }
-
- idi_do_req(card, chan, ASSIGN, 1);
- idi_do_req(card, chan, CALL_RES, 0);
- return(0);
-}
-
-int
-idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
- char *eazmsn, int si1, int si2)
-{
- int l = 0;
- int i;
- unsigned char tmp;
- unsigned char *sub, *sp;
- unsigned char bc[5];
- unsigned char hlc[5];
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- if ((!card) || (!chan))
- return 1;
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
- reqbuf->Req = CALL_REQ;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
-
- sub = NULL;
- sp = phone;
- while (*sp) {
- if (*sp == '.') {
- sub = sp + 1;
- *sp = 0;
- } else
- sp++;
- }
- reqbuf->XBuffer.P[l++] = CPN;
- reqbuf->XBuffer.P[l++] = strlen(phone) + 1;
- reqbuf->XBuffer.P[l++] = 0x81;
- for(i=0; i<strlen(phone);i++)
- reqbuf->XBuffer.P[l++] = phone[i] & 0x7f;
- if (sub) {
- reqbuf->XBuffer.P[l++] = DSA;
- reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
- reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
- reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
- while (*sub)
- reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
- }
-
- sub = NULL;
- sp = eazmsn;
- while (*sp) {
- if (*sp == '.') {
- sub = sp + 1;
- *sp = 0;
- } else
- sp++;
- }
- reqbuf->XBuffer.P[l++] = OAD;
- reqbuf->XBuffer.P[l++] = strlen(eazmsn) + 2;
- reqbuf->XBuffer.P[l++] = 0x01;
- reqbuf->XBuffer.P[l++] = 0x80;
- for(i=0; i<strlen(eazmsn);i++)
- reqbuf->XBuffer.P[l++] = eazmsn[i] & 0x7f;
- if (sub) {
- reqbuf->XBuffer.P[l++] = OSA;
- reqbuf->XBuffer.P[l++] = strlen(sub) + 2;
- reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */
- reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */
- while (*sub)
- reqbuf->XBuffer.P[l++] = *sub++ & 0x7f;
- }
-
- if (si2 > 2) {
- reqbuf->XBuffer.P[l++] = SHIFT|6;
- reqbuf->XBuffer.P[l++] = SIN;
- reqbuf->XBuffer.P[l++] = 2;
- reqbuf->XBuffer.P[l++] = si1;
- reqbuf->XBuffer.P[l++] = si2;
- }
- else if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) {
- reqbuf->XBuffer.P[l++] = BC;
- reqbuf->XBuffer.P[l++] = tmp;
- for(i=0; i<tmp;i++)
- reqbuf->XBuffer.P[l++] = bc[i];
- if ((tmp=hlc[0])) {
- reqbuf->XBuffer.P[l++] = HLC;
- reqbuf->XBuffer.P[l++] = tmp;
- for(i=1; i<=tmp;i++)
- reqbuf->XBuffer.P[l++] = hlc[i];
- }
- }
-
- reqbuf->XBuffer.P[l++] = CAI;
- reqbuf->XBuffer.P[l++] = 6;
- reqbuf->XBuffer.P[l++] = 0x09;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->XBuffer.P[l++] = 32;
- reqbuf->XBuffer.P[l++] = 0;
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- case ISDN_PROTO_L2_HDLC:
- reqbuf->XBuffer.P[l-6] = 5;
- reqbuf->XBuffer.P[l-7] = 1;
- l -= 5;
- break;
- case ISDN_PROTO_L2_V11096:
- reqbuf->XBuffer.P[l-7] = 3;
- reqbuf->XBuffer.P[l-6] = 0x0d;
- reqbuf->XBuffer.P[l-5] = 5;
- reqbuf->XBuffer.P[l-4] = 0;
- l -= 3;
- break;
- case ISDN_PROTO_L2_V11019:
- reqbuf->XBuffer.P[l-7] = 3;
- reqbuf->XBuffer.P[l-6] = 0x0d;
- reqbuf->XBuffer.P[l-5] = 6;
- reqbuf->XBuffer.P[l-4] = 0;
- l -= 3;
- break;
- case ISDN_PROTO_L2_V11038:
- reqbuf->XBuffer.P[l-7] = 3;
- reqbuf->XBuffer.P[l-6] = 0x0d;
- reqbuf->XBuffer.P[l-5] = 7;
- reqbuf->XBuffer.P[l-4] = 0;
- l -= 3;
- break;
- case ISDN_PROTO_L2_MODEM:
- /* reqbuf->XBuffer.P[l-7] = 12; */
- reqbuf->XBuffer.P[l-6] = 0x11;
- reqbuf->XBuffer.P[l-5] = 7;
- reqbuf->XBuffer.P[l-4] = 0;
- reqbuf->XBuffer.P[l-3] = 0;
- reqbuf->XBuffer.P[l-2] = 32;
- reqbuf->XBuffer.P[l-1] = 0;
- break;
- case ISDN_PROTO_L2_FAX:
- reqbuf->XBuffer.P[l-6] = 0x10;
- reqbuf->XBuffer.P[l-5] = 0;
- reqbuf->XBuffer.P[l-4] = 0;
- reqbuf->XBuffer.P[l-3] = 0;
- reqbuf->XBuffer.P[l-2] = 32;
- reqbuf->XBuffer.P[l-1] = 0;
- break;
- case ISDN_PROTO_L2_TRANS:
- switch(chan->l3prot) {
- case ISDN_PROTO_L3_TRANSDSP:
- reqbuf->XBuffer.P[l-6] = 22; /* DTMF, audio events on */
- }
- break;
- }
-
- reqbuf->XBuffer.P[l++] = 0; /* end */
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 0; /* Sig Entity */
-
- if (chan->statectrl & WAITING_FOR_HANGUP) {
- /* If the line did not disconnect yet,
- we have to delay this command */
- eicon_log(card, 32, "idi_req: Ch%d: delaying conn_req\n", chan->No);
- chan->statectrl |= HAVE_CONN_REQ;
- chan->tskb1 = skb;
- chan->tskb2 = skb2;
- } else {
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_tx_request(card);
- }
-
- eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone);
- return(0);
-}
-
-
-static void
-idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsigned char *buffer, int len)
-{
- int i,j;
- int pos = 0;
- int codeset = 0;
- int wlen = 0;
- int lock = 0;
- __u8 w;
- __u16 code;
- isdn_ctrl cmd;
-
- memset(message, 0, sizeof(idi_ind_message));
-
- if ((!len) || (!buffer[pos])) return;
-
- while(pos <= len) {
- w = buffer[pos++];
- if (!w) return;
- if (w & 0x80) {
- wlen = 0;
- }
- else {
- wlen = buffer[pos++];
- }
-
- if (pos > len) return;
-
- if (lock & 0x80) lock &= 0x7f;
- else codeset = lock;
-
- if((w&0xf0) == SHIFT) {
- codeset = w;
- if(!(codeset & 0x08)) lock = codeset & 7;
- codeset &= 7;
- lock |= 0x80;
- }
- else {
- if (w==ESC && wlen >=2) {
- code = buffer[pos++]|0x800;
- wlen--;
- }
- else code = w;
- code |= (codeset<<8);
-
- if (pos + wlen > len) {
- eicon_log(ccard, 1, "idi_err: Ch%d: IElen %d of %x exceeds Ind_Length (+%d)\n", chan->No,
- wlen, code, (pos + wlen) - len);
- return;
- }
-
- switch(code) {
- case OAD:
- if (wlen > sizeof(message->oad)) {
- pos += wlen;
- break;
- }
- j = 1;
- if (wlen) {
- message->plan = buffer[pos++];
- if (message->plan &0x80)
- message->screen = 0;
- else {
- message->screen = buffer[pos++];
- j = 2;
- }
- }
- for(i=0; i < wlen-j; i++)
- message->oad[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No,
- message->plan, message->screen, message->oad);
- break;
- case RDN:
- if (wlen > sizeof(message->rdn)) {
- pos += wlen;
- break;
- }
- j = 1;
- if (wlen) {
- if (!(buffer[pos++] & 0x80)) {
- pos++;
- j = 2;
- }
- }
- for(i=0; i < wlen-j; i++)
- message->rdn[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: RDN= %s\n", chan->No,
- message->rdn);
- break;
- case CPN:
- if (wlen > sizeof(message->cpn)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->cpn[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No,
- (__u8)message->cpn[0], message->cpn + 1);
- break;
- case DSA:
- if (wlen > sizeof(message->dsa)) {
- pos += wlen;
- break;
- }
- pos += 2;
- for(i=0; i < wlen-2; i++)
- message->dsa[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa);
- break;
- case OSA:
- if (wlen > sizeof(message->osa)) {
- pos += wlen;
- break;
- }
- pos += 2;
- for(i=0; i < wlen-2; i++)
- message->osa[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
- break;
- case CAD:
- pos += wlen;
- eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n",
- chan->No, wlen);
- break;
- case BC:
- if (wlen > sizeof(message->bc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->bc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No,
- message->bc[0],message->bc[1],message->bc[2]);
- break;
- case 0x800|BC:
- if (wlen > sizeof(message->e_bc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->e_bc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]);
- break;
- case LLC:
- if (wlen > sizeof(message->llc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->llc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: LLC=%d %d %d %d ...\n", chan->No, message->llc[0],
- message->llc[1],message->llc[2],message->llc[3]);
- break;
- case HLC:
- if (wlen > sizeof(message->hlc)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->hlc[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: HLC=%x %x %x %x %x ...\n", chan->No,
- message->hlc[0], message->hlc[1],
- message->hlc[2], message->hlc[3], message->hlc[4]);
- break;
- case DSP:
- case 0x600|DSP:
- if (wlen > sizeof(message->display)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->display[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: Display: %s\n", chan->No,
- message->display);
- break;
- case 0x600|KEY:
- if (wlen > sizeof(message->keypad)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->keypad[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: Keypad: %s\n", chan->No,
- message->keypad);
- break;
- case NI:
- case 0x600|NI:
- if (wlen) {
- switch(buffer[pos] & 127) {
- case 0:
- eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No);
- break;
- case 1:
- eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No);
- break;
- case 2:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No);
- break;
- default:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n",
- chan->No, buffer[pos] & 127);
- }
- pos += wlen;
- }
- break;
- case PI:
- case 0x600|PI:
- if (wlen > 1) {
- switch(buffer[pos+1] & 127) {
- case 1:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No);
- break;
- case 2:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No);
- break;
- case 3:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No);
- break;
- case 4:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No);
- break;
- case 5:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No);
- break;
- case 8:
- eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No);
- break;
- default:
- eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n",
- chan->No, buffer[pos+1] & 127);
- }
- }
- pos += wlen;
- break;
- case CAU:
- if (wlen > sizeof(message->cau)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->cau[i] = buffer[pos++];
- memcpy(&chan->cause, &message->cau, 2);
- eicon_log(ccard, 4, "idi_inf: Ch%d: CAU=%d %d\n", chan->No,
- message->cau[0],message->cau[1]);
- break;
- case 0x800|CAU:
- if (wlen > sizeof(message->e_cau)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->e_cau[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: ECAU=%d %d\n", chan->No,
- message->e_cau[0],message->e_cau[1]);
- break;
- case 0x800|CHI:
- if (wlen > sizeof(message->e_chi)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->e_chi[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/CHI=%d\n", chan->No,
- message->e_cau[0]);
- break;
- case 0x800|0x7a:
- pos ++;
- message->e_mt=buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt);
- break;
- case DT:
- if (wlen > sizeof(message->dt)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->dt[i] = buffer[pos++];
- eicon_log(ccard, 4, "idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No,
- message->dt[2], message->dt[1], message->dt[0],
- message->dt[3], message->dt[4], message->dt[5]);
- break;
- case 0x600|SIN:
- if (wlen > sizeof(message->sin)) {
- pos += wlen;
- break;
- }
- for(i=0; i < wlen; i++)
- message->sin[i] = buffer[pos++];
- eicon_log(ccard, 2, "idi_inf: Ch%d: SIN=%d %d\n", chan->No,
- message->sin[0],message->sin[1]);
- break;
- case 0x600|CPS:
- eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No);
- pos += wlen;
- break;
- case 0x600|CIF:
- for (i = 0; i < wlen; i++)
- if (buffer[pos + i] != '0') break;
- memcpy(&cmd.parm.num, &buffer[pos + i], wlen - i);
- cmd.parm.num[wlen - i] = 0;
- eicon_log(ccard, 2, "idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num);
- pos += wlen;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_CINF;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- break;
- case 0x600|DATE:
- eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No);
- pos += wlen;
- break;
- case 0xa1:
- eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No);
- pos += wlen;
- break;
- case 0xe08:
- case 0xe7a:
- case 0xe04:
- case 0xe00:
- /* *** TODO *** */
- case CHA:
- /* Charge advice */
- case FTY:
- case 0x600|FTY:
- case CHI:
- case 0x800:
- /* Not yet interested in this */
- pos += wlen;
- break;
- case 0x880:
- /* Managment Information Element */
- if (!manbuf) {
- eicon_log(ccard, 1, "idi_err: manbuf not allocated\n");
- }
- else {
- memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen);
- manbuf->length[manbuf->count] = wlen;
- manbuf->count++;
- manbuf->pos += wlen;
- }
- pos += wlen;
- break;
- default:
- pos += wlen;
- eicon_log(ccard, 6, "idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n",
- chan->No, code, wlen);
- }
- }
- }
-}
-
-static void
-idi_bc2si(unsigned char *bc, unsigned char *hlc, unsigned char *sin, unsigned char *si1, unsigned char *si2)
-{
- si1[0] = 0;
- si2[0] = 0;
-
- switch (bc[0] & 0x7f) {
- case 0x00: /* Speech */
- si1[0] = 1;
-#ifdef EICON_FULL_SERVICE_OKTETT
- si1[0] = sin[0];
- si2[0] = sin[1];
-#endif
- break;
- case 0x10: /* 3.1 Khz audio */
- si1[0] = 1;
-#ifdef EICON_FULL_SERVICE_OKTETT
- si1[0] = sin[0];
- si2[0] = sin[1];
-#endif
- break;
- case 0x08: /* Unrestricted digital information */
- si1[0] = 7;
- si2[0] = sin[1];
- break;
- case 0x09: /* Restricted digital information */
- si1[0] = 2;
- break;
- case 0x11:
- /* Unrestr. digital information with
- * tones/announcements ( or 7 kHz audio
- */
- si1[0] = 3;
- break;
- case 0x18: /* Video */
- si1[0] = 4;
- break;
- }
- switch (bc[1] & 0x7f) {
- case 0x40: /* packed mode */
- si1[0] = 8;
- break;
- case 0x10: /* 64 kbit */
- case 0x11: /* 2*64 kbit */
- case 0x13: /* 384 kbit */
- case 0x15: /* 1536 kbit */
- case 0x17: /* 1920 kbit */
- /* moderate = bc[1] & 0x7f; */
- break;
- }
-}
-
-/********************* FAX stuff ***************************/
-
-#ifdef CONFIG_ISDN_TTY_FAX
-
-static int
-idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer)
-{
- eicon_t30_s *t30 = (eicon_t30_s *) buffer;
-
- if (!chan->fax) {
- eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n");
- return 0;
- }
- memset(t30, 0, sizeof(eicon_t30_s));
- t30->station_id_len = EICON_FAXID_LEN;
- memcpy(&t30->station_id[0], &chan->fax->id[0], EICON_FAXID_LEN);
- t30->resolution = chan->fax->resolution;
- t30->rate = chan->fax->rate + 1; /* eicon rate starts with 1 */
- t30->format = T30_FORMAT_SFF;
- t30->pages_low = 0;
- t30->pages_high = 0;
- t30->atf = 1; /* optimised for AT+F command set */
- t30->code = 0;
- t30->feature_bits_low = 0;
- t30->feature_bits_high = 0;
- t30->control_bits_low = 0;
- t30->control_bits_high = 0;
-
- if (chan->fax->nbc) {
- /* set compression by DCC value */
- switch(chan->fax->compression) {
- case (0): /* 1-D modified */
- break;
- case (1): /* 2-D modified Read */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- break;
- case (2): /* 2-D uncompressed */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- break;
- case (3): /* 2-D modified Read */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
- t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
- t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- break;
- }
- } else {
- /* set compression to best */
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR;
- t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED;
- t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING;
- t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING;
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- }
- switch(chan->fax->ecm) {
- case (0): /* disable ECM */
- break;
- case (1):
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->control_bits_low |= T30_CONTROL_BIT_ECM_64_BYTES;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM_64_BYTES;
- break;
- case (2):
- t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM;
- t30->feature_bits_low |= T30_FEATURE_BIT_ECM;
- break;
- }
-
- if (DebugVar & 128) {
- char st[40];
- eicon_log(NULL, 128, "sT30:code = %x\n", t30->code);
- eicon_log(NULL, 128, "sT30:rate = %x\n", t30->rate);
- eicon_log(NULL, 128, "sT30:res = %x\n", t30->resolution);
- eicon_log(NULL, 128, "sT30:format = %x\n", t30->format);
- eicon_log(NULL, 128, "sT30:pages_low = %x\n", t30->pages_low);
- eicon_log(NULL, 128, "sT30:pages_high = %x\n", t30->pages_high);
- eicon_log(NULL, 128, "sT30:atf = %x\n", t30->atf);
- eicon_log(NULL, 128, "sT30:control_bits_low = %x\n", t30->control_bits_low);
- eicon_log(NULL, 128, "sT30:control_bits_high = %x\n", t30->control_bits_high);
- eicon_log(NULL, 128, "sT30:feature_bits_low = %x\n", t30->feature_bits_low);
- eicon_log(NULL, 128, "sT30:feature_bits_high = %x\n", t30->feature_bits_high);
- //eicon_log(NULL, 128, "sT30:universal_5 = %x\n", t30->universal_5);
- //eicon_log(NULL, 128, "sT30:universal_6 = %x\n", t30->universal_6);
- //eicon_log(NULL, 128, "sT30:universal_7 = %x\n", t30->universal_7);
- eicon_log(NULL, 128, "sT30:station_id_len = %x\n", t30->station_id_len);
- eicon_log(NULL, 128, "sT30:head_line_len = %x\n", t30->head_line_len);
- strlcpy(st, t30->station_id, t30->station_id_len + 1);
- eicon_log(NULL, 128, "sT30:station_id = <%s>\n", st);
- }
- return(sizeof(eicon_t30_s));
-}
-
-/* send fax struct */
-static int
-idi_send_edata(eicon_card *card, eicon_chan *chan)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
- eicon_log(card, 1, "idi_snd: Ch%d: send edata on state %d !\n", chan->No, chan->fsm_state);
- return -ENODEV;
- }
- eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No);
-
- skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
-
- reqbuf->Req = N_EDATA;
- reqbuf->ReqCh = chan->e.IndCh;
- reqbuf->ReqId = 1;
-
- reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
- reqbuf->Reference = 1; /* Net Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_tx_request(card);
- return (0);
-}
-
-static void
-idi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
-{
- eicon_t30_s *p = (eicon_t30_s *)buffer;
- int i;
-
- if (DebugVar & 128) {
- char st[40];
- eicon_log(ccard, 128, "rT30:len %d , size %d\n", len, sizeof(eicon_t30_s));
- eicon_log(ccard, 128, "rT30:code = %x\n", p->code);
- eicon_log(ccard, 128, "rT30:rate = %x\n", p->rate);
- eicon_log(ccard, 128, "rT30:res = %x\n", p->resolution);
- eicon_log(ccard, 128, "rT30:format = %x\n", p->format);
- eicon_log(ccard, 128, "rT30:pages_low = %x\n", p->pages_low);
- eicon_log(ccard, 128, "rT30:pages_high = %x\n", p->pages_high);
- eicon_log(ccard, 128, "rT30:atf = %x\n", p->atf);
- eicon_log(ccard, 128, "rT30:control_bits_low = %x\n", p->control_bits_low);
- eicon_log(ccard, 128, "rT30:control_bits_high = %x\n", p->control_bits_high);
- eicon_log(ccard, 128, "rT30:feature_bits_low = %x\n", p->feature_bits_low);
- eicon_log(ccard, 128, "rT30:feature_bits_high = %x\n", p->feature_bits_high);
- //eicon_log(ccard, 128, "rT30:universal_5 = %x\n", p->universal_5);
- //eicon_log(ccard, 128, "rT30:universal_6 = %x\n", p->universal_6);
- //eicon_log(ccard, 128, "rT30:universal_7 = %x\n", p->universal_7);
- eicon_log(ccard, 128, "rT30:station_id_len = %x\n", p->station_id_len);
- eicon_log(ccard, 128, "rT30:head_line_len = %x\n", p->head_line_len);
- strlcpy(st, p->station_id, p->station_id_len + 1);
- eicon_log(ccard, 128, "rT30:station_id = <%s>\n", st);
- }
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n");
- return;
- }
- chan->fax->code = p->code;
- i = (p->station_id_len < FAXIDLEN) ? p->station_id_len : (FAXIDLEN - 1);
- memcpy(chan->fax->r_id, p->station_id, i);
- chan->fax->r_id[i] = 0;
- chan->fax->r_resolution = p->resolution;
- chan->fax->r_rate = p->rate - 1;
- chan->fax->r_binary = 0; /* no binary support */
- chan->fax->r_width = 0;
- chan->fax->r_length = 2;
- chan->fax->r_scantime = 0;
- chan->fax->r_compression = 0;
- chan->fax->r_ecm = 0;
- if (p->feature_bits_low & T30_FEATURE_BIT_2D_CODING) {
- chan->fax->r_compression = 1;
- if (p->feature_bits_low & T30_FEATURE_BIT_UNCOMPR_ENABLED) {
- chan->fax->r_compression = 2;
- }
- }
- if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) {
- chan->fax->r_compression = 3;
- }
-
- if (p->feature_bits_low & T30_FEATURE_BIT_ECM) {
- chan->fax->r_ecm = 2;
- if (p->feature_bits_low & T30_FEATURE_BIT_ECM_64_BYTES)
- chan->fax->r_ecm = 1;
- }
-}
-
-static void
-idi_fax_send_header(eicon_card *card, eicon_chan *chan, int header)
-{
- static __u16 wd2sff[] = {
- 1728, 2048, 2432, 1216, 864
- };
- static __u16 ln2sff[2][3] = {
- { 1143, 1401, 0 } , { 2287, 2802, 0 }
- };
- struct sk_buff *skb;
- eicon_sff_dochead *doc;
- eicon_sff_pagehead *page;
- u_char *docp;
-
- if (!chan->fax) {
- eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n");
- return;
- }
- if (header == 2) { /* DocHeader + PageHeader */
- skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC);
- } else {
- skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC);
- }
- if (!skb) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No);
- return;
- }
-
- if (header == 2) { /* DocHeader + PageHeader */
- docp = skb_put(skb, sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
- doc = (eicon_sff_dochead *) docp;
- page = (eicon_sff_pagehead *) (docp + sizeof(eicon_sff_dochead));
- memset(docp, 0,sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead));
- doc->id = 0x66666653;
- doc->version = 0x01;
- doc->off1pagehead = sizeof(eicon_sff_dochead);
- } else {
- page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead));
- memset(page, 0, sizeof(eicon_sff_pagehead));
- }
-
- switch(header) {
- case 1: /* PageHeaderEnd */
- page->pageheadid = 254;
- page->pageheadlen = 0;
- break;
- case 0: /* PageHeader */
- case 2: /* DocHeader + PageHeader */
- page->pageheadid = 254;
- page->pageheadlen = sizeof(eicon_sff_pagehead) - 2;
- page->resvert = chan->fax->resolution;
- page->reshoriz = 0; /* always 203 dpi */
- page->coding = 0; /* always 1D */
- page->linelength = wd2sff[chan->fax->width];
- page->pagelength = ln2sff[chan->fax->resolution][chan->fax->length];
- eicon_log(card, 128, "sSFF-Head: linelength = %d\n", page->linelength);
- eicon_log(card, 128, "sSFF-Head: pagelength = %d\n", page->pagelength);
- break;
- }
- idi_send_data(card, chan, 0, skb, 0, 0);
-}
-
-void
-idi_fax_cmd(eicon_card *card, eicon_chan *chan)
-{
- isdn_ctrl cmd;
-
- if ((!card) || (!chan))
- return;
-
- if (!chan->fax) {
- eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n");
- return;
- }
- switch (chan->fax->code) {
- case ISDN_TTY_FAX_DT:
- if (chan->fax->phase == ISDN_FAX_PHASE_B) {
- idi_send_edata(card, chan);
- break;
- }
- if (chan->fax->phase == ISDN_FAX_PHASE_D) {
- idi_send_edata(card, chan);
- break;
- }
- break;
-
- case ISDN_TTY_FAX_DR:
- if (chan->fax->phase == ISDN_FAX_PHASE_B) {
- idi_send_edata(card, chan);
-
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_CFR;
- card->interface.statcallb(&cmd);
-
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_RID;
- card->interface.statcallb(&cmd);
-
- /* telling 1-D compression */
- chan->fax->r_compression = 0;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DCS;
- card->interface.statcallb(&cmd);
-
- chan->fax2.NextObject = FAX_OBJECT_DOCU;
- chan->fax2.PrevObject = FAX_OBJECT_DOCU;
-
- break;
- }
- if (chan->fax->phase == ISDN_FAX_PHASE_D) {
- idi_send_edata(card, chan);
- break;
- }
- break;
-
- case ISDN_TTY_FAX_ET:
- switch(chan->fax->fet) {
- case 0:
- case 1:
- idi_fax_send_header(card, chan, 0);
- break;
- case 2:
- idi_fax_send_header(card, chan, 1);
- break;
- }
- break;
- }
-}
-
-static void
-idi_edata_rcveop(eicon_card *card, eicon_chan *chan)
-{
- isdn_ctrl cmd;
-
- if (!chan->fax) {
- eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n");
- return;
- }
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_ET;
- card->interface.statcallb(&cmd);
-}
-
-static void
-idi_reset_fax_stat(eicon_chan *chan)
-{
- chan->fax2.LineLen = 0;
- chan->fax2.LineData = 0;
- chan->fax2.LineDataLen = 0;
- chan->fax2.NullByteExist = 0;
- chan->fax2.Dle = 0;
- chan->fax2.PageCount = 0;
- chan->fax2.Eop = 0;
-}
-
-static void
-idi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len)
-{
- isdn_ctrl cmd;
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n");
- return;
- }
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) {
- idi_parse_edata(ccard, chan, buffer, len);
-
- if (chan->fax->phase == ISDN_FAX_PHASE_A) {
- idi_reset_fax_stat(chan);
-
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "");
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_FCON;
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_RID;
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DIS;
- ccard->interface.statcallb(&cmd);
-
- if (chan->fax->r_compression != 0) {
- /* telling fake compression in second DIS message */
- chan->fax->r_compression = 0;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DIS;
- ccard->interface.statcallb(&cmd);
- }
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */
- ccard->interface.statcallb(&cmd);
- } else
- if (chan->fax->phase == ISDN_FAX_PHASE_D) {
-
- if ((chan->fax->code == EDATA_T30_MCF) &&
- (chan->fax->fet != 2)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_PTS;
- ccard->interface.statcallb(&cmd);
- }
-
- switch(chan->fax->fet) {
- case 0: /* new page */
- /* stay in phase D , wait on cmd +FDT */
- break;
- case 1: /* new document */
- /* link-level switch to phase B */
- break;
- case 2: /* session end */
- default:
- /* send_edata produces error on some */
- /* fax-machines here, so we don't */
- /* idi_send_edata(ccard, chan); */
- break;
- }
- }
- }
-
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
- idi_parse_edata(ccard, chan, buffer, len);
-
- if ((chan->fax->code == EDATA_T30_DCS) &&
- (chan->fax->phase == ISDN_FAX_PHASE_A)) {
- idi_reset_fax_stat(chan);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "");
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_FCON_I;
- ccard->interface.statcallb(&cmd);
- } else
- if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
- (chan->fax->phase == ISDN_FAX_PHASE_A)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_RID;
- ccard->interface.statcallb(&cmd);
-
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
- ccard->interface.statcallb(&cmd);
- } else
- if ((chan->fax->code == EDATA_T30_TRAIN_OK) &&
- (chan->fax->phase == ISDN_FAX_PHASE_B)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK;
- ccard->interface.statcallb(&cmd);
- } else
- if (chan->fax->phase == ISDN_FAX_PHASE_C) {
- switch(chan->fax->code) {
- case EDATA_T30_TRAIN_OK:
- idi_send_edata(ccard, chan);
- break;
- case EDATA_T30_MPS:
- chan->fax->fet = 0;
- idi_edata_rcveop(ccard, chan);
- break;
- case EDATA_T30_EOM:
- chan->fax->fet = 1;
- idi_edata_rcveop(ccard, chan);
- break;
- case EDATA_T30_EOP:
- chan->fax->fet = 2;
- idi_edata_rcveop(ccard, chan);
- break;
- }
- }
- }
-}
-
-static void
-fax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No);
- return;
- }
- skb_reserve(skb, MAX_HEADER_LEN);
- memcpy(skb_put(skb, len), Data, len);
- ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
-}
-
-static void
-idi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
-{
- eicon_OBJBUFFER InBuf;
- eicon_OBJBUFFER LineBuf;
- unsigned int Length = 0;
- unsigned int aLength = 0;
- unsigned int ObjectSize = 0;
- unsigned int ObjHeadLen = 0;
- unsigned int ObjDataLen = 0;
- __u8 Recordtype;
- __u8 PageHeaderLen;
- __u8 Event;
- eicon_sff_pagehead *ob_page;
-
- __u16 Cl2Eol = 0x8000;
-
-# define EVENT_NONE 0
-# define EVENT_NEEDDATA 1
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n");
- return;
- }
-
-
-
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
- InBuf.Data = skb->data;
- InBuf.Size = skb->len;
- InBuf.Len = 0;
- InBuf.Next = InBuf.Data;
- LineBuf.Data = chan->fax2.abLine;
- LineBuf.Size = sizeof(chan->fax2.abLine);
- LineBuf.Len = chan->fax2.LineLen;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
-
- Event = EVENT_NONE;
- while (Event == EVENT_NONE) {
- switch(chan->fax2.NextObject) {
- case FAX_OBJECT_DOCU:
- Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
- if (Length < sizeof(eicon_sff_dochead)) {
- Event = EVENT_NEEDDATA;
- break;
- }
- ObjectSize = sizeof(eicon_sff_dochead);
- Length = ObjectSize;
- if (LineBuf.Len < Length) {
- Length -= LineBuf.Len;
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- InBuf.Len += Length;
- InBuf.Next += Length;
- } else {
- LineBuf.Len -= Length;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
- }
- chan->fax2.PrevObject = FAX_OBJECT_DOCU;
- chan->fax2.NextObject = FAX_OBJECT_PAGE;
- break;
-
- case FAX_OBJECT_PAGE:
- Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
- if (Length < 2) {
- Event = EVENT_NEEDDATA;
- break;
- }
- if (LineBuf.Len == 0) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- if (LineBuf.Len == 1) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- PageHeaderLen = *(LineBuf.Data + 1);
- ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead);
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- Length = ObjectSize;
- /* extract page dimensions */
- if (LineBuf.Len < Length) {
- aLength = Length - LineBuf.Len;
- memcpy(LineBuf.Next, InBuf.Next, aLength);
- LineBuf.Next += aLength;
- InBuf.Next += aLength;
- LineBuf.Len += aLength;
- InBuf.Len += aLength;
- }
- if (Length > 2) {
- ob_page = (eicon_sff_pagehead *)LineBuf.Data;
- switch(ob_page->linelength) {
- case 2048:
- chan->fax->r_width = 1;
- break;
- case 2432:
- chan->fax->r_width = 2;
- break;
- case 1216:
- chan->fax->r_width = 3;
- break;
- case 864:
- chan->fax->r_width = 4;
- break;
- case 1728:
- default:
- chan->fax->r_width = 0;
- }
- switch(ob_page->pagelength) {
- case 1143:
- case 2287:
- chan->fax->r_length = 0;
- break;
- case 1401:
- case 2802:
- chan->fax->r_length = 1;
- break;
- default:
- chan->fax->r_length = 2;
- }
- eicon_log(ccard, 128, "rSFF-Head: linelength = %d\n", ob_page->linelength);
- eicon_log(ccard, 128, "rSFF-Head: pagelength = %d\n", ob_page->pagelength);
- }
- LineBuf.Len -= Length;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
-
- chan->fax2.PrevObject = FAX_OBJECT_PAGE;
- chan->fax2.NextObject = FAX_OBJECT_LINE;
- break;
-
- case FAX_OBJECT_LINE:
- Length = LineBuf.Len + (InBuf.Size - InBuf.Len);
- if (Length < 1) {
- Event = EVENT_NEEDDATA;
- break;
- }
- if (LineBuf.Len == 0) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- Recordtype = *LineBuf.Data;
- if (Recordtype == 0) {
- /* recordtype pixel row (2 byte length) */
- ObjHeadLen = 3;
- if (Length < ObjHeadLen) {
- Event = EVENT_NEEDDATA;
- break;
- }
- while (LineBuf.Len < ObjHeadLen) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- ObjDataLen = *((__u16*) (LineBuf.Data + 1));
- ObjectSize = ObjHeadLen + ObjDataLen;
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- } else
- if ((Recordtype >= 1) && (Recordtype <= 216)) {
- /* recordtype pixel row (1 byte length) */
- ObjHeadLen = 1;
- ObjDataLen = Recordtype;
- ObjectSize = ObjHeadLen + ObjDataLen;
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- } else
- if ((Recordtype >= 217) && (Recordtype <= 253)) {
- /* recordtype empty lines */
- ObjHeadLen = 1;
- ObjDataLen = 0;
- ObjectSize = ObjHeadLen + ObjDataLen;
- LineBuf.Len--;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len);
- break;
- } else
- if (Recordtype == 254) {
- /* recordtype page header */
- chan->fax2.PrevObject = FAX_OBJECT_LINE;
- chan->fax2.NextObject = FAX_OBJECT_PAGE;
- break;
- } else {
- /* recordtype user information */
- ObjHeadLen = 2;
- if (Length < ObjHeadLen) {
- Event = EVENT_NEEDDATA;
- break;
- }
- while (LineBuf.Len < ObjHeadLen) {
- *LineBuf.Next++ = *InBuf.Next++;
- LineBuf.Len++;
- InBuf.Len++;
- }
- ObjDataLen = *(LineBuf.Data + 1);
- ObjectSize = ObjHeadLen + ObjDataLen;
- if (ObjDataLen == 0) {
- /* illegal line coding */
- LineBuf.Len -= ObjHeadLen;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + ObjHeadLen, LineBuf.Len);
- break;
- } else {
- /* user information */
- if (Length < ObjectSize) {
- Event = EVENT_NEEDDATA;
- break;
- }
- Length = ObjectSize;
- if (LineBuf.Len < Length) {
- Length -= LineBuf.Len;
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- InBuf.Len += Length;
- InBuf.Next += Length;
- } else {
- LineBuf.Len -= Length;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len);
- }
- }
- break;
- }
- Length = ObjectSize;
- if (LineBuf.Len > ObjHeadLen) {
- fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen,
- (LineBuf.Len - ObjHeadLen));
- }
- Length -= LineBuf.Len;
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- if (Length > 0) {
- fax_put_rcv(ccard, chan, InBuf.Next, Length);
- InBuf.Len += Length;
- InBuf.Next += Length;
- }
- fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol));
- break;
- } /* end of switch (chan->fax2.NextObject) */
- } /* end of while (Event==EVENT_NONE) */
- if (InBuf.Len < InBuf.Size) {
- Length = InBuf.Size - InBuf.Len;
- if ((LineBuf.Len + Length) > LineBuf.Size) {
- eicon_log(ccard, 1, "idi_fax: Ch%d: %d bytes dropping, small buffer\n", chan->No,
- Length);
- } else {
- memcpy(LineBuf.Next, InBuf.Next, Length);
- LineBuf.Len += Length;
- }
- }
- chan->fax2.LineLen = LineBuf.Len;
- } else { /* CONN_OUT */
- /* On CONN_OUT we do not need incoming data, drop it */
- /* maybe later for polling */
- }
-
-# undef EVENT_NONE
-# undef EVENT_NEEDDATA
-
- return;
-}
-
-static int
-idi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(OutBuf->Len, GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No);
- return(-1);
- }
- memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len);
-
- OutBuf->Len = 0;
- OutBuf->Next = OutBuf->Data;
-
- return(idi_send_data(ccard, chan, 0, skb, 1, 0));
-}
-
-int
-idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb)
-{
- isdn_ctrl cmd;
- eicon_OBJBUFFER InBuf;
- __u8 InData;
- __u8 InMask;
- eicon_OBJBUFFER OutBuf;
- eicon_OBJBUFFER LineBuf;
- __u32 LineData;
- unsigned int LineDataLen;
- __u8 Byte;
- __u8 Event;
- int ret = 1;
-
-# define EVENT_NONE 0
-# define EVENT_EOD 1
-# define EVENT_EOL 2
-# define EVENT_EOP 3
-
- if ((!ccard) || (!chan))
- return -1;
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n");
- return -1;
- }
-
- if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
- /* Simply ignore any data written in data mode when receiving a fax. */
- /* This is not completely correct because only XON's should come here. */
- dev_kfree_skb(skb);
- return 1;
- }
-
- if (chan->fax->phase != ISDN_FAX_PHASE_C) {
- dev_kfree_skb(skb);
- return 1;
- }
-
- if (chan->queued + skb->len > 1200)
- return 0;
- if (chan->pqueued > 1)
- return 0;
-
- InBuf.Data = skb->data;
- InBuf.Size = skb->len;
- InBuf.Len = 0;
- InBuf.Next = InBuf.Data;
- InData = 0;
- InMask = 0;
-
- LineBuf.Data = chan->fax2.abLine;
- LineBuf.Size = sizeof(chan->fax2.abLine);
- LineBuf.Len = chan->fax2.LineLen;
- LineBuf.Next = LineBuf.Data + LineBuf.Len;
- LineData = chan->fax2.LineData;
- LineDataLen = chan->fax2.LineDataLen;
-
- OutBuf.Data = chan->fax2.abFrame;
- OutBuf.Size = sizeof(chan->fax2.abFrame);
- OutBuf.Len = 0;
- OutBuf.Next = OutBuf.Data;
-
- Event = EVENT_NONE;
-
- chan->fax2.Eop = 0;
-
- for (;;) {
- for (;;) {
- if (InMask == 0) {
- if (InBuf.Len >= InBuf.Size) {
- Event = EVENT_EOD;
- break;
- }
- if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) {
- chan->fax2.Dle = _DLE_;
- InBuf.Next++;
- InBuf.Len++;
- if (InBuf.Len >= InBuf.Size) {
- Event = EVENT_EOD;
- break;
- }
- }
- if (chan->fax2.Dle == _DLE_) {
- chan->fax2.Dle = 0;
- if (*InBuf.Next == _ETX_) {
- Event = EVENT_EOP;
- break;
- } else
- if (*InBuf.Next == _DLE_) {
- /* do nothing */
- } else {
- eicon_log(ccard, 1,
- "idi_err: Ch%d: unknown DLE escape %02x found\n",
- chan->No, *InBuf.Next);
- InBuf.Next++;
- InBuf.Len++;
- if (InBuf.Len >= InBuf.Size) {
- Event = EVENT_EOD;
- break;
- }
- }
- }
- InBuf.Len++;
- InData = *InBuf.Next++;
- InMask = (chan->fax->bor) ? 0x80 : 0x01;
- }
- while (InMask) {
- LineData >>= 1;
- LineDataLen++;
- if (InData & InMask)
- LineData |= 0x80000000;
- if (chan->fax->bor)
- InMask >>= 1;
- else
- InMask <<= 1;
-
- if ((LineDataLen >= T4_EOL_BITSIZE) &&
- ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) {
- Event = EVENT_EOL;
- if (LineDataLen > T4_EOL_BITSIZE) {
- Byte = (__u8)
- ((LineData & ~T4_EOL_MASK_DWORD) >>
- (32 - LineDataLen));
- if (Byte == 0) {
- if (! chan->fax2.NullByteExist) {
- chan->fax2.NullBytesPos = LineBuf.Len;
- chan->fax2.NullByteExist = 1;
- }
- } else {
- chan->fax2.NullByteExist = 0;
- }
- if (LineBuf.Len < LineBuf.Size) {
- *LineBuf.Next++ = Byte;
- LineBuf.Len++;
- }
- }
- LineDataLen = 0;
- break;
- }
- if (LineDataLen >= T4_EOL_BITSIZE + 8) {
- Byte = (__u8)
- ((LineData & ~T4_EOL_MASK_DWORD) >>
- (32 - T4_EOL_BITSIZE - 8));
- LineData &= T4_EOL_MASK_DWORD;
- LineDataLen = T4_EOL_BITSIZE;
- if (Byte == 0) {
- if (! chan->fax2.NullByteExist) {
- chan->fax2.NullBytesPos = LineBuf.Len;
- chan->fax2.NullByteExist = 1;
- }
- } else {
- chan->fax2.NullByteExist = 0;
- }
- if (LineBuf.Len < LineBuf.Size) {
- *LineBuf.Next++ = Byte;
- LineBuf.Len++;
- }
- }
- }
- if (Event != EVENT_NONE)
- break;
- }
-
- if ((Event != EVENT_EOL) && (Event != EVENT_EOP))
- break;
-
- if ((Event == EVENT_EOP) && (LineDataLen > 0)) {
- LineData >>= 32 - LineDataLen;
- LineDataLen = 0;
- while (LineData != 0) {
- Byte = (__u8) LineData;
- LineData >>= 8;
- if (Byte == 0) {
- if (! chan->fax2.NullByteExist) {
- chan->fax2.NullBytesPos = LineBuf.Len;
- chan->fax2.NullByteExist = 1;
- }
- } else {
- chan->fax2.NullByteExist = 0;
- }
- if (LineBuf.Len < LineBuf.Size) {
- *LineBuf.Next++ = Byte;
- LineBuf.Len++;
- }
-
- }
- }
- if (chan->fax2.NullByteExist) {
- if (chan->fax2.NullBytesPos == 0) {
- LineBuf.Len = 0;
- } else {
- LineBuf.Len = chan->fax2.NullBytesPos + 1;
- }
- }
- if (LineBuf.Len > 0) {
- if (OutBuf.Len + LineBuf.Len + SFF_LEN_FLD_SIZE > OutBuf.Size) {
- ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
- }
- if (LineBuf.Len <= 216) {
- *OutBuf.Next++ = (__u8) LineBuf.Len;
- OutBuf.Len++;
- } else {
- *OutBuf.Next++ = 0;
- *((__u16 *) OutBuf.Next)++ = (__u16) LineBuf.Len;
- OutBuf.Len += 3;
- }
- memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);
- OutBuf.Next += LineBuf.Len;
- OutBuf.Len += LineBuf.Len;
- }
- LineBuf.Len = 0;
- LineBuf.Next = LineBuf.Data;
- chan->fax2.NullByteExist = 0;
- if (Event == EVENT_EOP)
- break;
-
- Event = EVENT_NONE;
- }
-
- if (Event == EVENT_EOP) {
- chan->fax2.Eop = 1;
- chan->fax2.PageCount++;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_EOP;
- ccard->interface.statcallb(&cmd);
- }
- if (OutBuf.Len > 0) {
- ret = idi_fax_send_outbuf(ccard, chan, &OutBuf);
- }
-
- chan->fax2.LineLen = LineBuf.Len;
- chan->fax2.LineData = LineData;
- chan->fax2.LineDataLen = LineDataLen;
-
-# undef EVENT_NONE
-# undef EVENT_EOD
-# undef EVENT_EOL
-# undef EVENT_EOP
-
- if (ret >= 0)
- dev_kfree_skb(skb);
- if (ret == 0)
- ret = 1;
- return(ret);
-}
-
-static void
-idi_fax_hangup(eicon_card *ccard, eicon_chan *chan)
-{
- isdn_ctrl cmd;
-
- if (!chan->fax) {
- eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n");
- return;
- }
- if ((chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) &&
- (chan->fax->code == 0)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_PTS;
- ccard->interface.statcallb(&cmd);
- }
- if ((chan->fax->code > 1) && (chan->fax->code < 120))
- chan->fax->code += 120;
- eicon_log(ccard, 8, "idi_fax: Ch%d: Hangup (code=%d)\n", chan->No, chan->fax->code);
- chan->fax->r_code = ISDN_TTY_FAX_HNG;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
-}
-
-#endif /******** FAX ********/
-
-static int
-idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int len)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
-
- if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) {
- eicon_log(card, 1, "idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state);
- return -ENODEV;
- }
- eicon_log(card, 8, "idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No,
- UReq, buffer[0], buffer[1], buffer[2], buffer[3]);
-
- skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No);
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
-
- reqbuf->Req = N_UDATA;
- reqbuf->ReqCh = chan->e.IndCh;
- reqbuf->ReqId = 1;
-
- reqbuf->XBuffer.length = len + 1;
- reqbuf->XBuffer.P[0] = UReq;
- memcpy(&reqbuf->XBuffer.P[1], buffer, len);
- reqbuf->Reference = 1; /* Net Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_tx_request(card);
- return (0);
-}
-
-void
-idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value)
-{
- u_char buf[6];
- struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf;
-
- if ((!ccard) || (!chan))
- return;
-
- memset(buf, 0, 6);
- switch(cmd) {
- case ISDN_AUDIO_SETDD:
- if (value[0]) {
- dtmf_buf->tone = (__u16) (value[1] * 5);
- dtmf_buf->gap = (__u16) (value[1] * 5);
- idi_send_udata(ccard, chan,
- DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER,
- buf, 4);
- } else {
- idi_send_udata(ccard, chan,
- DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER,
- buf, 0);
- }
- break;
- }
-}
-
-static void
-idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len)
-{
- isdn_ctrl cmd;
- eicon_dsp_ind *p = (eicon_dsp_ind *) (&buffer[1]);
- static char *connmsg[] =
- {"", "V.21", "V.23", "V.22", "V.22bis", "V.32bis", "V.34",
- "V.8", "Bell 212A", "Bell 103", "V.29 Leased", "V.33 Leased", "V.90",
- "V.21 CH2", "V.27ter", "V.29", "V.33", "V.17", "V.32", "K56Flex",
- "X2", "V.18", "V.18LH", "V.18HL", "V.21LH", "V.21HL",
- "Bell 103LH", "Bell 103HL", "V.23", "V.23", "EDT 110",
- "Baudot45", "Baudot47", "Baudot50", "DTMF" };
- static u_char dtmf_code[] = {
- '1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D'
- };
-
- if ((!ccard) || (!chan))
- return;
-
- switch (buffer[0]) {
- case DSP_UDATA_INDICATION_SYNC:
- eicon_log(ccard, 16, "idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time);
- break;
- case DSP_UDATA_INDICATION_DCD_OFF:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time);
- break;
- case DSP_UDATA_INDICATION_DCD_ON:
- if ((chan->l2prot == ISDN_PROTO_L2_MODEM) &&
- ((chan->fsm_state == EICON_STATE_IBWAIT) ||
- (chan->fsm_state == EICON_STATE_WMCONN))) {
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- if (p->norm > 34) {
- sprintf(cmd.parm.num, "%d/(%d)", p->speed, p->norm);
- } else {
- sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]);
- }
- ccard->interface.statcallb(&cmd);
- }
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time);
- eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
- p->norm, p->options, p->speed, p->delay);
- break;
- case DSP_UDATA_INDICATION_CTS_OFF:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time);
- break;
- case DSP_UDATA_INDICATION_CTS_ON:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time);
- eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No,
- p->norm, p->options, p->speed, p->delay);
- break;
- case DSP_UDATA_INDICATION_DISCONNECT:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]);
- break;
- case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No,
- dtmf_code[buffer[1]]);
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_AUDIO;
- cmd.parm.num[0] = ISDN_AUDIO_DTMF;
- cmd.parm.num[1] = dtmf_code[buffer[1]];
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- break;
- default:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]);
- }
-}
-
-static void
-eicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len)
-{
- int i,j,n;
- int buflen = len * 3 + 30;
- char *p;
- struct trace_s {
- unsigned long time;
- unsigned short size;
- unsigned short code;
- unsigned char data[1];
- } *q;
-
- if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
- eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
- return;
- }
- memset(p, 0, buflen);
- q = (struct trace_s *)buffer;
-
- if (DebugVar & 512) {
- if ((q->code == 3) || (q->code == 4)) {
- n = (short) *(q->data);
- if (n) {
- j = sprintf(p, "DTRC:");
- for (i = 0; i < n; i++) {
- j += sprintf(p + j, "%02x ", q->data[i+2]);
- }
- j += sprintf(p + j, "\n");
- }
- }
- } else {
- j = sprintf(p, "XLOG: %lx %04x %04x ",
- q->time, q->size, q->code);
-
- for (i = 0; i < q->size; i++) {
- j += sprintf(p + j, "%02x ", q->data[i]);
- }
- j += sprintf(p + j, "\n");
- }
- if (strlen(p))
- eicon_putstatus(ccard, p);
- kfree(p);
-}
-
-void
-idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
-{
- int tmp;
- char tnum[64];
- int dlev;
- int free_buff;
- eicon_IND *ind = (eicon_IND *)skb->data;
- eicon_chan *chan;
- idi_ind_message message;
- isdn_ctrl cmd;
-
- if (!ccard) {
- eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n");
- dev_kfree_skb(skb);
- return;
- }
-
- if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
- eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n");
- dev_kfree_skb(skb);
- return;
- }
-
- if ((ind->Ind != 8) && (ind->Ind != 0xc))
- dlev = 144;
- else
- dlev = 128;
-
- eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%x Id=%x Ch=%x MInd=%x MLen=%x Len=%x\n", chan->No,
- ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
-
- free_buff = 1;
- /* Signal Layer */
- if (chan->e.D3Id == ind->IndId) {
- idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
- switch(ind->Ind) {
- case HANGUP:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Hangup\n", chan->No);
- skb_queue_purge(&chan->e.X);
- chan->queued = 0;
- chan->pqueued = 0;
- chan->waitq = 0;
- chan->waitpq = 0;
- if (message.e_cau[0] & 0x7f) {
- cmd.driver = ccard->myid;
- cmd.arg = chan->No;
- sprintf(cmd.parm.num,"E%02x%02x",
- chan->cause[0]&0x7f, message.e_cau[0]&0x7f);
- cmd.command = ISDN_STAT_CAUSE;
- ccard->interface.statcallb(&cmd);
- }
- chan->cause[0] = 0;
- if ((chan->fsm_state == EICON_STATE_ACTIVE) ||
- ((chan->l2prot == ISDN_PROTO_L2_FAX) &&
- (chan->fsm_state == EICON_STATE_OBWAIT))) {
- chan->fsm_state = EICON_STATE_NULL;
- } else {
- if (chan->e.B2Id)
- idi_do_req(ccard, chan, REMOVE, 1);
- chan->statectrl &= ~WAITING_FOR_HANGUP;
- chan->statectrl &= ~IN_HOLD;
- if (chan->statectrl & HAVE_CONN_REQ) {
- eicon_log(ccard, 32, "idi_req: Ch%d: queueing delayed conn_req\n", chan->No);
- chan->statectrl &= ~HAVE_CONN_REQ;
- if ((chan->tskb1) && (chan->tskb2)) {
- skb_queue_tail(&chan->e.X, chan->tskb1);
- skb_queue_tail(&ccard->sndq, chan->tskb2);
- }
- chan->tskb1 = NULL;
- chan->tskb2 = NULL;
- } else {
- chan->fsm_state = EICON_STATE_NULL;
- cmd.driver = ccard->myid;
- cmd.arg = chan->No;
- cmd.command = ISDN_STAT_DHUP;
- ccard->interface.statcallb(&cmd);
- eicon_idi_listen_req(ccard, chan);
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fax = 0;
-#endif
- }
- }
- break;
- case INDICATE_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Indicate_Ind\n", chan->No);
- if (chan->fsm_state != EICON_STATE_LISTEN) {
- eicon_log(ccard, 1, "idi_err: Ch%d: Incoming call on wrong state (%d).\n",
- chan->No, chan->fsm_state);
- idi_do_req(ccard, chan, HANGUP, 0);
- break;
- }
- chan->fsm_state = EICON_STATE_ICALL;
- idi_bc2si(message.bc, message.hlc, message.sin, &chan->si1, &chan->si2);
- strcpy(chan->cpn, message.cpn + 1);
- strcpy(chan->oad, message.oad);
- strcpy(chan->dsa, message.dsa);
- strcpy(chan->osa, message.osa);
- chan->plan = message.plan;
- chan->screen = message.screen;
- try_stat_icall_again:
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_ICALL;
- cmd.arg = chan->No;
- cmd.parm.setup.si1 = chan->si1;
- cmd.parm.setup.si2 = chan->si2;
- strcpy(tnum, chan->cpn);
- if (strlen(chan->dsa)) {
- strcat(tnum, ".");
- strcat(tnum, chan->dsa);
- }
- tnum[ISDN_MSNLEN - 1] = 0;
- strcpy(cmd.parm.setup.eazmsn, tnum);
- strcpy(tnum, chan->oad);
- if (strlen(chan->osa)) {
- strcat(tnum, ".");
- strcat(tnum, chan->osa);
- }
- tnum[ISDN_MSNLEN - 1] = 0;
- strcpy(cmd.parm.setup.phone, tnum);
- cmd.parm.setup.plan = chan->plan;
- cmd.parm.setup.screen = chan->screen;
- tmp = ccard->interface.statcallb(&cmd);
- switch(tmp) {
- case 0: /* no user responding */
- idi_do_req(ccard, chan, HANGUP, 0);
- chan->fsm_state = EICON_STATE_NULL;
- break;
- case 1: /* alert */
- eicon_log(ccard, 8, "idi_req: Ch%d: Call Alert\n", chan->No);
- if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_ICALLW)) {
- chan->fsm_state = EICON_STATE_ICALL;
- idi_do_req(ccard, chan, CALL_ALERT, 0);
- }
- break;
- case 2: /* reject */
- eicon_log(ccard, 8, "idi_req: Ch%d: Call Reject\n", chan->No);
- idi_do_req(ccard, chan, REJECT, 0);
- break;
- case 3: /* incomplete number */
- eicon_log(ccard, 8, "idi_req: Ch%d: Incomplete Number\n", chan->No);
- chan->fsm_state = EICON_STATE_ICALLW;
- break;
- }
- break;
- case INFO_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Info_Ind\n", chan->No);
- if ((chan->fsm_state == EICON_STATE_ICALLW) &&
- (message.cpn[0])) {
- strcat(chan->cpn, message.cpn + 1);
- goto try_stat_icall_again;
- }
- break;
- case CALL_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Ind\n", chan->No);
- if ((chan->fsm_state == EICON_STATE_ICALL) ||
- (chan->fsm_state == EICON_STATE_WMCONN) ||
- (chan->fsm_state == EICON_STATE_IWAIT)) {
- chan->fsm_state = EICON_STATE_IBWAIT;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_DCONN;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- switch(chan->l2prot) {
- case ISDN_PROTO_L2_FAX:
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->fax)
- chan->fax->phase = ISDN_FAX_PHASE_A;
-#endif
- break;
- case ISDN_PROTO_L2_MODEM:
- /* do nothing, wait for connect */
- break;
- case ISDN_PROTO_L2_V11096:
- case ISDN_PROTO_L2_V11019:
- case ISDN_PROTO_L2_V11038:
- case ISDN_PROTO_L2_TRANS:
- idi_do_req(ccard, chan, N_CONNECT, 1);
- break;
- default:
- /* On most incoming calls we use automatic connect */
- /* idi_do_req(ccard, chan, N_CONNECT, 1); */
- break;
- }
- } else {
- if (chan->fsm_state != EICON_STATE_ACTIVE)
- idi_hangup(ccard, chan);
- }
- break;
- case CALL_CON:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Con\n", chan->No);
- if (chan->fsm_state == EICON_STATE_OCALL) {
- /* check if old NetID has been removed */
- if (chan->e.B2Id) {
- eicon_log(ccard, 1, "idi_ind: Ch%d: old net_id %x still exist, removing.\n",
- chan->No, chan->e.B2Id);
- idi_do_req(ccard, chan, REMOVE, 1);
- }
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- if (chan->fax) {
- chan->fax->phase = ISDN_FAX_PHASE_A;
- } else {
- eicon_log(ccard, 1, "idi_ind: Call_Con with NULL fax struct, ERROR\n");
- idi_hangup(ccard, chan);
- break;
- }
- }
-#endif
- chan->fsm_state = EICON_STATE_OBWAIT;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_DCONN;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
-
- idi_do_req(ccard, chan, ASSIGN, 1);
- idi_do_req(ccard, chan, N_CONNECT, 1);
- } else
- idi_hangup(ccard, chan);
- break;
- case AOC_IND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Advice of Charge\n", chan->No);
- break;
- case CALL_HOLD_ACK:
- chan->statectrl |= IN_HOLD;
- eicon_log(ccard, 8, "idi_ind: Ch%d: Call Hold Ack\n", chan->No);
- break;
- case SUSPEND_REJ:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Rejected\n", chan->No);
- break;
- case SUSPEND:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Suspend Ack\n", chan->No);
- break;
- case RESUME:
- eicon_log(ccard, 8, "idi_ind: Ch%d: Resume Ack\n", chan->No);
- break;
- default:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind);
- }
- }
- /* Network Layer */
- else if (chan->e.B2Id == ind->IndId) {
-
- if (chan->No == ccard->nchannels) {
- /* Management Indication */
- if (ind->Ind == 0x04) { /* Trace_Ind */
- eicon_parse_trace(ccard, ind->RBuffer.P, ind->RBuffer.length);
- } else {
- idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
- chan->fsm_state = 1;
- }
- }
- else
- switch(ind->Ind) {
- case N_CONNECT_ACK:
- eicon_log(ccard, 16, "idi_ind: Ch%d: N_Connect_Ack\n", chan->No);
- if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
- chan->fsm_state = EICON_STATE_WMCONN;
- break;
- }
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fsm_state = EICON_STATE_ACTIVE;
- idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- if (chan->fax) {
- if (chan->fax->phase == ISDN_FAX_PHASE_B) {
- idi_fax_send_header(ccard, chan, 2);
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_DCS;
- ccard->interface.statcallb(&cmd);
- }
- }
- else {
- eicon_log(ccard, 1, "idi_ind: N_Connect_Ack with NULL fax struct, ERROR\n");
- }
-#endif
- break;
- }
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "64000");
- ccard->interface.statcallb(&cmd);
- break;
- case N_CONNECT:
- eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No);
- chan->e.IndCh = ind->IndCh;
- if (chan->e.B2Id) idi_do_req(ccard, chan, N_CONNECT_ACK, 1);
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- break;
- }
- if (chan->l2prot == ISDN_PROTO_L2_MODEM) {
- chan->fsm_state = EICON_STATE_WMCONN;
- break;
- }
- chan->fsm_state = EICON_STATE_ACTIVE;
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan->No;
- strcpy(cmd.parm.num, "64000");
- ccard->interface.statcallb(&cmd);
- break;
- case N_DISC:
- eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc\n", chan->No);
- if (chan->e.B2Id) {
- skb_queue_purge(&chan->e.X);
- idi_do_req(ccard, chan, N_DISC_ACK, 1);
- idi_do_req(ccard, chan, REMOVE, 1);
- }
-#ifdef CONFIG_ISDN_TTY_FAX
- if ((chan->l2prot == ISDN_PROTO_L2_FAX) && (chan->fax)){
- idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- idi_fax_hangup(ccard, chan);
- }
-#endif
- chan->e.IndCh = 0;
- chan->queued = 0;
- chan->pqueued = 0;
- chan->waitq = 0;
- chan->waitpq = 0;
- if (!(chan->statectrl & IN_HOLD)) {
- idi_do_req(ccard, chan, HANGUP, 0);
- }
- if (chan->fsm_state == EICON_STATE_ACTIVE) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BHUP;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- chan->fsm_state = EICON_STATE_NULL;
- if (!(chan->statectrl & IN_HOLD)) {
- chan->statectrl |= WAITING_FOR_HANGUP;
- }
- }
-#ifdef CONFIG_ISDN_TTY_FAX
- chan->fax = 0;
-#endif
- break;
- case N_DISC_ACK:
- eicon_log(ccard, 16, "idi_ind: Ch%d: N_Disc_Ack\n", chan->No);
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- idi_fax_hangup(ccard, chan);
- }
-#endif
- break;
- case N_DATA_ACK:
- eicon_log(ccard, 128, "idi_ind: Ch%d: N_Data_Ack\n", chan->No);
- break;
- case N_DATA:
- skb_pull(skb, sizeof(eicon_IND) - 1);
- eicon_log(ccard, 128, "idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len);
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
-#ifdef CONFIG_ISDN_TTY_FAX
- idi_faxdata_rcv(ccard, chan, skb);
-#endif
- } else {
- ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb);
- free_buff = 0;
- }
- break;
- case N_UDATA:
- idi_parse_udata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- break;
-#ifdef CONFIG_ISDN_TTY_FAX
- case N_EDATA:
- idi_edata_action(ccard, chan, ind->RBuffer.P, ind->RBuffer.length);
- break;
-#endif
- default:
- eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind);
- }
- }
- else {
- eicon_log(ccard, 1, "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No);
- }
- if (free_buff)
- dev_kfree_skb(skb);
-}
-
-static int
-idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
-{
- isdn_ctrl cmd;
- int tqueued = 0;
- int twaitpq = 0;
-
- if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) {
- /* I don't know why this happens, should not ! */
- /* just ignoring this RC */
- eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No,
- ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id);
- return 1;
- }
-
- /* Management Interface */
- if (chan->No == ccard->nchannels) {
- /* Managementinterface: changing state */
- if (chan->e.Req != 0x02)
- chan->fsm_state = 1;
- }
-
- /* Remove an Id */
- if (chan->e.Req == REMOVE) {
- if (ack->Reference != chan->e.ref) {
- /* This should not happen anymore */
- eicon_log(ccard, 16, "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No,
- ack->Reference, chan->e.ref);
- }
- ccard->IdTable[ack->RcId] = NULL;
- if (!chan->e.ReqCh)
- chan->e.D3Id = 0;
- else
- chan->e.B2Id = 0;
- eicon_log(ccard, 16, "idi_ack: Ch%d: Removed : Id=%x Ch=%d (%s)\n", chan->No,
- ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig");
- return 1;
- }
-
- /* Signal layer */
- if (!chan->e.ReqCh) {
- eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
- ack->RcId, ack->RcCh, ack->Reference);
- } else {
- /* Network layer */
- switch(chan->e.Req & 0x0f) {
- case N_CONNECT:
- chan->e.IndCh = ack->RcCh;
- eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
- ack->RcId, ack->RcCh, ack->Reference);
- break;
- case N_MDATA:
- case N_DATA:
- tqueued = chan->queued;
- twaitpq = chan->waitpq;
- if ((chan->e.Req & 0x0f) == N_DATA) {
- chan->waitpq = 0;
- if(chan->pqueued)
- chan->pqueued--;
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- if (((chan->queued - chan->waitq) < 1) &&
- (chan->fax2.Eop)) {
- chan->fax2.Eop = 0;
- if (chan->fax) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_FAXIND;
- cmd.arg = chan->No;
- chan->fax->r_code = ISDN_TTY_FAX_SENT;
- ccard->interface.statcallb(&cmd);
- }
- else {
- eicon_log(ccard, 1, "idi_ack: Sent with NULL fax struct, ERROR\n");
- }
- }
- }
-#endif
- }
- chan->queued -= chan->waitq;
- if (chan->queued < 0) chan->queued = 0;
- if (((chan->e.Req & 0x0f) == N_DATA) && (tqueued)) {
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_BSENT;
- cmd.arg = chan->No;
- cmd.parm.length = twaitpq;
- ccard->interface.statcallb(&cmd);
- }
- break;
- default:
- eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
- ack->RcId, ack->RcCh, ack->Reference);
- }
- }
- return 1;
-}
-
-void
-idi_handle_ack(eicon_card *ccard, struct sk_buff *skb)
-{
- int j;
- eicon_RC *ack = (eicon_RC *)skb->data;
- eicon_chan *chan;
- isdn_ctrl cmd;
- int dCh = -1;
-
- if (!ccard) {
- eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ack\n");
- dev_kfree_skb(skb);
- return;
- }
-
- if ((chan = ccard->IdTable[ack->RcId]) != NULL)
- dCh = chan->No;
-
- switch (ack->Rc) {
- case OK_FC:
- case N_FLOW_CONTROL:
- case ASSIGN_RC:
- eicon_log(ccard, 1, "idi_ack: Ch%d: unhandled RC 0x%x\n",
- dCh, ack->Rc);
- break;
- case READY_INT:
- case TIMER_INT:
- /* we do nothing here */
- break;
-
- case OK:
- if (!chan) {
- eicon_log(ccard, 1, "idi_ack: Ch%d: OK on chan without Id\n", dCh);
- break;
- }
- if (!idi_handle_ack_ok(ccard, chan, ack))
- chan = NULL;
- break;
-
- case ASSIGN_OK:
- if (chan) {
- eicon_log(ccard, 1, "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n",
- chan->No, chan->e.D3Id, chan->e.B2Id);
- }
- for(j = 0; j < ccard->nchannels + 1; j++) {
- if ((ccard->bch[j].e.ref == ack->Reference) &&
- (ccard->bch[j].e.Req == ASSIGN)) {
- if (!ccard->bch[j].e.ReqCh)
- ccard->bch[j].e.D3Id = ack->RcId;
- else
- ccard->bch[j].e.B2Id = ack->RcId;
- ccard->IdTable[ack->RcId] = &ccard->bch[j];
- chan = &ccard->bch[j];
- break;
- }
- }
- eicon_log(ccard, 16, "idi_ack: Ch%d: Id %x assigned (%s)\n", j,
- ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig");
- if (j > ccard->nchannels) {
- eicon_log(ccard, 24, "idi_ack: Ch??: ref %d not found for Id %d\n",
- ack->Reference, ack->RcId);
- }
- break;
-
- case OUT_OF_RESOURCES:
- case UNKNOWN_COMMAND:
- case WRONG_COMMAND:
- case WRONG_ID:
- case 0x08: /* ADAPTER_DEAD */
- case WRONG_CH:
- case UNKNOWN_IE:
- case WRONG_IE:
- default:
- if (!chan) {
- eicon_log(ccard, 1, "idi_ack: Ch%d: Not OK !! on chan without Id\n", dCh);
- break;
- } else
- switch (chan->e.Req) {
- case 12: /* Alert */
- eicon_log(ccard, 2, "idi_err: Ch%d: Alert Not OK : Rc=%d Id=%x Ch=%d\n",
- dCh, ack->Rc, ack->RcId, ack->RcCh);
- break;
- default:
- if (dCh != ccard->nchannels)
- eicon_log(ccard, 1, "idi_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
- dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
- }
- if (dCh == ccard->nchannels) { /* Management */
- chan->fsm_state = 2;
- eicon_log(ccard, 8, "idi_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
- dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
- } else if (dCh >= 0) {
- /* any other channel */
- /* card reports error: we hangup */
- idi_hangup(ccard, chan);
- cmd.driver = ccard->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan->No;
- ccard->interface.statcallb(&cmd);
- }
- }
- if (chan) {
- chan->e.ref = 0;
- chan->e.busy = 0;
- }
- dev_kfree_skb(skb);
-}
-
-int
-idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que, int chk)
-{
- struct sk_buff *xmit_skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan_ptr *chan2;
- int len, plen = 0, offset = 0;
-
- if ((!card) || (!chan)) {
- eicon_log(card, 1, "idi_err: Ch??: null card/chan in send_data\n");
- return -1;
- }
-
- if (chan->fsm_state != EICON_STATE_ACTIVE) {
- eicon_log(card, 1, "idi_snd: Ch%d: send bytes on state %d !\n", chan->No, chan->fsm_state);
- return -ENODEV;
- }
-
- len = skb->len;
- if (len > EICON_MAX_QUEUE) /* too much for the shared memory */
- return -1;
- if (!len)
- return 0;
-
- if ((chk) && (chan->pqueued > 1))
- return 0;
-
- eicon_log(card, 128, "idi_snd: Ch%d: %d bytes (Pqueue=%d)\n",
- chan->No, len, chan->pqueued);
- while(offset < len) {
-
- plen = ((len - offset) > 270) ? 270 : len - offset;
-
- xmit_skb = alloc_skb(plen + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!xmit_skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No);
- if (xmit_skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(xmit_skb, plen + sizeof(eicon_REQ));
- if ((len - offset) > 270) {
- reqbuf->Req = N_MDATA;
- } else {
- reqbuf->Req = N_DATA;
- /* if (ack) reqbuf->Req |= N_D_BIT; */
- }
- reqbuf->ReqCh = chan->e.IndCh;
- reqbuf->ReqId = 1;
- memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
- reqbuf->XBuffer.length = plen;
- reqbuf->Reference = 1; /* Net Entity */
-
- skb_queue_tail(&chan->e.X, xmit_skb);
- skb_queue_tail(&card->sndq, skb2);
-
- offset += plen;
- }
- if (que) {
- chan->queued += len;
- chan->pqueued++;
- }
- eicon_tx_request(card);
- dev_kfree_skb(skb);
- return len;
-}
-
-
-static int
-eicon_idi_manage_assign(eicon_card *card)
-{
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
-
- chan = &(card->bch[card->nchannels]);
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err: alloc_skb failed in manage_assign()\n");
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
-
- reqbuf->XBuffer.P[0] = 0;
- reqbuf->Req = ASSIGN;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = MAN_ID;
- reqbuf->XBuffer.length = 1;
- reqbuf->Reference = 2; /* Man Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
- eicon_tx_request(card);
- return(0);
-}
-
-int
-eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
-{
- int l = 0;
- int ret = 0;
- int timeout;
- int i;
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_REQ *reqbuf;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
-
- chan = &(card->bch[card->nchannels]);
-
- if (!(chan->e.D3Id)) {
- chan->e.D3Id = 1;
- skb_queue_purge(&chan->e.X);
- chan->e.busy = 0;
-
- if ((ret = eicon_idi_manage_assign(card))) {
- chan->e.D3Id = 0;
- return(ret);
- }
-
- timeout = jiffies + 50;
- while (time_before(jiffies, timeout)) {
- if (chan->e.B2Id) break;
- SLEEP(10);
- }
- if (!chan->e.B2Id) {
- chan->e.D3Id = 0;
- return -EIO;
- }
- }
-
- chan->fsm_state = 0;
-
- if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) {
- eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n");
- return -ENOMEM;
- }
- if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) {
- kfree(manbuf);
- return -EFAULT;
- }
-
- skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC);
- skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC);
-
- if ((!skb) || (!skb2)) {
- eicon_log(card, 1, "idi_err_manif: alloc_skb failed in manage()\n");
- if (skb)
- dev_kfree_skb(skb);
- if (skb2)
- dev_kfree_skb(skb2);
- kfree(manbuf);
- return -ENOMEM;
- }
-
- chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr));
- chan2->ptr = chan;
-
- reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ));
-
- reqbuf->XBuffer.P[l++] = ESC;
- reqbuf->XBuffer.P[l++] = 6;
- reqbuf->XBuffer.P[l++] = 0x80;
- for (i = 0; i < manbuf->length[0]; i++)
- reqbuf->XBuffer.P[l++] = manbuf->data[i];
- reqbuf->XBuffer.P[1] = manbuf->length[0] + 1;
-
- reqbuf->XBuffer.P[l++] = 0;
- reqbuf->Req = (manbuf->count) ? manbuf->count : MAN_READ;
- reqbuf->ReqCh = 0;
- reqbuf->ReqId = 1;
- reqbuf->XBuffer.length = l;
- reqbuf->Reference = 2; /* Man Entity */
-
- skb_queue_tail(&chan->e.X, skb);
- skb_queue_tail(&card->sndq, skb2);
-
- manbuf->count = 0;
- manbuf->pos = 0;
-
- eicon_tx_request(card);
-
- timeout = jiffies + 50;
- while (time_before(jiffies, timeout)) {
- if (chan->fsm_state) break;
- SLEEP(10);
- }
- if ((!chan->fsm_state) || (chan->fsm_state == 2)) {
- kfree(manbuf);
- return -EIO;
- }
- if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) {
- kfree(manbuf);
- return -EFAULT;
- }
-
- kfree(manbuf);
- return(0);
-}
diff --git a/drivers/isdn/hardware/eicon/i4l_idi.h b/drivers/isdn/hardware/eicon/i4l_idi.h
deleted file mode 100644
index 196888e87dbb..000000000000
--- a/drivers/isdn/hardware/eicon/i4l_idi.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/* $Id: i4l_idi.h,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
- *
- * ISDN interface module for Eicon active cards.
- * I4L - IDI Interface
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999-2002 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#ifndef E_IDI_H
-#define E_IDI_H
-
-#include <linux/config.h>
-
-#undef N_DATA
-#undef ID_MASK
-
-#include "pc.h"
-
-#define AOC_IND 26 /* Advice of Charge */
-#define PI 0x1e /* Progress Indicator */
-#define NI 0x27 /* Notification Indicator */
-
-/* defines for statectrl */
-#define WAITING_FOR_HANGUP 0x01
-#define HAVE_CONN_REQ 0x02
-#define IN_HOLD 0x04
-
-typedef struct {
- char cpn[32];
- char oad[32];
- char dsa[32];
- char osa[32];
- __u8 plan;
- __u8 screen;
- __u8 sin[4];
- __u8 chi[4];
- __u8 e_chi[4];
- __u8 bc[12];
- __u8 e_bc[12];
- __u8 llc[18];
- __u8 hlc[5];
- __u8 cau[4];
- __u8 e_cau[2];
- __u8 e_mt;
- __u8 dt[6];
- char display[83];
- char keypad[35];
- char rdn[32];
-} idi_ind_message;
-
-typedef struct {
- __u16 next __attribute__ ((packed));
- __u8 Req __attribute__ ((packed));
- __u8 ReqId __attribute__ ((packed));
- __u8 ReqCh __attribute__ ((packed));
- __u8 Reserved1 __attribute__ ((packed));
- __u16 Reference __attribute__ ((packed));
- __u8 Reserved[8] __attribute__ ((packed));
- eicon_PBUFFER XBuffer;
-} eicon_REQ;
-
-typedef struct {
- __u16 next __attribute__ ((packed));
- __u8 Rc __attribute__ ((packed));
- __u8 RcId __attribute__ ((packed));
- __u8 RcCh __attribute__ ((packed));
- __u8 Reserved1 __attribute__ ((packed));
- __u16 Reference __attribute__ ((packed));
- __u8 Reserved2[8] __attribute__ ((packed));
-} eicon_RC;
-
-typedef struct {
- __u16 next __attribute__ ((packed));
- __u8 Ind __attribute__ ((packed));
- __u8 IndId __attribute__ ((packed));
- __u8 IndCh __attribute__ ((packed));
- __u8 MInd __attribute__ ((packed));
- __u16 MLength __attribute__ ((packed));
- __u16 Reference __attribute__ ((packed));
- __u8 RNR __attribute__ ((packed));
- __u8 Reserved __attribute__ ((packed));
- __u32 Ack __attribute__ ((packed));
- eicon_PBUFFER RBuffer;
-} eicon_IND;
-
-typedef struct {
- __u8 *Data;
- unsigned int Size;
- unsigned int Len;
- __u8 *Next;
-} eicon_OBJBUFFER;
-
-extern int idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer);
-extern int idi_hangup(eicon_card *card, eicon_chan *chan);
-extern int idi_connect_res(eicon_card *card, eicon_chan *chan);
-extern int eicon_idi_listen_req(eicon_card *card, eicon_chan *chan);
-extern int idi_connect_req(eicon_card *card, eicon_chan *chan, char *phone,
- char *eazmsn, int si1, int si2);
-
-extern void idi_handle_ack(eicon_card *card, struct sk_buff *skb);
-extern void idi_handle_ind(eicon_card *card, struct sk_buff *skb);
-extern int eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb);
-extern int idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb, int que, int chk);
-extern void idi_audio_cmd(eicon_card *ccard, eicon_chan *chan, int cmd, u_char *value);
-extern int capipmsg(eicon_card *card, eicon_chan *chan, capi_msg *cm);
-#ifdef CONFIG_ISDN_TTY_FAX
-extern void idi_fax_cmd(eicon_card *card, eicon_chan *chan);
-extern int idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb);
-#endif
-
-#include "dsp_defs.h"
-
-#define DSP_UDATA_REQUEST_SWITCH_FRAMER 1
-/*
-parameters:
- <byte> transmit framer type
- <byte> receive framer type
-*/
-
-#define DSP_REQUEST_SWITCH_FRAMER_HDLC 0
-#define DSP_REQUEST_SWITCH_FRAMER_TRANSPARENT 1
-#define DSP_REQUEST_SWITCH_FRAMER_ASYNC 2
-
-
-#define DSP_UDATA_REQUEST_CLEARDOWN 2
-/*
-parameters:
- - none -
-*/
-
-
-#define DSP_UDATA_REQUEST_TX_CONFIRMATION_ON 3
-/*
-parameters:
- - none -
-*/
-
-
-#define DSP_UDATA_REQUEST_TX_CONFIRMATION_OFF 4
-/*
-parameters:
- - none -
-*/
-
-typedef struct eicon_dsp_ind {
- __u16 time __attribute__ ((packed));
- __u8 norm __attribute__ ((packed));
- __u16 options __attribute__ ((packed));
- __u32 speed __attribute__ ((packed));
- __u16 delay __attribute__ ((packed));
- __u32 txspeed __attribute__ ((packed));
- __u32 rxspeed __attribute__ ((packed));
-} eicon_dsp_ind;
-
-#define DSP_CONNECTED_OPTION_V42_TRANS 0x0002
-#define DSP_CONNECTED_OPTION_V42_LAPM 0x0004
-#define DSP_CONNECTED_OPTION_SHORT_TRAIN 0x0008
-#define DSP_CONNECTED_OPTION_TALKER_ECHO_PROTECT 0x0010
-
-#define DSP_UDATA_INDICATION_DISCONNECT 5
-/*
-returns:
- <byte> cause
-*/
-
-#define DSP_DISCONNECT_CAUSE_NONE 0x00
-#define DSP_DISCONNECT_CAUSE_BUSY_TONE 0x01
-#define DSP_DISCONNECT_CAUSE_CONGESTION_TONE 0x02
-#define DSP_DISCONNECT_CAUSE_INCOMPATIBILITY 0x03
-#define DSP_DISCONNECT_CAUSE_CLEARDOWN 0x04
-#define DSP_DISCONNECT_CAUSE_TRAINING_TIMEOUT 0x05
-
-#define DSP_UDATA_INDICATION_TX_CONFIRMATION 6
-/*
-returns:
- <word> confirmation number
-*/
-
-
-#define DSP_UDATA_REQUEST_SEND_DTMF_DIGITS 16
-/*
-parameters:
- <word> tone duration (ms)
- <word> gap duration (ms)
- <byte> digit 0 tone code
- ...
- <byte> digit n tone code
-*/
-
-#define DSP_SEND_DTMF_DIGITS_HEADER_LENGTH 5
-
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_697_HZ 0x00
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_770_HZ 0x01
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_852_HZ 0x02
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_941_HZ 0x03
-#define DSP_DTMF_DIGIT_TONE_LOW_GROUP_MASK 0x03
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1209_HZ 0x00
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1336_HZ 0x04
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1477_HZ 0x08
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_1633_HZ 0x0c
-#define DSP_DTMF_DIGIT_TONE_HIGH_GROUP_MASK 0x0c
-
-#define DSP_DTMF_DIGIT_TONE_CODE_0 0x07
-#define DSP_DTMF_DIGIT_TONE_CODE_1 0x00
-#define DSP_DTMF_DIGIT_TONE_CODE_2 0x04
-#define DSP_DTMF_DIGIT_TONE_CODE_3 0x08
-#define DSP_DTMF_DIGIT_TONE_CODE_4 0x01
-#define DSP_DTMF_DIGIT_TONE_CODE_5 0x05
-#define DSP_DTMF_DIGIT_TONE_CODE_6 0x09
-#define DSP_DTMF_DIGIT_TONE_CODE_7 0x02
-#define DSP_DTMF_DIGIT_TONE_CODE_8 0x06
-#define DSP_DTMF_DIGIT_TONE_CODE_9 0x0a
-#define DSP_DTMF_DIGIT_TONE_CODE_STAR 0x03
-#define DSP_DTMF_DIGIT_TONE_CODE_HASHMARK 0x0b
-#define DSP_DTMF_DIGIT_TONE_CODE_A 0x0c
-#define DSP_DTMF_DIGIT_TONE_CODE_B 0x0d
-#define DSP_DTMF_DIGIT_TONE_CODE_C 0x0e
-#define DSP_DTMF_DIGIT_TONE_CODE_D 0x0f
-
-
-#define DSP_UDATA_INDICATION_DTMF_DIGITS_SENT 16
-/*
-returns:
- - none -
- One indication will be sent for every request.
-*/
-
-
-#define DSP_UDATA_REQUEST_ENABLE_DTMF_RECEIVER 17
-/*
-parameters:
- <word> tone duration (ms)
- <word> gap duration (ms)
-*/
-typedef struct enable_dtmf_s {
- __u16 tone;
- __u16 gap;
-} enable_dtmf_s;
-
-#define DSP_UDATA_REQUEST_DISABLE_DTMF_RECEIVER 18
-/*
-parameters:
- - none -
-*/
-
-#define DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED 17
-/*
-returns:
- <byte> digit 0 tone code
- ...
- <byte> digit n tone code
-*/
-
-#define DSP_DTMF_DIGITS_RECEIVED_HEADER_LENGTH 1
-
-
-#define DSP_UDATA_INDICATION_MODEM_CALLING_TONE 18
-/*
-returns:
- - none -
-*/
-
-#define DSP_UDATA_INDICATION_FAX_CALLING_TONE 19
-/*
-returns:
- - none -
-*/
-
-#define DSP_UDATA_INDICATION_ANSWER_TONE 20
-/*
-returns:
- - none -
-*/
-
-/* ============= FAX ================ */
-
-#define EICON_FAXID_LEN 20
-
-typedef struct eicon_t30_s {
- __u8 code;
- __u8 rate;
- __u8 resolution;
- __u8 format;
- __u8 pages_low;
- __u8 pages_high;
- __u8 atf;
- __u8 control_bits_low;
- __u8 control_bits_high;
- __u8 feature_bits_low;
- __u8 feature_bits_high;
- __u8 universal_5;
- __u8 universal_6;
- __u8 universal_7;
- __u8 station_id_len;
- __u8 head_line_len;
- __u8 station_id[EICON_FAXID_LEN];
-/* __u8 head_line[]; */
-} eicon_t30_s;
-
- /* EDATA transmit messages */
-#define EDATA_T30_DIS 0x01
-#define EDATA_T30_FTT 0x02
-#define EDATA_T30_MCF 0x03
-
- /* EDATA receive messages */
-#define EDATA_T30_DCS 0x81
-#define EDATA_T30_TRAIN_OK 0x82
-#define EDATA_T30_EOP 0x83
-#define EDATA_T30_MPS 0x84
-#define EDATA_T30_EOM 0x85
-#define EDATA_T30_DTC 0x86
-
-#define T30_FORMAT_SFF 0
-#define T30_FORMAT_ASCII 1
-#define T30_FORMAT_COUNT 2
-
-#define T30_CONTROL_BIT_DISABLE_FINE 0x0001
-#define T30_CONTROL_BIT_ENABLE_ECM 0x0002
-#define T30_CONTROL_BIT_ECM_64_BYTES 0x0004
-#define T30_CONTROL_BIT_ENABLE_2D_CODING 0x0008
-#define T30_CONTROL_BIT_ENABLE_T6_CODING 0x0010
-#define T30_CONTROL_BIT_ENABLE_UNCOMPR 0x0020
-#define T30_CONTROL_BIT_ACCEPT_POLLING 0x0040
-#define T30_CONTROL_BIT_REQUEST_POLLING 0x0080
-#define T30_CONTROL_BIT_MORE_DOCUMENTS 0x0100
-
-#define T30_CONTROL_BIT_ALL_FEATURES\
- (T30_CONTROL_BIT_ENABLE_ECM | T30_CONTROL_BIT_ENABLE_2D_CODING |\
- T30_CONTROL_BIT_ENABLE_T6_CODING | T30_CONTROL_BIT_ENABLE_UNCOMPR)
-
-#define T30_FEATURE_BIT_FINE 0x0001
-#define T30_FEATURE_BIT_ECM 0x0002
-#define T30_FEATURE_BIT_ECM_64_BYTES 0x0004
-#define T30_FEATURE_BIT_2D_CODING 0x0008
-#define T30_FEATURE_BIT_T6_CODING 0x0010
-#define T30_FEATURE_BIT_UNCOMPR_ENABLED 0x0020
-#define T30_FEATURE_BIT_POLLING 0x0040
-
-#define FAX_OBJECT_DOCU 1
-#define FAX_OBJECT_PAGE 2
-#define FAX_OBJECT_LINE 3
-
-#define T4_EOL 0x800
-#define T4_EOL_BITSIZE 12
-#define T4_EOL_DWORD (T4_EOL << (32 - T4_EOL_BITSIZE))
-#define T4_EOL_MASK_DWORD ((__u32) -1 << (32 - T4_EOL_BITSIZE))
-
-#define SFF_LEN_FLD_SIZE 3
-
-#define _DLE_ 0x10
-#define _ETX_ 0x03
-
-typedef struct eicon_sff_dochead {
- __u32 id __attribute__ ((packed));
- __u8 version __attribute__ ((packed));
- __u8 reserved1 __attribute__ ((packed));
- __u16 userinfo __attribute__ ((packed));
- __u16 pagecount __attribute__ ((packed));
- __u16 off1pagehead __attribute__ ((packed));
- __u32 offnpagehead __attribute__ ((packed));
- __u32 offdocend __attribute__ ((packed));
-} eicon_sff_dochead;
-
-typedef struct eicon_sff_pagehead {
- __u8 pageheadid __attribute__ ((packed));
- __u8 pageheadlen __attribute__ ((packed));
- __u8 resvert __attribute__ ((packed));
- __u8 reshoriz __attribute__ ((packed));
- __u8 coding __attribute__ ((packed));
- __u8 reserved2 __attribute__ ((packed));
- __u16 linelength __attribute__ ((packed));
- __u16 pagelength __attribute__ ((packed));
- __u32 offprevpage __attribute__ ((packed));
- __u32 offnextpage __attribute__ ((packed));
-} eicon_sff_pagehead;
-
-#endif /* E_IDI_H */
diff --git a/drivers/isdn/hardware/eicon/i4lididrv.c b/drivers/isdn/hardware/eicon/i4lididrv.c
deleted file mode 100644
index 5eda595b7f2f..000000000000
--- a/drivers/isdn/hardware/eicon/i4lididrv.c
+++ /dev/null
@@ -1,1418 +0,0 @@
-/* $Id: i4lididrv.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
- *
- * ISDN interface module for Eicon active cards.
- * I4L - IDI Interface
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999-2002 Cytronics & Melware (info@melware.de)
- *
- * Thanks to Deutsche Mailbox Saar-Lor-Lux GmbH
- * for sponsoring and testing fax
- * capabilities with Diva Server cards.
- * (dor@deutschemailbox.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/vmalloc.h>
-
-#include "i4lididrv.h"
-#include <linux/smp_lock.h>
-#include "divasync.h"
-
-#include "../avmb1/capicmd.h" /* this should be moved in a common place */
-
-#define INCLUDE_INLINE_FUNCS
-
-static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains
- start of card-list */
-
-static char *DRIVERNAME = "Eicon Diva - native I4L Interface driver (http://www.melware.net)";
-static char *DRIVERLNAME = "diva2i4l";
-static char *DRIVERRELEASE = "2.0";
-static char *eicon_revision = "$Revision: 1.1.2.2 $";
-extern char *eicon_idi_revision;
-
-#define EICON_CTRL_VERSION 2
-
-ulong DebugVar;
-
-static spinlock_t status_lock;
-static spinlock_t ll_lock;
-
-#define MAX_DESCRIPTORS 32
-extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
-
-static dword notify_handle;
-static DESCRIPTOR DAdapter;
-static DESCRIPTOR MAdapter;
-
-/* Parameter to be set by insmod */
-static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-static int debug = 1;
-
-MODULE_DESCRIPTION( "ISDN4Linux Interface for Eicon active card driver");
-MODULE_AUTHOR( "Armin Schindler");
-MODULE_SUPPORTED_DEVICE( "ISDN subsystem and Eicon active card driver");
-MODULE_PARM_DESC(id, "ID-String for ISDN4Linux");
-MODULE_PARM(id, "s");
-MODULE_PARM_DESC(debug, "Initial debug value");
-MODULE_PARM(debug, "i");
-MODULE_LICENSE("GPL");
-
-void no_printf (unsigned char * x ,...)
-{
- /* dummy debug function */
-}
-DIVA_DI_PRINTF dprintf = no_printf;
-
-#define DBG_MINIMUM (DL_LOG + DL_FTL + DL_ERR)
-#define DBG_DEFAULT (DBG_MINIMUM + DL_XLOG + DL_REG)
-#include "debuglib.c"
-
-static char *
-eicon_getrev(const char *revision)
-{
- char *rev;
- char *p;
- if ((p = strchr(revision, ':'))) {
- rev = p + 2;
- p = strchr(rev, '$');
- *--p = 0;
- } else rev = "1.0";
- return rev;
-
-}
-
-static void
-stop_dbg(void)
-{
- DbgDeregister();
- memset(&MAdapter, 0, sizeof(MAdapter));
- dprintf = no_printf;
-}
-
-static eicon_chan *
-find_channel(eicon_card *card, int channel)
-{
- if ((channel >= 0) && (channel < card->nchannels))
- return &(card->bch[channel]);
- eicon_log(card, 1, "%s: Invalid channel %d\n", DRIVERLNAME, channel);
- return NULL;
-}
-
-static void
-eicon_rx_request(struct eicon_card *card)
-{
- struct sk_buff *skb, *skb2, *skb_new;
- eicon_IND *ind, *ind2, *ind_new;
- eicon_chan *chan;
-
- if (!card) {
- eicon_log(card, 1, "%s: NULL card in rcv_dispatch !\n", DRIVERLNAME);
- return;
- }
-
- while((skb = skb_dequeue(&card->rcvq))) {
- ind = (eicon_IND *)skb->data;
-
- if ((chan = card->IdTable[ind->IndId]) == NULL) {
- if (DebugVar & 1) {
- switch(ind->Ind) {
- case N_DISC_ACK:
- /* doesn't matter if this happens */
- break;
- default:
- eicon_log(card, 1, "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId);
- eicon_log(card, 1, "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
- ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
- }
- }
- dev_kfree_skb(skb);
- continue;
- }
-
- if (chan->e.complete) { /* check for rec-buffer chaining */
- if (ind->MLength == ind->RBuffer.length) {
- chan->e.complete = 1;
- idi_handle_ind(card, skb);
- continue;
- }
- else {
- chan->e.complete = 0;
- ind->Ind = ind->MInd;
- skb_queue_tail(&chan->e.R, skb);
- continue;
- }
- }
- else {
- if (!(skb2 = skb_dequeue(&chan->e.R))) {
- chan->e.complete = 1;
- eicon_log(card, 1, "%s: buffer incomplete, but 0 in queue\n", DRIVERLNAME);
- dev_kfree_skb(skb);
- continue;
- }
- ind2 = (eicon_IND *)skb2->data;
- skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length),
- GFP_ATOMIC);
- if (!skb_new) {
- eicon_log(card, 1, "%s: skb_alloc failed in rcv_dispatch()\n", DRIVERLNAME);
- dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
- continue;
- }
- ind_new = (eicon_IND *)skb_put(skb_new,
- ((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length));
- ind_new->Ind = ind2->Ind;
- ind_new->IndId = ind2->IndId;
- ind_new->IndCh = ind2->IndCh;
- ind_new->MInd = ind2->MInd;
- ind_new->MLength = ind2->MLength;
- ind_new->RBuffer.length = ind2->RBuffer.length + ind->RBuffer.length;
- memcpy(&ind_new->RBuffer.P, &ind2->RBuffer.P, ind2->RBuffer.length);
- memcpy((&ind_new->RBuffer.P)+ind2->RBuffer.length, &ind->RBuffer.P, ind->RBuffer.length);
- dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
- if (ind->MLength == ind->RBuffer.length) {
- chan->e.complete = 2;
- idi_handle_ind(card, skb_new);
- continue;
- }
- else {
- chan->e.complete = 0;
- skb_queue_tail(&chan->e.R, skb_new);
- continue;
- }
- }
- }
-}
-
-static void
-eicon_ack_request(struct eicon_card *card)
-{
- struct sk_buff *skb;
-
- if (!card) {
- eicon_log(card, 1, "%s: NULL card in ack_dispatch!\n", DRIVERLNAME);
- return;
- }
- while((skb = skb_dequeue(&card->rackq))) {
- idi_handle_ack(card, skb);
- }
-}
-
-/*
- * IDI-Callback function
- */
-static void
-eicon_idi_callback(ENTITY *de)
-{
- eicon_card *ccard = (eicon_card *)de->R;
- struct sk_buff *skb;
- eicon_RC *ack;
- eicon_IND *ind;
- int len = 0;
-
- if (de->complete == 255) {
- /* Return Code */
- skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "%s: skb_alloc failed in _idi_callback()\n", DRIVERLNAME);
- } else {
- ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
- ack->Rc = de->Rc;
- if (de->Rc == ASSIGN_OK) {
- ack->RcId = de->Id;
- de->user[1] = de->Id;
- } else {
- ack->RcId = de->user[1];
- }
- ack->RcCh = de->RcCh;
- ack->Reference = de->user[0];
- skb_queue_tail(&ccard->rackq, skb);
- eicon_ack_request(ccard);
- eicon_log(ccard, 128, "idi_cbk: Ch%d: Rc=%x Id=%x RLen=%x compl=%x\n",
- de->user[0], de->Rc, ack->RcId, de->RLength, de->complete);
- DBG_TRC(("idi_cbk: Ch%d: Rc=%x Id=%x RLen=%x compl=%x",
- de->user[0], de->Rc, ack->RcId, de->RLength, de->complete))
- de->Rc = 0;
- }
- } else {
- /* Indication */
- if (de->complete) {
- len = de->RLength;
- } else {
- len = 270;
- if (de->RLength <= 270)
- eicon_log(ccard, 1, "idi_cbk: ind not complete but <= 270\n");
- }
- skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
- if (!skb) {
- eicon_log(ccard, 1, "%s: skb_alloc failed in _idi_callback()\n", DRIVERLNAME);
- } else {
- ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
- ind->Ind = de->Ind;
- ind->IndId = de->user[1];
- ind->IndCh = de->IndCh;
- ind->MInd = de->Ind;
- ind->RBuffer.length = len;
- ind->MLength = de->RLength;
- memcpy(&ind->RBuffer.P, &de->RBuffer->P, len);
- skb_queue_tail(&ccard->rcvq, skb);
- eicon_rx_request(ccard);
- eicon_log(ccard, 128, "idi_cbk: Ch%d: Ind=%x Id=%x RLen=%x compl=%x\n",
- de->user[0], de->Ind, ind->IndId, de->RLength, de->complete);
- DBG_TRC(("idi_cbk: Ch%d: Ind=%x Id=%x RLen=%x compl=%x",
- de->user[0], de->Ind, ind->IndId, de->RLength, de->complete))
- de->Ind = 0;
- }
- }
- de->RNum = 0;
- de->RNR = 0;
- eicon_tx_request(ccard);
-}
-
-/*
-** Kernel thread to prevent in_interrupt
-*/
-static DECLARE_TASK_QUEUE(tq_divad);
-static struct semaphore diva_thread_sem;
-static struct semaphore diva_thread_end;
-static int divad_pid = -1;
-static int divad_thread(void * data);
-static void diva_tx(void *data);
-static atomic_t thread_running;
-
-static void __init
-diva_init_thread(void)
-{
- int pid = 0;
-
- pid = kernel_thread(divad_thread, NULL, CLONE_KERNEL);
- if (pid >= 0) {
- divad_pid = pid;
- }
-}
-
-static int
-divad_thread(void * data)
-{
- atomic_inc(&thread_running);
- if (atomic_read(&thread_running) > 1) {
- printk(KERN_WARNING"%s: thread already running\n", DRIVERLNAME);
- return(0);
- }
-
- printk(KERN_INFO "%s: thread started with pid %d\n", DRIVERLNAME, current->pid);
- exit_mm(current);
- exit_files(current);
- exit_fs(current);
-
- /* Set to RealTime */
- current->policy = SCHED_FIFO;
- current->rt_priority = 33;
-
- strcpy(current->comm, "kdiva2i4ld");
-
- for(;;) {
- down_interruptible(&diva_thread_sem);
- if(!(atomic_read(&thread_running)))
- break;
- if(signal_pending(current)) {
- flush_signals(current);
- } else {
- run_task_queue(&tq_divad);
- }
- }
- up(&diva_thread_end);
- divad_pid = -1;
- return 0;
-}
-
-static void
-stop_diva_thread(void)
-{
- if (divad_pid >= 0) {
- atomic_set(&thread_running, 0);
- up(&diva_thread_sem);
- down_interruptible(&diva_thread_end);
- }
-}
-
-void
-eicon_tx_request(struct eicon_card *card)
-{
- card->tq.routine = diva_tx;
- card->tq.data = (void *)card;
- queue_task(&card->tq, &tq_divad);
- up(&diva_thread_sem);
-}
-
-static void
-diva_tx(void *data)
-{
- struct eicon_card *card = (eicon_card *) data;
- struct sk_buff *skb;
- struct sk_buff *skb2;
- eicon_chan *chan;
- eicon_chan_ptr *chan2;
- eicon_REQ *reqbuf = 0;
- int ReqCount = 0;
- int tmpid = 0;
- int quloop = 1;
- int dlev = 0;
- ENTITY *ep = 0;
-
- if (!card) {
- eicon_log(card, 1, "%s: NULL card in transmit !\n", DRIVERLNAME);
- return;
- }
-
- ReqCount = 0;
- if (!(skb2 = skb_dequeue(&card->sndq)))
- quloop = 0;
- while(quloop) {
- chan2 = (eicon_chan_ptr *)skb2->data;
- chan = chan2->ptr;
- if (!chan->e.busy) {
- if((skb = skb_dequeue(&chan->e.X))) {
-
- reqbuf = (eicon_REQ *)skb->data;
- if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
- eicon_log(card, 16, "%s: transmit: error Id=0 on %d (Net)\n", DRIVERLNAME, chan->No);
- } else {
- dlev = 160;
- if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
-
- if (!reqbuf->Reference) { /* Signal Layer */
- ep = &chan->de;
- tmpid = chan->e.D3Id;
- chan->e.ReqCh = 0;
- }
- else { /* Net Layer */
- ep = &chan->be;
- tmpid = chan->e.B2Id;
- chan->e.ReqCh = 1;
- if (((reqbuf->Req & 0x0f) == 0x08) ||
- ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */
- chan->waitq = reqbuf->XBuffer.length;
- chan->waitpq += reqbuf->XBuffer.length;
- dlev = 128;
- }
- }
-
- } else { /* It is an ASSIGN */
- if (!reqbuf->Reference)
- ep = &chan->de;
- else
- ep = &chan->be;
- ep->Id = reqbuf->ReqId;
- tmpid = reqbuf->ReqId;
-
- if (!reqbuf->Reference)
- chan->e.ReqCh = 0;
- else
- chan->e.ReqCh = 1;
- }
-
- chan->e.ref = chan->No;
- chan->e.Req = reqbuf->Req;
- ReqCount++;
- if (ep) {
- ep->callback = eicon_idi_callback;
- ep->R = (BUFFERS *)card;
- ep->user[0] = (word)chan->No;
- ep->user[1] = (word)tmpid;
- ep->XNum = 1;
- ep->RNum = 0;
- ep->RNR = 0;
- ep->Rc = 0;
- ep->Ind = 0;
- ep->X->PLength = reqbuf->XBuffer.length;
- memcpy(ep->X->P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
- ep->ReqCh = reqbuf->ReqCh;
- ep->Req = reqbuf->Req;
- }
- chan->e.busy = 1;
- eicon_log(card, dlev, "idi: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n",
- reqbuf->Req, tmpid,
- reqbuf->ReqCh, reqbuf->XBuffer.length,
- chan->e.ref);
- if (ep) {
- card->d.request(ep);
- if (ep->Rc)
- eicon_idi_callback(ep);
- }
- }
- dev_kfree_skb(skb);
- }
- dev_kfree_skb(skb2);
- }
- else {
- skb_queue_tail(&card->sackq, skb2);
- eicon_log(card, 128, "%s: transmit: busy chan %d\n", DRIVERLNAME, chan->No);
- }
- if (!(skb2 = skb_dequeue(&card->sndq)))
- quloop = 0;
- }
- while((skb = skb_dequeue(&card->sackq))) {
- skb_queue_tail(&card->sndq, skb);
- }
-}
-
-static int
-eicon_command(eicon_card * card, isdn_ctrl * c)
-{
- ulong a;
- eicon_chan *chan;
- isdn_ctrl cmd;
- int ret = 0;
-
- eicon_log(card, 16, "%s_cmd 0x%x with arg 0x%lx (0x%lx)\n", DRIVERLNAME,
- c->command, c->arg, (ulong) *c->parm.num);
-
- switch (c->command) {
- case ISDN_CMD_IOCTL:
- memcpy(&a, c->parm.num, sizeof(ulong));
- switch (c->arg) {
- case EICON_IOCTL_GETVER:
- return(EICON_CTRL_VERSION);
- case EICON_IOCTL_MANIF:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!card->d.features & DI_MANAGE)
- return -ENODEV;
- ret = eicon_idi_manage(
- card,
- (eicon_manifbuf *)a);
- return ret;
-
- case EICON_IOCTL_GETXLOG:
- return -ENODEV;
- case EICON_IOCTL_DEBUGVAR:
- DebugVar = a;
- eicon_log(card, 1, "%s: Debug Value set to %ld\n", DRIVERLNAME, DebugVar);
- return 0;
- case EICON_IOCTL_LOADPCI:
- eicon_log(card, 1, "%s: Wrong version of load-utility,\n", DRIVERLNAME);
- eicon_log(card, 1, "%s: re-compile eiconctrl !\n", DRIVERLNAME);
- eicon_log(card, 1, "%s: Maybe update of utility is necessary !\n", DRIVERLNAME);
- return -EINVAL;
- default:
- return -EINVAL;
- }
- break;
- case ISDN_CMD_DIAL:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) {
- eicon_log(card, 1, "%s: Dial on channel %d with state %d\n", DRIVERLNAME,
- chan->No, chan->fsm_state);
- return -EBUSY;
- }
- chan->fsm_state = EICON_STATE_OCALL;
-
- ret = idi_connect_req(card, chan, c->parm.setup.phone,
- c->parm.setup.eazmsn,
- c->parm.setup.si1,
- c->parm.setup.si2);
- if (ret) {
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg &= 0x1f;
- card->interface.statcallb(&cmd);
- }
- return ret;
- case ISDN_CMD_ACCEPTD:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if (chan->fsm_state == EICON_STATE_ICALL) {
- idi_connect_res(card, chan);
- }
- return 0;
- case ISDN_CMD_ACCEPTB:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- return 0;
- case ISDN_CMD_HANGUP:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- idi_hangup(card, chan);
- return 0;
- case ISDN_CMD_SETEAZ:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->eazmask = 0x3ff;
- eicon_idi_listen_req(card, chan);
- return 0;
- case ISDN_CMD_CLREAZ:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->eazmask = 0;
- eicon_idi_listen_req(card, chan);
- return 0;
- case ISDN_CMD_SETL2:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->l2prot = (c->arg >> 8);
- memcpy(chan->a_para, c->parm.aux.para, sizeof(chan->a_para));
- return 0;
- case ISDN_CMD_SETL3:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- chan->l3prot = (c->arg >> 8);
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l3prot == ISDN_PROTO_L3_FCLASS2) {
- chan->fax = c->parm.fax;
- eicon_log(card, 128, "idi_cmd: Ch%d: SETL3 struct fax=0x%x\n",chan->No, chan->fax);
- }
-#endif
- return 0;
-#ifdef CONFIG_ISDN_TTY_FAX
- case ISDN_CMD_FAXCMD:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if (!chan->fax)
- break;
- idi_fax_cmd(card, chan);
- return 0;
-#endif
- case ISDN_CMD_AUDIO:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);
- return 0;
- case CAPI_PUT_MESSAGE:
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x1f)))
- break;
- if (c->parm.cmsg.Length < 8)
- break;
- switch(c->parm.cmsg.Command) {
- case CAPI_FACILITY:
- if (c->parm.cmsg.Subcommand == CAPI_REQ)
- return(capipmsg(card, chan, &c->parm.cmsg));
- break;
- case CAPI_MANUFACTURER:
- default:
- break;
- }
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int
-find_free_number(void)
-{
- int num = 0;
- char cid[40];
- eicon_card *p;
- ulong flags;
-
- spin_lock_irqsave(&ll_lock, flags);
- while(num < 100) {
- sprintf(cid, "%s%d", id, num);
- num++;
- p = cards;
- while (p) {
- if (!strcmp(p->regname, cid))
- break;
- p = p->next;
- }
- if (p)
- {
- spin_unlock_irqrestore(&ll_lock, flags);
- return(num - 1);
- }
- }
- spin_unlock_irqrestore(&ll_lock, flags);
- return(999);
-}
-
-/*
- * Find card with given driverId
- */
-static inline eicon_card *
-eicon_findcard(int driverid)
-{
- eicon_card *p;
- ulong flags;
-
- spin_lock_irqsave(&ll_lock, flags);
- p = cards;
- while (p) {
- if (p->myid == driverid) {
- spin_unlock_irqrestore(&ll_lock, flags);
- return p;
- }
- p = p->next;
- }
- spin_unlock_irqrestore(&ll_lock, flags);
- return (eicon_card *) 0;
-}
-
-/*
- * Wrapper functions for interface to linklevel
- */
-static int
-if_command(isdn_ctrl * c)
-{
- eicon_card *card = eicon_findcard(c->driver);
-
- if (card)
- return (eicon_command(card, c));
- printk(KERN_ERR
- "%s: if_command %d called with invalid driverId %d!\n", DRIVERLNAME,
- c->command, c->driver);
- return -ENODEV;
-}
-
-static int
-if_writecmd(const u_char * buf, int len, int user, int id, int channel)
-{
- /* Not used */
- return (len);
-}
-
-static int
-if_readstatus(u_char * buf, int len, int user, int id, int channel)
-{
- int count = 0;
- int cnt = 0;
- u_char *p = buf;
- struct sk_buff *skb;
- ulong flags;
-
- eicon_card *card = eicon_findcard(id);
-
- if (card) {
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
-
- spin_lock_irqsave(&status_lock, flags);
- while((skb = skb_dequeue(&card->statq))) {
-
- if ((skb->len + count) > len)
- cnt = len - count;
- else
- cnt = skb->len;
-
- if (user)
- copy_to_user(p, skb->data, cnt);
- else
- memcpy(p, skb->data, cnt);
-
- count += cnt;
- p += cnt;
-
- if (cnt == skb->len) {
- dev_kfree_skb(skb);
- if (card->statq_entries > 0)
- card->statq_entries--;
- } else {
- skb_pull(skb, cnt);
- skb_queue_head(&card->statq, skb);
- spin_unlock_irqrestore(&status_lock, flags);
- return count;
- }
- }
- card->statq_entries = 0;
- spin_unlock_irqrestore(&status_lock, flags);
- return count;
- }
- printk(KERN_ERR
- "%s: if_readstatus called with invalid driverId!\n", DRIVERLNAME);
- return 0;
-}
-
-static int
-if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
-{
- eicon_card *card = eicon_findcard(id);
- eicon_chan *chan;
- int ret = 0;
- int len;
-
- len = skb->len;
-
- if (card) {
- if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
- if (!(chan = find_channel(card, channel)))
- return -ENODEV;
-
- if (chan->fsm_state == EICON_STATE_ACTIVE) {
-#ifdef CONFIG_ISDN_TTY_FAX
- if (chan->l2prot == ISDN_PROTO_L2_FAX) {
- if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
- ret = len;
- }
- else
-#endif
- ret = idi_send_data(card, chan, ack, skb, 1, 1);
- return (ret);
- } else {
- return -ENODEV;
- }
- }
- printk(KERN_ERR
- "%s: if_sendbuf called with invalid driverId!\n", DRIVERLNAME);
- return -ENODEV;
-}
-
-/* jiftime() copied from HiSax */
-static inline int jiftime(char *s, long mark)
-{
- s += 8;
-
- *s-- = '\0';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = '.';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 6 + '0';
- mark /= 6;
- *s-- = ':';
- *s-- = mark % 10 + '0';
- mark /= 10;
- *s-- = mark % 10 + '0';
- return(8);
-}
-
-void
-eicon_putstatus(eicon_card * card, char * buf)
-{
- int count;
- isdn_ctrl cmd;
- u_char *p;
- struct sk_buff *skb;
- ulong flags;
-
- if (!card) {
- if (!(card = cards))
- return;
- }
-
- spin_lock_irqsave(&status_lock, flags);
- count = strlen(buf);
- skb = alloc_skb(count, GFP_ATOMIC);
- if (!skb) {
- spin_unlock_irqrestore(&status_lock, flags);
- printk(KERN_ERR "%s: could not alloc skb in putstatus\n", DRIVERLNAME);
- return;
- }
- p = skb_put(skb, count);
- memcpy(p, buf, count);
-
- skb_queue_tail(&card->statq, skb);
-
- if (card->statq_entries >= MAX_STATUS_BUFFER) {
- if ((skb = skb_dequeue(&card->statq))) {
- count -= skb->len;
- dev_kfree_skb(skb);
- } else
- count = 0;
- } else
- card->statq_entries++;
-
- spin_unlock_irqrestore(&status_lock, flags);
- if (count) {
- cmd.command = ISDN_STAT_STAVAIL;
- cmd.driver = card->myid;
- cmd.arg = count;
- card->interface.statcallb(&cmd);
- }
-}
-
-/*
- * Debug and Log
- */
-void
-eicon_log(eicon_card * card, int level, const char *fmt, ...)
-{
- va_list args;
- char Line[160];
- u_char *p;
-
-
- if ((DebugVar & level) || (DebugVar & 256)) {
- va_start(args, fmt);
-
- if (DebugVar & level) {
- if (DebugVar & 256) {
- /* log-buffer */
- p = Line;
- p += jiftime(p, jiffies);
- *p++ = 32;
- p += vsprintf(p, fmt, args);
- *p = 0;
- eicon_putstatus(card, Line);
- } else {
- /* printk, syslogd */
- vsprintf(Line, fmt, args);
- printk(KERN_DEBUG "%s", Line);
- }
- }
-
- va_end(args);
- }
-}
-
-
-/*
- * Allocate a new card-struct, initialize it
- * link it into cards-list.
- */
-static void
-eicon_alloccard(DESCRIPTOR *d)
-{
- int j;
- char cid[40];
- eicon_card *card;
- ulong flags;
-
- sprintf(cid, "%s%d", id, find_free_number());
- if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {
- eicon_log(card, 1,
- "%s: (%s) Could not allocate card-struct.\n", DRIVERLNAME, cid);
- return;
- }
- memset((char *) card, 0, sizeof(eicon_card));
- skb_queue_head_init(&card->sndq);
- skb_queue_head_init(&card->rcvq);
- skb_queue_head_init(&card->rackq);
- skb_queue_head_init(&card->sackq);
- skb_queue_head_init(&card->statq);
- card->statq_entries = 0;
- card->interface.owner = THIS_MODULE;
- 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_L2_TRANS |
- ISDN_FEATURE_L3_TRANS |
- ISDN_FEATURE_L3_TRANSDSP |
- ISDN_FEATURE_P_UNKNOWN;
- card->interface.hl_hdrlen = 20;
- card->ptype = ISDN_PTYPE_UNKNOWN;
- strcpy(card->interface.id, cid);
- card->myid = -1;
- card->type = d->type;
-
- if (d->features & (DI_FAX3 | DI_EXTD_FAX))
- card->interface.features |= (ISDN_FEATURE_L2_FAX | ISDN_FEATURE_L3_FCLASS2);
- if (d->features & DI_MODEM)
- card->interface.features |= ISDN_FEATURE_L2_MODEM;
- if (d->features & DI_V110)
- card->interface.features |= (ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038);
-
- card->flags = 0;
- card->nchannels = d->channels;
- card->interface.channels = d->channels;
- if (!(card->bch = (eicon_chan *) vmalloc(sizeof(eicon_chan) * (card->nchannels + 1)))) {
- eicon_log(card, 1,
- "%s: (%s) Could not allocate bch-struct.\n", DRIVERLNAME, cid);
- kfree(card);
- return;
- }
- for (j=0; j< (card->nchannels + 1); j++) {
- memset((char *)&card->bch[j], 0, sizeof(eicon_chan));
- card->bch[j].statectrl = 0;
- card->bch[j].l2prot = ISDN_PROTO_L2_X75I;
- card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;
- card->bch[j].e.D3Id = 0;
- card->bch[j].e.B2Id = 0;
- card->bch[j].e.Req = 0;
- card->bch[j].No = j;
- card->bch[j].tskb1 = NULL;
- card->bch[j].tskb2 = NULL;
- skb_queue_head_init(&card->bch[j].e.X);
- skb_queue_head_init(&card->bch[j].e.R);
- }
-
- if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2
- , GFP_KERNEL))) {
- eicon_log(card, 1,
- "%s: (%s) Could not allocate DBUFFER-struct.\n", DRIVERLNAME, cid);
- kfree(card);
- vfree(card->bch);
- return;
- }
- if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
- eicon_log(card, 1,
- "%s: (%s) Could not allocate BUFFERS-struct.\n", DRIVERLNAME, cid);
- kfree(card);
- vfree(card->bch);
- kfree(card->dbuf);
- return;
- }
- if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
- eicon_log(card, 1,
- "%s: (%s) Could not allocate BUFFERSP-struct.\n", DRIVERLNAME, cid);
- kfree(card);
- vfree(card->bch);
- kfree(card->dbuf);
- kfree(card->sbuf);
- return;
- }
- for (j=0; j< (card->nchannels + 1); j++) {
- memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER));
- card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j];
- memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
- card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)];
-
- memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS));
- card->bch[j].de.X = (BUFFERS *)&card->sbuf[j];
- memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
- card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)];
-
- memset((char *)&card->sbufp[j], 0, 270);
- card->bch[j].de.X->P = (char *)&card->sbufp[j * 270];
- memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270);
- card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270];
- }
- memcpy(&card->d, d, sizeof(*d)); /* DESCRIPTOR entries */
-
- /* initializing some variables */
- card->lock = SPIN_LOCK_UNLOCKED;
- card->ReadyInt = 0;
-
- for(j = 0; j < 256; j++)
- card->IdTable[j] = NULL;
-
- for(j = 0; j < (card->d.channels + 1); j++) {
- card->bch[j].e.busy = 0;
- card->bch[j].e.D3Id = 0;
- card->bch[j].e.B2Id = 0;
- card->bch[j].e.ref = 0;
- card->bch[j].e.Req = 0;
- card->bch[j].e.complete = 1;
- card->bch[j].fsm_state = EICON_STATE_NULL;
- }
- printk(KERN_INFO "%s: registered card '%s' with %d channels\n",
- DRIVERLNAME, cid, d->channels);
-
- spin_lock_irqsave(&ll_lock, flags);
- card->next = cards;
- cards = card;
- spin_unlock_irqrestore(&ll_lock, flags);
-}
-
-/*
- * register card at linklevel
- */
-static int
-eicon_registercard(eicon_card * card)
-{
- isdn_ctrl cmd;
-
- if (!register_isdn(&card->interface)) {
- printk(KERN_WARNING
- "%s: Unable to register %s\n", DRIVERLNAME,
- card->interface.id);
- return -1;
- }
- card->myid = card->interface.channels;
- sprintf(card->regname, "%s", card->interface.id);
-
- /* after register we start it */
- card->flags |= EICON_FLAGS_LOADED;
- card->flags |= EICON_FLAGS_RUNNING;
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- card->interface.statcallb(&cmd);
-
- return 0;
-}
-
-static void
-unregister_card(eicon_card * card, int rme)
-{
- int count;
- int channel;
- isdn_ctrl cmd;
- eicon_chan *chan;
-
- if(rme) {
- /* before unload we need to remove the signal entity */
- for(channel = 0; channel < card->nchannels; channel++)
- {
- chan = &(card->bch[channel]);
- if (chan->e.D3Id) {
- idi_do_req(card, chan, REMOVE, 0);
- count = 100;
- while(count--) {
- if (!chan->e.D3Id)
- break;
- SLEEP(2);
- }
- if (!count)
- printk(KERN_WARNING"%s: ch:%d unlink to diva module not successful !\n",
- DRIVERLNAME, chan->No);
- }
- }
- }
-
- cmd.command = ISDN_STAT_UNLOAD;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- DBG_TRC(("channel entities freed"));
-}
-
-static void
-eicon_freecard(eicon_card *card) {
- int i;
-
- for(i = 0; i < (card->nchannels + 1); i++) {
- skb_queue_purge(&card->bch[i].e.X);
- skb_queue_purge(&card->bch[i].e.R);
- }
- skb_queue_purge(&card->sndq);
- skb_queue_purge(&card->rcvq);
- skb_queue_purge(&card->rackq);
- skb_queue_purge(&card->sackq);
- skb_queue_purge(&card->statq);
-
- kfree(card->sbufp);
- kfree(card->sbuf);
- kfree(card->dbuf);
- vfree(card->bch);
- kfree(card);
- DBG_TRC(("card structures freed"));
-}
-
-static int
-eicon_addcard(DESCRIPTOR *d)
-{
- eicon_card *p;
- eicon_card *q = NULL;
- int registered;
- int added = 0;
- int failed = 0;
- ulong flags;
-
- eicon_alloccard(d);
- p = cards;
- while (p) {
- registered = 0;
- if (!p->interface.statcallb) {
- /* Not yet registered.
- * Try to register and activate it.
- */
- added++;
- if (!eicon_registercard(p))
- registered = 1;
- } else {
- /* Card already registered */
- registered = 1;
- }
-
- if (registered) {
- /* Init OK, next card ... */
- spin_lock_irqsave(&ll_lock, flags);
- q = p;
- p = p->next;
- spin_unlock_irqrestore(&ll_lock, flags);
- } else {
- /* registering failed, remove card from list, free memory */
- printk(KERN_ERR
- "%s: Initialization of %s failed\n", DRIVERLNAME,
- p->interface.id);
- spin_lock_irqsave(&ll_lock, flags);
- if (q) {
- q->next = p->next;
- eicon_freecard(p);
- p = q->next;
- } else {
- cards = p->next;
- eicon_freecard(p);
- p = cards;
- }
- spin_unlock_irqrestore(&ll_lock, flags);
- failed++;
- }
- }
- return (added - failed);
-}
-
-static void *
-didd_callback(void *context, DESCRIPTOR* adapter, int removal)
-{
- eicon_card *cp = NULL, *lastcp = NULL;
- ulong flags;
-
- if (adapter->type == IDI_DADAPTER)
- {
- printk(KERN_ERR "%s: Change in DAdapter ? Oops ?.\n", DRIVERLNAME);
- DBG_ERR(("Notification about IDI_DADAPTER change ! Oops."));
- return(NULL);
- }
- else if (adapter->type == IDI_DIMAINT)
- {
- if (removal)
- {
- stop_dbg();
- }
- else
- {
- memcpy(&MAdapter, adapter, sizeof(MAdapter));
- dprintf = (DIVA_DI_PRINTF)MAdapter.request;
- DbgRegister("I4L", DRIVERRELEASE, DBG_DEFAULT);
- }
- }
- else if ((adapter->type > 0) &&
- (adapter->type < 16))
- { /* IDI Adapter */
- if (removal)
- {
- spin_lock_irqsave(&ll_lock, flags);
- lastcp = cp = cards;
- while (cp) {
- if (cp->d.request == adapter->request)
- {
- spin_unlock_irqrestore(&ll_lock, flags);
- DBG_LOG(("remove adapter from list"));
- unregister_card(cp, 0);
- spin_lock_irqsave(&ll_lock, flags);
- if (cp == lastcp)
- cards = cp->next;
- else
- lastcp->next = cp->next;
- eicon_freecard(cp);
- break;
- }
- lastcp = cp;
- cp = cp->next;
- }
- spin_unlock_irqrestore(&ll_lock, flags);
- }
- else
- {
- if (adapter->channels) {
- DBG_LOG(("add adapter to list"));
- eicon_addcard(adapter);
- }
- }
- }
- return(NULL);
-}
-
-static int __init
-connect_didd(void)
-{
- int x = 0;
- int dadapter = 0;
- IDI_SYNC_REQ req;
- DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS];
-
- DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table));
-
- for (x = 0; x < MAX_DESCRIPTORS; x++)
- {
- if (DIDD_Table[x].type == IDI_DADAPTER)
- { /* DADAPTER found */
- dadapter = 1;
- memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter));
- req.didd_notify.e.Req = 0;
- req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY;
- req.didd_notify.info.callback = didd_callback;
- req.didd_notify.info.context = 0;
- DAdapter.request((ENTITY *)&req);
- if (req.didd_notify.e.Rc != 0xff)
- {
- stop_dbg();
- return(0);
- }
- notify_handle = req.didd_notify.info.handle;
- }
- else if (DIDD_Table[x].type == IDI_DIMAINT)
- { /* MAINT found */
- memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter));
- dprintf = (DIVA_DI_PRINTF)MAdapter.request;
- DbgRegister("I4L", DRIVERRELEASE, DBG_DEFAULT);
- }
- else if ((DIDD_Table[x].type > 0) &&
- (DIDD_Table[x].type < 16))
- { /* IDI Adapter found */
- if (DIDD_Table[x].channels) {
- eicon_addcard(&DIDD_Table[x]);
- }
- }
- }
-
- if (!dadapter) {
- stop_dbg();
- }
-
- return(dadapter);
-}
-
-static void __exit
-disconnect_didd(void)
-{
- IDI_SYNC_REQ req;
-
- stop_dbg();
-
- req.didd_notify.e.Req = 0;
- req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY;
- req.didd_notify.info.handle = notify_handle;
- DAdapter.request((ENTITY *)&req);
-}
-
-/*
-** proc entry
-*/
-extern struct proc_dir_entry *proc_net_isdn_eicon;
-static struct proc_dir_entry *i4lidi_proc_entry = NULL;
-
-static int
-i4lidi_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-{
- int len = 0;
- char tmprev[32];
-
- len += sprintf(page+len, "%s\n", DRIVERNAME);
- len += sprintf(page+len, "name : %s\n", DRIVERLNAME);
- len += sprintf(page+len, "release : %s\n", DRIVERRELEASE);
- strcpy(tmprev, eicon_revision);
- len += sprintf(page+len, "revision : %s/", eicon_getrev(tmprev));
- strcpy(tmprev, eicon_idi_revision);
- len += sprintf(page+len, "%s\n", eicon_getrev(tmprev));
-
- if (off + count >= len)
- *eof = 1;
- if (len < off)
- return 0;
- *start = page + off;
- return((count < len-off) ? count : len-off);
-}
-
-static void __init
-create_proc(void)
-{
- if(!(i4lidi_proc_entry = create_proc_entry(DRIVERLNAME,
- S_IFREG | S_IRUGO | S_IWUSR, proc_net_isdn_eicon)))
- {
- printk(KERN_WARNING "%s: failed to create proc entry.\n", DRIVERLNAME);
- return;
- }
- i4lidi_proc_entry->read_proc = i4lidi_proc_read;
- i4lidi_proc_entry->owner = THIS_MODULE;
-}
-
-static void __exit
-remove_proc(void)
-{
- if(i4lidi_proc_entry)
- remove_proc_entry(DRIVERLNAME, proc_net_isdn_eicon);
-}
-
-/*
-** load / unload
-*/
-static int __init
-i4l_idi_init(void)
-{
- int ret = 0;
- char tmprev[50];
-
- status_lock = SPIN_LOCK_UNLOCKED;
- ll_lock = SPIN_LOCK_UNLOCKED;
-
- if (strlen(id) < 1)
- strcpy(id, "diva");
-
- DebugVar = debug;
-
- init_MUTEX_LOCKED(&diva_thread_sem);
- init_MUTEX_LOCKED(&diva_thread_end);
-
- printk(KERN_INFO "%s\n", DRIVERNAME);
- printk(KERN_INFO "%s: Rel:%s Rev:",DRIVERLNAME , DRIVERRELEASE);
- strcpy(tmprev, eicon_revision);
- printk("%s/", eicon_getrev(tmprev));
- strcpy(tmprev, eicon_idi_revision);
- printk("%s\n", eicon_getrev(tmprev));
-
- diva_init_thread();
-
- if(!connect_didd()) {
- printk(KERN_ERR "%s: failed to connect to DIDD.\n", DRIVERLNAME);
- stop_diva_thread();
- ret = -EIO;
- goto out;
- }
- create_proc();
-
-out:
- return(ret);
-}
-
-static void __exit
-i4l_idi_exit(void)
-{
- eicon_card *card, *last, *cc;
- ulong flags;
-
- spin_lock_irqsave(&ll_lock, flags);
- cc = cards;
- card = cc;
- cards = NULL;
- spin_unlock_irqrestore(&ll_lock, flags);
-
- remove_proc();
-
- while (card) {
- unregister_card(card, 1);
- card = card->next;
- }
-
- stop_diva_thread();
- disconnect_didd();
-
- card = cc;
- while (card) {
- last = card;
- card = card->next;
- eicon_freecard(last);
- }
- printk(KERN_INFO "%s: module unloaded.\n", DRIVERLNAME);
-}
-
-module_init(i4l_idi_init);
-module_exit(i4l_idi_exit);
diff --git a/drivers/isdn/hardware/eicon/i4lididrv.h b/drivers/isdn/hardware/eicon/i4lididrv.h
deleted file mode 100644
index bb4692082ab6..000000000000
--- a/drivers/isdn/hardware/eicon/i4lididrv.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/* $Id: i4lididrv.h,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
- *
- * ISDN interface module for Eicon active cards.
- * I4L - IDI Interface
- *
- * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
- * Copyright 1999-2002 Cytronics & Melware (info@melware.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-
-#ifndef i4lididrv_h
-#define i4lididrv_h
-
-#include <linux/isdn.h>
-#include <linux/isdnif.h>
-
-#include "platform.h"
-#include "di_defs.h"
-
-#define EICON_IOCTL_GETTYPE 6
-#define EICON_IOCTL_LOADPCI 7
-#define EICON_IOCTL_GETVER 9
-#define EICON_IOCTL_GETXLOG 10
-
-#define EICON_IOCTL_MANIF 90
-
-#define EICON_IOCTL_FREEIT 97
-#define EICON_IOCTL_TEST 98
-#define EICON_IOCTL_DEBUGVAR 99
-
-/* Constants for describing Card-Type */
-#define EICON_CTYPE_S 0
-#define EICON_CTYPE_SX 1
-#define EICON_CTYPE_SCOM 2
-#define EICON_CTYPE_QUADRO 3
-#define EICON_CTYPE_S2M 4
-#define EICON_CTYPE_MAESTRA 5
-#define EICON_CTYPE_MAESTRAQ 6
-#define EICON_CTYPE_MAESTRAQ_U 7
-#define EICON_CTYPE_MAESTRAP 8
-#define EICON_CTYPE_ISABRI 0x10
-#define EICON_CTYPE_ISAPRI 0x20
-#define EICON_CTYPE_MASK 0x0f
-#define EICON_CTYPE_QUADRO_NR(n) (n<<4)
-
-#define MAX_HEADER_LEN 10
-
-#define MAX_STATUS_BUFFER 150
-
-/* Data for Management interface */
-typedef struct {
- int count;
- int pos;
- int length[50];
- unsigned char data[700];
-} eicon_manifbuf;
-
-#define TRACE_OK (1)
-
-#ifdef __KERNEL__
-
-/* Macro for delay via schedule() */
-#define SLEEP(j) { \
- set_current_state(TASK_INTERRUPTIBLE); \
- schedule_timeout(j); \
-}
-
-/* Kernel includes */
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/skbuff.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-
-typedef struct {
- __u16 length __attribute__ ((packed)); /* length of data/parameter field */
- __u8 P[1]; /* data/parameter field */
-} eicon_PBUFFER;
-
-typedef struct {
- __u16 NextReq __attribute__ ((packed)); /* pointer to next Req Buffer */
- __u16 NextRc __attribute__ ((packed)); /* pointer to next Rc Buffer */
- __u16 NextInd __attribute__ ((packed)); /* pointer to next Ind Buffer */
- __u8 ReqInput __attribute__ ((packed)); /* number of Req Buffers sent */
- __u8 ReqOutput __attribute__ ((packed)); /* number of Req Buffers returned */
- __u8 ReqReserved __attribute__ ((packed));/*number of Req Buffers reserved */
- __u8 Int __attribute__ ((packed)); /* ISDN-P interrupt */
- __u8 XLock __attribute__ ((packed)); /* Lock field for arbitration */
- __u8 RcOutput __attribute__ ((packed)); /* number of Rc buffers received */
- __u8 IndOutput __attribute__ ((packed)); /* number of Ind buffers received */
- __u8 IMask __attribute__ ((packed)); /* Interrupt Mask Flag */
- __u8 Reserved1[2] __attribute__ ((packed)); /* reserved field, do not use */
- __u8 ReadyInt __attribute__ ((packed)); /* request field for ready int */
- __u8 Reserved2[12] __attribute__ ((packed)); /* reserved field, do not use */
- __u8 InterfaceType __attribute__ ((packed)); /* interface type 1=16K */
- __u16 Signature __attribute__ ((packed)); /* ISDN-P initialized ind */
- __u8 B[1]; /* buffer space for Req,Ind and Rc */
-} eicon_pr_ram;
-
-typedef struct {
- __u8 Req; /* pending request */
- __u8 Rc; /* return code received */
- __u8 Ind; /* indication received */
- __u8 ReqCh; /* channel of current Req */
- __u8 RcCh; /* channel of current Rc */
- __u8 IndCh; /* channel of current Ind */
- __u8 D3Id; /* ID used by this entity */
- __u8 B2Id; /* ID used by this entity */
- __u8 GlobalId; /* reserved field */
- __u8 XNum; /* number of X-buffers */
- __u8 RNum; /* number of R-buffers */
- struct sk_buff_head X; /* X-buffer queue */
- struct sk_buff_head R; /* R-buffer queue */
- __u8 RNR; /* receive not ready flag */
- __u8 complete; /* receive complete status */
- __u8 busy; /* busy flag */
- __u16 ref; /* saved reference */
-} entity;
-
-#define FAX_MAX_SCANLINE 2500
-
-typedef struct {
- __u8 PrevObject;
- __u8 NextObject;
- __u8 abLine[FAX_MAX_SCANLINE];
- __u8 abFrame[FAX_MAX_SCANLINE];
- unsigned int LineLen;
- unsigned int LineDataLen;
- __u32 LineData;
- unsigned int NullBytesPos;
- __u8 NullByteExist;
- int PageCount;
- __u8 Dle;
- __u8 Eop;
-} eicon_ch_fax_buf;
-
-typedef struct {
- int No; /* Channel Number */
- unsigned short fsm_state; /* Current D-Channel state */
- unsigned short statectrl; /* State controling bits */
- unsigned short eazmask; /* EAZ-Mask for this Channel */
- int queued; /* User-Data Bytes in TX queue */
- int pqueued; /* User-Data Packets in TX queue */
- int waitq; /* User-Data Bytes in wait queue */
- int waitpq; /* User-Data Bytes in packet queue */
- struct sk_buff *tskb1; /* temp skb 1 */
- struct sk_buff *tskb2; /* temp skb 2 */
- unsigned char l2prot; /* Layer 2 protocol */
- unsigned char l3prot; /* Layer 3 protocol */
-#ifdef CONFIG_ISDN_TTY_FAX
- T30_s *fax; /* pointer to fax data in LL */
- eicon_ch_fax_buf fax2; /* fax related struct */
-#endif
- entity e; /* Native Entity */
- ENTITY de; /* Divas D Entity */
- ENTITY be; /* Divas B Entity */
- char cpn[32]; /* remember cpn */
- char oad[32]; /* remember oad */
- char dsa[32]; /* remember dsa */
- char osa[32]; /* remember osa */
- unsigned char cause[2]; /* Last Cause */
- unsigned char si1;
- unsigned char si2;
- unsigned char plan;
- unsigned char screen;
- unsigned char a_para[8]; /* Additional parameter */
-} eicon_chan;
-
-typedef struct {
- eicon_chan *ptr;
-} eicon_chan_ptr;
-
-
-#define EICON_FLAGS_RUNNING 1 /* Cards driver activated */
-#define EICON_FLAGS_LOADED 8 /* Firmware loaded */
-
-/* D-Channel states */
-#define EICON_STATE_NULL 0
-#define EICON_STATE_ICALL 1
-#define EICON_STATE_OCALL 2
-#define EICON_STATE_IWAIT 3
-#define EICON_STATE_OWAIT 4
-#define EICON_STATE_IBWAIT 5
-#define EICON_STATE_OBWAIT 6
-#define EICON_STATE_BWAIT 7
-#define EICON_STATE_BHWAIT 8
-#define EICON_STATE_BHWAIT2 9
-#define EICON_STATE_DHWAIT 10
-#define EICON_STATE_DHWAIT2 11
-#define EICON_STATE_BSETUP 12
-#define EICON_STATE_ACTIVE 13
-#define EICON_STATE_ICALLW 14
-#define EICON_STATE_LISTEN 15
-#define EICON_STATE_WMCONN 16
-
-#define EICON_MAX_QUEUE 2138
-
-typedef struct {
- __u8 ret;
- __u8 id;
- __u8 ch;
-} eicon_ack;
-
-typedef struct {
- __u8 code;
- __u8 id;
- __u8 ch;
-} eicon_req;
-
-typedef struct {
- __u8 ret;
- __u8 id;
- __u8 ch;
- __u8 more;
-} eicon_indhdr;
-
-/*
- * Per card driver data
- */
-typedef struct eicon_card {
- DESCRIPTOR d; /* IDI Descriptor */
- u_char ptype; /* Protocol type (1TR6 or Euro) */
- u_char type; /* Cardtype (EICON_CTYPE_...) */
- struct eicon_card *qnext; /* Pointer to next quadro adapter */
- int Feature; /* Protocol Feature Value */
- struct eicon_card *next; /* Pointer to next device struct */
- int myid; /* Driver-Nr. assigned by linklevel */
- unsigned long flags; /* Statusflags */
- struct sk_buff_head rcvq; /* Receive-Message queue */
- struct sk_buff_head sndq; /* Send-Message queue */
- struct sk_buff_head rackq; /* Req-Ack-Message queue */
- struct sk_buff_head sackq; /* Data-Ack-Message queue */
- struct sk_buff_head statq; /* Status-Message queue */
- int statq_entries;
- eicon_chan* IdTable[256]; /* Table to find entity */
- __u16 ref_in;
- __u16 ref_out;
- int nchannels; /* Number of B-Channels */
- int ReadyInt; /* Ready Interrupt */
- eicon_chan *bch; /* B-Channel status/control */
- DBUFFER *dbuf; /* Dbuffer for Diva Server */
- BUFFERS *sbuf; /* Buffer for Diva Server */
- char *sbufp; /* Data Buffer for Diva Server */
- isdn_if interface; /* Interface to upper layer */
- char regname[35]; /* Drivers card name */
- spinlock_t lock; /* spin lock per card */
- struct tq_struct tq; /* task queue for thread */
-} eicon_card;
-
-#include "i4l_idi.h"
-
-extern eicon_card *cards;
-extern char *eicon_ctype_name[];
-
-extern ulong DebugVar;
-extern void eicon_log(eicon_card * card, int level, const char *fmt, ...);
-extern void eicon_putstatus(eicon_card * card, char * buf);
-
-extern void eicon_tx_request(struct eicon_card *);
-
-extern spinlock_t eicon_lock;
-
-#endif /* __KERNEL__ */
-
-#endif /* i4lididrv_h */