linux/drivers/isdn/hisax/callc.c
<<
>>
Prefs
   1/* $Id: callc.c,v 2.59.2.4 2004/02/11 13:21:32 keil Exp $
   2 *
   3 * Author       Karsten Keil
   4 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
   5 *
   6 * This software may be used and distributed according to the terms
   7 * of the GNU General Public License, incorporated herein by reference.
   8 *
   9 * For changes and modifications please read
  10 * Documentation/isdn/HiSax.cert
  11 *
  12 * based on the teles driver from Jan den Ouden
  13 *
  14 * Thanks to    Jan den Ouden
  15 *              Fritz Elfert
  16 *
  17 */
  18
  19#include <linux/module.h>
  20#include <linux/slab.h>
  21#include <linux/init.h>
  22#include "hisax.h"
  23#include <linux/isdn/capicmd.h>
  24
  25const char *lli_revision = "$Revision: 2.59.2.4 $";
  26
  27extern struct IsdnCard cards[];
  28
  29static int init_b_st(struct Channel *chanp, int incoming);
  30static void release_b_st(struct Channel *chanp);
  31
  32static struct Fsm callcfsm;
  33static int chancount;
  34
  35/* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */
  36#define ALERT_REJECT 0
  37
  38/* Value to delay the sending of the first B-channel packet after CONNECT
  39 * here is no value given by ITU, but experience shows that 300 ms will
  40 * work on many networks, if you or your other side is behind local exchanges
  41 * a greater value may be recommented. If the delay is to short the first paket
  42 * will be lost and autodetect on many comercial routers goes wrong !
  43 * You can adjust this value on runtime with
  44 * hisaxctrl <id> 2 <value>
  45 * value is in milliseconds
  46 */
  47#define DEFAULT_B_DELAY 300
  48
  49/* Flags for remembering action done in lli */
  50
  51#define  FLG_START_B    0
  52
  53/*
  54 * Find card with given driverId
  55 */
  56static inline struct IsdnCardState *
  57hisax_findcard(int driverid)
  58{
  59        int i;
  60
  61        for (i = 0; i < nrcards; i++)
  62                if (cards[i].cs)
  63                        if (cards[i].cs->myid == driverid)
  64                                return (cards[i].cs);
  65        return (struct IsdnCardState *) 0;
  66}
  67
  68static __printf(3, 4) void
  69        link_debug(struct Channel *chanp, int direction, char *fmt, ...)
  70{
  71        va_list args;
  72        char tmp[16];
  73
  74        va_start(args, fmt);
  75        sprintf(tmp, "Ch%d %s ", chanp->chan,
  76                direction ? "LL->HL" : "HL->LL");
  77        VHiSax_putstatus(chanp->cs, tmp, fmt, args);
  78        va_end(args);
  79}
  80
  81enum {
  82        ST_NULL,                /*  0 inactive */
  83        ST_OUT_DIAL,            /*  1 outgoing, SETUP send; awaiting confirm */
  84        ST_IN_WAIT_LL,          /*  2 incoming call received; wait for LL confirm */
  85        ST_IN_ALERT_SENT,       /*  3 incoming call received; ALERT send */
  86        ST_IN_WAIT_CONN_ACK,    /*  4 incoming CONNECT send; awaiting CONN_ACK */
  87        ST_WAIT_BCONN,          /*  5 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */
  88        ST_ACTIVE,              /*  6 active, b channel prot. established */
  89        ST_WAIT_BRELEASE,       /*  7 call clear. (initiator), awaiting b channel prot. rel. */
  90        ST_WAIT_BREL_DISC,      /*  8 call clear. (receiver), DISCONNECT req. received */
  91        ST_WAIT_DCOMMAND,       /*  9 call clear. (receiver), awaiting DCHANNEL message */
  92        ST_WAIT_DRELEASE,       /* 10 DISCONNECT sent, awaiting RELEASE */
  93        ST_WAIT_D_REL_CNF,      /* 11 RELEASE sent, awaiting RELEASE confirm */
  94        ST_IN_PROCEED_SEND,     /* 12 incoming call, proceeding send */
  95};
  96
  97
  98#define STATE_COUNT (ST_IN_PROCEED_SEND + 1)
  99
 100static char *strState[] =
 101{
 102        "ST_NULL",
 103        "ST_OUT_DIAL",
 104        "ST_IN_WAIT_LL",
 105        "ST_IN_ALERT_SENT",
 106        "ST_IN_WAIT_CONN_ACK",
 107        "ST_WAIT_BCONN",
 108        "ST_ACTIVE",
 109        "ST_WAIT_BRELEASE",
 110        "ST_WAIT_BREL_DISC",
 111        "ST_WAIT_DCOMMAND",
 112        "ST_WAIT_DRELEASE",
 113        "ST_WAIT_D_REL_CNF",
 114        "ST_IN_PROCEED_SEND",
 115};
 116
 117enum {
 118        EV_DIAL,                /*  0 */
 119        EV_SETUP_CNF,           /*  1 */
 120        EV_ACCEPTB,             /*  2 */
 121        EV_DISCONNECT_IND,      /*  3 */
 122        EV_RELEASE,             /*  4 */
 123        EV_LEASED,              /*  5 */
 124        EV_LEASED_REL,          /*  6 */
 125        EV_SETUP_IND,           /*  7 */
 126        EV_ACCEPTD,             /*  8 */
 127        EV_SETUP_CMPL_IND,      /*  9 */
 128        EV_BC_EST,              /* 10 */
 129        EV_WRITEBUF,            /* 11 */
 130        EV_HANGUP,              /* 12 */
 131        EV_BC_REL,              /* 13 */
 132        EV_CINF,                /* 14 */
 133        EV_SUSPEND,             /* 15 */
 134        EV_RESUME,              /* 16 */
 135        EV_NOSETUP_RSP,         /* 17 */
 136        EV_SETUP_ERR,           /* 18 */
 137        EV_CONNECT_ERR,         /* 19 */
 138        EV_PROCEED,             /* 20 */
 139        EV_ALERT,               /* 21 */
 140        EV_REDIR,               /* 22 */
 141};
 142
 143#define EVENT_COUNT (EV_REDIR + 1)
 144
 145static char *strEvent[] =
 146{
 147        "EV_DIAL",
 148        "EV_SETUP_CNF",
 149        "EV_ACCEPTB",
 150        "EV_DISCONNECT_IND",
 151        "EV_RELEASE",
 152        "EV_LEASED",
 153        "EV_LEASED_REL",
 154        "EV_SETUP_IND",
 155        "EV_ACCEPTD",
 156        "EV_SETUP_CMPL_IND",
 157        "EV_BC_EST",
 158        "EV_WRITEBUF",
 159        "EV_HANGUP",
 160        "EV_BC_REL",
 161        "EV_CINF",
 162        "EV_SUSPEND",
 163        "EV_RESUME",
 164        "EV_NOSETUP_RSP",
 165        "EV_SETUP_ERR",
 166        "EV_CONNECT_ERR",
 167        "EV_PROCEED",
 168        "EV_ALERT",
 169        "EV_REDIR",
 170};
 171
 172
 173static inline void
 174HL_LL(struct Channel *chanp, int command)
 175{
 176        isdn_ctrl ic;
 177
 178        ic.driver = chanp->cs->myid;
 179        ic.command = command;
 180        ic.arg = chanp->chan;
 181        chanp->cs->iif.statcallb(&ic);
 182}
 183
 184static inline void
 185lli_deliver_cause(struct Channel *chanp)
 186{
 187        isdn_ctrl ic;
 188
 189        if (!chanp->proc)
 190                return;
 191        if (chanp->proc->para.cause == NO_CAUSE)
 192                return;
 193        ic.driver = chanp->cs->myid;
 194        ic.command = ISDN_STAT_CAUSE;
 195        ic.arg = chanp->chan;
 196        if (chanp->cs->protocol == ISDN_PTYPE_EURO)
 197                sprintf(ic.parm.num, "E%02X%02X", chanp->proc->para.loc & 0x7f,
 198                        chanp->proc->para.cause & 0x7f);
 199        else
 200                sprintf(ic.parm.num, "%02X%02X", chanp->proc->para.loc & 0x7f,
 201                        chanp->proc->para.cause & 0x7f);
 202        chanp->cs->iif.statcallb(&ic);
 203}
 204
 205static inline void
 206lli_close(struct FsmInst *fi)
 207{
 208        struct Channel *chanp = fi->userdata;
 209
 210        FsmChangeState(fi, ST_NULL);
 211        chanp->Flags = 0;
 212        chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 213}
 214
 215static void
 216lli_leased_in(struct FsmInst *fi, int event, void *arg)
 217{
 218        struct Channel *chanp = fi->userdata;
 219        isdn_ctrl ic;
 220        int ret;
 221
 222        if (!chanp->leased)
 223                return;
 224        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
 225        FsmChangeState(fi, ST_IN_WAIT_LL);
 226        if (chanp->debug & 1)
 227                link_debug(chanp, 0, "STAT_ICALL_LEASED");
 228        ic.driver = chanp->cs->myid;
 229        ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW);
 230        ic.arg = chanp->chan;
 231        ic.parm.setup.si1 = 7;
 232        ic.parm.setup.si2 = 0;
 233        ic.parm.setup.plan = 0;
 234        ic.parm.setup.screen = 0;
 235        sprintf(ic.parm.setup.eazmsn, "%d", chanp->chan + 1);
 236        sprintf(ic.parm.setup.phone, "LEASED%d", chanp->cs->myid);
 237        ret = chanp->cs->iif.statcallb(&ic);
 238        if (chanp->debug & 1)
 239                link_debug(chanp, 1, "statcallb ret=%d", ret);
 240        if (!ret) {
 241                chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 242                FsmChangeState(fi, ST_NULL);
 243        }
 244}
 245
 246
 247/*
 248 * Dial out
 249 */
 250static void
 251lli_init_bchan_out(struct FsmInst *fi, int event, void *arg)
 252{
 253        struct Channel *chanp = fi->userdata;
 254
 255        FsmChangeState(fi, ST_WAIT_BCONN);
 256        if (chanp->debug & 1)
 257                link_debug(chanp, 0, "STAT_DCONN");
 258        HL_LL(chanp, ISDN_STAT_DCONN);
 259        init_b_st(chanp, 0);
 260        chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL);
 261}
 262
 263static void
 264lli_prep_dialout(struct FsmInst *fi, int event, void *arg)
 265{
 266        struct Channel *chanp = fi->userdata;
 267
 268        FsmDelTimer(&chanp->drel_timer, 60);
 269        FsmDelTimer(&chanp->dial_timer, 73);
 270        chanp->l2_active_protocol = chanp->l2_protocol;
 271        chanp->incoming = 0;
 272        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
 273        if (chanp->leased) {
 274                lli_init_bchan_out(fi, event, arg);
 275        } else {
 276                FsmChangeState(fi, ST_OUT_DIAL);
 277                chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | REQUEST, chanp);
 278        }
 279}
 280
 281static void
 282lli_resume(struct FsmInst *fi, int event, void *arg)
 283{
 284        struct Channel *chanp = fi->userdata;
 285
 286        FsmDelTimer(&chanp->drel_timer, 60);
 287        FsmDelTimer(&chanp->dial_timer, 73);
 288        chanp->l2_active_protocol = chanp->l2_protocol;
 289        chanp->incoming = 0;
 290        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
 291        if (chanp->leased) {
 292                lli_init_bchan_out(fi, event, arg);
 293        } else {
 294                FsmChangeState(fi, ST_OUT_DIAL);
 295                chanp->d_st->lli.l4l3(chanp->d_st, CC_RESUME | REQUEST, chanp);
 296        }
 297}
 298
 299static void
 300lli_go_active(struct FsmInst *fi, int event, void *arg)
 301{
 302        struct Channel *chanp = fi->userdata;
 303        isdn_ctrl ic;
 304
 305
 306        FsmChangeState(fi, ST_ACTIVE);
 307        chanp->data_open = !0;
 308        if (chanp->bcs->conmsg)
 309                strcpy(ic.parm.num, chanp->bcs->conmsg);
 310        else
 311                ic.parm.num[0] = 0;
 312        if (chanp->debug & 1)
 313                link_debug(chanp, 0, "STAT_BCONN %s", ic.parm.num);
 314        ic.driver = chanp->cs->myid;
 315        ic.command = ISDN_STAT_BCONN;
 316        ic.arg = chanp->chan;
 317        chanp->cs->iif.statcallb(&ic);
 318        chanp->cs->cardmsg(chanp->cs, MDL_INFO_CONN, (void *) (long)chanp->chan);
 319}
 320
 321
 322/*
 323 * RESUME
 324 */
 325
 326/* incoming call */
 327
 328static void
 329lli_deliver_call(struct FsmInst *fi, int event, void *arg)
 330{
 331        struct Channel *chanp = fi->userdata;
 332        isdn_ctrl ic;
 333        int ret;
 334
 335        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
 336        /*
 337         * Report incoming calls only once to linklevel, use CallFlags
 338         * which is set to 3 with each broadcast message in isdnl1.c
 339         * and resetted if a interface  answered the STAT_ICALL.
 340         */
 341        if (1) { /* for only one TEI */
 342                FsmChangeState(fi, ST_IN_WAIT_LL);
 343                if (chanp->debug & 1)
 344                        link_debug(chanp, 0, (chanp->chan < 2) ? "STAT_ICALL" : "STAT_ICALLW");
 345                ic.driver = chanp->cs->myid;
 346                ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW);
 347
 348                ic.arg = chanp->chan;
 349                /*
 350                 * No need to return "unknown" for calls without OAD,
 351                 * cause that's handled in linklevel now (replaced by '0')
 352                 */
 353                memcpy(&ic.parm.setup, &chanp->proc->para.setup, sizeof(setup_parm));
 354                ret = chanp->cs->iif.statcallb(&ic);
 355                if (chanp->debug & 1)
 356                        link_debug(chanp, 1, "statcallb ret=%d", ret);
 357
 358                switch (ret) {
 359                case 1: /* OK, someone likes this call */
 360                        FsmDelTimer(&chanp->drel_timer, 61);
 361                        FsmChangeState(fi, ST_IN_ALERT_SENT);
 362                        chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 363                        break;
 364                case 5: /* direct redirect */
 365                case 4: /* Proceeding desired */
 366                        FsmDelTimer(&chanp->drel_timer, 61);
 367                        FsmChangeState(fi, ST_IN_PROCEED_SEND);
 368                        chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc);
 369                        if (ret == 5) {
 370                                memcpy(&chanp->setup, &ic.parm.setup, sizeof(setup_parm));
 371                                chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);
 372                        }
 373                        break;
 374                case 2: /* Rejecting Call */
 375                        break;
 376                case 3: /* incomplete number */
 377                        FsmDelTimer(&chanp->drel_timer, 61);
 378                        chanp->d_st->lli.l4l3(chanp->d_st, CC_MORE_INFO | REQUEST, chanp->proc);
 379                        break;
 380                case 0: /* OK, nobody likes this call */
 381                default:        /* statcallb problems */
 382                        chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
 383                        chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 384                        FsmChangeState(fi, ST_NULL);
 385                        break;
 386                }
 387        } else {
 388                chanp->d_st->lli.l4l3(chanp->d_st, CC_IGNORE | REQUEST, chanp->proc);
 389                chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 390        }
 391}
 392
 393static void
 394lli_send_dconnect(struct FsmInst *fi, int event, void *arg)
 395{
 396        struct Channel *chanp = fi->userdata;
 397
 398        FsmChangeState(fi, ST_IN_WAIT_CONN_ACK);
 399        chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc);
 400}
 401
 402static void
 403lli_send_alert(struct FsmInst *fi, int event, void *arg)
 404{
 405        struct Channel *chanp = fi->userdata;
 406
 407        FsmChangeState(fi, ST_IN_ALERT_SENT);
 408        chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 409}
 410
 411static void
 412lli_send_redir(struct FsmInst *fi, int event, void *arg)
 413{
 414        struct Channel *chanp = fi->userdata;
 415
 416        chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);
 417}
 418
 419static void
 420lli_init_bchan_in(struct FsmInst *fi, int event, void *arg)
 421{
 422        struct Channel *chanp = fi->userdata;
 423
 424        FsmChangeState(fi, ST_WAIT_BCONN);
 425        if (chanp->debug & 1)
 426                link_debug(chanp, 0, "STAT_DCONN");
 427        HL_LL(chanp, ISDN_STAT_DCONN);
 428        chanp->l2_active_protocol = chanp->l2_protocol;
 429        chanp->incoming = !0;
 430        init_b_st(chanp, !0);
 431        chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL);
 432}
 433
 434static void
 435lli_setup_rsp(struct FsmInst *fi, int event, void *arg)
 436{
 437        struct Channel *chanp = fi->userdata;
 438
 439        if (chanp->leased) {
 440                lli_init_bchan_in(fi, event, arg);
 441        } else {
 442                FsmChangeState(fi, ST_IN_WAIT_CONN_ACK);
 443#ifdef WANT_ALERT
 444                chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 445#endif
 446                chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc);
 447        }
 448}
 449
 450/* Call suspend */
 451
 452static void
 453lli_suspend(struct FsmInst *fi, int event, void *arg)
 454{
 455        struct Channel *chanp = fi->userdata;
 456
 457        chanp->d_st->lli.l4l3(chanp->d_st, CC_SUSPEND | REQUEST, chanp->proc);
 458}
 459
 460/* Call clearing */
 461
 462static void
 463lli_leased_hup(struct FsmInst *fi, struct Channel *chanp)
 464{
 465        isdn_ctrl ic;
 466
 467        ic.driver = chanp->cs->myid;
 468        ic.command = ISDN_STAT_CAUSE;
 469        ic.arg = chanp->chan;
 470        sprintf(ic.parm.num, "L0010");
 471        chanp->cs->iif.statcallb(&ic);
 472        if (chanp->debug & 1)
 473                link_debug(chanp, 0, "STAT_DHUP");
 474        HL_LL(chanp, ISDN_STAT_DHUP);
 475        lli_close(fi);
 476}
 477
 478static void
 479lli_disconnect_req(struct FsmInst *fi, int event, void *arg)
 480{
 481        struct Channel *chanp = fi->userdata;
 482
 483        if (chanp->leased) {
 484                lli_leased_hup(fi, chanp);
 485        } else {
 486                FsmChangeState(fi, ST_WAIT_DRELEASE);
 487                if (chanp->proc)
 488                        chanp->proc->para.cause = 0x10; /* Normal Call Clearing */
 489                chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST,
 490                                      chanp->proc);
 491        }
 492}
 493
 494static void
 495lli_disconnect_reject(struct FsmInst *fi, int event, void *arg)
 496{
 497        struct Channel *chanp = fi->userdata;
 498
 499        if (chanp->leased) {
 500                lli_leased_hup(fi, chanp);
 501        } else {
 502                FsmChangeState(fi, ST_WAIT_DRELEASE);
 503                if (chanp->proc)
 504                        chanp->proc->para.cause = 0x15; /* Call Rejected */
 505                chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST,
 506                                      chanp->proc);
 507        }
 508}
 509
 510static void
 511lli_dhup_close(struct FsmInst *fi, int event, void *arg)
 512{
 513        struct Channel *chanp = fi->userdata;
 514
 515        if (chanp->leased) {
 516                lli_leased_hup(fi, chanp);
 517        } else {
 518                if (chanp->debug & 1)
 519                        link_debug(chanp, 0, "STAT_DHUP");
 520                lli_deliver_cause(chanp);
 521                HL_LL(chanp, ISDN_STAT_DHUP);
 522                lli_close(fi);
 523        }
 524}
 525
 526static void
 527lli_reject_req(struct FsmInst *fi, int event, void *arg)
 528{
 529        struct Channel *chanp = fi->userdata;
 530
 531        if (chanp->leased) {
 532                lli_leased_hup(fi, chanp);
 533                return;
 534        }
 535#ifndef ALERT_REJECT
 536        if (chanp->proc)
 537                chanp->proc->para.cause = 0x15; /* Call Rejected */
 538        chanp->d_st->lli.l4l3(chanp->d_st, CC_REJECT | REQUEST, chanp->proc);
 539        lli_dhup_close(fi, event, arg);
 540#else
 541        FsmRestartTimer(&chanp->drel_timer, 40, EV_HANGUP, NULL, 63);
 542        FsmChangeState(fi, ST_IN_ALERT_SENT);
 543        chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 544#endif
 545}
 546
 547static void
 548lli_disconn_bchan(struct FsmInst *fi, int event, void *arg)
 549{
 550        struct Channel *chanp = fi->userdata;
 551
 552        chanp->data_open = 0;
 553        FsmChangeState(fi, ST_WAIT_BRELEASE);
 554        chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
 555}
 556
 557static void
 558lli_start_disc(struct FsmInst *fi, int event, void *arg)
 559{
 560        struct Channel *chanp = fi->userdata;
 561
 562        if (chanp->leased) {
 563                lli_leased_hup(fi, chanp);
 564        } else {
 565                lli_disconnect_req(fi, event, arg);
 566        }
 567}
 568
 569static void
 570lli_rel_b_disc(struct FsmInst *fi, int event, void *arg)
 571{
 572        struct Channel *chanp = fi->userdata;
 573
 574        release_b_st(chanp);
 575        lli_start_disc(fi, event, arg);
 576}
 577
 578static void
 579lli_bhup_disc(struct FsmInst *fi, int event, void *arg)
 580{
 581        struct Channel *chanp = fi->userdata;
 582
 583        if (chanp->debug & 1)
 584                link_debug(chanp, 0, "STAT_BHUP");
 585        HL_LL(chanp, ISDN_STAT_BHUP);
 586        lli_rel_b_disc(fi, event, arg);
 587}
 588
 589static void
 590lli_bhup_rel_b(struct FsmInst *fi, int event, void *arg)
 591{
 592        struct Channel *chanp = fi->userdata;
 593
 594        FsmChangeState(fi, ST_WAIT_DCOMMAND);
 595        chanp->data_open = 0;
 596        if (chanp->debug & 1)
 597                link_debug(chanp, 0, "STAT_BHUP");
 598        HL_LL(chanp, ISDN_STAT_BHUP);
 599        release_b_st(chanp);
 600}
 601
 602static void
 603lli_release_bchan(struct FsmInst *fi, int event, void *arg)
 604{
 605        struct Channel *chanp = fi->userdata;
 606
 607        chanp->data_open = 0;
 608        FsmChangeState(fi, ST_WAIT_BREL_DISC);
 609        chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
 610}
 611
 612
 613static void
 614lli_rel_b_dhup(struct FsmInst *fi, int event, void *arg)
 615{
 616        struct Channel *chanp = fi->userdata;
 617
 618        release_b_st(chanp);
 619        lli_dhup_close(fi, event, arg);
 620}
 621
 622static void
 623lli_bhup_dhup(struct FsmInst *fi, int event, void *arg)
 624{
 625        struct Channel *chanp = fi->userdata;
 626
 627        if (chanp->debug & 1)
 628                link_debug(chanp, 0, "STAT_BHUP");
 629        HL_LL(chanp, ISDN_STAT_BHUP);
 630        lli_rel_b_dhup(fi, event, arg);
 631}
 632
 633static void
 634lli_abort(struct FsmInst *fi, int event, void *arg)
 635{
 636        struct Channel *chanp = fi->userdata;
 637
 638        chanp->data_open = 0;
 639        chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
 640        lli_bhup_dhup(fi, event, arg);
 641}
 642
 643static void
 644lli_release_req(struct FsmInst *fi, int event, void *arg)
 645{
 646        struct Channel *chanp = fi->userdata;
 647
 648        if (chanp->leased) {
 649                lli_leased_hup(fi, chanp);
 650        } else {
 651                FsmChangeState(fi, ST_WAIT_D_REL_CNF);
 652                chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST,
 653                                      chanp->proc);
 654        }
 655}
 656
 657static void
 658lli_rel_b_release_req(struct FsmInst *fi, int event, void *arg)
 659{
 660        struct Channel *chanp = fi->userdata;
 661
 662        release_b_st(chanp);
 663        lli_release_req(fi, event, arg);
 664}
 665
 666static void
 667lli_bhup_release_req(struct FsmInst *fi, int event, void *arg)
 668{
 669        struct Channel *chanp = fi->userdata;
 670
 671        if (chanp->debug & 1)
 672                link_debug(chanp, 0, "STAT_BHUP");
 673        HL_LL(chanp, ISDN_STAT_BHUP);
 674        lli_rel_b_release_req(fi, event, arg);
 675}
 676
 677
 678/* processing charge info */
 679static void
 680lli_charge_info(struct FsmInst *fi, int event, void *arg)
 681{
 682        struct Channel *chanp = fi->userdata;
 683        isdn_ctrl ic;
 684
 685        ic.driver = chanp->cs->myid;
 686        ic.command = ISDN_STAT_CINF;
 687        ic.arg = chanp->chan;
 688        sprintf(ic.parm.num, "%d", chanp->proc->para.chargeinfo);
 689        chanp->cs->iif.statcallb(&ic);
 690}
 691
 692/* error procedures */
 693
 694static void
 695lli_dchan_not_ready(struct FsmInst *fi, int event, void *arg)
 696{
 697        struct Channel *chanp = fi->userdata;
 698
 699        if (chanp->debug & 1)
 700                link_debug(chanp, 0, "STAT_DHUP");
 701        HL_LL(chanp, ISDN_STAT_DHUP);
 702}
 703
 704static void
 705lli_no_setup_rsp(struct FsmInst *fi, int event, void *arg)
 706{
 707        struct Channel *chanp = fi->userdata;
 708
 709        if (chanp->debug & 1)
 710                link_debug(chanp, 0, "STAT_DHUP");
 711        HL_LL(chanp, ISDN_STAT_DHUP);
 712        lli_close(fi);
 713}
 714
 715static void
 716lli_error(struct FsmInst *fi, int event, void *arg)
 717{
 718        FsmChangeState(fi, ST_WAIT_DRELEASE);
 719}
 720
 721static void
 722lli_failure_l(struct FsmInst *fi, int event, void *arg)
 723{
 724        struct Channel *chanp = fi->userdata;
 725        isdn_ctrl ic;
 726
 727        FsmChangeState(fi, ST_NULL);
 728        ic.driver = chanp->cs->myid;
 729        ic.command = ISDN_STAT_CAUSE;
 730        ic.arg = chanp->chan;
 731        sprintf(ic.parm.num, "L%02X%02X", 0, 0x2f);
 732        chanp->cs->iif.statcallb(&ic);
 733        HL_LL(chanp, ISDN_STAT_DHUP);
 734        chanp->Flags = 0;
 735        chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 736}
 737
 738static void
 739lli_rel_b_fail(struct FsmInst *fi, int event, void *arg)
 740{
 741        struct Channel *chanp = fi->userdata;
 742
 743        release_b_st(chanp);
 744        lli_failure_l(fi, event, arg);
 745}
 746
 747static void
 748lli_bhup_fail(struct FsmInst *fi, int event, void *arg)
 749{
 750        struct Channel *chanp = fi->userdata;
 751
 752        if (chanp->debug & 1)
 753                link_debug(chanp, 0, "STAT_BHUP");
 754        HL_LL(chanp, ISDN_STAT_BHUP);
 755        lli_rel_b_fail(fi, event, arg);
 756}
 757
 758static void
 759lli_failure_a(struct FsmInst *fi, int event, void *arg)
 760{
 761        struct Channel *chanp = fi->userdata;
 762
 763        chanp->data_open = 0;
 764        chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
 765        lli_bhup_fail(fi, event, arg);
 766}
 767
 768/* *INDENT-OFF* */
 769static struct FsmNode fnlist[] __initdata =
 770{
 771        {ST_NULL,               EV_DIAL,                lli_prep_dialout},
 772        {ST_NULL,               EV_RESUME,              lli_resume},
 773        {ST_NULL,               EV_SETUP_IND,           lli_deliver_call},
 774        {ST_NULL,               EV_LEASED,              lli_leased_in},
 775        {ST_OUT_DIAL,           EV_SETUP_CNF,           lli_init_bchan_out},
 776        {ST_OUT_DIAL,           EV_HANGUP,              lli_disconnect_req},
 777        {ST_OUT_DIAL,           EV_DISCONNECT_IND,      lli_release_req},
 778        {ST_OUT_DIAL,           EV_RELEASE,             lli_dhup_close},
 779        {ST_OUT_DIAL,           EV_NOSETUP_RSP,         lli_no_setup_rsp},
 780        {ST_OUT_DIAL,           EV_SETUP_ERR,           lli_error},
 781        {ST_IN_WAIT_LL,         EV_LEASED_REL,          lli_failure_l},
 782        {ST_IN_WAIT_LL,         EV_ACCEPTD,             lli_setup_rsp},
 783        {ST_IN_WAIT_LL,         EV_HANGUP,              lli_reject_req},
 784        {ST_IN_WAIT_LL,         EV_DISCONNECT_IND,      lli_release_req},
 785        {ST_IN_WAIT_LL,         EV_RELEASE,             lli_dhup_close},
 786        {ST_IN_WAIT_LL,         EV_SETUP_IND,           lli_deliver_call},
 787        {ST_IN_WAIT_LL,         EV_SETUP_ERR,           lli_error},
 788        {ST_IN_ALERT_SENT,      EV_SETUP_CMPL_IND,      lli_init_bchan_in},
 789        {ST_IN_ALERT_SENT,      EV_ACCEPTD,             lli_send_dconnect},
 790        {ST_IN_ALERT_SENT,      EV_HANGUP,              lli_disconnect_reject},
 791        {ST_IN_ALERT_SENT,      EV_DISCONNECT_IND,      lli_release_req},
 792        {ST_IN_ALERT_SENT,      EV_RELEASE,             lli_dhup_close},
 793        {ST_IN_ALERT_SENT,      EV_REDIR,               lli_send_redir},
 794        {ST_IN_PROCEED_SEND,    EV_REDIR,               lli_send_redir},
 795        {ST_IN_PROCEED_SEND,    EV_ALERT,               lli_send_alert},
 796        {ST_IN_PROCEED_SEND,    EV_ACCEPTD,             lli_send_dconnect},
 797        {ST_IN_PROCEED_SEND,    EV_HANGUP,              lli_disconnect_reject},
 798        {ST_IN_PROCEED_SEND,    EV_DISCONNECT_IND,      lli_dhup_close},
 799        {ST_IN_ALERT_SENT,      EV_RELEASE,             lli_dhup_close},
 800        {ST_IN_WAIT_CONN_ACK,   EV_SETUP_CMPL_IND,      lli_init_bchan_in},
 801        {ST_IN_WAIT_CONN_ACK,   EV_HANGUP,              lli_disconnect_req},
 802        {ST_IN_WAIT_CONN_ACK,   EV_DISCONNECT_IND,      lli_release_req},
 803        {ST_IN_WAIT_CONN_ACK,   EV_RELEASE,             lli_dhup_close},
 804        {ST_IN_WAIT_CONN_ACK,   EV_CONNECT_ERR,         lli_error},
 805        {ST_WAIT_BCONN,         EV_BC_EST,              lli_go_active},
 806        {ST_WAIT_BCONN,         EV_BC_REL,              lli_rel_b_disc},
 807        {ST_WAIT_BCONN,         EV_HANGUP,              lli_rel_b_disc},
 808        {ST_WAIT_BCONN,         EV_DISCONNECT_IND,      lli_rel_b_release_req},
 809        {ST_WAIT_BCONN,         EV_RELEASE,             lli_rel_b_dhup},
 810        {ST_WAIT_BCONN,         EV_LEASED_REL,          lli_rel_b_fail},
 811        {ST_WAIT_BCONN,         EV_CINF,                lli_charge_info},
 812        {ST_ACTIVE,             EV_CINF,                lli_charge_info},
 813        {ST_ACTIVE,             EV_BC_REL,              lli_bhup_rel_b},
 814        {ST_ACTIVE,             EV_SUSPEND,             lli_suspend},
 815        {ST_ACTIVE,             EV_HANGUP,              lli_disconn_bchan},
 816        {ST_ACTIVE,             EV_DISCONNECT_IND,      lli_release_bchan},
 817        {ST_ACTIVE,             EV_RELEASE,             lli_abort},
 818        {ST_ACTIVE,             EV_LEASED_REL,          lli_failure_a},
 819        {ST_WAIT_BRELEASE,      EV_BC_REL,              lli_bhup_disc},
 820        {ST_WAIT_BRELEASE,      EV_DISCONNECT_IND,      lli_bhup_release_req},
 821        {ST_WAIT_BRELEASE,      EV_RELEASE,             lli_bhup_dhup},
 822        {ST_WAIT_BRELEASE,      EV_LEASED_REL,          lli_bhup_fail},
 823        {ST_WAIT_BREL_DISC,     EV_BC_REL,              lli_bhup_release_req},
 824        {ST_WAIT_BREL_DISC,     EV_RELEASE,             lli_bhup_dhup},
 825        {ST_WAIT_DCOMMAND,      EV_HANGUP,              lli_start_disc},
 826        {ST_WAIT_DCOMMAND,      EV_DISCONNECT_IND,      lli_release_req},
 827        {ST_WAIT_DCOMMAND,      EV_RELEASE,             lli_dhup_close},
 828        {ST_WAIT_DCOMMAND,      EV_LEASED_REL,          lli_failure_l},
 829        {ST_WAIT_DRELEASE,      EV_RELEASE,             lli_dhup_close},
 830        {ST_WAIT_DRELEASE,      EV_DIAL,                lli_dchan_not_ready},
 831        /* ETS 300-104 16.1 */
 832        {ST_WAIT_D_REL_CNF,     EV_RELEASE,             lli_dhup_close},
 833        {ST_WAIT_D_REL_CNF,     EV_DIAL,                lli_dchan_not_ready},
 834};
 835/* *INDENT-ON* */
 836
 837int __init
 838CallcNew(void)
 839{
 840        callcfsm.state_count = STATE_COUNT;
 841        callcfsm.event_count = EVENT_COUNT;
 842        callcfsm.strEvent = strEvent;
 843        callcfsm.strState = strState;
 844        return FsmNew(&callcfsm, fnlist, ARRAY_SIZE(fnlist));
 845}
 846
 847void
 848CallcFree(void)
 849{
 850        FsmFree(&callcfsm);
 851}
 852
 853static void
 854release_b_st(struct Channel *chanp)
 855{
 856        struct PStack *st = chanp->b_st;
 857
 858        if (test_and_clear_bit(FLG_START_B, &chanp->Flags)) {
 859                chanp->bcs->BC_Close(chanp->bcs);
 860                switch (chanp->l2_active_protocol) {
 861                case (ISDN_PROTO_L2_X75I):
 862                        releasestack_isdnl2(st);
 863                        break;
 864                case (ISDN_PROTO_L2_HDLC):
 865                case (ISDN_PROTO_L2_HDLC_56K):
 866                case (ISDN_PROTO_L2_TRANS):
 867                case (ISDN_PROTO_L2_MODEM):
 868                case (ISDN_PROTO_L2_FAX):
 869                        releasestack_transl2(st);
 870                        break;
 871                }
 872        }
 873}
 874
 875static struct Channel
 876*selectfreechannel(struct PStack *st, int bch)
 877{
 878        struct IsdnCardState *cs = st->l1.hardware;
 879        struct Channel *chanp = st->lli.userdata;
 880        int i;
 881
 882        if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags))
 883                i = 1;
 884        else
 885                i = 0;
 886
 887        if (!bch) {
 888                i = 2; /* virtual channel */
 889                chanp += 2;
 890        }
 891
 892        while (i < ((bch) ? cs->chanlimit : (2 + MAX_WAITING_CALLS))) {
 893                if (chanp->fi.state == ST_NULL)
 894                        return (chanp);
 895                chanp++;
 896                i++;
 897        }
 898
 899        if (bch) /* number of channels is limited */ {
 900                i = 2; /* virtual channel */
 901                chanp = st->lli.userdata;
 902                chanp += i;
 903                while (i < (2 + MAX_WAITING_CALLS)) {
 904                        if (chanp->fi.state == ST_NULL)
 905                                return (chanp);
 906                        chanp++;
 907                        i++;
 908                }
 909        }
 910        return (NULL);
 911}
 912
 913static void stat_redir_result(struct IsdnCardState *cs, int chan, ulong result)
 914{       isdn_ctrl ic;
 915
 916        ic.driver = cs->myid;
 917        ic.command = ISDN_STAT_REDIR;
 918        ic.arg = chan;
 919        ic.parm.num[0] = result;
 920        cs->iif.statcallb(&ic);
 921} /* stat_redir_result */
 922
 923static void
 924dchan_l3l4(struct PStack *st, int pr, void *arg)
 925{
 926        struct l3_process *pc = arg;
 927        struct IsdnCardState *cs = st->l1.hardware;
 928        struct Channel *chanp;
 929
 930        if (!pc)
 931                return;
 932
 933        if (pr == (CC_SETUP | INDICATION)) {
 934                if (!(chanp = selectfreechannel(pc->st, pc->para.bchannel))) {
 935                        pc->para.cause = 0x11;  /* User busy */
 936                        pc->st->lli.l4l3(pc->st, CC_REJECT | REQUEST, pc);
 937                } else {
 938                        chanp->proc = pc;
 939                        pc->chan = chanp;
 940                        FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
 941                }
 942                return;
 943        }
 944        if (!(chanp = pc->chan))
 945                return;
 946
 947        switch (pr) {
 948        case (CC_MORE_INFO | INDICATION):
 949                FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
 950                break;
 951        case (CC_DISCONNECT | INDICATION):
 952                FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
 953                break;
 954        case (CC_RELEASE | CONFIRM):
 955                FsmEvent(&chanp->fi, EV_RELEASE, NULL);
 956                break;
 957        case (CC_SUSPEND | CONFIRM):
 958                FsmEvent(&chanp->fi, EV_RELEASE, NULL);
 959                break;
 960        case (CC_RESUME | CONFIRM):
 961                FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
 962                break;
 963        case (CC_RESUME_ERR):
 964                FsmEvent(&chanp->fi, EV_RELEASE, NULL);
 965                break;
 966        case (CC_RELEASE | INDICATION):
 967                FsmEvent(&chanp->fi, EV_RELEASE, NULL);
 968                break;
 969        case (CC_SETUP_COMPL | INDICATION):
 970                FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL);
 971                break;
 972        case (CC_SETUP | CONFIRM):
 973                FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
 974                break;
 975        case (CC_CHARGE | INDICATION):
 976                FsmEvent(&chanp->fi, EV_CINF, NULL);
 977                break;
 978        case (CC_NOSETUP_RSP):
 979                FsmEvent(&chanp->fi, EV_NOSETUP_RSP, NULL);
 980                break;
 981        case (CC_SETUP_ERR):
 982                FsmEvent(&chanp->fi, EV_SETUP_ERR, NULL);
 983                break;
 984        case (CC_CONNECT_ERR):
 985                FsmEvent(&chanp->fi, EV_CONNECT_ERR, NULL);
 986                break;
 987        case (CC_RELEASE_ERR):
 988                FsmEvent(&chanp->fi, EV_RELEASE, NULL);
 989                break;
 990        case (CC_PROCEED_SEND | INDICATION):
 991        case (CC_PROCEEDING | INDICATION):
 992        case (CC_ALERTING | INDICATION):
 993        case (CC_PROGRESS | INDICATION):
 994        case (CC_NOTIFY | INDICATION):
 995                break;
 996        case (CC_REDIR | INDICATION):
 997                stat_redir_result(cs, chanp->chan, pc->redir_result);
 998                break;
 999        default:
1000                if (chanp->debug & 0x800) {
1001                        HiSax_putstatus(chanp->cs, "Ch",
1002                                        "%d L3->L4 unknown primitiv %#x",
1003                                        chanp->chan, pr);
1004                }
1005        }
1006}
1007
1008static void
1009dummy_pstack(struct PStack *st, int pr, void *arg) {
1010        printk(KERN_WARNING"call to dummy_pstack pr=%04x arg %lx\n", pr, (long)arg);
1011}
1012
1013static int
1014init_PStack(struct PStack **stp) {
1015        *stp = kmalloc(sizeof(struct PStack), GFP_ATOMIC);
1016        if (!*stp)
1017                return -ENOMEM;
1018        (*stp)->next = NULL;
1019        (*stp)->l1.l1l2 = dummy_pstack;
1020        (*stp)->l1.l1hw = dummy_pstack;
1021        (*stp)->l1.l1tei = dummy_pstack;
1022        (*stp)->l2.l2tei = dummy_pstack;
1023        (*stp)->l2.l2l1 = dummy_pstack;
1024        (*stp)->l2.l2l3 = dummy_pstack;
1025        (*stp)->l3.l3l2 = dummy_pstack;
1026        (*stp)->l3.l3ml3 = dummy_pstack;
1027        (*stp)->l3.l3l4 = dummy_pstack;
1028        (*stp)->lli.l4l3 = dummy_pstack;
1029        (*stp)->ma.layer = dummy_pstack;
1030        return 0;
1031}
1032
1033static int
1034init_d_st(struct Channel *chanp)
1035{
1036        struct PStack *st;
1037        struct IsdnCardState *cs = chanp->cs;
1038        char tmp[16];
1039        int err;
1040
1041        err = init_PStack(&chanp->d_st);
1042        if (err)
1043                return err;
1044        st = chanp->d_st;
1045        st->next = NULL;
1046        HiSax_addlist(cs, st);
1047        setstack_HiSax(st, cs);
1048        st->l2.sap = 0;
1049        st->l2.tei = -1;
1050        st->l2.flag = 0;
1051        test_and_set_bit(FLG_MOD128, &st->l2.flag);
1052        test_and_set_bit(FLG_LAPD, &st->l2.flag);
1053        test_and_set_bit(FLG_ORIG, &st->l2.flag);
1054        st->l2.maxlen = MAX_DFRAME_LEN;
1055        st->l2.window = 1;
1056        st->l2.T200 = 1000;     /* 1000 milliseconds  */
1057        st->l2.N200 = 3;        /* try 3 times        */
1058        st->l2.T203 = 10000;    /* 10000 milliseconds */
1059        if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags))
1060                sprintf(tmp, "DCh%d Q.921 ", chanp->chan);
1061        else
1062                sprintf(tmp, "DCh Q.921 ");
1063        setstack_isdnl2(st, tmp);
1064        setstack_l3dc(st, chanp);
1065        st->lli.userdata = chanp;
1066        st->l3.l3l4 = dchan_l3l4;
1067
1068        return 0;
1069}
1070
1071static __printf(2, 3) void
1072        callc_debug(struct FsmInst *fi, char *fmt, ...)
1073{
1074        va_list args;
1075        struct Channel *chanp = fi->userdata;
1076        char tmp[16];
1077
1078        va_start(args, fmt);
1079        sprintf(tmp, "Ch%d callc ", chanp->chan);
1080        VHiSax_putstatus(chanp->cs, tmp, fmt, args);
1081        va_end(args);
1082}
1083
1084static int
1085init_chan(int chan, struct IsdnCardState *csta)
1086{
1087        struct Channel *chanp = csta->channel + chan;
1088        int err;
1089
1090        chanp->cs = csta;
1091        chanp->bcs = csta->bcs + chan;
1092        chanp->chan = chan;
1093        chanp->incoming = 0;
1094        chanp->debug = 0;
1095        chanp->Flags = 0;
1096        chanp->leased = 0;
1097        err = init_PStack(&chanp->b_st);
1098        if (err)
1099                return err;
1100        chanp->b_st->l1.delay = DEFAULT_B_DELAY;
1101        chanp->fi.fsm = &callcfsm;
1102        chanp->fi.state = ST_NULL;
1103        chanp->fi.debug = 0;
1104        chanp->fi.userdata = chanp;
1105        chanp->fi.printdebug = callc_debug;
1106        FsmInitTimer(&chanp->fi, &chanp->dial_timer);
1107        FsmInitTimer(&chanp->fi, &chanp->drel_timer);
1108        if (!chan || (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags) && chan < 2)) {
1109                err = init_d_st(chanp);
1110                if (err)
1111                        return err;
1112        } else {
1113                chanp->d_st = csta->channel->d_st;
1114        }
1115        chanp->data_open = 0;
1116        return 0;
1117}
1118
1119int
1120CallcNewChan(struct IsdnCardState *csta) {
1121        int i, err;
1122
1123        chancount += 2;
1124        err = init_chan(0, csta);
1125        if (err)
1126                return err;
1127        err = init_chan(1, csta);
1128        if (err)
1129                return err;
1130        printk(KERN_INFO "HiSax: 2 channels added\n");
1131
1132        for (i = 0; i < MAX_WAITING_CALLS; i++) {
1133                err = init_chan(i + 2, csta);
1134                if (err)
1135                        return err;
1136        }
1137        printk(KERN_INFO "HiSax: MAX_WAITING_CALLS added\n");
1138        if (test_bit(FLG_PTP, &csta->channel->d_st->l2.flag)) {
1139                printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
1140                csta->channel->d_st->lli.l4l3(csta->channel->d_st,
1141                                              DL_ESTABLISH | REQUEST, NULL);
1142        }
1143        return (0);
1144}
1145
1146static void
1147release_d_st(struct Channel *chanp)
1148{
1149        struct PStack *st = chanp->d_st;
1150
1151        if (!st)
1152                return;
1153        releasestack_isdnl2(st);
1154        releasestack_isdnl3(st);
1155        HiSax_rmlist(st->l1.hardware, st);
1156        kfree(st);
1157        chanp->d_st = NULL;
1158}
1159
1160void
1161CallcFreeChan(struct IsdnCardState *csta)
1162{
1163        int i;
1164
1165        for (i = 0; i < 2; i++) {
1166                FsmDelTimer(&csta->channel[i].drel_timer, 74);
1167                FsmDelTimer(&csta->channel[i].dial_timer, 75);
1168                if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags))
1169                        release_d_st(csta->channel + i);
1170                if (csta->channel[i].b_st) {
1171                        release_b_st(csta->channel + i);
1172                        kfree(csta->channel[i].b_st);
1173                        csta->channel[i].b_st = NULL;
1174                } else
1175                        printk(KERN_WARNING "CallcFreeChan b_st ch%d already freed\n", i);
1176                if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {
1177                        release_d_st(csta->channel + i);
1178                } else
1179                        csta->channel[i].d_st = NULL;
1180        }
1181}
1182
1183static void
1184lldata_handler(struct PStack *st, int pr, void *arg)
1185{
1186        struct Channel *chanp = (struct Channel *) st->lli.userdata;
1187        struct sk_buff *skb = arg;
1188
1189        switch (pr) {
1190        case (DL_DATA  | INDICATION):
1191                if (chanp->data_open) {
1192                        if (chanp->debug & 0x800)
1193                                link_debug(chanp, 0, "lldata: %d", skb->len);
1194                        chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb);
1195                } else {
1196                        link_debug(chanp, 0, "lldata: channel not open");
1197                        dev_kfree_skb(skb);
1198                }
1199                break;
1200        case (DL_ESTABLISH | INDICATION):
1201        case (DL_ESTABLISH | CONFIRM):
1202                FsmEvent(&chanp->fi, EV_BC_EST, NULL);
1203                break;
1204        case (DL_RELEASE | INDICATION):
1205        case (DL_RELEASE | CONFIRM):
1206                FsmEvent(&chanp->fi, EV_BC_REL, NULL);
1207                break;
1208        default:
1209                printk(KERN_WARNING "lldata_handler unknown primitive %#x\n",
1210                       pr);
1211                break;
1212        }
1213}
1214
1215static void
1216lltrans_handler(struct PStack *st, int pr, void *arg)
1217{
1218        struct Channel *chanp = (struct Channel *) st->lli.userdata;
1219        struct sk_buff *skb = arg;
1220
1221        switch (pr) {
1222        case (PH_DATA | INDICATION):
1223                if (chanp->data_open) {
1224                        if (chanp->debug & 0x800)
1225                                link_debug(chanp, 0, "lltrans: %d", skb->len);
1226                        chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb);
1227                } else {
1228                        link_debug(chanp, 0, "lltrans: channel not open");
1229                        dev_kfree_skb(skb);
1230                }
1231                break;
1232        case (PH_ACTIVATE | INDICATION):
1233        case (PH_ACTIVATE | CONFIRM):
1234                FsmEvent(&chanp->fi, EV_BC_EST, NULL);
1235                break;
1236        case (PH_DEACTIVATE | INDICATION):
1237        case (PH_DEACTIVATE | CONFIRM):
1238                FsmEvent(&chanp->fi, EV_BC_REL, NULL);
1239                break;
1240        default:
1241                printk(KERN_WARNING "lltrans_handler unknown primitive %#x\n",
1242                       pr);
1243                break;
1244        }
1245}
1246
1247void
1248lli_writewakeup(struct PStack *st, int len)
1249{
1250        struct Channel *chanp = st->lli.userdata;
1251        isdn_ctrl ic;
1252
1253        if (chanp->debug & 0x800)
1254                link_debug(chanp, 0, "llwakeup: %d", len);
1255        ic.driver = chanp->cs->myid;
1256        ic.command = ISDN_STAT_BSENT;
1257        ic.arg = chanp->chan;
1258        ic.parm.length = len;
1259        chanp->cs->iif.statcallb(&ic);
1260}
1261
1262static int
1263init_b_st(struct Channel *chanp, int incoming)
1264{
1265        struct PStack *st = chanp->b_st;
1266        struct IsdnCardState *cs = chanp->cs;
1267        char tmp[16];
1268
1269        st->l1.hardware = cs;
1270        if (chanp->leased)
1271                st->l1.bc = chanp->chan & 1;
1272        else
1273                st->l1.bc = chanp->proc->para.bchannel - 1;
1274        switch (chanp->l2_active_protocol) {
1275        case (ISDN_PROTO_L2_X75I):
1276        case (ISDN_PROTO_L2_HDLC):
1277                st->l1.mode = L1_MODE_HDLC;
1278                break;
1279        case (ISDN_PROTO_L2_HDLC_56K):
1280                st->l1.mode = L1_MODE_HDLC_56K;
1281                break;
1282        case (ISDN_PROTO_L2_TRANS):
1283                st->l1.mode = L1_MODE_TRANS;
1284                break;
1285        case (ISDN_PROTO_L2_MODEM):
1286                st->l1.mode = L1_MODE_V32;
1287                break;
1288        case (ISDN_PROTO_L2_FAX):
1289                st->l1.mode = L1_MODE_FAX;
1290                break;
1291        }
1292        chanp->bcs->conmsg = NULL;
1293        if (chanp->bcs->BC_SetStack(st, chanp->bcs))
1294                return (-1);
1295        st->l2.flag = 0;
1296        test_and_set_bit(FLG_LAPB, &st->l2.flag);
1297        st->l2.maxlen = MAX_DATA_SIZE;
1298        if (!incoming)
1299                test_and_set_bit(FLG_ORIG, &st->l2.flag);
1300        st->l2.T200 = 1000;     /* 1000 milliseconds */
1301        st->l2.window = 7;
1302        st->l2.N200 = 4;        /* try 4 times       */
1303        st->l2.T203 = 5000;     /* 5000 milliseconds */
1304        st->l3.debug = 0;
1305        switch (chanp->l2_active_protocol) {
1306        case (ISDN_PROTO_L2_X75I):
1307                sprintf(tmp, "Ch%d X.75", chanp->chan);
1308                setstack_isdnl2(st, tmp);
1309                setstack_l3bc(st, chanp);
1310                st->l2.l2l3 = lldata_handler;
1311                st->lli.userdata = chanp;
1312                test_and_clear_bit(FLG_LLI_L1WAKEUP, &st->lli.flag);
1313                test_and_set_bit(FLG_LLI_L2WAKEUP, &st->lli.flag);
1314                st->l2.l2m.debug = chanp->debug & 16;
1315                st->l2.debug = chanp->debug & 64;
1316                break;
1317        case (ISDN_PROTO_L2_HDLC):
1318        case (ISDN_PROTO_L2_HDLC_56K):
1319        case (ISDN_PROTO_L2_TRANS):
1320        case (ISDN_PROTO_L2_MODEM):
1321        case (ISDN_PROTO_L2_FAX):
1322                st->l1.l1l2 = lltrans_handler;
1323                st->lli.userdata = chanp;
1324                test_and_set_bit(FLG_LLI_L1WAKEUP, &st->lli.flag);
1325                test_and_clear_bit(FLG_LLI_L2WAKEUP, &st->lli.flag);
1326                setstack_transl2(st);
1327                setstack_l3bc(st, chanp);
1328                break;
1329        }
1330        test_and_set_bit(FLG_START_B, &chanp->Flags);
1331        return (0);
1332}
1333
1334static void
1335leased_l4l3(struct PStack *st, int pr, void *arg)
1336{
1337        struct Channel *chanp = (struct Channel *) st->lli.userdata;
1338        struct sk_buff *skb = arg;
1339
1340        switch (pr) {
1341        case (DL_DATA | REQUEST):
1342                link_debug(chanp, 0, "leased line d-channel DATA");
1343                dev_kfree_skb(skb);
1344                break;
1345        case (DL_ESTABLISH | REQUEST):
1346                st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);
1347                break;
1348        case (DL_RELEASE | REQUEST):
1349                break;
1350        default:
1351                printk(KERN_WARNING "transd_l4l3 unknown primitive %#x\n",
1352                       pr);
1353                break;
1354        }
1355}
1356
1357static void
1358leased_l1l2(struct PStack *st, int pr, void *arg)
1359{
1360        struct Channel *chanp = (struct Channel *) st->lli.userdata;
1361        struct sk_buff *skb = arg;
1362        int i, event = EV_LEASED_REL;
1363
1364        switch (pr) {
1365        case (PH_DATA | INDICATION):
1366                link_debug(chanp, 0, "leased line d-channel DATA");
1367                dev_kfree_skb(skb);
1368                break;
1369        case (PH_ACTIVATE | INDICATION):
1370        case (PH_ACTIVATE | CONFIRM):
1371                event = EV_LEASED;
1372        case (PH_DEACTIVATE | INDICATION):
1373        case (PH_DEACTIVATE | CONFIRM):
1374                if (test_bit(FLG_TWO_DCHAN, &chanp->cs->HW_Flags))
1375                        i = 1;
1376                else
1377                        i = 0;
1378                while (i < 2) {
1379                        FsmEvent(&chanp->fi, event, NULL);
1380                        chanp++;
1381                        i++;
1382                }
1383                break;
1384        default:
1385                printk(KERN_WARNING
1386                       "transd_l1l2 unknown primitive %#x\n", pr);
1387                break;
1388        }
1389}
1390
1391static void
1392distr_debug(struct IsdnCardState *csta, int debugflags)
1393{
1394        int i;
1395        struct Channel *chanp = csta->channel;
1396
1397        for (i = 0; i < (2 + MAX_WAITING_CALLS); i++) {
1398                chanp[i].debug = debugflags;
1399                chanp[i].fi.debug = debugflags & 2;
1400                chanp[i].d_st->l2.l2m.debug = debugflags & 8;
1401                chanp[i].b_st->l2.l2m.debug = debugflags & 0x10;
1402                chanp[i].d_st->l2.debug = debugflags & 0x20;
1403                chanp[i].b_st->l2.debug = debugflags & 0x40;
1404                chanp[i].d_st->l3.l3m.debug = debugflags & 0x80;
1405                chanp[i].b_st->l3.l3m.debug = debugflags & 0x100;
1406                chanp[i].b_st->ma.tei_m.debug = debugflags & 0x200;
1407                chanp[i].b_st->ma.debug = debugflags & 0x200;
1408                chanp[i].d_st->l1.l1m.debug = debugflags & 0x1000;
1409                chanp[i].b_st->l1.l1m.debug = debugflags & 0x2000;
1410        }
1411        if (debugflags & 4)
1412                csta->debug |= DEB_DLOG_HEX;
1413        else
1414                csta->debug &= ~DEB_DLOG_HEX;
1415}
1416
1417static char tmpbuf[256];
1418
1419static void
1420capi_debug(struct Channel *chanp, capi_msg *cm)
1421{
1422        char *t = tmpbuf;
1423
1424        t += QuickHex(t, (u_char *)cm, (cm->Length > 50) ? 50 : cm->Length);
1425        t--;
1426        *t = 0;
1427        HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);
1428}
1429
1430static void
1431lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
1432        if ((cm->para[0] != 3) || (cm->para[1] != 0))
1433                return;
1434        if (cm->para[2] < 3)
1435                return;
1436        if (cm->para[4] != 0)
1437                return;
1438        switch (cm->para[3]) {
1439        case 4: /* Suspend */
1440                strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] + 1);
1441                FsmEvent(&chanp->fi, EV_SUSPEND, cm);
1442                break;
1443        case 5: /* Resume */
1444                strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] + 1);
1445                if (chanp->fi.state == ST_NULL) {
1446                        FsmEvent(&chanp->fi, EV_RESUME, cm);
1447                } else {
1448                        FsmDelTimer(&chanp->dial_timer, 72);
1449                        FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73);
1450                }
1451                break;
1452        }
1453}
1454
1455static void
1456lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
1457        if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||
1458            (cs->typ == ISDN_CTYPE_ELSA_PCI)) {
1459                if (cs->hw.elsa.MFlag) {
1460                        cs->cardmsg(cs, CARD_AUX_IND, cm->para);
1461                }
1462        }
1463}
1464
1465
1466/***************************************************************/
1467/* Limit the available number of channels for the current card */
1468/***************************************************************/
1469static int
1470set_channel_limit(struct IsdnCardState *cs, int chanmax)
1471{
1472        isdn_ctrl ic;
1473        int i, ii;
1474
1475        if ((chanmax < 0) || (chanmax > 2))
1476                return (-EINVAL);
1477        cs->chanlimit = 0;
1478        for (ii = 0; ii < 2; ii++) {
1479                ic.driver = cs->myid;
1480                ic.command = ISDN_STAT_DISCH;
1481                ic.arg = ii;
1482                if (ii >= chanmax)
1483                        ic.parm.num[0] = 0; /* disabled */
1484                else
1485                        ic.parm.num[0] = 1; /* enabled */
1486                i = cs->iif.statcallb(&ic);
1487                if (i) return (-EINVAL);
1488                if (ii < chanmax)
1489                        cs->chanlimit++;
1490        }
1491        return (0);
1492} /* set_channel_limit */
1493
1494int
1495HiSax_command(isdn_ctrl *ic)
1496{
1497        struct IsdnCardState *csta = hisax_findcard(ic->driver);
1498        struct PStack *st;
1499        struct Channel *chanp;
1500        int i;
1501        u_int num;
1502
1503        if (!csta) {
1504                printk(KERN_ERR
1505                       "HiSax: if_command %d called with invalid driverId %d!\n",
1506                       ic->command, ic->driver);
1507                return -ENODEV;
1508        }
1509        switch (ic->command) {
1510        case (ISDN_CMD_SETEAZ):
1511                chanp = csta->channel + ic->arg;
1512                break;
1513        case (ISDN_CMD_SETL2):
1514                chanp = csta->channel + (ic->arg & 0xff);
1515                if (chanp->debug & 1)
1516                        link_debug(chanp, 1, "SETL2 card %d %ld",
1517                                   csta->cardnr + 1, ic->arg >> 8);
1518                chanp->l2_protocol = ic->arg >> 8;
1519                break;
1520        case (ISDN_CMD_SETL3):
1521                chanp = csta->channel + (ic->arg & 0xff);
1522                if (chanp->debug & 1)
1523                        link_debug(chanp, 1, "SETL3 card %d %ld",
1524                                   csta->cardnr + 1, ic->arg >> 8);
1525                chanp->l3_protocol = ic->arg >> 8;
1526                break;
1527        case (ISDN_CMD_DIAL):
1528                chanp = csta->channel + (ic->arg & 0xff);
1529                if (chanp->debug & 1)
1530                        link_debug(chanp, 1, "DIAL %s -> %s (%d,%d)",
1531                                   ic->parm.setup.eazmsn, ic->parm.setup.phone,
1532                                   ic->parm.setup.si1, ic->parm.setup.si2);
1533                memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
1534                if (!strcmp(chanp->setup.eazmsn, "0"))
1535                        chanp->setup.eazmsn[0] = '\0';
1536                /* this solution is dirty and may be change, if
1537                 * we make a callreference based callmanager */
1538                if (chanp->fi.state == ST_NULL) {
1539                        FsmEvent(&chanp->fi, EV_DIAL, NULL);
1540                } else {
1541                        FsmDelTimer(&chanp->dial_timer, 70);
1542                        FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71);
1543                }
1544                break;
1545        case (ISDN_CMD_ACCEPTB):
1546                chanp = csta->channel + ic->arg;
1547                if (chanp->debug & 1)
1548                        link_debug(chanp, 1, "ACCEPTB");
1549                FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);
1550                break;
1551        case (ISDN_CMD_ACCEPTD):
1552                chanp = csta->channel + ic->arg;
1553                memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
1554                if (chanp->debug & 1)
1555                        link_debug(chanp, 1, "ACCEPTD");
1556                FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);
1557                break;
1558        case (ISDN_CMD_HANGUP):
1559                chanp = csta->channel + ic->arg;
1560                if (chanp->debug & 1)
1561                        link_debug(chanp, 1, "HANGUP");
1562                FsmEvent(&chanp->fi, EV_HANGUP, NULL);
1563                break;
1564        case (CAPI_PUT_MESSAGE):
1565                chanp = csta->channel + ic->arg;
1566                if (chanp->debug & 1)
1567                        capi_debug(chanp, &ic->parm.cmsg);
1568                if (ic->parm.cmsg.Length < 8)
1569                        break;
1570                switch (ic->parm.cmsg.Command) {
1571                case CAPI_FACILITY:
1572                        if (ic->parm.cmsg.Subcommand == CAPI_REQ)
1573                                lli_got_fac_req(chanp, &ic->parm.cmsg);
1574                        break;
1575                case CAPI_MANUFACTURER:
1576                        if (ic->parm.cmsg.Subcommand == CAPI_REQ)
1577                                lli_got_manufacturer(chanp, csta, &ic->parm.cmsg);
1578                        break;
1579                default:
1580                        break;
1581                }
1582                break;
1583        case (ISDN_CMD_IOCTL):
1584                switch (ic->arg) {
1585                case (0):
1586                        num = *(unsigned int *) ic->parm.num;
1587                        HiSax_reportcard(csta->cardnr, num);
1588                        break;
1589                case (1):
1590                        num = *(unsigned int *) ic->parm.num;
1591                        distr_debug(csta, num);
1592                        printk(KERN_DEBUG "HiSax: debugging flags card %d set to %x\n",
1593                               csta->cardnr + 1, num);
1594                        HiSax_putstatus(csta, "debugging flags ",
1595                                        "card %d set to %x", csta->cardnr + 1, num);
1596                        break;
1597                case (2):
1598                        num = *(unsigned int *) ic->parm.num;
1599                        csta->channel[0].b_st->l1.delay = num;
1600                        csta->channel[1].b_st->l1.delay = num;
1601                        HiSax_putstatus(csta, "delay ", "card %d set to %d ms",
1602                                        csta->cardnr + 1, num);
1603                        printk(KERN_DEBUG "HiSax: delay card %d set to %d ms\n",
1604                               csta->cardnr + 1, num);
1605                        break;
1606                case (5):       /* set card in leased mode */
1607                        num = *(unsigned int *) ic->parm.num;
1608                        if ((num < 1) || (num > 2)) {
1609                                HiSax_putstatus(csta, "Set LEASED ",
1610                                                "wrong channel %d", num);
1611                                printk(KERN_WARNING "HiSax: Set LEASED wrong channel %d\n",
1612                                       num);
1613                        } else {
1614                                num--;
1615                                chanp = csta->channel + num;
1616                                chanp->leased = 1;
1617                                HiSax_putstatus(csta, "Card",
1618                                                "%d channel %d set leased mode\n",
1619                                                csta->cardnr + 1, num + 1);
1620                                chanp->d_st->l1.l1l2 = leased_l1l2;
1621                                chanp->d_st->lli.l4l3 = leased_l4l3;
1622                                chanp->d_st->lli.l4l3(chanp->d_st,
1623                                                      DL_ESTABLISH | REQUEST, NULL);
1624                        }
1625                        break;
1626                case (6):       /* set B-channel test loop */
1627                        num = *(unsigned int *) ic->parm.num;
1628                        if (csta->stlist)
1629                                csta->stlist->l2.l2l1(csta->stlist,
1630                                                      PH_TESTLOOP | REQUEST, (void *) (long)num);
1631                        break;
1632                case (7):       /* set card in PTP mode */
1633                        num = *(unsigned int *) ic->parm.num;
1634                        if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {
1635                                printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n");
1636                        } else if (num) {
1637                                test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
1638                                test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
1639                                csta->channel[0].d_st->l2.tei = 0;
1640                                HiSax_putstatus(csta, "set card ", "in PTP mode");
1641                                printk(KERN_DEBUG "HiSax: set card in PTP mode\n");
1642                                printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
1643                                csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st,
1644                                                                DL_ESTABLISH | REQUEST, NULL);
1645                        } else {
1646                                test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
1647                                test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
1648                                HiSax_putstatus(csta, "set card ", "in PTMP mode");
1649                                printk(KERN_DEBUG "HiSax: set card in PTMP mode\n");
1650                        }
1651                        break;
1652                case (8):       /* set card in FIXED TEI mode */
1653                        num = *(unsigned int *)ic->parm.num;
1654                        chanp = csta->channel + (num & 1);
1655                        num = num >> 1;
1656                        if (num == 127) {
1657                                test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
1658                                chanp->d_st->l2.tei = -1;
1659                                HiSax_putstatus(csta, "set card ", "in VAR TEI mode");
1660                                printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n");
1661                        } else {
1662                                test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
1663                                chanp->d_st->l2.tei = num;
1664                                HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num);
1665                                printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n",
1666                                       num);
1667                        }
1668                        chanp->d_st->lli.l4l3(chanp->d_st,
1669                                              DL_ESTABLISH | REQUEST, NULL);
1670                        break;
1671                case (11):
1672                        num = csta->debug & DEB_DLOG_HEX;
1673                        csta->debug = *(unsigned int *) ic->parm.num;
1674                        csta->debug |= num;
1675                        HiSax_putstatus(cards[0].cs, "l1 debugging ",
1676                                        "flags card %d set to %x",
1677                                        csta->cardnr + 1, csta->debug);
1678                        printk(KERN_DEBUG "HiSax: l1 debugging flags card %d set to %x\n",
1679                               csta->cardnr + 1, csta->debug);
1680                        break;
1681                case (13):
1682                        csta->channel[0].d_st->l3.debug = *(unsigned int *) ic->parm.num;
1683                        csta->channel[1].d_st->l3.debug = *(unsigned int *) ic->parm.num;
1684                        HiSax_putstatus(cards[0].cs, "l3 debugging ",
1685                                        "flags card %d set to %x\n", csta->cardnr + 1,
1686                                        *(unsigned int *) ic->parm.num);
1687                        printk(KERN_DEBUG "HiSax: l3 debugging flags card %d set to %x\n",
1688                               csta->cardnr + 1, *(unsigned int *) ic->parm.num);
1689                        break;
1690                case (10):
1691                        i = *(unsigned int *) ic->parm.num;
1692                        return (set_channel_limit(csta, i));
1693                default:
1694                        if (csta->auxcmd)
1695                                return (csta->auxcmd(csta, ic));
1696                        printk(KERN_DEBUG "HiSax: invalid ioctl %d\n",
1697                               (int) ic->arg);
1698                        return (-EINVAL);
1699                }
1700                break;
1701
1702        case (ISDN_CMD_PROCEED):
1703                chanp = csta->channel + ic->arg;
1704                if (chanp->debug & 1)
1705                        link_debug(chanp, 1, "PROCEED");
1706                FsmEvent(&chanp->fi, EV_PROCEED, NULL);
1707                break;
1708
1709        case (ISDN_CMD_ALERT):
1710                chanp = csta->channel + ic->arg;
1711                if (chanp->debug & 1)
1712                        link_debug(chanp, 1, "ALERT");
1713                FsmEvent(&chanp->fi, EV_ALERT, NULL);
1714                break;
1715
1716        case (ISDN_CMD_REDIR):
1717                chanp = csta->channel + ic->arg;
1718                if (chanp->debug & 1)
1719                        link_debug(chanp, 1, "REDIR");
1720                memcpy(&chanp->setup, &ic->parm.setup, sizeof(setup_parm));
1721                FsmEvent(&chanp->fi, EV_REDIR, NULL);
1722                break;
1723
1724                /* protocol specific io commands */
1725        case (ISDN_CMD_PROT_IO):
1726                for (st = csta->stlist; st; st = st->next)
1727                        if (st->protocol == (ic->arg & 0xFF))
1728                                return (st->lli.l4l3_proto(st, ic));
1729                return (-EINVAL);
1730                break;
1731        default:
1732                if (csta->auxcmd)
1733                        return (csta->auxcmd(csta, ic));
1734                return (-EINVAL);
1735        }
1736        return (0);
1737}
1738
1739int
1740HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb)
1741{
1742        struct IsdnCardState *csta = hisax_findcard(id);
1743        struct Channel *chanp;
1744        struct PStack *st;
1745        int len = skb->len;
1746        struct sk_buff *nskb;
1747
1748        if (!csta) {
1749                printk(KERN_ERR
1750                       "HiSax: if_sendbuf called with invalid driverId!\n");
1751                return -ENODEV;
1752        }
1753        chanp = csta->channel + chan;
1754        st = chanp->b_st;
1755        if (!chanp->data_open) {
1756                link_debug(chanp, 1, "writebuf: channel not open");
1757                return -EIO;
1758        }
1759        if (len > MAX_DATA_SIZE) {
1760                link_debug(chanp, 1, "writebuf: packet too large (%d bytes)", len);
1761                printk(KERN_WARNING "HiSax_writebuf: packet too large (%d bytes) !\n",
1762                       len);
1763                return -EINVAL;
1764        }
1765        if (len) {
1766                if ((len + chanp->bcs->tx_cnt) > MAX_DATA_MEM) {
1767                        /* Must return 0 here, since this is not an error
1768                         * but a temporary lack of resources.
1769                         */
1770                        if (chanp->debug & 0x800)
1771                                link_debug(chanp, 1, "writebuf: no buffers for %d bytes", len);
1772                        return 0;
1773                } else if (chanp->debug & 0x800)
1774                        link_debug(chanp, 1, "writebuf %d/%d/%d", len, chanp->bcs->tx_cnt, MAX_DATA_MEM);
1775                nskb = skb_clone(skb, GFP_ATOMIC);
1776                if (nskb) {
1777                        nskb->truesize = nskb->len;
1778                        if (!ack)
1779                                nskb->pkt_type = PACKET_NOACK;
1780                        if (chanp->l2_active_protocol == ISDN_PROTO_L2_X75I)
1781                                st->l3.l3l2(st, DL_DATA | REQUEST, nskb);
1782                        else {
1783                                chanp->bcs->tx_cnt += len;
1784                                st->l2.l2l1(st, PH_DATA | REQUEST, nskb);
1785                        }
1786                        dev_kfree_skb(skb);
1787                } else
1788                        len = 0;
1789        }
1790        return (len);
1791}
1792