linux/drivers/isdn/capi/capidrv.c
<<
>>
Prefs
   1/* $Id: capidrv.c,v 1.1.2.2 2004/01/12 23:17:24 keil Exp $
   2 *
   3 * ISDN4Linux Driver, using capi20 interface (kernelcapi)
   4 *
   5 * Copyright 1997 by Carsten Paeth <calle@calle.de>
   6 *
   7 * This software may be used and distributed according to the terms
   8 * of the GNU General Public License, incorporated herein by reference.
   9 *
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/errno.h>
  14#include <linux/kernel.h>
  15#include <linux/major.h>
  16#include <linux/slab.h>
  17#include <linux/fcntl.h>
  18#include <linux/fs.h>
  19#include <linux/signal.h>
  20#include <linux/mm.h>
  21#include <linux/timer.h>
  22#include <linux/wait.h>
  23#include <linux/skbuff.h>
  24#include <linux/isdn.h>
  25#include <linux/isdnif.h>
  26#include <linux/proc_fs.h>
  27#include <linux/seq_file.h>
  28#include <linux/capi.h>
  29#include <linux/kernelcapi.h>
  30#include <linux/ctype.h>
  31#include <linux/init.h>
  32#include <linux/moduleparam.h>
  33
  34#include <linux/isdn/capiutil.h>
  35#include <linux/isdn/capicmd.h>
  36#include "capidrv.h"
  37
  38static int debugmode = 0;
  39
  40MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
  41MODULE_AUTHOR("Carsten Paeth");
  42MODULE_LICENSE("GPL");
  43module_param(debugmode, uint, S_IRUGO | S_IWUSR);
  44
  45/* -------- type definitions ----------------------------------------- */
  46
  47
  48struct capidrv_contr {
  49
  50        struct capidrv_contr *next;
  51        struct module *owner;
  52        u32 contrnr;
  53        char name[20];
  54
  55        /*
  56         * for isdn4linux
  57         */
  58        isdn_if interface;
  59        int myid;
  60
  61        /*
  62         * LISTEN state
  63         */
  64        int state;
  65        u32 cipmask;
  66        u32 cipmask2;
  67        struct timer_list listentimer;
  68
  69        /*
  70         * ID of capi message sent
  71         */
  72        u16 msgid;
  73
  74        /*
  75         * B-Channels
  76         */
  77        int nbchan;
  78        struct capidrv_bchan {
  79                struct capidrv_contr *contr;
  80                u8 msn[ISDN_MSNLEN];
  81                int l2;
  82                int l3;
  83                u8 num[ISDN_MSNLEN];
  84                u8 mynum[ISDN_MSNLEN];
  85                int si1;
  86                int si2;
  87                int incoming;
  88                int disconnecting;
  89                struct capidrv_plci {
  90                        struct capidrv_plci *next;
  91                        u32 plci;
  92                        u32 ncci;       /* ncci for CONNECT_ACTIVE_IND */
  93                        u16 msgid;      /* to identfy CONNECT_CONF */
  94                        int chan;
  95                        int state;
  96                        int leasedline;
  97                        struct capidrv_ncci {
  98                                struct capidrv_ncci *next;
  99                                struct capidrv_plci *plcip;
 100                                u32 ncci;
 101                                u16 msgid;      /* to identfy CONNECT_B3_CONF */
 102                                int chan;
 103                                int state;
 104                                int oldstate;
 105                                /* */
 106                                u16 datahandle;
 107                                struct ncci_datahandle_queue {
 108                                        struct ncci_datahandle_queue *next;
 109                                        u16                         datahandle;
 110                                        int                           len;
 111                                } *ackqueue;
 112                        } *ncci_list;
 113                } *plcip;
 114                struct capidrv_ncci *nccip;
 115        } *bchans;
 116
 117        struct capidrv_plci *plci_list;
 118
 119        /* for q931 data */
 120        u8  q931_buf[4096];
 121        u8 *q931_read;
 122        u8 *q931_write;
 123        u8 *q931_end;
 124};
 125
 126
 127struct capidrv_data {
 128        struct capi20_appl ap;
 129        int ncontr;
 130        struct capidrv_contr *contr_list;
 131};
 132
 133typedef struct capidrv_plci capidrv_plci;
 134typedef struct capidrv_ncci capidrv_ncci;
 135typedef struct capidrv_contr capidrv_contr;
 136typedef struct capidrv_data capidrv_data;
 137typedef struct capidrv_bchan capidrv_bchan;
 138
 139/* -------- data definitions ----------------------------------------- */
 140
 141static capidrv_data global;
 142static DEFINE_SPINLOCK(global_lock);
 143
 144static void handle_dtrace_data(capidrv_contr *card,
 145                               int send, int level2, u8 *data, u16 len);
 146
 147/* -------- convert functions ---------------------------------------- */
 148
 149static inline u32 b1prot(int l2, int l3)
 150{
 151        switch (l2) {
 152        case ISDN_PROTO_L2_X75I:
 153        case ISDN_PROTO_L2_X75UI:
 154        case ISDN_PROTO_L2_X75BUI:
 155                return 0;
 156        case ISDN_PROTO_L2_HDLC:
 157        default:
 158                return 0;
 159        case ISDN_PROTO_L2_TRANS:
 160                return 1;
 161        case ISDN_PROTO_L2_V11096:
 162        case ISDN_PROTO_L2_V11019:
 163        case ISDN_PROTO_L2_V11038:
 164                return 2;
 165        case ISDN_PROTO_L2_FAX:
 166                return 4;
 167        case ISDN_PROTO_L2_MODEM:
 168                return 8;
 169        }
 170}
 171
 172static inline u32 b2prot(int l2, int l3)
 173{
 174        switch (l2) {
 175        case ISDN_PROTO_L2_X75I:
 176        case ISDN_PROTO_L2_X75UI:
 177        case ISDN_PROTO_L2_X75BUI:
 178        default:
 179                return 0;
 180        case ISDN_PROTO_L2_HDLC:
 181        case ISDN_PROTO_L2_TRANS:
 182        case ISDN_PROTO_L2_V11096:
 183        case ISDN_PROTO_L2_V11019:
 184        case ISDN_PROTO_L2_V11038:
 185        case ISDN_PROTO_L2_MODEM:
 186                return 1;
 187        case ISDN_PROTO_L2_FAX:
 188                return 4;
 189        }
 190}
 191
 192static inline u32 b3prot(int l2, int l3)
 193{
 194        switch (l2) {
 195        case ISDN_PROTO_L2_X75I:
 196        case ISDN_PROTO_L2_X75UI:
 197        case ISDN_PROTO_L2_X75BUI:
 198        case ISDN_PROTO_L2_HDLC:
 199        case ISDN_PROTO_L2_TRANS:
 200        case ISDN_PROTO_L2_V11096:
 201        case ISDN_PROTO_L2_V11019:
 202        case ISDN_PROTO_L2_V11038:
 203        case ISDN_PROTO_L2_MODEM:
 204        default:
 205                return 0;
 206        case ISDN_PROTO_L2_FAX:
 207                return 4;
 208        }
 209}
 210
 211static _cstruct b1config_async_v110(u16 rate)
 212{
 213        /* CAPI-Spec "B1 Configuration" */
 214        static unsigned char buf[9];
 215        buf[0] = 8; /* len */
 216        /* maximum bitrate */
 217        buf[1] = rate & 0xff; buf[2] = (rate >> 8) & 0xff;
 218        buf[3] = 8; buf[4] = 0; /* 8 bits per character */
 219        buf[5] = 0; buf[6] = 0; /* parity none */
 220        buf[7] = 0; buf[8] = 0; /* 1 stop bit */
 221        return buf;
 222}
 223
 224static _cstruct b1config(int l2, int l3)
 225{
 226        switch (l2) {
 227        case ISDN_PROTO_L2_X75I:
 228        case ISDN_PROTO_L2_X75UI:
 229        case ISDN_PROTO_L2_X75BUI:
 230        case ISDN_PROTO_L2_HDLC:
 231        case ISDN_PROTO_L2_TRANS:
 232        default:
 233                return NULL;
 234        case ISDN_PROTO_L2_V11096:
 235                return b1config_async_v110(9600);
 236        case ISDN_PROTO_L2_V11019:
 237                return b1config_async_v110(19200);
 238        case ISDN_PROTO_L2_V11038:
 239                return b1config_async_v110(38400);
 240        }
 241}
 242
 243static inline u16 si2cip(u8 si1, u8 si2)
 244{
 245        static const u8 cip[17][5] =
 246                {
 247                        /*  0  1  2  3  4  */
 248                        {0, 0, 0, 0, 0},        /*0 */
 249                        {16, 16, 4, 26, 16},    /*1 */
 250                        {17, 17, 17, 4, 4},     /*2 */
 251                        {2, 2, 2, 2, 2},        /*3 */
 252                        {18, 18, 18, 18, 18},   /*4 */
 253                        {2, 2, 2, 2, 2},        /*5 */
 254                        {0, 0, 0, 0, 0},        /*6 */
 255                        {2, 2, 2, 2, 2},        /*7 */
 256                        {2, 2, 2, 2, 2},        /*8 */
 257                        {21, 21, 21, 21, 21},   /*9 */
 258                        {19, 19, 19, 19, 19},   /*10 */
 259                        {0, 0, 0, 0, 0},        /*11 */
 260                        {0, 0, 0, 0, 0},        /*12 */
 261                        {0, 0, 0, 0, 0},        /*13 */
 262                        {0, 0, 0, 0, 0},        /*14 */
 263                        {22, 22, 22, 22, 22},   /*15 */
 264                        {27, 27, 27, 28, 27}    /*16 */
 265                };
 266        if (si1 > 16)
 267                si1 = 0;
 268        if (si2 > 4)
 269                si2 = 0;
 270
 271        return (u16) cip[si1][si2];
 272}
 273
 274static inline u8 cip2si1(u16 cipval)
 275{
 276        static const u8 si[32] =
 277                {7, 1, 7, 7, 1, 1, 7, 7,        /*0-7 */
 278                 7, 1, 0, 0, 0, 0, 0, 0,        /*8-15 */
 279                 1, 2, 4, 10, 9, 9, 15, 7,      /*16-23 */
 280                 7, 7, 1, 16, 16, 0, 0, 0};     /*24-31 */
 281
 282        if (cipval > 31)
 283                cipval = 0;     /* .... */
 284        return si[cipval];
 285}
 286
 287static inline u8 cip2si2(u16 cipval)
 288{
 289        static const u8 si[32] =
 290                {0, 0, 0, 0, 2, 3, 0, 0,        /*0-7 */
 291                 0, 3, 0, 0, 0, 0, 0, 0,        /*8-15 */
 292                 1, 2, 0, 0, 9, 0, 0, 0,        /*16-23 */
 293                 0, 0, 3, 2, 3, 0, 0, 0};       /*24-31 */
 294
 295        if (cipval > 31)
 296                cipval = 0;     /* .... */
 297        return si[cipval];
 298}
 299
 300
 301/* -------- controller management ------------------------------------- */
 302
 303static inline capidrv_contr *findcontrbydriverid(int driverid)
 304{
 305        unsigned long flags;
 306        capidrv_contr *p;
 307
 308        spin_lock_irqsave(&global_lock, flags);
 309        for (p = global.contr_list; p; p = p->next)
 310                if (p->myid == driverid)
 311                        break;
 312        spin_unlock_irqrestore(&global_lock, flags);
 313        return p;
 314}
 315
 316static capidrv_contr *findcontrbynumber(u32 contr)
 317{
 318        unsigned long flags;
 319        capidrv_contr *p = global.contr_list;
 320
 321        spin_lock_irqsave(&global_lock, flags);
 322        for (p = global.contr_list; p; p = p->next)
 323                if (p->contrnr == contr)
 324                        break;
 325        spin_unlock_irqrestore(&global_lock, flags);
 326        return p;
 327}
 328
 329
 330/* -------- plci management ------------------------------------------ */
 331
 332static capidrv_plci *new_plci(capidrv_contr *card, int chan)
 333{
 334        capidrv_plci *plcip;
 335
 336        plcip = kzalloc(sizeof(capidrv_plci), GFP_ATOMIC);
 337
 338        if (plcip == NULL)
 339                return NULL;
 340
 341        plcip->state = ST_PLCI_NONE;
 342        plcip->plci = 0;
 343        plcip->msgid = 0;
 344        plcip->chan = chan;
 345        plcip->next = card->plci_list;
 346        card->plci_list = plcip;
 347        card->bchans[chan].plcip = plcip;
 348
 349        return plcip;
 350}
 351
 352static capidrv_plci *find_plci_by_plci(capidrv_contr *card, u32 plci)
 353{
 354        capidrv_plci *p;
 355        for (p = card->plci_list; p; p = p->next)
 356                if (p->plci == plci)
 357                        return p;
 358        return NULL;
 359}
 360
 361static capidrv_plci *find_plci_by_msgid(capidrv_contr *card, u16 msgid)
 362{
 363        capidrv_plci *p;
 364        for (p = card->plci_list; p; p = p->next)
 365                if (p->msgid == msgid)
 366                        return p;
 367        return NULL;
 368}
 369
 370static capidrv_plci *find_plci_by_ncci(capidrv_contr *card, u32 ncci)
 371{
 372        capidrv_plci *p;
 373        for (p = card->plci_list; p; p = p->next)
 374                if (p->plci == (ncci & 0xffff))
 375                        return p;
 376        return NULL;
 377}
 378
 379static void free_plci(capidrv_contr *card, capidrv_plci *plcip)
 380{
 381        capidrv_plci **pp;
 382
 383        for (pp = &card->plci_list; *pp; pp = &(*pp)->next) {
 384                if (*pp == plcip) {
 385                        *pp = (*pp)->next;
 386                        card->bchans[plcip->chan].plcip = NULL;
 387                        card->bchans[plcip->chan].disconnecting = 0;
 388                        card->bchans[plcip->chan].incoming = 0;
 389                        kfree(plcip);
 390                        return;
 391                }
 392        }
 393        printk(KERN_ERR "capidrv-%d: free_plci %p (0x%x) not found, Huh?\n",
 394               card->contrnr, plcip, plcip->plci);
 395}
 396
 397/* -------- ncci management ------------------------------------------ */
 398
 399static inline capidrv_ncci *new_ncci(capidrv_contr *card,
 400                                     capidrv_plci *plcip,
 401                                     u32 ncci)
 402{
 403        capidrv_ncci *nccip;
 404
 405        nccip = kzalloc(sizeof(capidrv_ncci), GFP_ATOMIC);
 406
 407        if (nccip == NULL)
 408                return NULL;
 409
 410        nccip->ncci = ncci;
 411        nccip->state = ST_NCCI_NONE;
 412        nccip->plcip = plcip;
 413        nccip->chan = plcip->chan;
 414        nccip->datahandle = 0;
 415
 416        nccip->next = plcip->ncci_list;
 417        plcip->ncci_list = nccip;
 418
 419        card->bchans[plcip->chan].nccip = nccip;
 420
 421        return nccip;
 422}
 423
 424static inline capidrv_ncci *find_ncci(capidrv_contr *card, u32 ncci)
 425{
 426        capidrv_plci *plcip;
 427        capidrv_ncci *p;
 428
 429        if ((plcip = find_plci_by_ncci(card, ncci)) == NULL)
 430                return NULL;
 431
 432        for (p = plcip->ncci_list; p; p = p->next)
 433                if (p->ncci == ncci)
 434                        return p;
 435        return NULL;
 436}
 437
 438static inline capidrv_ncci *find_ncci_by_msgid(capidrv_contr *card,
 439                                               u32 ncci, u16 msgid)
 440{
 441        capidrv_plci *plcip;
 442        capidrv_ncci *p;
 443
 444        if ((plcip = find_plci_by_ncci(card, ncci)) == NULL)
 445                return NULL;
 446
 447        for (p = plcip->ncci_list; p; p = p->next)
 448                if (p->msgid == msgid)
 449                        return p;
 450        return NULL;
 451}
 452
 453static void free_ncci(capidrv_contr *card, struct capidrv_ncci *nccip)
 454{
 455        struct capidrv_ncci **pp;
 456
 457        for (pp = &(nccip->plcip->ncci_list); *pp; pp = &(*pp)->next) {
 458                if (*pp == nccip) {
 459                        *pp = (*pp)->next;
 460                        break;
 461                }
 462        }
 463        card->bchans[nccip->chan].nccip = NULL;
 464        kfree(nccip);
 465}
 466
 467static int capidrv_add_ack(struct capidrv_ncci *nccip,
 468                           u16 datahandle, int len)
 469{
 470        struct ncci_datahandle_queue *n, **pp;
 471
 472        n = kmalloc(sizeof(struct ncci_datahandle_queue), GFP_ATOMIC);
 473        if (!n) {
 474                printk(KERN_ERR "capidrv: kmalloc ncci_datahandle failed\n");
 475                return -1;
 476        }
 477        n->next = NULL;
 478        n->datahandle = datahandle;
 479        n->len = len;
 480        for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next);
 481        *pp = n;
 482        return 0;
 483}
 484
 485static int capidrv_del_ack(struct capidrv_ncci *nccip, u16 datahandle)
 486{
 487        struct ncci_datahandle_queue **pp, *p;
 488        int len;
 489
 490        for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) {
 491                if ((*pp)->datahandle == datahandle) {
 492                        p = *pp;
 493                        len = p->len;
 494                        *pp = (*pp)->next;
 495                        kfree(p);
 496                        return len;
 497                }
 498        }
 499        return -1;
 500}
 501
 502/* -------- convert and send capi message ---------------------------- */
 503
 504static void send_message(capidrv_contr *card, _cmsg *cmsg)
 505{
 506        struct sk_buff *skb;
 507        size_t len;
 508
 509        if (capi_cmsg2message(cmsg, cmsg->buf)) {
 510                printk(KERN_ERR "capidrv::send_message: parser failure\n");
 511                return;
 512        }
 513        len = CAPIMSG_LEN(cmsg->buf);
 514        skb = alloc_skb(len, GFP_ATOMIC);
 515        if (!skb) {
 516                printk(KERN_ERR "capidrv::send_message: can't allocate mem\n");
 517                return;
 518        }
 519        skb_put_data(skb, cmsg->buf, len);
 520        if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
 521                kfree_skb(skb);
 522}
 523
 524/* -------- state machine -------------------------------------------- */
 525
 526struct listenstatechange {
 527        int actstate;
 528        int nextstate;
 529        int event;
 530};
 531
 532static struct listenstatechange listentable[] =
 533{
 534        {ST_LISTEN_NONE, ST_LISTEN_WAIT_CONF, EV_LISTEN_REQ},
 535        {ST_LISTEN_ACTIVE, ST_LISTEN_ACTIVE_WAIT_CONF, EV_LISTEN_REQ},
 536        {ST_LISTEN_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_ERROR},
 537        {ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_ERROR},
 538        {ST_LISTEN_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_EMPTY},
 539        {ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_NONE, EV_LISTEN_CONF_EMPTY},
 540        {ST_LISTEN_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_OK},
 541        {ST_LISTEN_ACTIVE_WAIT_CONF, ST_LISTEN_ACTIVE, EV_LISTEN_CONF_OK},
 542        {},
 543};
 544
 545static void listen_change_state(capidrv_contr *card, int event)
 546{
 547        struct listenstatechange *p = listentable;
 548        while (p->event) {
 549                if (card->state == p->actstate && p->event == event) {
 550                        if (debugmode)
 551                                printk(KERN_DEBUG "capidrv-%d: listen_change_state %d -> %d\n",
 552                                       card->contrnr, card->state, p->nextstate);
 553                        card->state = p->nextstate;
 554                        return;
 555                }
 556                p++;
 557        }
 558        printk(KERN_ERR "capidrv-%d: listen_change_state state=%d event=%d ????\n",
 559               card->contrnr, card->state, event);
 560
 561}
 562
 563/* ------------------------------------------------------------------ */
 564
 565static void p0(capidrv_contr *card, capidrv_plci *plci)
 566{
 567        isdn_ctrl cmd;
 568
 569        card->bchans[plci->chan].contr = NULL;
 570        cmd.command = ISDN_STAT_DHUP;
 571        cmd.driver = card->myid;
 572        cmd.arg = plci->chan;
 573        card->interface.statcallb(&cmd);
 574        free_plci(card, plci);
 575}
 576
 577/* ------------------------------------------------------------------ */
 578
 579struct plcistatechange {
 580        int actstate;
 581        int nextstate;
 582        int event;
 583        void (*changefunc)(capidrv_contr *card, capidrv_plci *plci);
 584};
 585
 586static struct plcistatechange plcitable[] =
 587{
 588        /* P-0 */
 589        {ST_PLCI_NONE, ST_PLCI_OUTGOING, EV_PLCI_CONNECT_REQ, NULL},
 590        {ST_PLCI_NONE, ST_PLCI_ALLOCATED, EV_PLCI_FACILITY_IND_UP, NULL},
 591        {ST_PLCI_NONE, ST_PLCI_INCOMING, EV_PLCI_CONNECT_IND, NULL},
 592        {ST_PLCI_NONE, ST_PLCI_RESUMEING, EV_PLCI_RESUME_REQ, NULL},
 593        /* P-0.1 */
 594        {ST_PLCI_OUTGOING, ST_PLCI_NONE, EV_PLCI_CONNECT_CONF_ERROR, p0},
 595        {ST_PLCI_OUTGOING, ST_PLCI_ALLOCATED, EV_PLCI_CONNECT_CONF_OK, NULL},
 596        /* P-1 */
 597        {ST_PLCI_ALLOCATED, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
 598        {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
 599        {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
 600        {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
 601        /* P-ACT */
 602        {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
 603        {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
 604        {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
 605        {ST_PLCI_ACTIVE, ST_PLCI_HELD, EV_PLCI_HOLD_IND, NULL},
 606        {ST_PLCI_ACTIVE, ST_PLCI_DISCONNECTING, EV_PLCI_SUSPEND_IND, NULL},
 607        /* P-2 */
 608        {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_CONNECT_REJECT, NULL},
 609        {ST_PLCI_INCOMING, ST_PLCI_FACILITY_IND, EV_PLCI_FACILITY_IND_UP, NULL},
 610        {ST_PLCI_INCOMING, ST_PLCI_ACCEPTING, EV_PLCI_CONNECT_RESP, NULL},
 611        {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
 612        {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
 613        {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
 614        {ST_PLCI_INCOMING, ST_PLCI_DISCONNECTING, EV_PLCI_CD_IND, NULL},
 615        /* P-3 */
 616        {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_CONNECT_REJECT, NULL},
 617        {ST_PLCI_FACILITY_IND, ST_PLCI_ACCEPTING, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
 618        {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
 619        {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
 620        {ST_PLCI_FACILITY_IND, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
 621        /* P-4 */
 622        {ST_PLCI_ACCEPTING, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, NULL},
 623        {ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, NULL},
 624        {ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, NULL},
 625        {ST_PLCI_ACCEPTING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
 626        /* P-5 */
 627        {ST_PLCI_DISCONNECTING, ST_PLCI_DISCONNECTED, EV_PLCI_DISCONNECT_IND, NULL},
 628        /* P-6 */
 629        {ST_PLCI_DISCONNECTED, ST_PLCI_NONE, EV_PLCI_DISCONNECT_RESP, p0},
 630        /* P-0.Res */
 631        {ST_PLCI_RESUMEING, ST_PLCI_NONE, EV_PLCI_RESUME_CONF_ERROR, p0},
 632        {ST_PLCI_RESUMEING, ST_PLCI_RESUME, EV_PLCI_RESUME_CONF_OK, NULL},
 633        /* P-RES */
 634        {ST_PLCI_RESUME, ST_PLCI_ACTIVE, EV_PLCI_RESUME_IND, NULL},
 635        /* P-HELD */
 636        {ST_PLCI_HELD, ST_PLCI_ACTIVE, EV_PLCI_RETRIEVE_IND, NULL},
 637        {},
 638};
 639
 640static void plci_change_state(capidrv_contr *card, capidrv_plci *plci, int event)
 641{
 642        struct plcistatechange *p = plcitable;
 643        while (p->event) {
 644                if (plci->state == p->actstate && p->event == event) {
 645                        if (debugmode)
 646                                printk(KERN_DEBUG "capidrv-%d: plci_change_state:0x%x %d -> %d\n",
 647                                       card->contrnr, plci->plci, plci->state, p->nextstate);
 648                        plci->state = p->nextstate;
 649                        if (p->changefunc)
 650                                p->changefunc(card, plci);
 651                        return;
 652                }
 653                p++;
 654        }
 655        printk(KERN_ERR "capidrv-%d: plci_change_state:0x%x state=%d event=%d ????\n",
 656               card->contrnr, plci->plci, plci->state, event);
 657}
 658
 659/* ------------------------------------------------------------------ */
 660
 661static _cmsg cmsg;
 662
 663static void n0(capidrv_contr *card, capidrv_ncci *ncci)
 664{
 665        isdn_ctrl cmd;
 666
 667        capi_fill_DISCONNECT_REQ(&cmsg,
 668                                 global.ap.applid,
 669                                 card->msgid++,
 670                                 ncci->plcip->plci,
 671                                 NULL,  /* BChannelinformation */
 672                                 NULL,  /* Keypadfacility */
 673                                 NULL,  /* Useruserdata */   /* $$$$ */
 674                                 NULL   /* Facilitydataarray */
 675                );
 676        plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
 677        send_message(card, &cmsg);
 678
 679        cmd.command = ISDN_STAT_BHUP;
 680        cmd.driver = card->myid;
 681        cmd.arg = ncci->chan;
 682        card->interface.statcallb(&cmd);
 683        free_ncci(card, ncci);
 684}
 685
 686/* ------------------------------------------------------------------ */
 687
 688struct nccistatechange {
 689        int actstate;
 690        int nextstate;
 691        int event;
 692        void (*changefunc)(capidrv_contr *card, capidrv_ncci *ncci);
 693};
 694
 695static struct nccistatechange nccitable[] =
 696{
 697        /* N-0 */
 698        {ST_NCCI_NONE, ST_NCCI_OUTGOING, EV_NCCI_CONNECT_B3_REQ, NULL},
 699        {ST_NCCI_NONE, ST_NCCI_INCOMING, EV_NCCI_CONNECT_B3_IND, NULL},
 700        /* N-0.1 */
 701        {ST_NCCI_OUTGOING, ST_NCCI_ALLOCATED, EV_NCCI_CONNECT_B3_CONF_OK, NULL},
 702        {ST_NCCI_OUTGOING, ST_NCCI_NONE, EV_NCCI_CONNECT_B3_CONF_ERROR, n0},
 703        /* N-1 */
 704        {ST_NCCI_INCOMING, ST_NCCI_DISCONNECTING, EV_NCCI_CONNECT_B3_REJECT, NULL},
 705        {ST_NCCI_INCOMING, ST_NCCI_ALLOCATED, EV_NCCI_CONNECT_B3_RESP, NULL},
 706        {ST_NCCI_INCOMING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
 707        {ST_NCCI_INCOMING, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
 708        /* N-2 */
 709        {ST_NCCI_ALLOCATED, ST_NCCI_ACTIVE, EV_NCCI_CONNECT_B3_ACTIVE_IND, NULL},
 710        {ST_NCCI_ALLOCATED, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
 711        {ST_NCCI_ALLOCATED, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
 712        /* N-ACT */
 713        {ST_NCCI_ACTIVE, ST_NCCI_ACTIVE, EV_NCCI_RESET_B3_IND, NULL},
 714        {ST_NCCI_ACTIVE, ST_NCCI_RESETING, EV_NCCI_RESET_B3_REQ, NULL},
 715        {ST_NCCI_ACTIVE, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
 716        {ST_NCCI_ACTIVE, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
 717        /* N-3 */
 718        {ST_NCCI_RESETING, ST_NCCI_ACTIVE, EV_NCCI_RESET_B3_IND, NULL},
 719        {ST_NCCI_RESETING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
 720        {ST_NCCI_RESETING, ST_NCCI_DISCONNECTING, EV_NCCI_DISCONNECT_B3_REQ, NULL},
 721        /* N-4 */
 722        {ST_NCCI_DISCONNECTING, ST_NCCI_DISCONNECTED, EV_NCCI_DISCONNECT_B3_IND, NULL},
 723        {ST_NCCI_DISCONNECTING, ST_NCCI_PREVIOUS, EV_NCCI_DISCONNECT_B3_CONF_ERROR, NULL},
 724        /* N-5 */
 725        {ST_NCCI_DISCONNECTED, ST_NCCI_NONE, EV_NCCI_DISCONNECT_B3_RESP, n0},
 726        {},
 727};
 728
 729static void ncci_change_state(capidrv_contr *card, capidrv_ncci *ncci, int event)
 730{
 731        struct nccistatechange *p = nccitable;
 732        while (p->event) {
 733                if (ncci->state == p->actstate && p->event == event) {
 734                        if (debugmode)
 735                                printk(KERN_DEBUG "capidrv-%d: ncci_change_state:0x%x %d -> %d\n",
 736                                       card->contrnr, ncci->ncci, ncci->state, p->nextstate);
 737                        if (p->nextstate == ST_NCCI_PREVIOUS) {
 738                                ncci->state = ncci->oldstate;
 739                                ncci->oldstate = p->actstate;
 740                        } else {
 741                                ncci->oldstate = p->actstate;
 742                                ncci->state = p->nextstate;
 743                        }
 744                        if (p->changefunc)
 745                                p->changefunc(card, ncci);
 746                        return;
 747                }
 748                p++;
 749        }
 750        printk(KERN_ERR "capidrv-%d: ncci_change_state:0x%x state=%d event=%d ????\n",
 751               card->contrnr, ncci->ncci, ncci->state, event);
 752}
 753
 754/* ------------------------------------------------------------------- */
 755
 756static inline int new_bchan(capidrv_contr *card)
 757{
 758        int i;
 759        for (i = 0; i < card->nbchan; i++) {
 760                if (card->bchans[i].plcip == NULL) {
 761                        card->bchans[i].disconnecting = 0;
 762                        return i;
 763                }
 764        }
 765        return -1;
 766}
 767
 768/* ------------------------------------------------------------------- */
 769static char *capi_info2str(u16 reason)
 770{
 771#ifndef CONFIG_ISDN_CAPI_CAPIDRV_VERBOSE
 772        return "..";
 773#else
 774        switch (reason) {
 775
 776/*-- informative values (corresponding message was processed) -----*/
 777        case 0x0001:
 778                return "NCPI not supported by current protocol, NCPI ignored";
 779        case 0x0002:
 780                return "Flags not supported by current protocol, flags ignored";
 781        case 0x0003:
 782                return "Alert already sent by another application";
 783
 784/*-- error information concerning CAPI_REGISTER -----*/
 785        case 0x1001:
 786                return "Too many applications";
 787        case 0x1002:
 788                return "Logical block size too small, must be at least 128 Bytes";
 789        case 0x1003:
 790                return "Buffer exceeds 64 kByte";
 791        case 0x1004:
 792                return "Message buffer size too small, must be at least 1024 Bytes";
 793        case 0x1005:
 794                return "Max. number of logical connections not supported";
 795        case 0x1006:
 796                return "Reserved";
 797        case 0x1007:
 798                return "The message could not be accepted because of an internal busy condition";
 799        case 0x1008:
 800                return "OS resource error (no memory ?)";
 801        case 0x1009:
 802                return "CAPI not installed";
 803        case 0x100A:
 804                return "Controller does not support external equipment";
 805        case 0x100B:
 806                return "Controller does only support external equipment";
 807
 808/*-- error information concerning message exchange functions -----*/
 809        case 0x1101:
 810                return "Illegal application number";
 811        case 0x1102:
 812                return "Illegal command or subcommand or message length less than 12 bytes";
 813        case 0x1103:
 814                return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI";
 815        case 0x1104:
 816                return "Queue is empty";
 817        case 0x1105:
 818                return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE";
 819        case 0x1106:
 820                return "Unknown notification parameter";
 821        case 0x1107:
 822                return "The Message could not be accepted because of an internal busy condition";
 823        case 0x1108:
 824                return "OS Resource error (no memory ?)";
 825        case 0x1109:
 826                return "CAPI not installed";
 827        case 0x110A:
 828                return "Controller does not support external equipment";
 829        case 0x110B:
 830                return "Controller does only support external equipment";
 831
 832/*-- error information concerning resource / coding problems -----*/
 833        case 0x2001:
 834                return "Message not supported in current state";
 835        case 0x2002:
 836                return "Illegal Controller / PLCI / NCCI";
 837        case 0x2003:
 838                return "Out of PLCI";
 839        case 0x2004:
 840                return "Out of NCCI";
 841        case 0x2005:
 842                return "Out of LISTEN";
 843        case 0x2006:
 844                return "Out of FAX resources (protocol T.30)";
 845        case 0x2007:
 846                return "Illegal message parameter coding";
 847
 848/*-- error information concerning requested services  -----*/
 849        case 0x3001:
 850                return "B1 protocol not supported";
 851        case 0x3002:
 852                return "B2 protocol not supported";
 853        case 0x3003:
 854                return "B3 protocol not supported";
 855        case 0x3004:
 856                return "B1 protocol parameter not supported";
 857        case 0x3005:
 858                return "B2 protocol parameter not supported";
 859        case 0x3006:
 860                return "B3 protocol parameter not supported";
 861        case 0x3007:
 862                return "B protocol combination not supported";
 863        case 0x3008:
 864                return "NCPI not supported";
 865        case 0x3009:
 866                return "CIP Value unknown";
 867        case 0x300A:
 868                return "Flags not supported (reserved bits)";
 869        case 0x300B:
 870                return "Facility not supported";
 871        case 0x300C:
 872                return "Data length not supported by current protocol";
 873        case 0x300D:
 874                return "Reset procedure not supported by current protocol";
 875
 876/*-- informations about the clearing of a physical connection -----*/
 877        case 0x3301:
 878                return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)";
 879        case 0x3302:
 880                return "Protocol error layer 2";
 881        case 0x3303:
 882                return "Protocol error layer 3";
 883        case 0x3304:
 884                return "Another application got that call";
 885/*-- T.30 specific reasons -----*/
 886        case 0x3311:
 887                return "Connecting not successful (remote station is no FAX G3 machine)";
 888        case 0x3312:
 889                return "Connecting not successful (training error)";
 890        case 0x3313:
 891                return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)";
 892        case 0x3314:
 893                return "Disconnected during transfer (remote abort)";
 894        case 0x3315:
 895                return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)";
 896        case 0x3316:
 897                return "Disconnected during transfer (local tx data underrun)";
 898        case 0x3317:
 899                return "Disconnected during transfer (local rx data overflow)";
 900        case 0x3318:
 901                return "Disconnected during transfer (local abort)";
 902        case 0x3319:
 903                return "Illegal parameter coding (e.g. SFF coding error)";
 904
 905/*-- disconnect causes from the network according to ETS 300 102-1/Q.931 -----*/
 906        case 0x3481: return "Unallocated (unassigned) number";
 907        case 0x3482: return "No route to specified transit network";
 908        case 0x3483: return "No route to destination";
 909        case 0x3486: return "Channel unacceptable";
 910        case 0x3487:
 911                return "Call awarded and being delivered in an established channel";
 912        case 0x3490: return "Normal call clearing";
 913        case 0x3491: return "User busy";
 914        case 0x3492: return "No user responding";
 915        case 0x3493: return "No answer from user (user alerted)";
 916        case 0x3495: return "Call rejected";
 917        case 0x3496: return "Number changed";
 918        case 0x349A: return "Non-selected user clearing";
 919        case 0x349B: return "Destination out of order";
 920        case 0x349C: return "Invalid number format";
 921        case 0x349D: return "Facility rejected";
 922        case 0x349E: return "Response to STATUS ENQUIRY";
 923        case 0x349F: return "Normal, unspecified";
 924        case 0x34A2: return "No circuit / channel available";
 925        case 0x34A6: return "Network out of order";
 926        case 0x34A9: return "Temporary failure";
 927        case 0x34AA: return "Switching equipment congestion";
 928        case 0x34AB: return "Access information discarded";
 929        case 0x34AC: return "Requested circuit / channel not available";
 930        case 0x34AF: return "Resources unavailable, unspecified";
 931        case 0x34B1: return "Quality of service unavailable";
 932        case 0x34B2: return "Requested facility not subscribed";
 933        case 0x34B9: return "Bearer capability not authorized";
 934        case 0x34BA: return "Bearer capability not presently available";
 935        case 0x34BF: return "Service or option not available, unspecified";
 936        case 0x34C1: return "Bearer capability not implemented";
 937        case 0x34C2: return "Channel type not implemented";
 938        case 0x34C5: return "Requested facility not implemented";
 939        case 0x34C6: return "Only restricted digital information bearer capability is available";
 940        case 0x34CF: return "Service or option not implemented, unspecified";
 941        case 0x34D1: return "Invalid call reference value";
 942        case 0x34D2: return "Identified channel does not exist";
 943        case 0x34D3: return "A suspended call exists, but this call identity does not";
 944        case 0x34D4: return "Call identity in use";
 945        case 0x34D5: return "No call suspended";
 946        case 0x34D6: return "Call having the requested call identity has been cleared";
 947        case 0x34D8: return "Incompatible destination";
 948        case 0x34DB: return "Invalid transit network selection";
 949        case 0x34DF: return "Invalid message, unspecified";
 950        case 0x34E0: return "Mandatory information element is missing";
 951        case 0x34E1: return "Message type non-existent or not implemented";
 952        case 0x34E2: return "Message not compatible with call state or message type non-existent or not implemented";
 953        case 0x34E3: return "Information element non-existent or not implemented";
 954        case 0x34E4: return "Invalid information element contents";
 955        case 0x34E5: return "Message not compatible with call state";
 956        case 0x34E6: return "Recovery on timer expiry";
 957        case 0x34EF: return "Protocol error, unspecified";
 958        case 0x34FF: return "Interworking, unspecified";
 959
 960        default: return "No additional information";
 961        }
 962#endif
 963}
 964
 965static void handle_controller(_cmsg *cmsg)
 966{
 967        capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
 968
 969        if (!card) {
 970                printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",
 971                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
 972                       cmsg->adr.adrController & 0x7f);
 973                return;
 974        }
 975        switch (CAPICMD(cmsg->Command, cmsg->Subcommand)) {
 976
 977        case CAPI_LISTEN_CONF:  /* Controller */
 978                if (debugmode)
 979                        printk(KERN_DEBUG "capidrv-%d: listenconf Info=0x%4x (%s) cipmask=0x%x\n",
 980                               card->contrnr, cmsg->Info, capi_info2str(cmsg->Info), card->cipmask);
 981                if (cmsg->Info) {
 982                        listen_change_state(card, EV_LISTEN_CONF_ERROR);
 983                } else if (card->cipmask == 0) {
 984                        listen_change_state(card, EV_LISTEN_CONF_EMPTY);
 985                } else {
 986                        listen_change_state(card, EV_LISTEN_CONF_OK);
 987                }
 988                break;
 989
 990        case CAPI_MANUFACTURER_IND:     /* Controller */
 991                if (cmsg->ManuID == 0x214D5641
 992                    && cmsg->Class == 0
 993                    && cmsg->Function == 1) {
 994                        u8  *data = cmsg->ManuData + 3;
 995                        u16  len = cmsg->ManuData[0];
 996                        u16 layer;
 997                        int direction;
 998                        if (len == 255) {
 999                                len = (cmsg->ManuData[1] | (cmsg->ManuData[2] << 8));
1000                                data += 2;
1001                        }
1002                        len -= 2;
1003                        layer = ((*(data - 1)) << 8) | *(data - 2);
1004                        if (layer & 0x300)
1005                                direction = (layer & 0x200) ? 0 : 1;
1006                        else direction = (layer & 0x800) ? 0 : 1;
1007                        if (layer & 0x0C00) {
1008                                if ((layer & 0xff) == 0x80) {
1009                                        handle_dtrace_data(card, direction, 1, data, len);
1010                                        break;
1011                                }
1012                        } else if ((layer & 0xff) < 0x80) {
1013                                handle_dtrace_data(card, direction, 0, data, len);
1014                                break;
1015                        }
1016                        printk(KERN_INFO "capidrv-%d: %s from controller 0x%x layer 0x%x, ignored\n",
1017                               card->contrnr,
1018                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1019                               cmsg->adr.adrController, layer);
1020                        break;
1021                }
1022                goto ignored;
1023        case CAPI_MANUFACTURER_CONF:    /* Controller */
1024                if (cmsg->ManuID == 0x214D5641) {
1025                        char *s = NULL;
1026                        switch (cmsg->Class) {
1027                        case 0: break;
1028                        case 1: s = "unknown class"; break;
1029                        case 2: s = "unknown function"; break;
1030                        default: s = "unknown error"; break;
1031                        }
1032                        if (s)
1033                                printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
1034                                       card->contrnr,
1035                                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1036                                       cmsg->adr.adrController,
1037                                       cmsg->Function, s);
1038                        break;
1039                }
1040                goto ignored;
1041        case CAPI_FACILITY_IND: /* Controller/plci/ncci */
1042                goto ignored;
1043        case CAPI_FACILITY_CONF:        /* Controller/plci/ncci */
1044                goto ignored;
1045        case CAPI_INFO_IND:     /* Controller/plci */
1046                goto ignored;
1047        case CAPI_INFO_CONF:    /* Controller/plci */
1048                goto ignored;
1049
1050        default:
1051                printk(KERN_ERR "capidrv-%d: got %s from controller 0x%x ???",
1052                       card->contrnr,
1053                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1054                       cmsg->adr.adrController);
1055        }
1056        return;
1057
1058ignored:
1059        printk(KERN_INFO "capidrv-%d: %s from controller 0x%x ignored\n",
1060               card->contrnr,
1061               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1062               cmsg->adr.adrController);
1063}
1064
1065static void handle_incoming_call(capidrv_contr *card, _cmsg *cmsg)
1066{
1067        capidrv_plci *plcip;
1068        capidrv_bchan *bchan;
1069        isdn_ctrl cmd;
1070        int chan;
1071
1072        if ((chan = new_bchan(card)) == -1) {
1073                printk(KERN_ERR "capidrv-%d: incoming call on not existing bchan ?\n", card->contrnr);
1074                return;
1075        }
1076        bchan = &card->bchans[chan];
1077        if ((plcip = new_plci(card, chan)) == NULL) {
1078                printk(KERN_ERR "capidrv-%d: incoming call: no memory, sorry.\n", card->contrnr);
1079                return;
1080        }
1081        bchan->incoming = 1;
1082        plcip->plci = cmsg->adr.adrPLCI;
1083        plci_change_state(card, plcip, EV_PLCI_CONNECT_IND);
1084
1085        cmd.command = ISDN_STAT_ICALL;
1086        cmd.driver = card->myid;
1087        cmd.arg = chan;
1088        memset(&cmd.parm.setup, 0, sizeof(cmd.parm.setup));
1089        strncpy(cmd.parm.setup.phone,
1090                cmsg->CallingPartyNumber + 3,
1091                cmsg->CallingPartyNumber[0] - 2);
1092        strncpy(cmd.parm.setup.eazmsn,
1093                cmsg->CalledPartyNumber + 2,
1094                cmsg->CalledPartyNumber[0] - 1);
1095        cmd.parm.setup.si1 = cip2si1(cmsg->CIPValue);
1096        cmd.parm.setup.si2 = cip2si2(cmsg->CIPValue);
1097        cmd.parm.setup.plan = cmsg->CallingPartyNumber[1];
1098        cmd.parm.setup.screen = cmsg->CallingPartyNumber[2];
1099
1100        printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s\n",
1101               card->contrnr,
1102               cmd.parm.setup.phone,
1103               cmd.parm.setup.si1,
1104               cmd.parm.setup.si2,
1105               cmd.parm.setup.eazmsn);
1106
1107        if (cmd.parm.setup.si1 == 1 && cmd.parm.setup.si2 != 0) {
1108                printk(KERN_INFO "capidrv-%d: patching si2=%d to 0 for VBOX\n",
1109                       card->contrnr,
1110                       cmd.parm.setup.si2);
1111                cmd.parm.setup.si2 = 0;
1112        }
1113
1114        switch (card->interface.statcallb(&cmd)) {
1115        case 0:
1116        case 3:
1117                /* No device matching this call.
1118                 * and isdn_common.c has send a HANGUP command
1119                 * which is ignored in state ST_PLCI_INCOMING,
1120                 * so we send RESP to ignore the call
1121                 */
1122                capi_cmsg_answer(cmsg);
1123                cmsg->Reject = 1;       /* ignore */
1124                plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
1125                send_message(card, cmsg);
1126                printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
1127                       card->contrnr,
1128                       cmd.parm.setup.phone,
1129                       cmd.parm.setup.si1,
1130                       cmd.parm.setup.si2,
1131                       cmd.parm.setup.eazmsn);
1132                break;
1133        case 1:
1134                /* At least one device matching this call (RING on ttyI)
1135                 * HL-driver may send ALERTING on the D-channel in this
1136                 * case.
1137                 * really means: RING on ttyI or a net interface
1138                 * accepted this call already.
1139                 *
1140                 * If the call was accepted, state has already changed,
1141                 * and CONNECT_RESP already sent.
1142                 */
1143                if (plcip->state == ST_PLCI_INCOMING) {
1144                        printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s tty alerting\n",
1145                               card->contrnr,
1146                               cmd.parm.setup.phone,
1147                               cmd.parm.setup.si1,
1148                               cmd.parm.setup.si2,
1149                               cmd.parm.setup.eazmsn);
1150                        capi_fill_ALERT_REQ(cmsg,
1151                                            global.ap.applid,
1152                                            card->msgid++,
1153                                            plcip->plci,        /* adr */
1154                                            NULL,/* BChannelinformation */
1155                                            NULL,/* Keypadfacility */
1156                                            NULL,/* Useruserdata */
1157                                            NULL /* Facilitydataarray */
1158                                );
1159                        plcip->msgid = cmsg->Messagenumber;
1160                        send_message(card, cmsg);
1161                } else {
1162                        printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s on netdev\n",
1163                               card->contrnr,
1164                               cmd.parm.setup.phone,
1165                               cmd.parm.setup.si1,
1166                               cmd.parm.setup.si2,
1167                               cmd.parm.setup.eazmsn);
1168                }
1169                break;
1170
1171        case 2:         /* Call will be rejected. */
1172                capi_cmsg_answer(cmsg);
1173                cmsg->Reject = 2;       /* reject call, normal call clearing */
1174                plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
1175                send_message(card, cmsg);
1176                break;
1177
1178        default:
1179                /* An error happened. (Invalid parameters for example.) */
1180                capi_cmsg_answer(cmsg);
1181                cmsg->Reject = 8;       /* reject call,
1182                                           destination out of order */
1183                plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
1184                send_message(card, cmsg);
1185                break;
1186        }
1187        return;
1188}
1189
1190static void handle_plci(_cmsg *cmsg)
1191{
1192        capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
1193        capidrv_plci *plcip;
1194        isdn_ctrl cmd;
1195        _cdebbuf *cdb;
1196
1197        if (!card) {
1198                printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",
1199                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1200                       cmsg->adr.adrController & 0x7f);
1201                return;
1202        }
1203        switch (CAPICMD(cmsg->Command, cmsg->Subcommand)) {
1204
1205        case CAPI_DISCONNECT_IND:       /* plci */
1206                if (cmsg->Reason) {
1207                        printk(KERN_INFO "capidrv-%d: %s reason 0x%x (%s) for plci 0x%x\n",
1208                               card->contrnr,
1209                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1210                               cmsg->Reason, capi_info2str(cmsg->Reason), cmsg->adr.adrPLCI);
1211                }
1212                if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI))) {
1213                        capi_cmsg_answer(cmsg);
1214                        send_message(card, cmsg);
1215                        goto notfound;
1216                }
1217                card->bchans[plcip->chan].disconnecting = 1;
1218                plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND);
1219                capi_cmsg_answer(cmsg);
1220                plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP);
1221                send_message(card, cmsg);
1222                break;
1223
1224        case CAPI_DISCONNECT_CONF:      /* plci */
1225                if (cmsg->Info) {
1226                        printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n",
1227                               card->contrnr,
1228                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1229                               cmsg->Info, capi_info2str(cmsg->Info),
1230                               cmsg->adr.adrPLCI);
1231                }
1232                if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI)))
1233                        goto notfound;
1234
1235                card->bchans[plcip->chan].disconnecting = 1;
1236                break;
1237
1238        case CAPI_ALERT_CONF:   /* plci */
1239                if (cmsg->Info) {
1240                        printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n",
1241                               card->contrnr,
1242                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1243                               cmsg->Info, capi_info2str(cmsg->Info),
1244                               cmsg->adr.adrPLCI);
1245                }
1246                break;
1247
1248        case CAPI_CONNECT_IND:  /* plci */
1249                handle_incoming_call(card, cmsg);
1250                break;
1251
1252        case CAPI_CONNECT_CONF: /* plci */
1253                if (cmsg->Info) {
1254                        printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for plci 0x%x\n",
1255                               card->contrnr,
1256                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1257                               cmsg->Info, capi_info2str(cmsg->Info),
1258                               cmsg->adr.adrPLCI);
1259                }
1260                if (!(plcip = find_plci_by_msgid(card, cmsg->Messagenumber)))
1261                        goto notfound;
1262
1263                plcip->plci = cmsg->adr.adrPLCI;
1264                if (cmsg->Info) {
1265                        plci_change_state(card, plcip, EV_PLCI_CONNECT_CONF_ERROR);
1266                } else {
1267                        plci_change_state(card, plcip, EV_PLCI_CONNECT_CONF_OK);
1268                }
1269                break;
1270
1271        case CAPI_CONNECT_ACTIVE_IND:   /* plci */
1272
1273                if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI)))
1274                        goto notfound;
1275
1276                if (card->bchans[plcip->chan].incoming) {
1277                        capi_cmsg_answer(cmsg);
1278                        plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
1279                        send_message(card, cmsg);
1280                } else {
1281                        capidrv_ncci *nccip;
1282                        capi_cmsg_answer(cmsg);
1283                        send_message(card, cmsg);
1284
1285                        nccip = new_ncci(card, plcip, cmsg->adr.adrPLCI);
1286
1287                        if (!nccip) {
1288                                printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr);
1289                                break;  /* $$$$ */
1290                        }
1291                        capi_fill_CONNECT_B3_REQ(cmsg,
1292                                                 global.ap.applid,
1293                                                 card->msgid++,
1294                                                 plcip->plci,   /* adr */
1295                                                 NULL   /* NCPI */
1296                                );
1297                        nccip->msgid = cmsg->Messagenumber;
1298                        plci_change_state(card, plcip,
1299                                          EV_PLCI_CONNECT_ACTIVE_IND);
1300                        ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
1301                        send_message(card, cmsg);
1302                        cmd.command = ISDN_STAT_DCONN;
1303                        cmd.driver = card->myid;
1304                        cmd.arg = plcip->chan;
1305                        card->interface.statcallb(&cmd);
1306                }
1307                break;
1308
1309        case CAPI_INFO_IND:     /* Controller/plci */
1310
1311                if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI)))
1312                        goto notfound;
1313
1314                if (cmsg->InfoNumber == 0x4000) {
1315                        if (cmsg->InfoElement[0] == 4) {
1316                                cmd.command = ISDN_STAT_CINF;
1317                                cmd.driver = card->myid;
1318                                cmd.arg = plcip->chan;
1319                                sprintf(cmd.parm.num, "%lu",
1320                                        (unsigned long)
1321                                        ((u32) cmsg->InfoElement[1]
1322                                         | ((u32) (cmsg->InfoElement[2]) << 8)
1323                                         | ((u32) (cmsg->InfoElement[3]) << 16)
1324                                         | ((u32) (cmsg->InfoElement[4]) << 24)));
1325                                card->interface.statcallb(&cmd);
1326                                break;
1327                        }
1328                }
1329                cdb = capi_cmsg2str(cmsg);
1330                if (cdb) {
1331                        printk(KERN_WARNING "capidrv-%d: %s\n",
1332                               card->contrnr, cdb->buf);
1333                        cdebbuf_free(cdb);
1334                } else
1335                        printk(KERN_WARNING "capidrv-%d: CAPI_INFO_IND InfoNumber %x not handled\n",
1336                               card->contrnr, cmsg->InfoNumber);
1337
1338                break;
1339
1340        case CAPI_CONNECT_ACTIVE_CONF:          /* plci */
1341                goto ignored;
1342        case CAPI_SELECT_B_PROTOCOL_CONF:       /* plci */
1343                goto ignored;
1344        case CAPI_FACILITY_IND: /* Controller/plci/ncci */
1345                goto ignored;
1346        case CAPI_FACILITY_CONF:        /* Controller/plci/ncci */
1347                goto ignored;
1348
1349        case CAPI_INFO_CONF:    /* Controller/plci */
1350                goto ignored;
1351
1352        default:
1353                printk(KERN_ERR "capidrv-%d: got %s for plci 0x%x ???",
1354                       card->contrnr,
1355                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1356                       cmsg->adr.adrPLCI);
1357        }
1358        return;
1359ignored:
1360        printk(KERN_INFO "capidrv-%d: %s for plci 0x%x ignored\n",
1361               card->contrnr,
1362               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1363               cmsg->adr.adrPLCI);
1364        return;
1365notfound:
1366        printk(KERN_ERR "capidrv-%d: %s: plci 0x%x not found\n",
1367               card->contrnr,
1368               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1369               cmsg->adr.adrPLCI);
1370        return;
1371}
1372
1373static void handle_ncci(_cmsg *cmsg)
1374{
1375        capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
1376        capidrv_plci *plcip;
1377        capidrv_ncci *nccip;
1378        isdn_ctrl cmd;
1379        int len;
1380
1381        if (!card) {
1382                printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",
1383                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1384                       cmsg->adr.adrController & 0x7f);
1385                return;
1386        }
1387        switch (CAPICMD(cmsg->Command, cmsg->Subcommand)) {
1388
1389        case CAPI_CONNECT_B3_ACTIVE_IND:        /* ncci */
1390                if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
1391                        goto notfound;
1392
1393                capi_cmsg_answer(cmsg);
1394                ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND);
1395                send_message(card, cmsg);
1396
1397                cmd.command = ISDN_STAT_BCONN;
1398                cmd.driver = card->myid;
1399                cmd.arg = nccip->chan;
1400                card->interface.statcallb(&cmd);
1401
1402                printk(KERN_INFO "capidrv-%d: chan %d up with ncci 0x%x\n",
1403                       card->contrnr, nccip->chan, nccip->ncci);
1404                break;
1405
1406        case CAPI_CONNECT_B3_ACTIVE_CONF:       /* ncci */
1407                goto ignored;
1408
1409        case CAPI_CONNECT_B3_IND:       /* ncci */
1410
1411                plcip = find_plci_by_ncci(card, cmsg->adr.adrNCCI);
1412                if (plcip) {
1413                        nccip = new_ncci(card, plcip, cmsg->adr.adrNCCI);
1414                        if (nccip) {
1415                                ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_IND);
1416                                capi_fill_CONNECT_B3_RESP(cmsg,
1417                                                          global.ap.applid,
1418                                                          card->msgid++,
1419                                                          nccip->ncci,  /* adr */
1420                                                          0,    /* Reject */
1421                                                          NULL  /* NCPI */
1422                                        );
1423                                ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
1424                                send_message(card, cmsg);
1425                                break;
1426                        }
1427                        printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n",                                                 card->contrnr);
1428                } else {
1429                        printk(KERN_ERR "capidrv-%d: %s: plci for ncci 0x%x not found\n",
1430                               card->contrnr,
1431                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1432                               cmsg->adr.adrNCCI);
1433                }
1434                capi_fill_CONNECT_B3_RESP(cmsg,
1435                                          global.ap.applid,
1436                                          card->msgid++,
1437                                          cmsg->adr.adrNCCI,
1438                                          2,    /* Reject */
1439                                          NULL  /* NCPI */
1440                        );
1441                send_message(card, cmsg);
1442                break;
1443
1444        case CAPI_CONNECT_B3_CONF:      /* ncci */
1445
1446                if (!(nccip = find_ncci_by_msgid(card,
1447                                                 cmsg->adr.adrNCCI,
1448                                                 cmsg->Messagenumber)))
1449                        goto notfound;
1450
1451                nccip->ncci = cmsg->adr.adrNCCI;
1452                if (cmsg->Info) {
1453                        printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n",
1454                               card->contrnr,
1455                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1456                               cmsg->Info, capi_info2str(cmsg->Info),
1457                               cmsg->adr.adrNCCI);
1458                }
1459
1460                if (cmsg->Info)
1461                        ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_CONF_ERROR);
1462                else
1463                        ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_CONF_OK);
1464                break;
1465
1466        case CAPI_CONNECT_B3_T90_ACTIVE_IND:    /* ncci */
1467                capi_cmsg_answer(cmsg);
1468                send_message(card, cmsg);
1469                break;
1470
1471        case CAPI_DATA_B3_IND:  /* ncci */
1472                /* handled in handle_data() */
1473                goto ignored;
1474
1475        case CAPI_DATA_B3_CONF: /* ncci */
1476                if (cmsg->Info) {
1477                        printk(KERN_WARNING "CAPI_DATA_B3_CONF: Info %x - %s\n",
1478                               cmsg->Info, capi_info2str(cmsg->Info));
1479                }
1480                if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
1481                        goto notfound;
1482
1483                len = capidrv_del_ack(nccip, cmsg->DataHandle);
1484                if (len < 0)
1485                        break;
1486                cmd.command = ISDN_STAT_BSENT;
1487                cmd.driver = card->myid;
1488                cmd.arg = nccip->chan;
1489                cmd.parm.length = len;
1490                card->interface.statcallb(&cmd);
1491                break;
1492
1493        case CAPI_DISCONNECT_B3_IND:    /* ncci */
1494                if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
1495                        goto notfound;
1496
1497                card->bchans[nccip->chan].disconnecting = 1;
1498                ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);
1499                capi_cmsg_answer(cmsg);
1500                ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);
1501                send_message(card, cmsg);
1502                break;
1503
1504        case CAPI_DISCONNECT_B3_CONF:   /* ncci */
1505                if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
1506                        goto notfound;
1507                if (cmsg->Info) {
1508                        printk(KERN_INFO "capidrv-%d: %s info 0x%x (%s) for ncci 0x%x\n",
1509                               card->contrnr,
1510                               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1511                               cmsg->Info, capi_info2str(cmsg->Info),
1512                               cmsg->adr.adrNCCI);
1513                        ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_CONF_ERROR);
1514                }
1515                break;
1516
1517        case CAPI_RESET_B3_IND: /* ncci */
1518                if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
1519                        goto notfound;
1520                ncci_change_state(card, nccip, EV_NCCI_RESET_B3_IND);
1521                capi_cmsg_answer(cmsg);
1522                send_message(card, cmsg);
1523                break;
1524
1525        case CAPI_RESET_B3_CONF:        /* ncci */
1526                goto ignored;   /* $$$$ */
1527
1528        case CAPI_FACILITY_IND: /* Controller/plci/ncci */
1529                goto ignored;
1530        case CAPI_FACILITY_CONF:        /* Controller/plci/ncci */
1531                goto ignored;
1532
1533        default:
1534                printk(KERN_ERR "capidrv-%d: got %s for ncci 0x%x ???",
1535                       card->contrnr,
1536                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1537                       cmsg->adr.adrNCCI);
1538        }
1539        return;
1540ignored:
1541        printk(KERN_INFO "capidrv-%d: %s for ncci 0x%x ignored\n",
1542               card->contrnr,
1543               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1544               cmsg->adr.adrNCCI);
1545        return;
1546notfound:
1547        printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n",
1548               card->contrnr,
1549               capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1550               cmsg->adr.adrNCCI);
1551}
1552
1553
1554static void handle_data(_cmsg *cmsg, struct sk_buff *skb)
1555{
1556        capidrv_contr *card = findcontrbynumber(cmsg->adr.adrController & 0x7f);
1557        capidrv_ncci *nccip;
1558
1559        if (!card) {
1560                printk(KERN_ERR "capidrv: %s from unknown controller 0x%x\n",
1561                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1562                       cmsg->adr.adrController & 0x7f);
1563                kfree_skb(skb);
1564                return;
1565        }
1566        if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI))) {
1567                printk(KERN_ERR "capidrv-%d: %s: ncci 0x%x not found\n",
1568                       card->contrnr,
1569                       capi_cmd2str(cmsg->Command, cmsg->Subcommand),
1570                       cmsg->adr.adrNCCI);
1571                kfree_skb(skb);
1572                return;
1573        }
1574        (void) skb_pull(skb, CAPIMSG_LEN(skb->data));
1575        card->interface.rcvcallb_skb(card->myid, nccip->chan, skb);
1576        capi_cmsg_answer(cmsg);
1577        send_message(card, cmsg);
1578}
1579
1580static _cmsg s_cmsg;
1581
1582static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
1583{
1584        if (capi_message2cmsg(&s_cmsg, skb->data)) {
1585                printk(KERN_ERR "capidrv: applid=%d: received invalid message\n",
1586                       ap->applid);
1587                kfree_skb(skb);
1588                return;
1589        }
1590        if (debugmode > 3) {
1591                _cdebbuf *cdb = capi_cmsg2str(&s_cmsg);
1592
1593                if (cdb) {
1594                        printk(KERN_DEBUG "%s: applid=%d %s\n", __func__,
1595                               ap->applid, cdb->buf);
1596                        cdebbuf_free(cdb);
1597                } else
1598                        printk(KERN_DEBUG "%s: applid=%d %s not traced\n",
1599                               __func__, ap->applid,
1600                               capi_cmd2str(s_cmsg.Command, s_cmsg.Subcommand));
1601        }
1602        if (s_cmsg.Command == CAPI_DATA_B3
1603            && s_cmsg.Subcommand == CAPI_IND) {
1604                handle_data(&s_cmsg, skb);
1605                return;
1606        }
1607        if ((s_cmsg.adr.adrController & 0xffffff00) == 0)
1608                handle_controller(&s_cmsg);
1609        else if ((s_cmsg.adr.adrPLCI & 0xffff0000) == 0)
1610                handle_plci(&s_cmsg);
1611        else
1612                handle_ncci(&s_cmsg);
1613        /*
1614         * data of skb used in s_cmsg,
1615         * free data when s_cmsg is not used again
1616         * thanks to Lars Heete <hel@admin.de>
1617         */
1618        kfree_skb(skb);
1619}
1620
1621/* ------------------------------------------------------------------- */
1622
1623#define PUTBYTE_TO_STATUS(card, byte)                           \
1624        do {                                                    \
1625                *(card)->q931_write++ = (byte);                 \
1626                if ((card)->q931_write > (card)->q931_end)      \
1627                        (card)->q931_write = (card)->q931_buf;  \
1628        } while (0)
1629
1630static void handle_dtrace_data(capidrv_contr *card,
1631                               int send, int level2, u8 *data, u16 len)
1632{
1633        u8 *p, *end;
1634        isdn_ctrl cmd;
1635
1636        if (!len) {
1637                printk(KERN_DEBUG "capidrv-%d: avmb1_q931_data: len == %d\n",
1638                       card->contrnr, len);
1639                return;
1640        }
1641
1642        if (level2) {
1643                PUTBYTE_TO_STATUS(card, 'D');
1644                PUTBYTE_TO_STATUS(card, '2');
1645                PUTBYTE_TO_STATUS(card, send ? '>' : '<');
1646                PUTBYTE_TO_STATUS(card, ':');
1647        } else {
1648                PUTBYTE_TO_STATUS(card, 'D');
1649                PUTBYTE_TO_STATUS(card, '3');
1650                PUTBYTE_TO_STATUS(card, send ? '>' : '<');
1651                PUTBYTE_TO_STATUS(card, ':');
1652        }
1653
1654        for (p = data, end = data + len; p < end; p++) {
1655                PUTBYTE_TO_STATUS(card, ' ');
1656                PUTBYTE_TO_STATUS(card, hex_asc_hi(*p));
1657                PUTBYTE_TO_STATUS(card, hex_asc_lo(*p));
1658        }
1659        PUTBYTE_TO_STATUS(card, '\n');
1660
1661        cmd.command = ISDN_STAT_STAVAIL;
1662        cmd.driver = card->myid;
1663        cmd.arg = len * 3 + 5;
1664        card->interface.statcallb(&cmd);
1665}
1666
1667/* ------------------------------------------------------------------- */
1668
1669static _cmsg cmdcmsg;
1670
1671static int capidrv_ioctl(isdn_ctrl *c, capidrv_contr *card)
1672{
1673        switch (c->arg) {
1674        case 1:
1675                debugmode = (int)(*((unsigned int *)c->parm.num));
1676                printk(KERN_DEBUG "capidrv-%d: debugmode=%d\n",
1677                       card->contrnr, debugmode);
1678                return 0;
1679        default:
1680                printk(KERN_DEBUG "capidrv-%d: capidrv_ioctl(%ld) called ??\n",
1681                       card->contrnr, c->arg);
1682                return -EINVAL;
1683        }
1684        return -EINVAL;
1685}
1686
1687/*
1688 * Handle leased lines (CAPI-Bundling)
1689 */
1690
1691struct internal_bchannelinfo {
1692        unsigned short channelalloc;
1693        unsigned short operation;
1694        unsigned char  cmask[31];
1695};
1696
1697static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep)
1698{
1699        unsigned long bmask = 0;
1700        int active = !0;
1701        char *s;
1702        int i;
1703
1704        if (strncmp(teln, "FV:", 3) != 0)
1705                return 1;
1706        s = teln + 3;
1707        while (*s && *s == ' ') s++;
1708        if (!*s) return -2;
1709        if (*s == 'p' || *s == 'P') {
1710                active = 0;
1711                s++;
1712        }
1713        if (*s == 'a' || *s == 'A') {
1714                active = !0;
1715                s++;
1716        }
1717        while (*s) {
1718                int digit1 = 0;
1719                int digit2 = 0;
1720                char *endp;
1721
1722                digit1 = simple_strtoul(s, &endp, 10);
1723                if (s == endp)
1724                        return -3;
1725                s = endp;
1726
1727                if (digit1 <= 0 || digit1 > 30) return -4;
1728                if (*s == 0 || *s == ',' || *s == ' ') {
1729                        bmask |= (1 << digit1);
1730                        digit1 = 0;
1731                        if (*s) s++;
1732                        continue;
1733                }
1734                if (*s != '-') return -5;
1735                s++;
1736
1737                digit2 = simple_strtoul(s, &endp, 10);
1738                if (s == endp)
1739                        return -3;
1740                s = endp;
1741
1742                if (digit2 <= 0 || digit2 > 30) return -4;
1743                if (*s == 0 || *s == ',' || *s == ' ') {
1744                        if (digit1 > digit2)
1745                                for (i = digit2; i <= digit1; i++)
1746                                        bmask |= (1 << i);
1747                        else
1748                                for (i = digit1; i <= digit2; i++)
1749                                        bmask |= (1 << i);
1750                        digit1 = digit2 = 0;
1751                        if (*s) s++;
1752                        continue;
1753                }
1754                return -6;
1755        }
1756        if (activep) *activep = active;
1757        if (bmaskp) *bmaskp = bmask;
1758        return 0;
1759}
1760
1761static int FVteln2capi20(char *teln, u8 AdditionalInfo[1 + 2 + 2 + 31])
1762{
1763        unsigned long bmask;
1764        int active;
1765        int rc, i;
1766
1767        rc = decodeFVteln(teln, &bmask, &active);
1768        if (rc) return rc;
1769        /* Length */
1770        AdditionalInfo[0] = 2 + 2 + 31;
1771        /* Channel: 3 => use channel allocation */
1772        AdditionalInfo[1] = 3; AdditionalInfo[2] = 0;
1773        /* Operation: 0 => DTE mode, 1 => DCE mode */
1774        if (active) {
1775                AdditionalInfo[3] = 0; AdditionalInfo[4] = 0;
1776        } else {
1777                AdditionalInfo[3] = 1; AdditionalInfo[4] = 0;
1778        }
1779        /* Channel mask array */
1780        AdditionalInfo[5] = 0; /* no D-Channel */
1781        for (i = 1; i <= 30; i++)
1782                AdditionalInfo[5 + i] = (bmask & (1 << i)) ? 0xff : 0;
1783        return 0;
1784}
1785
1786static int capidrv_command(isdn_ctrl *c, capidrv_contr *card)
1787{
1788        isdn_ctrl cmd;
1789        struct capidrv_bchan *bchan;
1790        struct capidrv_plci *plcip;
1791        u8 AdditionalInfo[1 + 2 + 2 + 31];
1792        int rc, isleasedline = 0;
1793
1794        if (c->command == ISDN_CMD_IOCTL)
1795                return capidrv_ioctl(c, card);
1796
1797        switch (c->command) {
1798        case ISDN_CMD_DIAL: {
1799                u8 calling[ISDN_MSNLEN + 3];
1800                u8 called[ISDN_MSNLEN + 2];
1801
1802                if (debugmode)
1803                        printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_DIAL(ch=%ld,\"%s,%d,%d,%s\")\n",
1804                               card->contrnr,
1805                               c->arg,
1806                               c->parm.setup.phone,
1807                               c->parm.setup.si1,
1808                               c->parm.setup.si2,
1809                               c->parm.setup.eazmsn);
1810
1811                bchan = &card->bchans[c->arg % card->nbchan];
1812
1813                if (bchan->plcip) {
1814                        printk(KERN_ERR "capidrv-%d: dail ch=%ld,\"%s,%d,%d,%s\" in use (plci=0x%x)\n",
1815                               card->contrnr,
1816                               c->arg,
1817                               c->parm.setup.phone,
1818                               c->parm.setup.si1,
1819                               c->parm.setup.si2,
1820                               c->parm.setup.eazmsn,
1821                               bchan->plcip->plci);
1822                        return 0;
1823                }
1824                bchan->si1 = c->parm.setup.si1;
1825                bchan->si2 = c->parm.setup.si2;
1826
1827                strncpy(bchan->num, c->parm.setup.phone, sizeof(bchan->num));
1828                strncpy(bchan->mynum, c->parm.setup.eazmsn, sizeof(bchan->mynum));
1829                rc = FVteln2capi20(bchan->num, AdditionalInfo);
1830                isleasedline = (rc == 0);
1831                if (rc < 0)
1832                        printk(KERN_ERR "capidrv-%d: WARNING: invalid leased linedefinition \"%s\"\n", card->contrnr, bchan->num);
1833
1834                if (isleasedline) {
1835                        calling[0] = 0;
1836                        called[0] = 0;
1837                        if (debugmode)
1838                                printk(KERN_DEBUG "capidrv-%d: connecting leased line\n", card->contrnr);
1839                } else {
1840                        calling[0] = strlen(bchan->mynum) + 2;
1841                        calling[1] = 0;
1842                        calling[2] = 0x80;
1843                        strncpy(calling + 3, bchan->mynum, ISDN_MSNLEN);
1844                        called[0] = strlen(bchan->num) + 1;
1845                        called[1] = 0x80;
1846                        strncpy(called + 2, bchan->num, ISDN_MSNLEN);
1847                }
1848
1849                capi_fill_CONNECT_REQ(&cmdcmsg,
1850                                      global.ap.applid,
1851                                      card->msgid++,
1852                                      card->contrnr,    /* adr */
1853                                      si2cip(bchan->si1, bchan->si2),   /* cipvalue */
1854                                      called,   /* CalledPartyNumber */
1855                                      calling,  /* CallingPartyNumber */
1856                                      NULL,     /* CalledPartySubaddress */
1857                                      NULL,     /* CallingPartySubaddress */
1858                                      b1prot(bchan->l2, bchan->l3),     /* B1protocol */
1859                                      b2prot(bchan->l2, bchan->l3),     /* B2protocol */
1860                                      b3prot(bchan->l2, bchan->l3),     /* B3protocol */
1861                                      b1config(bchan->l2, bchan->l3),   /* B1configuration */
1862                                      NULL,     /* B2configuration */
1863                                      NULL,     /* B3configuration */
1864                                      NULL,     /* BC */
1865                                      NULL,     /* LLC */
1866                                      NULL,     /* HLC */
1867                                      /* BChannelinformation */
1868                                      isleasedline ? AdditionalInfo : NULL,
1869                                      NULL,     /* Keypadfacility */
1870                                      NULL,     /* Useruserdata */
1871                                      NULL      /* Facilitydataarray */
1872                        );
1873                if ((plcip = new_plci(card, (c->arg % card->nbchan))) == NULL) {
1874                        cmd.command = ISDN_STAT_DHUP;
1875                        cmd.driver = card->myid;
1876                        cmd.arg = (c->arg % card->nbchan);
1877                        card->interface.statcallb(&cmd);
1878                        return -1;
1879                }
1880                plcip->msgid = cmdcmsg.Messagenumber;
1881                plcip->leasedline = isleasedline;
1882                plci_change_state(card, plcip, EV_PLCI_CONNECT_REQ);
1883                send_message(card, &cmdcmsg);
1884                return 0;
1885        }
1886
1887        case ISDN_CMD_ACCEPTD:
1888
1889                bchan = &card->bchans[c->arg % card->nbchan];
1890                if (debugmode)
1891                        printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_ACCEPTD(ch=%ld) l2=%d l3=%d\n",
1892                               card->contrnr,
1893                               c->arg, bchan->l2, bchan->l3);
1894
1895                capi_fill_CONNECT_RESP(&cmdcmsg,
1896                                       global.ap.applid,
1897                                       card->msgid++,
1898                                       bchan->plcip->plci,      /* adr */
1899                                       0,       /* Reject */
1900                                       b1prot(bchan->l2, bchan->l3),    /* B1protocol */
1901                                       b2prot(bchan->l2, bchan->l3),    /* B2protocol */
1902                                       b3prot(bchan->l2, bchan->l3),    /* B3protocol */
1903                                       b1config(bchan->l2, bchan->l3),  /* B1configuration */
1904                                       NULL,    /* B2configuration */
1905                                       NULL,    /* B3configuration */
1906                                       NULL,    /* ConnectedNumber */
1907                                       NULL,    /* ConnectedSubaddress */
1908                                       NULL,    /* LLC */
1909                                       NULL,    /* BChannelinformation */
1910                                       NULL,    /* Keypadfacility */
1911                                       NULL,    /* Useruserdata */
1912                                       NULL     /* Facilitydataarray */
1913                        );
1914                if (capi_cmsg2message(&cmdcmsg, cmdcmsg.buf)) {
1915                        printk(KERN_ERR "capidrv-%d: capidrv_command: parser failure\n",
1916                               card->contrnr);
1917                        return -EINVAL;
1918                }
1919                plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP);
1920                send_message(card, &cmdcmsg);
1921                return 0;
1922
1923        case ISDN_CMD_ACCEPTB:
1924                if (debugmode)
1925                        printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_ACCEPTB(ch=%ld)\n",
1926                               card->contrnr,
1927                               c->arg);
1928                return -ENOSYS;
1929
1930        case ISDN_CMD_HANGUP:
1931                if (debugmode)
1932                        printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_HANGUP(ch=%ld)\n",
1933                               card->contrnr,
1934                               c->arg);
1935                bchan = &card->bchans[c->arg % card->nbchan];
1936
1937                if (bchan->disconnecting) {
1938                        if (debugmode)
1939                                printk(KERN_DEBUG "capidrv-%d: chan %ld already disconnecting ...\n",
1940                                       card->contrnr,
1941                                       c->arg);
1942                        return 0;
1943                }
1944                if (bchan->nccip) {
1945                        bchan->disconnecting = 1;
1946                        capi_fill_DISCONNECT_B3_REQ(&cmdcmsg,
1947                                                    global.ap.applid,
1948                                                    card->msgid++,
1949                                                    bchan->nccip->ncci,
1950                                                    NULL        /* NCPI */
1951                                );
1952                        ncci_change_state(card, bchan->nccip, EV_NCCI_DISCONNECT_B3_REQ);
1953                        send_message(card, &cmdcmsg);
1954                        return 0;
1955                } else if (bchan->plcip) {
1956                        if (bchan->plcip->state == ST_PLCI_INCOMING) {
1957                                /*
1958                                 * just ignore, we a called from
1959                                 * isdn_status_callback(),
1960                                 * which will return 0 or 2, this is handled
1961                                 * by the CONNECT_IND handler
1962                                 */
1963                                bchan->disconnecting = 1;
1964                                return 0;
1965                        } else if (bchan->plcip->plci) {
1966                                bchan->disconnecting = 1;
1967                                capi_fill_DISCONNECT_REQ(&cmdcmsg,
1968                                                         global.ap.applid,
1969                                                         card->msgid++,
1970                                                         bchan->plcip->plci,
1971                                                         NULL,  /* BChannelinformation */
1972                                                         NULL,  /* Keypadfacility */
1973                                                         NULL,  /* Useruserdata */
1974                                                         NULL   /* Facilitydataarray */
1975                                        );
1976                                plci_change_state(card, bchan->plcip, EV_PLCI_DISCONNECT_REQ);
1977                                send_message(card, &cmdcmsg);
1978                                return 0;
1979                        } else {
1980                                printk(KERN_ERR "capidrv-%d: chan %ld disconnect request while waiting for CONNECT_CONF\n",
1981                                       card->contrnr,
1982                                       c->arg);
1983                                return -EINVAL;
1984                        }
1985                }
1986                printk(KERN_ERR "capidrv-%d: chan %ld disconnect request on free channel\n",
1987                       card->contrnr,
1988                       c->arg);
1989                return -EINVAL;
1990/* ready */
1991
1992        case ISDN_CMD_SETL2:
1993                if (debugmode)
1994                        printk(KERN_DEBUG "capidrv-%d: set L2 on chan %ld to %ld\n",
1995                               card->contrnr,
1996                               (c->arg & 0xff), (c->arg >> 8));
1997                bchan = &card->bchans[(c->arg & 0xff) % card->nbchan];
1998                bchan->l2 = (c->arg >> 8);
1999                return 0;
2000
2001        case ISDN_CMD_SETL3:
2002                if (debugmode)
2003                        printk(KERN_DEBUG "capidrv-%d: set L3 on chan %ld to %ld\n",
2004                               card->contrnr,
2005                               (c->arg & 0xff), (c->arg >> 8));
2006                bchan = &card->bchans[(c->arg & 0xff) % card->nbchan];
2007                bchan->l3 = (c->arg >> 8);
2008                return 0;
2009
2010        case ISDN_CMD_SETEAZ:
2011                if (debugmode)
2012                        printk(KERN_DEBUG "capidrv-%d: set EAZ \"%s\" on chan %ld\n",
2013                               card->contrnr,
2014                               c->parm.num, c->arg);
2015                bchan = &card->bchans[c->arg % card->nbchan];
2016                strncpy(bchan->msn, c->parm.num, ISDN_MSNLEN);
2017                return 0;
2018
2019        case ISDN_CMD_CLREAZ:
2020                if (debugmode)
2021                        printk(KERN_DEBUG "capidrv-%d: clearing EAZ on chan %ld\n",
2022                               card->contrnr, c->arg);
2023                bchan = &card->bchans[c->arg % card->nbchan];
2024                bchan->msn[0] = 0;
2025                return 0;
2026
2027        default:
2028                printk(KERN_ERR "capidrv-%d: ISDN_CMD_%d, Huh?\n",
2029                       card->contrnr, c->command);
2030                return -EINVAL;
2031        }
2032        return 0;
2033}
2034
2035static int if_command(isdn_ctrl *c)
2036{
2037        capidrv_contr *card = findcontrbydriverid(c->driver);
2038
2039        if (card)
2040                return capidrv_command(c, card);
2041
2042        printk(KERN_ERR
2043               "capidrv: if_command %d called with invalid driverId %d!\n",
2044               c->command, c->driver);
2045        return -ENODEV;
2046}
2047
2048static _cmsg sendcmsg;
2049
2050static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
2051{
2052        capidrv_contr *card = findcontrbydriverid(id);
2053        capidrv_bchan *bchan;
2054        capidrv_ncci *nccip;
2055        int len = skb->len;
2056        int msglen;
2057        u16 errcode;
2058        u16 datahandle;
2059        u32 data;
2060
2061        if (!card) {
2062                printk(KERN_ERR "capidrv: if_sendbuf called with invalid driverId %d!\n",
2063                       id);
2064                return 0;
2065        }
2066        if (debugmode > 4)
2067                printk(KERN_DEBUG "capidrv-%d: sendbuf len=%d skb=%p doack=%d\n",
2068                       card->contrnr, len, skb, doack);
2069        bchan = &card->bchans[channel % card->nbchan];
2070        nccip = bchan->nccip;
2071        if (!nccip || nccip->state != ST_NCCI_ACTIVE) {
2072                printk(KERN_ERR "capidrv-%d: if_sendbuf: %s:%d: chan not up!\n",
2073                       card->contrnr, card->name, channel);
2074                return 0;
2075        }
2076        datahandle = nccip->datahandle;
2077
2078        /*
2079         * Here we copy pointer skb->data into the 32-bit 'Data' field.
2080         * The 'Data' field is not used in practice in linux kernel
2081         * (neither in 32 or 64 bit), but should have some value,
2082         * since a CAPI message trace will display it.
2083         *
2084         * The correct value in the 32 bit case is the address of the
2085         * data, in 64 bit it makes no sense, we use 0 there.
2086         */
2087
2088#ifdef CONFIG_64BIT
2089        data = 0;
2090#else
2091        data = (unsigned long) skb->data;
2092#endif
2093
2094        capi_fill_DATA_B3_REQ(&sendcmsg, global.ap.applid, card->msgid++,
2095                              nccip->ncci,      /* adr */
2096                              data,             /* Data */
2097                              skb->len,         /* DataLength */
2098                              datahandle,       /* DataHandle */
2099                              0 /* Flags */
2100                );
2101
2102        if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0)
2103                return 0;
2104
2105        if (capi_cmsg2message(&sendcmsg, sendcmsg.buf)) {
2106                printk(KERN_ERR "capidrv-%d: if_sendbuf: parser failure\n",
2107                       card->contrnr);
2108                return -EINVAL;
2109        }
2110        msglen = CAPIMSG_LEN(sendcmsg.buf);
2111        if (skb_headroom(skb) < msglen) {
2112                struct sk_buff *nskb = skb_realloc_headroom(skb, msglen);
2113                if (!nskb) {
2114                        printk(KERN_ERR "capidrv-%d: if_sendbuf: no memory\n",
2115                               card->contrnr);
2116                        (void)capidrv_del_ack(nccip, datahandle);
2117                        return 0;
2118                }
2119                printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom, need %d\n",
2120                       card->contrnr, skb_headroom(skb), msglen);
2121                memcpy(skb_push(nskb, msglen), sendcmsg.buf, msglen);
2122                errcode = capi20_put_message(&global.ap, nskb);
2123                if (errcode == CAPI_NOERROR) {
2124                        dev_kfree_skb(skb);
2125                        nccip->datahandle++;
2126                        return len;
2127                }
2128                if (debugmode > 3)
2129                        printk(KERN_DEBUG "capidrv-%d: sendbuf putmsg ret(%x) - %s\n",
2130                               card->contrnr, errcode, capi_info2str(errcode));
2131                (void)capidrv_del_ack(nccip, datahandle);
2132                dev_kfree_skb(nskb);
2133                return errcode == CAPI_SENDQUEUEFULL ? 0 : -1;
2134        } else {
2135                memcpy(skb_push(skb, msglen), sendcmsg.buf, msglen);
2136                errcode = capi20_put_message(&global.ap, skb);
2137                if (errcode == CAPI_NOERROR) {
2138                        nccip->datahandle++;
2139                        return len;
2140                }
2141                if (debugmode > 3)
2142                        printk(KERN_DEBUG "capidrv-%d: sendbuf putmsg ret(%x) - %s\n",
2143                               card->contrnr, errcode, capi_info2str(errcode));
2144                skb_pull(skb, msglen);
2145                (void)capidrv_del_ack(nccip, datahandle);
2146                return errcode == CAPI_SENDQUEUEFULL ? 0 : -1;
2147        }
2148}
2149
2150static int if_readstat(u8 __user *buf, int len, int id, int channel)
2151{
2152        capidrv_contr *card = findcontrbydriverid(id);
2153        int count;
2154        u8 __user *p;
2155
2156        if (!card) {
2157                printk(KERN_ERR "capidrv: if_readstat called with invalid driverId %d!\n",
2158                       id);
2159                return -ENODEV;
2160        }
2161
2162        for (p = buf, count = 0; count < len; p++, count++) {
2163                if (put_user(*card->q931_read++, p))
2164                        return -EFAULT;
2165                if (card->q931_read > card->q931_end)
2166                        card->q931_read = card->q931_buf;
2167        }
2168        return count;
2169
2170}
2171
2172static void enable_dchannel_trace(capidrv_contr *card)
2173{
2174        u8 manufacturer[CAPI_MANUFACTURER_LEN];
2175        capi_version version;
2176        u16 contr = card->contrnr;
2177        u16 errcode;
2178        u16 avmversion[3];
2179
2180        errcode = capi20_get_manufacturer(contr, manufacturer);
2181        if (errcode != CAPI_NOERROR) {
2182                printk(KERN_ERR "%s: can't get manufacturer (0x%x)\n",
2183                       card->name, errcode);
2184                return;
2185        }
2186        if (strstr(manufacturer, "AVM") == NULL) {
2187                printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
2188                       card->name, manufacturer);
2189                return;
2190        }
2191        errcode = capi20_get_version(contr, &version);
2192        if (errcode != CAPI_NOERROR) {
2193                printk(KERN_ERR "%s: can't get version (0x%x)\n",
2194                       card->name, errcode);
2195                return;
2196        }
2197        avmversion[0] = (version.majormanuversion >> 4) & 0x0f;
2198        avmversion[1] = (version.majormanuversion << 4) & 0xf0;
2199        avmversion[1] |= (version.minormanuversion >> 4) & 0x0f;
2200        avmversion[2] |= version.minormanuversion & 0x0f;
2201
2202        if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) {
2203                printk(KERN_INFO "%s: D2 trace enabled\n", card->name);
2204                capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.ap.applid,
2205                                           card->msgid++,
2206                                           contr,
2207                                           0x214D5641,  /* ManuID */
2208                                           0,           /* Class */
2209                                           1,           /* Function */
2210                                           (_cstruct)"\004\200\014\000\000");
2211        } else {
2212                printk(KERN_INFO "%s: D3 trace enabled\n", card->name);
2213                capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.ap.applid,
2214                                           card->msgid++,
2215                                           contr,
2216                                           0x214D5641,  /* ManuID */
2217                                           0,           /* Class */
2218                                           1,           /* Function */
2219                                           (_cstruct)"\004\002\003\000\000");
2220        }
2221        send_message(card, &cmdcmsg);
2222}
2223
2224
2225static void send_listen(capidrv_contr *card)
2226{
2227        capi_fill_LISTEN_REQ(&cmdcmsg, global.ap.applid,
2228                             card->msgid++,
2229                             card->contrnr, /* controller */
2230                             1 << 6,    /* Infomask */
2231                             card->cipmask,
2232                             card->cipmask2,
2233                             NULL, NULL);
2234        listen_change_state(card, EV_LISTEN_REQ);
2235        send_message(card, &cmdcmsg);
2236}
2237
2238static void listentimerfunc(struct timer_list *t)
2239{
2240        capidrv_contr *card = from_timer(card, t, listentimer);
2241        if (card->state != ST_LISTEN_NONE && card->state != ST_LISTEN_ACTIVE)
2242                printk(KERN_ERR "%s: controller dead ??\n", card->name);
2243        send_listen(card);
2244        mod_timer(&card->listentimer, jiffies + 60 * HZ);
2245}
2246
2247
2248static int capidrv_addcontr(u16 contr, struct capi_profile *profp)
2249{
2250        capidrv_contr *card;
2251        unsigned long flags;
2252        isdn_ctrl cmd;
2253        char id[20];
2254        int i;
2255
2256        sprintf(id, "capidrv-%d", contr);
2257        if (!try_module_get(THIS_MODULE)) {
2258                printk(KERN_WARNING "capidrv: (%s) Could not reserve module\n", id);
2259                return -1;
2260        }
2261        if (!(card = kzalloc(sizeof(capidrv_contr), GFP_ATOMIC))) {
2262                printk(KERN_WARNING
2263                       "capidrv: (%s) Could not allocate contr-struct.\n", id);
2264                return -1;
2265        }
2266        card->owner = THIS_MODULE;
2267        timer_setup(&card->listentimer, listentimerfunc, 0);
2268        strcpy(card->name, id);
2269        card->contrnr = contr;
2270        card->nbchan = profp->nbchannel;
2271        card->bchans = kmalloc(sizeof(capidrv_bchan) * card->nbchan, GFP_ATOMIC);
2272        if (!card->bchans) {
2273                printk(KERN_WARNING
2274                       "capidrv: (%s) Could not allocate bchan-structs.\n", id);
2275                module_put(card->owner);
2276                kfree(card);
2277                return -1;
2278        }
2279        card->interface.channels = profp->nbchannel;
2280        card->interface.maxbufsize = 2048;
2281        card->interface.command = if_command;
2282        card->interface.writebuf_skb = if_sendbuf;
2283        card->interface.writecmd = NULL;
2284        card->interface.readstat = if_readstat;
2285        card->interface.features =
2286                ISDN_FEATURE_L2_HDLC |
2287                ISDN_FEATURE_L2_TRANS |
2288                ISDN_FEATURE_L3_TRANS |
2289                ISDN_FEATURE_P_UNKNOWN |
2290                ISDN_FEATURE_L2_X75I |
2291                ISDN_FEATURE_L2_X75UI |
2292                ISDN_FEATURE_L2_X75BUI;
2293        if (profp->support1 & (1 << 2))
2294                card->interface.features |=
2295                        ISDN_FEATURE_L2_V11096 |
2296                        ISDN_FEATURE_L2_V11019 |
2297                        ISDN_FEATURE_L2_V11038;
2298        if (profp->support1 & (1 << 8))
2299                card->interface.features |= ISDN_FEATURE_L2_MODEM;
2300        card->interface.hl_hdrlen = 22; /* len of DATA_B3_REQ */
2301        strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
2302
2303
2304        card->q931_read = card->q931_buf;
2305        card->q931_write = card->q931_buf;
2306        card->q931_end = card->q931_buf + sizeof(card->q931_buf) - 1;
2307
2308        if (!register_isdn(&card->interface)) {
2309                printk(KERN_ERR "capidrv: Unable to register contr %s\n", id);
2310                kfree(card->bchans);
2311                module_put(card->owner);
2312                kfree(card);
2313                return -1;
2314        }
2315        card->myid = card->interface.channels;
2316        memset(card->bchans, 0, sizeof(capidrv_bchan) * card->nbchan);
2317        for (i = 0; i < card->nbchan; i++) {
2318                card->bchans[i].contr = card;
2319        }
2320
2321        spin_lock_irqsave(&global_lock, flags);
2322        card->next = global.contr_list;
2323        global.contr_list = card;
2324        global.ncontr++;
2325        spin_unlock_irqrestore(&global_lock, flags);
2326
2327        cmd.command = ISDN_STAT_RUN;
2328        cmd.driver = card->myid;
2329        card->interface.statcallb(&cmd);
2330
2331        card->cipmask = 0x1FFF03FF;     /* any */
2332        card->cipmask2 = 0;
2333
2334        send_listen(card);
2335        mod_timer(&card->listentimer, jiffies + 60 * HZ);
2336
2337        printk(KERN_INFO "%s: now up (%d B channels)\n",
2338               card->name, card->nbchan);
2339
2340        enable_dchannel_trace(card);
2341
2342        return 0;
2343}
2344
2345static int capidrv_delcontr(u16 contr)
2346{
2347        capidrv_contr **pp, *card;
2348        unsigned long flags;
2349        isdn_ctrl cmd;
2350
2351        spin_lock_irqsave(&global_lock, flags);
2352        for (card = global.contr_list; card; card = card->next) {
2353                if (card->contrnr == contr)
2354                        break;
2355        }
2356        if (!card) {
2357                spin_unlock_irqrestore(&global_lock, flags);
2358                printk(KERN_ERR "capidrv: delcontr: no contr %u\n", contr);
2359                return -1;
2360        }
2361
2362        /* FIXME: maybe a race condition the card should be removed
2363         * here from global list /kkeil
2364         */
2365        spin_unlock_irqrestore(&global_lock, flags);
2366
2367        del_timer(&card->listentimer);
2368
2369        if (debugmode)
2370                printk(KERN_DEBUG "capidrv-%d: id=%d unloading\n",
2371                       card->contrnr, card->myid);
2372
2373        cmd.command = ISDN_STAT_STOP;
2374        cmd.driver = card->myid;
2375        card->interface.statcallb(&cmd);
2376
2377        while (card->nbchan) {
2378
2379                cmd.command = ISDN_STAT_DISCH;
2380                cmd.driver = card->myid;
2381                cmd.arg = card->nbchan - 1;
2382                cmd.parm.num[0] = 0;
2383                if (debugmode)
2384                        printk(KERN_DEBUG "capidrv-%d: id=%d disable chan=%ld\n",
2385                               card->contrnr, card->myid, cmd.arg);
2386                card->interface.statcallb(&cmd);
2387
2388                if (card->bchans[card->nbchan - 1].nccip)
2389                        free_ncci(card, card->bchans[card->nbchan - 1].nccip);
2390                if (card->bchans[card->nbchan - 1].plcip)
2391                        free_plci(card, card->bchans[card->nbchan - 1].plcip);
2392                if (card->plci_list)
2393                        printk(KERN_ERR "capidrv: bug in free_plci()\n");
2394                card->nbchan--;
2395        }
2396        kfree(card->bchans);
2397        card->bchans = NULL;
2398
2399        if (debugmode)
2400                printk(KERN_DEBUG "capidrv-%d: id=%d isdn unload\n",
2401                       card->contrnr, card->myid);
2402
2403        cmd.command = ISDN_STAT_UNLOAD;
2404        cmd.driver = card->myid;
2405        card->interface.statcallb(&cmd);
2406
2407        if (debugmode)
2408                printk(KERN_DEBUG "capidrv-%d: id=%d remove contr from list\n",
2409                       card->contrnr, card->myid);
2410
2411        spin_lock_irqsave(&global_lock, flags);
2412        for (pp = &global.contr_list; *pp; pp = &(*pp)->next) {
2413                if (*pp == card) {
2414                        *pp = (*pp)->next;
2415                        card->next = NULL;
2416                        global.ncontr--;
2417                        break;
2418                }
2419        }
2420        spin_unlock_irqrestore(&global_lock, flags);
2421
2422        module_put(card->owner);
2423        printk(KERN_INFO "%s: now down.\n", card->name);
2424        kfree(card);
2425        return 0;
2426}
2427
2428
2429static int
2430lower_callback(struct notifier_block *nb, unsigned long val, void *v)
2431{
2432        capi_profile profile;
2433        u32 contr = (long)v;
2434
2435        switch (val) {
2436        case CAPICTR_UP:
2437                printk(KERN_INFO "capidrv: controller %hu up\n", contr);
2438                if (capi20_get_profile(contr, &profile) == CAPI_NOERROR)
2439                        (void) capidrv_addcontr(contr, &profile);
2440                break;
2441        case CAPICTR_DOWN:
2442                printk(KERN_INFO "capidrv: controller %hu down\n", contr);
2443                (void) capidrv_delcontr(contr);
2444                break;
2445        }
2446        return NOTIFY_OK;
2447}
2448
2449/*
2450 * /proc/capi/capidrv:
2451 * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
2452 */
2453static int capidrv_proc_show(struct seq_file *m, void *v)
2454{
2455        seq_printf(m, "%lu %lu %lu %lu\n",
2456                   global.ap.nrecvctlpkt,
2457                   global.ap.nrecvdatapkt,
2458                   global.ap.nsentctlpkt,
2459                   global.ap.nsentdatapkt);
2460        return 0;
2461}
2462
2463static int capidrv_proc_open(struct inode *inode, struct file *file)
2464{
2465        return single_open(file, capidrv_proc_show, NULL);
2466}
2467
2468static const struct file_operations capidrv_proc_fops = {
2469        .owner          = THIS_MODULE,
2470        .open           = capidrv_proc_open,
2471        .read           = seq_read,
2472        .llseek         = seq_lseek,
2473        .release        = single_release,
2474};
2475
2476static void __init proc_init(void)
2477{
2478        proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
2479}
2480
2481static void __exit proc_exit(void)
2482{
2483        remove_proc_entry("capi/capidrv", NULL);
2484}
2485
2486static struct notifier_block capictr_nb = {
2487        .notifier_call = lower_callback,
2488};
2489
2490static int __init capidrv_init(void)
2491{
2492        capi_profile profile;
2493        u32 ncontr, contr;
2494        u16 errcode;
2495
2496        global.ap.rparam.level3cnt = -2;  /* number of bchannels twice */
2497        global.ap.rparam.datablkcnt = 16;
2498        global.ap.rparam.datablklen = 2048;
2499
2500        global.ap.recv_message = capidrv_recv_message;
2501        errcode = capi20_register(&global.ap);
2502        if (errcode) {
2503                return -EIO;
2504        }
2505
2506        register_capictr_notifier(&capictr_nb);
2507
2508        errcode = capi20_get_profile(0, &profile);
2509        if (errcode != CAPI_NOERROR) {
2510                unregister_capictr_notifier(&capictr_nb);
2511                capi20_release(&global.ap);
2512                return -EIO;
2513        }
2514
2515        ncontr = profile.ncontroller;
2516        for (contr = 1; contr <= ncontr; contr++) {
2517                errcode = capi20_get_profile(contr, &profile);
2518                if (errcode != CAPI_NOERROR)
2519                        continue;
2520                (void) capidrv_addcontr(contr, &profile);
2521        }
2522        proc_init();
2523
2524        return 0;
2525}
2526
2527static void __exit capidrv_exit(void)
2528{
2529        unregister_capictr_notifier(&capictr_nb);
2530        capi20_release(&global.ap);
2531
2532        proc_exit();
2533}
2534
2535module_init(capidrv_init);
2536module_exit(capidrv_exit);
2537