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. r2_1
  8. r2_2
  9. r3
  10. r3_1
  11. r4
  12. r5
  13. r6
  14. r7
  15. r8
  16. r9
  17. r10
  18. r12
  19. prp
  20. r15
  21. r16
  22. r17
  23. r17_1
  24. r18
  25. r19
  26. r20
  27. r21
  28. r22
  29. r23
  30. r23_1
  31. r24
  32. r25
  33. r26
  34. lc_r1
  35. lc_r6
  36. lc_r2
  37. lc_r3
  38. lc_r4
  39. lc_r5
  40. CallcNew
  41. CallcFree
  42. release_ds
  43. cc_l1man
  44. cc_l2man
  45. dcc_l1man
  46. dcc_l2man
  47. ll_handler
  48. init_is
  49. callc_debug
  50. lc_debug
  51. dlc_debug
  52. lccall_d
  53. lccall_b
  54. init_chan
  55. CallcNewChan
  56. release_is
  57. release_chan
  58. CallcFreeChan
  59. lldata_handler
  60. lltrans_handler
  61. ll_writewakeup
  62. init_ds
  63. channel_report
  64. command_debug
  65. distr_debug
  66. teles_command
  67. teles_writebuf
  68. strcpyupto

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

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