root/drivers/isdn/teles/callc.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. stat_debug
  2. stat_error
  3. my_atoi
  4. r1
  5. ll_hangup
  6. r2
  7. r3
  8. r4
  9. r5
  10. r6
  11. r7
  12. r8
  13. r9
  14. r10
  15. r12
  16. prp
  17. r15
  18. r16
  19. r17
  20. r18
  21. r19
  22. r20
  23. r21
  24. r22
  25. r23
  26. r24
  27. r25
  28. r26
  29. lc_r1
  30. lc_r6
  31. lc_r2
  32. lc_r3
  33. lc_r4
  34. lc_r5
  35. CallcNew
  36. CallcFree
  37. release_ds
  38. cc_l1man
  39. cc_l2man
  40. dcc_l1man
  41. dcc_l2man
  42. ll_handler
  43. init_is
  44. callc_debug
  45. lc_debug
  46. dlc_debug
  47. lccall_d
  48. lccall_b
  49. init_chan
  50. CallcNewChan
  51. release_is
  52. release_chan
  53. CallcFreeChan
  54. lldata_handler
  55. lltrans_handler
  56. ll_writewakeup
  57. init_ds
  58. channel_report
  59. command_debug
  60. distr_debug
  61. teles_command
  62. teles_writebuf
  63. strcpyupto

   1 #define __NO_VERSION__
   2 #include "teles.h"
   3 
   4 extern struct IsdnCard cards[];
   5 extern int      nrcards;
   6 extern int      drid;
   7 extern isdn_if  iif;
   8 extern void     teles_mod_dec_use_count(void);
   9 extern void     teles_mod_inc_use_count(void);
  10 
  11 static int      init_ds(int chan, int incoming);
  12 static void     release_ds(int chan);
  13 static char    *strcpyupto(char *dest, char *src, char upto);
  14 
  15 static struct Fsm callcfsm =
  16 {NULL, 0, 0},   lcfsm =
  17 {NULL, 0, 0};
  18 
  19 struct Channel *chanlist;
  20 static int      chancount = 0;
  21 unsigned int    debugflags = 0;
  22 
  23 #define TMR_DCHAN_EST 2000
  24 
  25 static void
  26 stat_debug(struct Channel *chanp, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
  27 {
  28         char            tmp[100], tm[32];
  29 
  30         jiftime(tm, jiffies);
  31         sprintf(tmp, "%s Channel %d HL->LL %s\n", tm, chanp->chan, s);
  32         teles_putstatus(tmp);
  33 }
  34 
  35 #ifdef DEFINED_BUT_NOT_USED
  36 static void
  37 stat_error(struct Channel *chanp, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
  38 {
  39         char            tmp[100];
  40 
  41         sprintf(tmp, "Channel %d: %s\n", chanp->chan, s);
  42         teles_putstatus(tmp);
  43 }
  44 #endif
  45 
  46 enum {
  47         ST_NULL,           /*  0 inactive                                               */
  48         ST_OUT,            /*  1 outgoing, awaiting SETUP confirm                       */
  49         ST_CLEAR,          /*  2 call release, awaiting RELEASE confirm                 */
  50         ST_OUT_W,          /*  3 outgoing, awaiting d-channel establishment             */
  51         ST_REL_W,          /*  4 awaiting d-channel release                             */
  52         ST_IN_W,           /*  5 incoming, awaiting d-channel establishment             */
  53         ST_IN,             /*  6 incoming call received                                 */
  54         ST_IN_SETUP,       /*  7 incoming, SETUP response sent                          */
  55         ST_IN_DACT,        /*  8 incoming connected, no b-channel prot.                 */
  56         ST_OUT_ESTB,       /* 10 outgoing connected, awaiting b-channel prot. estbl.    */
  57         ST_ACTIVE,         /* 11 active, b channel prot. established                    */
  58         ST_BC_HANGUP,      /* 12 call clear. (initiator), awaiting b channel prot. rel. */
  59         ST_PRO_W,          /* 13 call clear. (initiator), DISCONNECT req. sent          */
  60         ST_ANT_W,          /* 14 call clear. (receiver), awaiting DISCONNECT ind.       */
  61         ST_DISC_BC_HANGUP, /*    d channel gone, wait for b channel deactivation        */
  62         ST_D_ERR,          /*    d channel released while active                        */
  63 };
  64 
  65 #define STATE_COUNT (ST_D_ERR+1)
  66 
  67 static char    *strState[] =
  68 {
  69         "ST_NULL",
  70         "ST_OUT",
  71         "ST_CLEAR",
  72         "ST_OUT_W",
  73         "ST_REL_W",
  74         "ST_IN_W",
  75         "ST_IN",
  76         "ST_IN_SETUP",
  77         "ST_IN_DACT",
  78         "ST_OUT_ESTB",
  79         "ST_ACTIVE",
  80         "ST_BC_HANGUP",
  81         "ST_PRO_W",
  82         "ST_ANT_W",
  83         "ST_DISC_BC_HANGUP",
  84         "ST_D_ERR",
  85 };
  86 
  87 enum {
  88         EV_DIAL,           /*  0 */
  89         EV_SETUP_CNF,      /*  1 */
  90         EV_ACCEPTB,        /*  2 */
  91         EV_DISCONNECT_CNF, /*  5 */
  92         EV_DISCONNECT_IND, /*  6 */
  93         EV_RELEASE_CNF,    /*  7 */
  94         EV_DLEST,          /*  8 */
  95         EV_DLRL,           /*  9 */
  96         EV_SETUP_IND,      /* 10 */
  97         EV_RELEASE_IND,    /* 11 */
  98         EV_ACCEPTD,        /* 12 */
  99         EV_SETUP_CMPL_IND, /* 13 */
 100         EV_BC_EST,         /* 14 */
 101         EV_WRITEBUF,       /* 15 */
 102         EV_DATAIN,         /* 16 */
 103         EV_HANGUP,         /* 17 */
 104         EV_BC_REL,         /* 18 */
 105         EV_CINF,           /* 19 */
 106 };
 107 
 108 #define EVENT_COUNT (EV_CINF+1)
 109 
 110 static char    *strEvent[] =
 111 {
 112         "EV_DIAL",
 113         "EV_SETUP_CNF",
 114         "EV_ACCEPTB",
 115         "EV_DISCONNECT_CNF",
 116         "EV_DISCONNECT_IND",
 117         "EV_RELEASE_CNF",
 118         "EV_DLEST",
 119         "EV_DLRL",
 120         "EV_SETUP_IND",
 121         "EV_RELEASE_IND",
 122         "EV_ACCEPTD",
 123         "EV_SETUP_CMPL_IND",
 124         "EV_BC_EST",
 125         "EV_WRITEBUF",
 126         "EV_DATAIN",
 127         "EV_HANGUP",
 128         "EV_BC_REL",
 129         "EV_CINF",
 130 };
 131 
 132 enum {
 133         ST_LC_NULL,
 134         ST_LC_ACTIVATE_WAIT,
 135         ST_LC_DELAY,
 136         ST_LC_ESTABLISH_WAIT,
 137         ST_LC_CONNECTED,
 138         ST_LC_RELEASE_WAIT,
 139 };
 140 
 141 #define LC_STATE_COUNT (ST_LC_RELEASE_WAIT+1)
 142 
 143 static char    *strLcState[] =
 144 {
 145         "ST_LC_NULL",
 146         "ST_LC_ACTIVATE_WAIT",
 147         "ST_LC_DELAY",
 148         "ST_LC_ESTABLISH_WAIT",
 149         "ST_LC_CONNECTED",
 150         "ST_LC_RELEASE_WAIT",
 151 };
 152 
 153 enum {
 154         EV_LC_ESTABLISH,
 155         EV_LC_PH_ACTIVATE,
 156         EV_LC_PH_DEACTIVATE,
 157         EV_LC_DL_ESTABLISH,
 158         EV_LC_TIMER,
 159         EV_LC_DL_RELEASE,
 160         EV_LC_RELEASE,
 161 };
 162 
 163 #define LC_EVENT_COUNT (EV_LC_RELEASE+1)
 164 
 165 static char    *strLcEvent[] =
 166 {
 167         "EV_LC_ESTABLISH",
 168         "EV_LC_PH_ACTIVATE",
 169         "EV_LC_PH_DEACTIVATE",
 170         "EV_LC_DL_ESTABLISH",
 171         "EV_LC_TIMER",
 172         "EV_LC_DL_RELEASE",
 173         "EV_LC_RELEASE",
 174 };
 175 
 176 #define LC_D  0
 177 #define LC_B  1
 178 
 179 static int
 180 my_atoi(char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 181 {
 182         int             i, n;
 183 
 184         n = 0;
 185         if (!s)
 186                 return -1;
 187         for (i = 0; *s >= '0' && *s <= '9'; i++, s++)
 188                 n = 10 * n + (*s - '0');
 189         return n;
 190 }
 191 
 192 /*
 193  * Dial out
 194  */
 195 static void
 196 r1(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         isdn_ctrl      *ic = arg;
 199         struct Channel *chanp = fi->userdata;
 200         char           *ptr;
 201         char            sis[3];
 202 
 203         /* Destination Phone-Number */
 204         ptr = strcpyupto(chanp->para.called, ic->num, ',');
 205         /* Source Phone-Number */
 206         ptr = strcpyupto(chanp->para.calling, ptr + 1, ',');
 207         if (!strcmp(chanp->para.calling, "0"))
 208                 chanp->para.calling[0] = '\0';
 209 
 210         /* Service-Indicator 1 */
 211         ptr = strcpyupto(sis, ptr + 1, ',');
 212         chanp->para.info = my_atoi(sis);
 213 
 214         /* Service-Indicator 2 */
 215         ptr = strcpyupto(sis, ptr + 1, '\0');
 216         chanp->para.info2 = my_atoi(sis);
 217 
 218         chanp->l2_active_protocol = chanp->l2_protocol;
 219         chanp->incoming = 0;
 220         chanp->lc_b.l2_start = !0;
 221 
 222         switch (chanp->l2_active_protocol) {
 223           case (ISDN_PROTO_L2_X75I):
 224                   chanp->lc_b.l2_establish = !0;
 225                   break;
 226           case (ISDN_PROTO_L2_HDLC):
 227                   chanp->lc_b.l2_establish = 0;
 228                   break;
 229           default:
 230                   printk(KERN_WARNING "r1 unknown protocol\n");
 231                   break;
 232         }
 233 
 234         FsmChangeState(fi, ST_OUT_W);
 235         FsmEvent(&chanp->lc_d.lcfi, EV_LC_ESTABLISH, NULL);
 236 }
 237 
 238 static void
 239 ll_hangup(struct Channel *chanp, int bchantoo)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241         isdn_ctrl       ic;
 242 
 243         if (bchantoo) {
 244                 if (chanp->debug & 1)
 245                         stat_debug(chanp, "STAT_BHUP");
 246                 ic.driver = drid;
 247                 ic.command = ISDN_STAT_BHUP;
 248                 ic.arg = chanp->chan;
 249                 iif.statcallb(&ic);
 250         }
 251         if (chanp->debug & 1)
 252                 stat_debug(chanp, "STAT_DHUP");
 253         ic.driver = drid;
 254         ic.command = ISDN_STAT_DHUP;
 255         ic.arg = chanp->chan;
 256         iif.statcallb(&ic);
 257 }
 258 
 259 static void
 260 r2(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262         struct Channel *chanp = fi->userdata;
 263 
 264         chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
 265 
 266         FsmChangeState(fi, ST_CLEAR);
 267         ll_hangup(chanp, 0);
 268 }
 269 
 270 static void
 271 r3(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 272 {
 273         struct Channel *chanp = fi->userdata;
 274 
 275         FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
 276         FsmChangeState(fi, ST_REL_W);
 277 }
 278 
 279 static void
 280 r4(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282         FsmChangeState(fi, ST_NULL);
 283 }
 284 
 285 static void
 286 r5(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288         struct Channel *chanp = fi->userdata;
 289 
 290         chanp->para.callref = chanp->outcallref;
 291 
 292         chanp->outcallref++;
 293         if (chanp->outcallref == 128)
 294                 chanp->outcallref = 64;
 295 
 296         chanp->is.l4.l4l3(&chanp->is, CC_SETUP_REQ, NULL);
 297 
 298         FsmChangeState(fi, ST_OUT);
 299 }
 300 
 301 static void
 302 r6(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 303 {
 304         struct Channel *chanp = fi->userdata;
 305 
 306         FsmChangeState(fi, ST_IN_W);
 307         FsmEvent(&chanp->lc_d.lcfi, EV_LC_ESTABLISH, NULL);
 308 }
 309 
 310 static void
 311 r7(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 312 {
 313         struct Channel *chanp = fi->userdata;
 314         isdn_ctrl       ic;
 315 
 316         chanp->is.l4.l4l3(&chanp->is, CC_ALERTING_REQ, NULL);
 317 
 318         FsmChangeState(fi, ST_IN);
 319 
 320         /*
 321          * Report incoming calls only once to linklevel, use octet 3 of
 322          * channel identification information element. (it's value
 323          * is copied to chanp->para.bchannel in l3s12(), file isdnl3.c)
 324          */
 325         if (((chanp->chan & 1) + 1) & chanp->para.bchannel) {
 326                 if (chanp->debug & 1)
 327                         stat_debug(chanp, "STAT_ICALL");
 328                 ic.driver = drid;
 329                 ic.command = ISDN_STAT_ICALL;
 330                 ic.arg = chanp->chan;
 331                 /*
 332                  * No need to return "unknown" for calls without OAD,
 333                  * cause that's handled in linklevel now (replaced by '0')
 334                  */
 335                 sprintf(ic.num, "%s,%d,0,%s", chanp->para.calling, chanp->para.info,
 336                         chanp->para.called);
 337                 iif.statcallb(&ic);
 338         }
 339 }
 340 
 341 static void
 342 r8(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 343 {
 344         struct Channel *chanp = fi->userdata;
 345 
 346         FsmChangeState(fi, ST_IN_SETUP);
 347         chanp->is.l4.l4l3(&chanp->is, CC_SETUP_RSP, NULL);
 348 
 349 }
 350 
 351 static void
 352 r9(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354         struct Channel *chanp = fi->userdata;
 355 
 356         FsmChangeState(fi, ST_IN_DACT);
 357 
 358         chanp->l2_active_protocol = chanp->l2_protocol;
 359         chanp->incoming = !0;
 360         chanp->lc_b.l2_start = 0;
 361 
 362         switch (chanp->l2_active_protocol) {
 363           case (ISDN_PROTO_L2_X75I):
 364                   chanp->lc_b.l2_establish = !0;
 365                   break;
 366           case (ISDN_PROTO_L2_HDLC):
 367                   chanp->lc_b.l2_establish = 0;
 368                   break;
 369           default:
 370                   printk(KERN_WARNING "r9 unknown protocol\n");
 371                   break;
 372         }
 373 
 374         init_ds(chanp->chan, !0);
 375 
 376         FsmEvent(&chanp->lc_b.lcfi, EV_LC_ESTABLISH, NULL);
 377 }
 378 
 379 static void
 380 r10(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 381 {
 382         struct Channel *chanp = fi->userdata;
 383 
 384         FsmChangeState(fi, ST_OUT_ESTB);
 385 
 386         init_ds(chanp->chan, 0);
 387         FsmEvent(&chanp->lc_b.lcfi, EV_LC_ESTABLISH, NULL);
 388 
 389 }
 390 
 391 static void
 392 r12(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 393 {
 394         struct Channel *chanp = fi->userdata;
 395         isdn_ctrl       ic;
 396 
 397         FsmChangeState(fi, ST_ACTIVE);
 398         chanp->data_open = !0;
 399 
 400         if (chanp->debug & 1)
 401                 stat_debug(chanp, "STAT_DCONN");
 402         ic.driver = drid;
 403         ic.command = ISDN_STAT_DCONN;
 404         ic.arg = chanp->chan;
 405         iif.statcallb(&ic);
 406 
 407         if (chanp->debug & 1)
 408                 stat_debug(chanp, "STAT_BCONN");
 409         ic.driver = drid;
 410         ic.command = ISDN_STAT_BCONN;
 411         ic.arg = chanp->chan;
 412         iif.statcallb(&ic);
 413 }
 414 
 415 #ifdef DEFINED_BUT_NOT_USED
 416 static void
 417 prp(byte * p, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 418 {
 419         while (size--)
 420                 printk("%2x ", *p++);
 421         printk("\n");
 422 }
 423 #endif
 424 
 425 static void
 426 r15(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 427 {
 428         struct Channel *chanp = fi->userdata;
 429 
 430         chanp->data_open = 0;
 431         FsmChangeState(fi, ST_BC_HANGUP);
 432         FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
 433 }
 434 
 435 static void
 436 r16(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438         struct Channel *chanp = fi->userdata;
 439 
 440         release_ds(chanp->chan);
 441 
 442         FsmChangeState(fi, ST_PRO_W);
 443         chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
 444 }
 445 
 446 static void
 447 r17(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 448 {
 449         struct Channel *chanp = fi->userdata;
 450 
 451         chanp->data_open = 0;
 452         release_ds(chanp->chan);
 453 
 454         FsmChangeState(fi, ST_ANT_W);
 455 }
 456 
 457 static void
 458 r18(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 459 {
 460         struct Channel *chanp = fi->userdata;
 461 
 462         FsmChangeState(fi, ST_REL_W);
 463         FsmEvent(&chanp->lc_d.lcfi, EV_LC_RELEASE, NULL);
 464 
 465         ll_hangup(chanp, !0);
 466 }
 467 
 468 static void
 469 r19(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 470 {
 471         struct Channel *chanp = fi->userdata;
 472 
 473         FsmChangeState(fi, ST_CLEAR);
 474 
 475         chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
 476 
 477         ll_hangup(chanp, !0);
 478 }
 479 
 480 static void
 481 r20(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 482 {
 483         struct Channel *chanp = fi->userdata;
 484 
 485         FsmChangeState(fi, ST_NULL);
 486 
 487         ll_hangup(chanp, 0);
 488 }
 489 
 490 static void
 491 r21(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493         struct Channel *chanp = fi->userdata;
 494 
 495         chanp->data_open = 0;
 496         FsmChangeState(fi, ST_DISC_BC_HANGUP);
 497         FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
 498 }
 499 
 500 static void
 501 r22(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 502 {
 503         struct Channel *chanp = fi->userdata;
 504 
 505         release_ds(chanp->chan);
 506 
 507         FsmChangeState(fi, ST_CLEAR);
 508 
 509         chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
 510 
 511         ll_hangup(chanp, !0);
 512 }
 513 
 514 static void
 515 r23(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 516 {
 517         struct Channel *chanp = fi->userdata;
 518 
 519         release_ds(chanp->chan);
 520 
 521         FsmChangeState(fi, ST_PRO_W);
 522         chanp->is.l4.l4l3(&chanp->is, CC_DISCONNECT_REQ, NULL);
 523 }
 524 
 525 static void
 526 r24(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 527 {
 528         struct Channel *chanp = fi->userdata;
 529 
 530         chanp->data_open = 0;
 531         FsmChangeState(fi, ST_D_ERR);
 532         FsmEvent(&chanp->lc_b.lcfi, EV_LC_RELEASE, NULL);
 533 }
 534 
 535 static void
 536 r25(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538         struct Channel *chanp = fi->userdata;
 539 
 540         release_ds(chanp->chan);
 541 
 542         FsmChangeState(fi, ST_NULL);
 543 
 544         ll_hangup(chanp, !0);
 545 }
 546 
 547 static void
 548 r26(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 549 {
 550         struct Channel *chanp = fi->userdata;
 551         isdn_ctrl       ic;
 552 
 553 
 554         ic.driver = drid;
 555         ic.command = ISDN_STAT_CINF;
 556         ic.arg = chanp->chan;
 557         sprintf(ic.num, "%d", chanp->para.chargeinfo);
 558         iif.statcallb(&ic);
 559 }
 560 
 561 
 562 
 563 static struct FsmNode fnlist[] =
 564 {
 565         {ST_NULL, EV_DIAL, r1},
 566         {ST_OUT_W, EV_DLEST, r5},
 567         {ST_OUT_W, EV_DLRL, r20},
 568         {ST_OUT, EV_DISCONNECT_IND, r2},
 569         {ST_CLEAR, EV_RELEASE_CNF, r3},
 570         {ST_REL_W, EV_DLRL, r4},
 571         {ST_NULL, EV_SETUP_IND, r6},
 572         {ST_IN_W, EV_DLEST, r7},
 573         {ST_IN, EV_RELEASE_IND, r3},
 574         {ST_IN, EV_ACCEPTD, r8},
 575         {ST_IN_SETUP, EV_SETUP_CMPL_IND, r9},
 576         {ST_OUT, EV_SETUP_CNF, r10},
 577         {ST_OUT_ESTB, EV_BC_EST, r12},
 578         {ST_OUT_ESTB, EV_BC_REL, r23},
 579         {ST_IN_DACT, EV_BC_EST, r12},
 580         {ST_ACTIVE, EV_HANGUP, r15},
 581         {ST_BC_HANGUP, EV_BC_REL, r16},
 582         {ST_BC_HANGUP, EV_DISCONNECT_IND, r21},
 583         {ST_ACTIVE, EV_BC_REL, r17},
 584         {ST_ACTIVE, EV_DISCONNECT_IND, r21},
 585         {ST_ACTIVE, EV_DLRL, r24},
 586         {ST_ACTIVE, EV_CINF, r26},
 587         {ST_PRO_W, EV_RELEASE_IND, r18},
 588         {ST_ANT_W, EV_DISCONNECT_IND, r19},
 589         {ST_DISC_BC_HANGUP, EV_BC_REL, r22},
 590         {ST_D_ERR, EV_BC_REL, r25},
 591 };
 592 
 593 #define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
 594 
 595 static void
 596 lc_r1(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 597 {
 598         struct LcFsm   *lf = fi->userdata;
 599 
 600         FsmChangeState(fi, ST_LC_ACTIVATE_WAIT);
 601         FsmAddTimer(&lf->act_timer, 1000, EV_LC_TIMER, NULL, 50);
 602         lf->st->ma.manl1(lf->st, PH_ACTIVATE, NULL);
 603 
 604 }
 605 
 606 static void
 607 lc_r6(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 608 {
 609         struct LcFsm   *lf = fi->userdata;
 610 
 611         FsmDelTimer(&lf->act_timer, 50);
 612         FsmChangeState(fi, ST_LC_DELAY);
 613         FsmAddTimer(&lf->act_timer, 40, EV_LC_TIMER, NULL, 51);
 614 }
 615 
 616 static void
 617 lc_r2(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 618 {
 619         struct LcFsm   *lf = fi->userdata;
 620 
 621         if (lf->l2_establish) {
 622                 FsmChangeState(fi, ST_LC_ESTABLISH_WAIT);
 623                 if (lf->l2_start)
 624                         lf->st->ma.manl2(lf->st, DL_ESTABLISH, NULL);
 625         } else {
 626                 FsmChangeState(fi, ST_LC_CONNECTED);
 627                 lf->lccall(lf, LC_ESTABLISH, NULL);
 628         }
 629 }
 630 
 631 static void
 632 lc_r3(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 633 {
 634         struct LcFsm   *lf = fi->userdata;
 635 
 636         FsmChangeState(fi, ST_LC_CONNECTED);
 637         lf->lccall(lf, LC_ESTABLISH, NULL);
 638 }
 639 
 640 static void
 641 lc_r4(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643         struct LcFsm   *lf = fi->userdata;
 644 
 645         if (lf->l2_establish) {
 646                 FsmChangeState(fi, ST_LC_RELEASE_WAIT);
 647                 lf->st->ma.manl2(lf->st, DL_RELEASE, NULL);
 648         } else {
 649                 FsmChangeState(fi, ST_LC_NULL);
 650                 lf->st->ma.manl1(lf->st, PH_DEACTIVATE, NULL);
 651                 lf->lccall(lf, LC_RELEASE, NULL);
 652         }
 653 }
 654 
 655 static void
 656 lc_r5(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 657 {
 658         struct LcFsm   *lf = fi->userdata;
 659 
 660         FsmChangeState(fi, ST_LC_NULL);
 661         lf->st->ma.manl1(lf->st, PH_DEACTIVATE, NULL);
 662         lf->lccall(lf, LC_RELEASE, NULL);
 663 }
 664 
 665 static struct FsmNode LcFnList[] =
 666 {
 667         {ST_LC_NULL, EV_LC_ESTABLISH, lc_r1},
 668         {ST_LC_ACTIVATE_WAIT, EV_LC_PH_ACTIVATE, lc_r6},
 669         {ST_LC_DELAY, EV_LC_TIMER, lc_r2},
 670         {ST_LC_ESTABLISH_WAIT, EV_LC_DL_ESTABLISH, lc_r3},
 671         {ST_LC_CONNECTED, EV_LC_RELEASE, lc_r4},
 672         {ST_LC_CONNECTED, EV_LC_DL_RELEASE, lc_r5},
 673         {ST_LC_RELEASE_WAIT, EV_LC_DL_RELEASE, lc_r5},
 674         {ST_LC_ACTIVATE_WAIT, EV_LC_TIMER, lc_r5},
 675         {ST_LC_ESTABLISH_WAIT, EV_LC_DL_RELEASE, lc_r5},
 676 };
 677 
 678 #define LC_FN_COUNT (sizeof(LcFnList)/sizeof(struct FsmNode))
 679 
 680 void
 681 CallcNew(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 682 {
 683         callcfsm.state_count = STATE_COUNT;
 684         callcfsm.event_count = EVENT_COUNT;
 685         callcfsm.strEvent = strEvent;
 686         callcfsm.strState = strState;
 687         FsmNew(&callcfsm, fnlist, FNCOUNT);
 688 
 689         lcfsm.state_count = LC_STATE_COUNT;
 690         lcfsm.event_count = LC_EVENT_COUNT;
 691         lcfsm.strEvent = strLcEvent;
 692         lcfsm.strState = strLcState;
 693         FsmNew(&lcfsm, LcFnList, LC_FN_COUNT);
 694 }
 695 
 696 void
 697 CallcFree(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 698 {
 699         FsmFree(&lcfsm);
 700         FsmFree(&callcfsm);
 701 }
 702 
 703 static void
 704 release_ds(int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 705 {
 706         struct PStack  *st = &chanlist[chan].ds;
 707         struct IsdnCardState *sp;
 708         struct HscxState *hsp;
 709 
 710         sp = st->l1.hardware;
 711         hsp = sp->hs + chanlist[chan].hscx;
 712 
 713         close_hscxstate(hsp);
 714 
 715         switch (chanlist[chan].l2_active_protocol) {
 716           case (ISDN_PROTO_L2_X75I):
 717                   releasestack_isdnl2(st);
 718                   break;
 719           case (ISDN_PROTO_L2_HDLC):
 720                   releasestack_transl2(st);
 721                   break;
 722         }
 723 }
 724 
 725 static void
 726 cc_l1man(struct PStack *st, int pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 727 {
 728         struct Channel *chanp = (struct Channel *) st->l4.userdata;
 729 
 730         switch (pr) {
 731           case (PH_ACTIVATE):
 732                   FsmEvent(&chanp->lc_d.lcfi, EV_LC_PH_ACTIVATE, NULL);
 733                   break;
 734           case (PH_DEACTIVATE):
 735                   FsmEvent(&chanp->lc_d.lcfi, EV_LC_PH_DEACTIVATE, NULL);
 736                   break;
 737         }
 738 }
 739 
 740 static void
 741 cc_l2man(struct PStack *st, int pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 742 {
 743         struct Channel *chanp = (struct Channel *) st->l4.userdata;
 744 
 745         switch (pr) {
 746           case (DL_ESTABLISH):
 747                   FsmEvent(&chanp->lc_d.lcfi, EV_LC_DL_ESTABLISH, NULL);
 748                   break;
 749           case (DL_RELEASE):
 750                   FsmEvent(&chanp->lc_d.lcfi, EV_LC_DL_RELEASE, NULL);
 751                   break;
 752         }
 753 }
 754 
 755 static void
 756 dcc_l1man(struct PStack *st, int pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 757 {
 758         struct Channel *chanp = (struct Channel *) st->l4.userdata;
 759 
 760         switch (pr) {
 761           case (PH_ACTIVATE):
 762                   FsmEvent(&chanp->lc_b.lcfi, EV_LC_PH_ACTIVATE, NULL);
 763                   break;
 764           case (PH_DEACTIVATE):
 765                   FsmEvent(&chanp->lc_b.lcfi, EV_LC_PH_DEACTIVATE, NULL);
 766                   break;
 767         }
 768 }
 769 
 770 static void
 771 dcc_l2man(struct PStack *st, int pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 772 {
 773         struct Channel *chanp = (struct Channel *) st->l4.userdata;
 774 
 775         switch (pr) {
 776           case (DL_ESTABLISH):
 777                   FsmEvent(&chanp->lc_b.lcfi, EV_LC_DL_ESTABLISH, NULL);
 778                   break;
 779           case (DL_RELEASE):
 780                   FsmEvent(&chanp->lc_b.lcfi, EV_LC_DL_RELEASE, NULL);
 781                   break;
 782         }
 783 }
 784 
 785 static void
 786 ll_handler(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
 787            struct BufHeader *ibh)
 788 {
 789         struct Channel *chanp = (struct Channel *) st->l4.userdata;
 790 
 791         switch (pr) {
 792           case (CC_DISCONNECT_IND):
 793                   FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
 794                   break;
 795           case (CC_RELEASE_CNF):
 796                   FsmEvent(&chanp->fi, EV_RELEASE_CNF, NULL);
 797                   break;
 798           case (CC_SETUP_IND):
 799                   FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
 800                   break;
 801           case (CC_RELEASE_IND):
 802                   FsmEvent(&chanp->fi, EV_RELEASE_IND, NULL);
 803                   break;
 804           case (CC_SETUP_COMPLETE_IND):
 805                   FsmEvent(&chanp->fi, EV_SETUP_CMPL_IND, NULL);
 806                   break;
 807           case (CC_SETUP_CNF):
 808                   FsmEvent(&chanp->fi, EV_SETUP_CNF, NULL);
 809                   break;
 810           case (CC_INFO_CHARGE):
 811                   FsmEvent(&chanp->fi, EV_CINF, NULL);
 812                   break;
 813         }
 814 }
 815 
 816 static void
 817 init_is(int chan, unsigned int ces)
     /* [previous][next][first][last][top][bottom][index][help] */
 818 {
 819         struct PStack  *st = &(chanlist[chan].is);
 820         struct IsdnCardState *sp = chanlist[chan].sp;
 821         char            tmp[128];
 822 
 823         setstack_teles(st, sp);
 824 
 825         st->l2.sap = 0;
 826 
 827         st->l2.tei = 255;
 828 
 829         st->l2.ces = ces;
 830         st->l2.extended = !0;
 831         st->l2.laptype = LAPD;
 832         st->l2.window = 1;
 833         st->l2.orig = !0;
 834         st->l2.t200 = 1000;               /* 1000 milliseconds  */
 835         if (st->protocol == ISDN_PTYPE_1TR6) {
 836                 st->l2.n200 = 3;          /* try 3 times        */
 837                 st->l2.t203 = 10000;      /* 10000 milliseconds */
 838         } else {
 839                 st->l2.n200 = 4;          /* try 4 times        */
 840                 st->l2.t203 = 5000;       /* 5000 milliseconds  */
 841         }
 842 
 843         sprintf(tmp, "Channel %d q.921", chan);
 844         setstack_isdnl2(st, tmp);
 845         setstack_isdnl3(st);
 846         st->l2.debug = 2;
 847         st->l3.debug = 2;
 848         st->l2.debug = 0xff;
 849         st->l3.debug = 0xff;
 850         st->l4.userdata = chanlist + chan;
 851         st->l4.l2writewakeup = NULL;
 852 
 853         st->l3.l3l4 = ll_handler;
 854         st->l1.l1man = cc_l1man;
 855         st->l2.l2man = cc_l2man;
 856 
 857         st->pa = &chanlist[chan].para;
 858         teles_addlist(sp, st);
 859 }
 860 
 861 static void
 862 callc_debug(struct FsmInst *fi, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 863 {
 864         char            str[80], tm[32];
 865         struct Channel *chanp = fi->userdata;
 866 
 867         jiftime(tm, jiffies);
 868         sprintf(str, "%s Channel %d callc %s\n", tm, chanp->chan, s);
 869         teles_putstatus(str);
 870 }
 871 
 872 static void
 873 lc_debug(struct FsmInst *fi, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 874 {
 875         char            str[256], tm[32];
 876         struct LcFsm   *lf = fi->userdata;
 877 
 878         jiftime(tm, jiffies);
 879         sprintf(str, "%s Channel %d lc %s\n", tm, lf->ch->chan, s);
 880         teles_putstatus(str);
 881 }
 882 
 883 static void
 884 dlc_debug(struct FsmInst *fi, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 885 {
 886         char            str[256], tm[32];
 887         struct LcFsm   *lf = fi->userdata;
 888 
 889         jiftime(tm, jiffies);
 890         sprintf(str, "%s Channel %d dlc %s\n", tm, lf->ch->chan, s);
 891         teles_putstatus(str);
 892 }
 893 
 894 static void
 895 lccall_d(struct LcFsm *lf, int pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 896 {
 897         struct Channel *chanp = lf->ch;
 898 
 899         switch (pr) {
 900           case (LC_ESTABLISH):
 901                   FsmEvent(&chanp->fi, EV_DLEST, NULL);
 902                   break;
 903           case (LC_RELEASE):
 904                   FsmEvent(&chanp->fi, EV_DLRL, NULL);
 905                   break;
 906         }
 907 }
 908 
 909 static void
 910 lccall_b(struct LcFsm *lf, int pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 911 {
 912         struct Channel *chanp = lf->ch;
 913 
 914         switch (pr) {
 915           case (LC_ESTABLISH):
 916                   FsmEvent(&chanp->fi, EV_BC_EST, NULL);
 917                   break;
 918           case (LC_RELEASE):
 919                   FsmEvent(&chanp->fi, EV_BC_REL, NULL);
 920                   break;
 921         }
 922 }
 923 
 924 static void
 925 init_chan(int chan, int cardnr, int hscx,
     /* [previous][next][first][last][top][bottom][index][help] */
 926           unsigned int ces)
 927 {
 928         struct IsdnCard *card = cards + cardnr;
 929         struct Channel *chanp = chanlist + chan;
 930 
 931         chanp->sp = card->sp;
 932         chanp->hscx = hscx;
 933         chanp->chan = chan;
 934         chanp->incoming = 0;
 935         chanp->debug = 0;
 936         init_is(chan, ces);
 937 
 938         chanp->fi.fsm = &callcfsm;
 939         chanp->fi.state = ST_NULL;
 940         chanp->fi.debug = 0;
 941         chanp->fi.userdata = chanp;
 942         chanp->fi.printdebug = callc_debug;
 943 
 944         chanp->lc_d.lcfi.fsm = &lcfsm;
 945         chanp->lc_d.lcfi.state = ST_LC_NULL;
 946         chanp->lc_d.lcfi.debug = 0;
 947         chanp->lc_d.lcfi.userdata = &chanp->lc_d;
 948         chanp->lc_d.lcfi.printdebug = lc_debug;
 949         chanp->lc_d.type = LC_D;
 950         chanp->lc_d.ch = chanp;
 951         chanp->lc_d.st = &chanp->is;
 952         chanp->lc_d.l2_establish = !0;
 953         chanp->lc_d.l2_start = !0;
 954         chanp->lc_d.lccall = lccall_d;
 955         FsmInitTimer(&chanp->lc_d.lcfi, &chanp->lc_d.act_timer);
 956 
 957         chanp->lc_b.lcfi.fsm = &lcfsm;
 958         chanp->lc_b.lcfi.state = ST_LC_NULL;
 959         chanp->lc_b.lcfi.debug = 0;
 960         chanp->lc_b.lcfi.userdata = &chanp->lc_b;
 961         chanp->lc_b.lcfi.printdebug = dlc_debug;
 962         chanp->lc_b.type = LC_B;
 963         chanp->lc_b.ch = chanp;
 964         chanp->lc_b.st = &chanp->ds;
 965         chanp->lc_b.l2_establish = !0;
 966         chanp->lc_b.l2_start = !0;
 967         chanp->lc_b.lccall = lccall_b;
 968         FsmInitTimer(&chanp->lc_b.lcfi, &chanp->lc_b.act_timer);
 969 
 970         chanp->outcallref = 64;
 971         chanp->data_open = 0;
 972 }
 973 
 974 int
 975 CallcNewChan(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 976 {
 977         int             i, ces, c;
 978 
 979         chancount = 0;
 980         for (i = 0; i < nrcards; i++)
 981                 if (cards[i].sp)
 982                         chancount += 2;
 983 
 984         chanlist = (struct Channel *) Smalloc(sizeof(struct Channel) *
 985                                       chancount, GFP_KERNEL, "chanlist");
 986 
 987         c = 0;
 988         ces = randomces();
 989         for (i = 0; i < nrcards; i++)
 990                 if (cards[i].sp) {
 991                         init_chan(c++, i, 1, ces++);
 992                         ces %= 0xffff;
 993                         init_chan(c++, i, 0, ces++);
 994                         ces %= 0xffff;
 995                 }
 996         printk(KERN_INFO "channels %d\n", chancount);
 997         return (chancount);
 998 
 999 }
1000 
1001 static void
1002 release_is(int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
1003 {
1004         struct PStack  *st = &chanlist[chan].is;
1005 
1006         releasestack_isdnl2(st);
1007         teles_rmlist(st->l1.hardware, st);
1008         BufQueueRelease(&st->l2.i_queue);
1009 }
1010 
1011 static void
1012 release_chan(int chan)
     /* [previous][next][first][last][top][bottom][index][help] */
1013 {
1014 #if 0
1015         release_ds(chan);
1016 #endif
1017         release_is(chan);
1018 }
1019 
1020 void
1021 CallcFreeChan(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1022 {
1023         int             i;
1024 
1025         for (i = 0; i < chancount; i++)
1026                 release_chan(i);
1027         Sfree((void *) chanlist);
1028 }
1029 
1030 static void
1031 lldata_handler(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1032                void *arg)
1033 {
1034         struct Channel *chanp = (struct Channel *) st->l4.userdata;
1035         byte           *ptr;
1036         int             size;
1037         struct BufHeader *ibh = arg;
1038 
1039         switch (pr) {
1040           case (DL_DATA):
1041                   if (chanp->data_open) {
1042                           ptr = DATAPTR(ibh);
1043                           ptr += chanp->ds.l2.ihsize;
1044                           size = ibh->datasize - chanp->ds.l2.ihsize;
1045                           iif.rcvcallb(drid, chanp->chan, ptr, size);
1046                   }
1047                   BufPoolRelease(ibh);
1048                   break;
1049           default:
1050                   printk(KERN_WARNING "lldata_handler unknown primitive\n");
1051                   break;
1052         }
1053 }
1054 
1055 static void
1056 lltrans_handler(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1057                 struct BufHeader *ibh)
1058 {
1059         struct Channel *chanp = (struct Channel *) st->l4.userdata;
1060         byte           *ptr;
1061 
1062         switch (pr) {
1063           case (PH_DATA):
1064                   if (chanp->data_open) {
1065                           ptr = DATAPTR(ibh);
1066                           iif.rcvcallb(drid, chanp->chan, ptr, ibh->datasize);
1067                   }
1068                   BufPoolRelease(ibh);
1069                   break;
1070           default:
1071                   printk(KERN_WARNING "lltrans_handler unknown primitive\n");
1072                   break;
1073         }
1074 }
1075 
1076 static void
1077 ll_writewakeup(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1078 {
1079         struct Channel *chanp = st->l4.userdata;
1080         isdn_ctrl       ic;
1081 
1082         ic.driver = drid;
1083         ic.command = ISDN_STAT_BSENT;
1084         ic.arg = chanp->chan;
1085         iif.statcallb(&ic);
1086 }
1087 
1088 static int
1089 init_ds(int chan, int incoming)
     /* [previous][next][first][last][top][bottom][index][help] */
1090 {
1091         struct PStack  *st = &(chanlist[chan].ds);
1092         struct IsdnCardState *sp = (struct IsdnCardState *)
1093         chanlist[chan].is.l1.hardware;
1094         struct HscxState *hsp = sp->hs + chanlist[chan].hscx;
1095         char            tmp[128];
1096 
1097         st->l1.hardware = sp;
1098 
1099         hsp->mode = 2;
1100         hsp->transbufsize = 4000;
1101 
1102         if (setstack_hscx(st, hsp))
1103                 return (-1);
1104 
1105         st->l2.extended = 0;
1106         st->l2.laptype = LAPB;
1107         st->l2.orig = !incoming;
1108         st->l2.t200 = 1000;        /* 1000 milliseconds */
1109         st->l2.window = 3;
1110         st->l2.n200 = 4;           /* try 4 times       */
1111         st->l2.t203 = 5000;        /* 5000 milliseconds */
1112 
1113         st->l2.debug = 0xff;
1114         st->l3.debug = 0xff;
1115         switch (chanlist[chan].l2_active_protocol) {
1116           case (ISDN_PROTO_L2_X75I):
1117                   sprintf(tmp, "Channel %d x.75", chan);
1118                   setstack_isdnl2(st, tmp);
1119                   st->l2.l2l3 = lldata_handler;
1120                   st->l1.l1man = dcc_l1man;
1121                   st->l2.l2man = dcc_l2man;
1122                   st->l4.userdata = chanlist + chan;
1123                   st->l4.l1writewakeup = NULL;
1124                   st->l4.l2writewakeup = ll_writewakeup;
1125                   st->l2.l2m.debug = debugflags & 16;
1126                   st->ma.manl2(st, MDL_NOTEIPROC, NULL);
1127                   st->l1.hscxmode = 2;        /* Packet-Mode ? */
1128                   st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
1129                   break;
1130           case (ISDN_PROTO_L2_HDLC):
1131                   st->l1.l1l2 = lltrans_handler;
1132                   st->l1.l1man = dcc_l1man;
1133                   st->l4.userdata = chanlist + chan;
1134                   st->l4.l1writewakeup = ll_writewakeup;
1135                   st->l1.hscxmode = 2;
1136                   st->l1.hscxchannel = chanlist[chan].para.bchannel - 1;
1137                   break;
1138         }
1139 
1140         return (0);
1141 
1142 }
1143 
1144 static void
1145 channel_report(int i)
     /* [previous][next][first][last][top][bottom][index][help] */
1146 {
1147 }
1148 
1149 static void
1150 command_debug(struct Channel *chanp, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
1151 {
1152         char            tmp[64], tm[32];
1153 
1154         jiftime(tm, jiffies);
1155         sprintf(tmp, "%s Channel %d LL->HL %s\n", tm, chanp->chan, s);
1156         teles_putstatus(tmp);
1157 }
1158 
1159 static void
1160 distr_debug(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1161 {
1162         int             i;
1163 
1164         for (i = 0; i < chancount; i++) {
1165                 chanlist[i].debug = debugflags & 1;
1166                 chanlist[i].fi.debug = debugflags & 2;
1167                 chanlist[i].is.l2.l2m.debug = debugflags & 8;
1168                 chanlist[i].ds.l2.l2m.debug = debugflags & 16;
1169         }
1170         for (i = 0; i < nrcards; i++)
1171                 if (cards[i].sp)
1172                         cards[i].sp->dlogflag = debugflags & 4;
1173 }
1174 
1175 int
1176 teles_command(isdn_ctrl * ic)
     /* [previous][next][first][last][top][bottom][index][help] */
1177 {
1178         struct Channel *chanp;
1179         char            tmp[64];
1180         int             i;
1181         unsigned int    num;
1182 
1183         switch (ic->command) {
1184           case (ISDN_CMD_SETEAZ):
1185                   chanp = chanlist + ic->arg;
1186                   if (chanp->debug & 1)
1187                           command_debug(chanp, "SETEAZ");
1188                   return (0);
1189           case (ISDN_CMD_DIAL):
1190                   chanp = chanlist + (ic->arg & 0xff);
1191                   if (chanp->debug & 1) {
1192                           sprintf(tmp, "DIAL %s", ic->num);
1193                           command_debug(chanp, tmp);
1194                   }
1195                   FsmEvent(&chanp->fi, EV_DIAL, ic);
1196                   return (0);
1197           case (ISDN_CMD_ACCEPTB):
1198                   chanp = chanlist + ic->arg;
1199                   if (chanp->debug & 1)
1200                           command_debug(chanp, "ACCEPTB");
1201                   FsmEvent(&chanp->fi, EV_ACCEPTB, NULL);
1202                   break;
1203           case (ISDN_CMD_ACCEPTD):
1204                   chanp = chanlist + ic->arg;
1205                   if (chanp->debug & 1)
1206                           command_debug(chanp, "ACCEPTD");
1207                   FsmEvent(&chanp->fi, EV_ACCEPTD, NULL);
1208                   break;
1209           case (ISDN_CMD_HANGUP):
1210                   chanp = chanlist + ic->arg;
1211                   if (chanp->debug & 1)
1212                           command_debug(chanp, "HANGUP");
1213                   FsmEvent(&chanp->fi, EV_HANGUP, NULL);
1214                   break;
1215           case (ISDN_CMD_LOCK):
1216                   teles_mod_inc_use_count();
1217                   break;
1218           case (ISDN_CMD_UNLOCK):
1219                   teles_mod_dec_use_count();
1220                   break;
1221           case (ISDN_CMD_IOCTL):
1222                   switch (ic->arg) {
1223                     case (0):
1224                             for (i = 0; i < nrcards; i++)
1225                                     if (cards[i].sp)
1226                                             teles_reportcard(i);
1227                             for (i = 0; i < chancount; i++)
1228                                     channel_report(i);
1229                             break;
1230                     case (1):
1231                             debugflags = *(unsigned int *) ic->num;
1232                             distr_debug();
1233                             sprintf(tmp, "debugging flags set to %x\n", debugflags);
1234                             teles_putstatus(tmp);
1235                             break;
1236                     case (2):
1237                             num = *(unsigned int *) ic->num;
1238                             i = num >> 8;
1239                             if (i >= chancount)
1240                                     break;
1241                             chanp = chanlist + i;
1242                             chanp->impair = num & 0xff;
1243                             if (chanp->debug & 1) {
1244                                     sprintf(tmp, "IMPAIR %x", chanp->impair);
1245                                     command_debug(chanp, tmp);
1246                             }
1247                             break;
1248                   }
1249                   break;
1250           case (ISDN_CMD_SETL2):
1251                   chanp = chanlist + (ic->arg & 0xff);
1252                   if (chanp->debug & 1) {
1253                           sprintf(tmp, "SETL2 %ld", ic->arg >> 8);
1254                           command_debug(chanp, tmp);
1255                   }
1256                   chanp->l2_protocol = ic->arg >> 8;
1257                   break;
1258           default:
1259                   break;
1260         }
1261 
1262         return (0);
1263 }
1264 
1265 int
1266 teles_writebuf(int id, int chan, const u_char * buf, int count, int user)
     /* [previous][next][first][last][top][bottom][index][help] */
1267 {
1268         struct Channel *chanp = chanlist + chan;
1269         struct PStack  *st = &chanp->ds;
1270         struct BufHeader *ibh;
1271         int             err, i;
1272         byte           *ptr;
1273 
1274         err = BufPoolGet(&ibh, st->l1.sbufpool, GFP_ATOMIC, st, 21);
1275         if (err)
1276                 return (0);
1277 
1278         if (count > BUFFER_SIZE(HSCX_SBUF_ORDER, HSCX_SBUF_BPPS)) {
1279                 printk(KERN_WARNING "teles_writebuf: packet too large!\n");
1280                 return (-EINVAL);
1281         }
1282         ptr = DATAPTR(ibh);
1283         if (chanp->lc_b.l2_establish)
1284                 i = st->l2.ihsize;
1285         else
1286                 i = 0;
1287 
1288         ptr += i;
1289 
1290         if (user)
1291                 memcpy_fromfs(ptr, buf, count);
1292         else
1293                 memcpy(ptr, buf, count);
1294         ibh->datasize = count + i;
1295 
1296         if (chanp->data_open) {
1297                 if (chanp->lc_b.l2_establish)
1298                         chanp->ds.l3.l3l2(&chanp->ds, DL_DATA, ibh);
1299                 else
1300                         chanp->ds.l2.l2l1(&chanp->ds, PH_DATA, ibh);
1301                 return (count);
1302         } else {
1303                 BufPoolRelease(ibh);
1304                 return (0);
1305         }
1306 
1307 }
1308 
1309 static char    *
1310 strcpyupto(char *dest, char *src, char upto)
     /* [previous][next][first][last][top][bottom][index][help] */
1311 {
1312         while (*src && (*src != upto) && (*src != '\0'))
1313                 *dest++ = *src++;
1314         *dest = '\0';
1315         return (src);
1316 }

/* [previous][next][first][last][top][bottom][index][help] */