linux/drivers/isdn/gigaset/ev-layer.c
<<
>>
Prefs
   1/*
   2 * Stuff used by all variants of the driver
   3 *
   4 * Copyright (c) 2001 by Stefan Eilers,
   5 *                       Hansjoerg Lipp <hjlipp@web.de>,
   6 *                       Tilman Schmidt <tilman@imap.cc>.
   7 *
   8 * =====================================================================
   9 *      This program is free software; you can redistribute it and/or
  10 *      modify it under the terms of the GNU General Public License as
  11 *      published by the Free Software Foundation; either version 2 of
  12 *      the License, or (at your option) any later version.
  13 * =====================================================================
  14 */
  15
  16#include "gigaset.h"
  17
  18/* ========================================================== */
  19/* bit masks for pending commands */
  20#define PC_DIAL         0x001
  21#define PC_HUP          0x002
  22#define PC_INIT         0x004
  23#define PC_DLE0         0x008
  24#define PC_DLE1         0x010
  25#define PC_SHUTDOWN     0x020
  26#define PC_ACCEPT       0x040
  27#define PC_CID          0x080
  28#define PC_NOCID        0x100
  29#define PC_CIDMODE      0x200
  30#define PC_UMMODE       0x400
  31
  32/* types of modem responses */
  33#define RT_NOTHING      0
  34#define RT_ZSAU         1
  35#define RT_RING         2
  36#define RT_NUMBER       3
  37#define RT_STRING       4
  38#define RT_HEX          5
  39#define RT_ZCAU         6
  40
  41/* Possible ASCII responses */
  42#define RSP_OK          0
  43//#define RSP_BUSY      1
  44//#define RSP_CONNECT   2
  45#define RSP_ZGCI        3
  46#define RSP_RING        4
  47#define RSP_ZAOC        5
  48#define RSP_ZCSTR       6
  49#define RSP_ZCFGT       7
  50#define RSP_ZCFG        8
  51#define RSP_ZCCR        9
  52#define RSP_EMPTY       10
  53#define RSP_ZLOG        11
  54#define RSP_ZCAU        12
  55#define RSP_ZMWI        13
  56#define RSP_ZABINFO     14
  57#define RSP_ZSMLSTCHG   15
  58#define RSP_VAR         100
  59#define RSP_ZSAU        (RSP_VAR + VAR_ZSAU)
  60#define RSP_ZDLE        (RSP_VAR + VAR_ZDLE)
  61#define RSP_ZVLS        (RSP_VAR + VAR_ZVLS)
  62#define RSP_ZCTP        (RSP_VAR + VAR_ZCTP)
  63#define RSP_STR         (RSP_VAR + VAR_NUM)
  64#define RSP_NMBR        (RSP_STR + STR_NMBR)
  65#define RSP_ZCPN        (RSP_STR + STR_ZCPN)
  66#define RSP_ZCON        (RSP_STR + STR_ZCON)
  67#define RSP_ZBC         (RSP_STR + STR_ZBC)
  68#define RSP_ZHLC        (RSP_STR + STR_ZHLC)
  69#define RSP_ERROR       -1      /* ERROR              */
  70#define RSP_WRONG_CID   -2      /* unknown cid in cmd */
  71//#define RSP_EMPTY     -3
  72#define RSP_UNKNOWN     -4      /* unknown response   */
  73#define RSP_FAIL        -5      /* internal error     */
  74#define RSP_INVAL       -6      /* invalid response   */
  75
  76#define RSP_NONE        -19
  77#define RSP_STRING      -20
  78#define RSP_NULL        -21
  79//#define RSP_RETRYFAIL -22
  80//#define RSP_RETRY     -23
  81//#define RSP_SKIP      -24
  82#define RSP_INIT        -27
  83#define RSP_ANY         -26
  84#define RSP_LAST        -28
  85#define RSP_NODEV       -9
  86
  87/* actions for process_response */
  88#define ACT_NOTHING             0
  89#define ACT_SETDLE1             1
  90#define ACT_SETDLE0             2
  91#define ACT_FAILINIT            3
  92#define ACT_HUPMODEM            4
  93#define ACT_CONFIGMODE          5
  94#define ACT_INIT                6
  95#define ACT_DLE0                7
  96#define ACT_DLE1                8
  97#define ACT_FAILDLE0            9
  98#define ACT_FAILDLE1            10
  99#define ACT_RING                11
 100#define ACT_CID                 12
 101#define ACT_FAILCID             13
 102#define ACT_SDOWN               14
 103#define ACT_FAILSDOWN           15
 104#define ACT_DEBUG               16
 105#define ACT_WARN                17
 106#define ACT_DIALING             18
 107#define ACT_ABORTDIAL           19
 108#define ACT_DISCONNECT          20
 109#define ACT_CONNECT             21
 110#define ACT_REMOTEREJECT        22
 111#define ACT_CONNTIMEOUT         23
 112#define ACT_REMOTEHUP           24
 113#define ACT_ABORTHUP            25
 114#define ACT_ICALL               26
 115#define ACT_ACCEPTED            27
 116#define ACT_ABORTACCEPT         28
 117#define ACT_TIMEOUT             29
 118#define ACT_GETSTRING           30
 119#define ACT_SETVER              31
 120#define ACT_FAILVER             32
 121#define ACT_GOTVER              33
 122#define ACT_TEST                34
 123#define ACT_ERROR               35
 124#define ACT_ABORTCID            36
 125#define ACT_ZCAU                37
 126#define ACT_NOTIFY_BC_DOWN      38
 127#define ACT_NOTIFY_BC_UP        39
 128#define ACT_DIAL                40
 129#define ACT_ACCEPT              41
 130#define ACT_PROTO_L2            42
 131#define ACT_HUP                 43
 132#define ACT_IF_LOCK             44
 133#define ACT_START               45
 134#define ACT_STOP                46
 135#define ACT_FAKEDLE0            47
 136#define ACT_FAKEHUP             48
 137#define ACT_FAKESDOWN           49
 138#define ACT_SHUTDOWN            50
 139#define ACT_PROC_CIDMODE        51
 140#define ACT_UMODESET            52
 141#define ACT_FAILUMODE           53
 142#define ACT_CMODESET            54
 143#define ACT_FAILCMODE           55
 144#define ACT_IF_VER              56
 145#define ACT_CMD                 100
 146
 147/* at command sequences */
 148#define SEQ_NONE        0
 149#define SEQ_INIT        100
 150#define SEQ_DLE0        200
 151#define SEQ_DLE1        250
 152#define SEQ_CID         300
 153#define SEQ_NOCID       350
 154#define SEQ_HUP         400
 155#define SEQ_DIAL        600
 156#define SEQ_ACCEPT      720
 157#define SEQ_SHUTDOWN    500
 158#define SEQ_CIDMODE     10
 159#define SEQ_UMMODE      11
 160
 161
 162// 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring
 163struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */
 164{
 165        /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
 166
 167        /* initialize device, set cid mode if possible */
 168        //{RSP_INIT,     -1, -1,100,                900, 0, {ACT_TEST}},
 169        //{RSP_ERROR,   900,900, -1,                  0, 0, {ACT_FAILINIT}},
 170        //{RSP_OK,      900,900, -1,                100, INIT_TIMEOUT,
 171        //                                                  {ACT_TIMEOUT}},
 172
 173        {RSP_INIT,     -1, -1,SEQ_INIT,           100, INIT_TIMEOUT,
 174                                                          {ACT_TIMEOUT}},                /* wait until device is ready */
 175
 176        {EV_TIMEOUT,  100,100, -1,                101, 3, {0},             "Z\r"},       /* device in transparent mode? try to initialize it. */
 177        {RSP_OK,      101,103, -1,                120, 5, {ACT_GETSTRING}, "+GMR\r"},    /* get version */
 178
 179        {EV_TIMEOUT,  101,101, -1,                102, 5, {0},             "Z\r"},       /* timeout => try once again. */
 180        {RSP_ERROR,   101,101, -1,                102, 5, {0},             "Z\r"},       /* error => try once again. */
 181
 182        {EV_TIMEOUT,  102,102, -1,                108, 5, {ACT_SETDLE1},   "^SDLE=0\r"}, /* timeout => try again in DLE mode. */
 183        {RSP_OK,      108,108, -1,                104,-1},
 184        {RSP_ZDLE,    104,104,  0,                103, 5, {0},             "Z\r"},
 185        {EV_TIMEOUT,  104,104, -1,                  0, 0, {ACT_FAILINIT}},
 186        {RSP_ERROR,   108,108, -1,                  0, 0, {ACT_FAILINIT}},
 187
 188        {EV_TIMEOUT,  108,108, -1,                105, 2, {ACT_SETDLE0,
 189                                                           ACT_HUPMODEM,
 190                                                           ACT_TIMEOUT}},                /* still timeout => connection in unimodem mode? */
 191        {EV_TIMEOUT,  105,105, -1,                103, 5, {0},             "Z\r"},
 192
 193        {RSP_ERROR,   102,102, -1,                107, 5, {0},             "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */
 194        {RSP_OK,      107,107, -1,                  0, 0, {ACT_CONFIGMODE}},
 195        {RSP_ERROR,   107,107, -1,                  0, 0, {ACT_FAILINIT}},
 196        {EV_TIMEOUT,  107,107, -1,                  0, 0, {ACT_FAILINIT}},
 197
 198        {RSP_ERROR,   103,103, -1,                  0, 0, {ACT_FAILINIT}},
 199        {EV_TIMEOUT,  103,103, -1,                  0, 0, {ACT_FAILINIT}},
 200
 201        {RSP_STRING,  120,120, -1,                121,-1, {ACT_SETVER}},
 202
 203        {EV_TIMEOUT,  120,121, -1,                  0, 0, {ACT_FAILVER, ACT_INIT}},
 204        {RSP_ERROR,   120,121, -1,                  0, 0, {ACT_FAILVER, ACT_INIT}},
 205        {RSP_OK,      121,121, -1,                  0, 0, {ACT_GOTVER,  ACT_INIT}},
 206#if 0
 207        {EV_TIMEOUT,  120,121, -1,                130, 5, {ACT_FAILVER},   "^SGCI=1\r"},
 208        {RSP_ERROR,   120,121, -1,                130, 5, {ACT_FAILVER},   "^SGCI=1\r"},
 209        {RSP_OK,      121,121, -1,                130, 5, {ACT_GOTVER},    "^SGCI=1\r"},
 210
 211        {RSP_OK,      130,130, -1,                  0, 0, {ACT_INIT}},
 212        {RSP_ERROR,   130,130, -1,                  0, 0, {ACT_FAILINIT}},
 213        {EV_TIMEOUT,  130,130, -1,                  0, 0, {ACT_FAILINIT}},
 214#endif
 215
 216        /* leave dle mode */
 217        {RSP_INIT,      0,  0,SEQ_DLE0,           201, 5, {0},             "^SDLE=0\r"},
 218        {RSP_OK,      201,201, -1,                202,-1},
 219        //{RSP_ZDLE,    202,202,  0,                202, 0, {ACT_ERROR}},//DELETE
 220        {RSP_ZDLE,    202,202,  0,                  0, 0, {ACT_DLE0}},
 221        {RSP_NODEV,   200,249, -1,                  0, 0, {ACT_FAKEDLE0}},
 222        {RSP_ERROR,   200,249, -1,                  0, 0, {ACT_FAILDLE0}},
 223        {EV_TIMEOUT,  200,249, -1,                  0, 0, {ACT_FAILDLE0}},
 224
 225        /* enter dle mode */
 226        {RSP_INIT,      0,  0,SEQ_DLE1,           251, 5, {0},             "^SDLE=1\r"},
 227        {RSP_OK,      251,251, -1,                252,-1},
 228        {RSP_ZDLE,    252,252,  1,                  0, 0, {ACT_DLE1}},
 229        {RSP_ERROR,   250,299, -1,                  0, 0, {ACT_FAILDLE1}},
 230        {EV_TIMEOUT,  250,299, -1,                  0, 0, {ACT_FAILDLE1}},
 231
 232        /* incoming call */
 233        {RSP_RING,     -1, -1, -1,                 -1,-1, {ACT_RING}},
 234
 235        /* get cid */
 236        //{RSP_INIT,      0,  0,300,                901, 0, {ACT_TEST}},
 237        //{RSP_ERROR,   901,901, -1,                  0, 0, {ACT_FAILCID}},
 238        //{RSP_OK,      901,901, -1,                301, 5, {0},             "^SGCI?\r"},
 239
 240        {RSP_INIT,      0,  0,SEQ_CID,            301, 5, {0},             "^SGCI?\r"},
 241        {RSP_OK,      301,301, -1,                302,-1},
 242        {RSP_ZGCI,    302,302, -1,                  0, 0, {ACT_CID}},
 243        {RSP_ERROR,   301,349, -1,                  0, 0, {ACT_FAILCID}},
 244        {EV_TIMEOUT,  301,349, -1,                  0, 0, {ACT_FAILCID}},
 245
 246        /* enter cid mode */
 247        {RSP_INIT,      0,  0,SEQ_CIDMODE,        150, 5, {0},             "^SGCI=1\r"},
 248        {RSP_OK,      150,150, -1,                  0, 0, {ACT_CMODESET}},
 249        {RSP_ERROR,   150,150, -1,                  0, 0, {ACT_FAILCMODE}},
 250        {EV_TIMEOUT,  150,150, -1,                  0, 0, {ACT_FAILCMODE}},
 251
 252        /* leave cid mode */
 253        //{RSP_INIT,      0,  0,SEQ_UMMODE,         160, 5, {0},             "^SGCI=0\r"},
 254        {RSP_INIT,      0,  0,SEQ_UMMODE,         160, 5, {0},             "Z\r"},
 255        {RSP_OK,      160,160, -1,                  0, 0, {ACT_UMODESET}},
 256        {RSP_ERROR,   160,160, -1,                  0, 0, {ACT_FAILUMODE}},
 257        {EV_TIMEOUT,  160,160, -1,                  0, 0, {ACT_FAILUMODE}},
 258
 259        /* abort getting cid */
 260        {RSP_INIT,      0,  0,SEQ_NOCID,            0, 0, {ACT_ABORTCID}},
 261
 262        /* reset */
 263#if 0
 264        {RSP_INIT,      0,  0,SEQ_SHUTDOWN,       503, 5, {0},             "^SGCI=0\r"},
 265        {RSP_OK,      503,503, -1,                504, 5, {0},             "Z\r"},
 266#endif
 267        {RSP_INIT,      0,  0,SEQ_SHUTDOWN,       504, 5, {0},             "Z\r"},
 268        {RSP_OK,      504,504, -1,                  0, 0, {ACT_SDOWN}},
 269        {RSP_ERROR,   501,599, -1,                  0, 0, {ACT_FAILSDOWN}},
 270        {EV_TIMEOUT,  501,599, -1,                  0, 0, {ACT_FAILSDOWN}},
 271        {RSP_NODEV,   501,599, -1,                  0, 0, {ACT_FAKESDOWN}},
 272
 273        {EV_PROC_CIDMODE,-1, -1, -1,               -1,-1, {ACT_PROC_CIDMODE}}, //FIXME
 274        {EV_IF_LOCK,   -1, -1, -1,                 -1,-1, {ACT_IF_LOCK}}, //FIXME
 275        {EV_IF_VER,    -1, -1, -1,                 -1,-1, {ACT_IF_VER}}, //FIXME
 276        {EV_START,     -1, -1, -1,                 -1,-1, {ACT_START}}, //FIXME
 277        {EV_STOP,      -1, -1, -1,                 -1,-1, {ACT_STOP}}, //FIXME
 278        {EV_SHUTDOWN,  -1, -1, -1,                 -1,-1, {ACT_SHUTDOWN}}, //FIXME
 279
 280        /* misc. */
 281        {RSP_EMPTY,    -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 282        {RSP_ZCFGT,    -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 283        {RSP_ZCFG,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 284        {RSP_ZLOG,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 285        {RSP_ZMWI,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 286        {RSP_ZABINFO,  -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 287        {RSP_ZSMLSTCHG,-1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 288
 289        {RSP_ZCAU,     -1, -1, -1,                 -1,-1, {ACT_ZCAU}},
 290        {RSP_NONE,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}},
 291        {RSP_ANY,      -1, -1, -1,                 -1,-1, {ACT_WARN}},
 292        {RSP_LAST}
 293};
 294
 295// 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall
 296struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
 297{
 298        /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
 299
 300        /* dial */
 301        {EV_DIAL,      -1, -1, -1,                 -1,-1, {ACT_DIAL}}, //FIXME
 302        {RSP_INIT,      0,  0,SEQ_DIAL,           601, 5, {ACT_CMD+AT_BC}},
 303        {RSP_OK,      601,601, -1,                602, 5, {ACT_CMD+AT_HLC}},
 304        {RSP_NULL,    602,602, -1,                603, 5, {ACT_CMD+AT_PROTO}},
 305        {RSP_OK,      602,602, -1,                603, 5, {ACT_CMD+AT_PROTO}},
 306        {RSP_OK,      603,603, -1,                604, 5, {ACT_CMD+AT_TYPE}},
 307        {RSP_OK,      604,604, -1,                605, 5, {ACT_CMD+AT_MSN}},
 308        {RSP_OK,      605,605, -1,                606, 5, {ACT_CMD+AT_ISO}},
 309        {RSP_NULL,    605,605, -1,                606, 5, {ACT_CMD+AT_ISO}},
 310        {RSP_OK,      606,606, -1,                607, 5, {0},             "+VLS=17\r"}, /* set "Endgeraetemodus" */
 311        {RSP_OK,      607,607, -1,                608,-1},
 312        //{RSP_ZSAU,    608,608,ZSAU_PROCEEDING,    608, 0, {ACT_ERROR}},//DELETE
 313        {RSP_ZSAU,    608,608,ZSAU_PROCEEDING,    609, 5, {ACT_CMD+AT_DIAL}},
 314        {RSP_OK,      609,609, -1,                650, 0, {ACT_DIALING}},
 315
 316        {RSP_ZVLS,    608,608, 17,                 -1,-1, {ACT_DEBUG}},
 317        {RSP_ZCTP,    609,609, -1,                 -1,-1, {ACT_DEBUG}},
 318        {RSP_ZCPN,    609,609, -1,                 -1,-1, {ACT_DEBUG}},
 319        {RSP_ERROR,   601,609, -1,                  0, 0, {ACT_ABORTDIAL}},
 320        {EV_TIMEOUT,  601,609, -1,                  0, 0, {ACT_ABORTDIAL}},
 321
 322        /* dialing */
 323        {RSP_ZCTP,    650,650, -1,                 -1,-1, {ACT_DEBUG}},
 324        {RSP_ZCPN,    650,650, -1,                 -1,-1, {ACT_DEBUG}},
 325        {RSP_ZSAU,    650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */
 326
 327        /* connection established  */
 328        {RSP_ZSAU,    650,650,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
 329        {RSP_ZSAU,    750,750,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
 330
 331        {EV_BC_OPEN,  800,800, -1,                800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout
 332
 333        /* remote hangup */
 334        {RSP_ZSAU,    650,650,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEREJECT}},
 335        {RSP_ZSAU,    750,750,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
 336        {RSP_ZSAU,    800,800,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
 337
 338        /* hangup */
 339        {EV_HUP,       -1, -1, -1,                 -1,-1, {ACT_HUP}}, //FIXME
 340        {RSP_INIT,     -1, -1,SEQ_HUP,            401, 5, {0},             "+VLS=0\r"}, /* hang up */ //-1,-1?
 341        {RSP_OK,      401,401, -1,                402, 5},
 342        {RSP_ZVLS,    402,402,  0,                403, 5},
 343        {RSP_ZSAU,    403,403,ZSAU_DISCONNECT_REQ, -1,-1, {ACT_DEBUG}}, /* if not remote hup */
 344        //{RSP_ZSAU,    403,403,ZSAU_NULL,          401, 0, {ACT_ERROR}}, //DELETE//FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
 345        {RSP_ZSAU,    403,403,ZSAU_NULL,            0, 0, {ACT_DISCONNECT}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
 346        {RSP_NODEV,   401,403, -1,                  0, 0, {ACT_FAKEHUP}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
 347        {RSP_ERROR,   401,401, -1,                  0, 0, {ACT_ABORTHUP}},
 348        {EV_TIMEOUT,  401,403, -1,                  0, 0, {ACT_ABORTHUP}},
 349
 350        {EV_BC_CLOSED,  0,  0, -1,                  0,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME new constate + timeout
 351
 352        /* ring */
 353        {RSP_ZBC,     700,700, -1,                 -1,-1, {0}},
 354        {RSP_ZHLC,    700,700, -1,                 -1,-1, {0}},
 355        {RSP_NMBR,    700,700, -1,                 -1,-1, {0}},
 356        {RSP_ZCPN,    700,700, -1,                 -1,-1, {0}},
 357        {RSP_ZCTP,    700,700, -1,                 -1,-1, {0}},
 358        {EV_TIMEOUT,  700,700, -1,               720,720, {ACT_ICALL}},
 359        {EV_BC_CLOSED,720,720, -1,                  0,-1, {ACT_NOTIFY_BC_DOWN}},
 360
 361        /*accept icall*/
 362        {EV_ACCEPT,    -1, -1, -1,                 -1,-1, {ACT_ACCEPT}}, //FIXME
 363        {RSP_INIT,    720,720,SEQ_ACCEPT,         721, 5, {ACT_CMD+AT_PROTO}},
 364        {RSP_OK,      721,721, -1,                722, 5, {ACT_CMD+AT_ISO}},
 365        {RSP_OK,      722,722, -1,                723, 5, {0},             "+VLS=17\r"}, /* set "Endgeraetemodus" */
 366        {RSP_OK,      723,723, -1,                724, 5, {0}},
 367        {RSP_ZVLS,    724,724, 17,                750,50, {ACT_ACCEPTED}},
 368        {RSP_ERROR,   721,729, -1,                  0, 0, {ACT_ABORTACCEPT}},
 369        {EV_TIMEOUT,  721,729, -1,                  0, 0, {ACT_ABORTACCEPT}},
 370        {RSP_ZSAU,    700,729,ZSAU_NULL,            0, 0, {ACT_ABORTACCEPT}},
 371        {RSP_ZSAU,    700,729,ZSAU_ACTIVE,          0, 0, {ACT_ABORTACCEPT}},
 372        {RSP_ZSAU,    700,729,ZSAU_DISCONNECT_IND,  0, 0, {ACT_ABORTACCEPT}},
 373
 374        {EV_TIMEOUT,  750,750, -1,                  0, 0, {ACT_CONNTIMEOUT}},
 375
 376        /* B channel closed (general case) */
 377        {EV_BC_CLOSED, -1, -1, -1,                 -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
 378
 379        /* misc. */
 380        {EV_PROTO_L2,  -1, -1, -1,                 -1,-1, {ACT_PROTO_L2}}, //FIXME
 381
 382        {RSP_ZCON,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 383        {RSP_ZCCR,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 384        {RSP_ZAOC,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 385        {RSP_ZCSTR,    -1, -1, -1,                 -1,-1, {ACT_DEBUG}}, //FIXME
 386
 387        {RSP_ZCAU,     -1, -1, -1,                 -1,-1, {ACT_ZCAU}},
 388        {RSP_NONE,     -1, -1, -1,                 -1,-1, {ACT_DEBUG}},
 389        {RSP_ANY,      -1, -1, -1,                 -1,-1, {ACT_WARN}},
 390        {RSP_LAST}
 391};
 392
 393
 394#if 0
 395static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME
 396{
 397        /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
 398
 399        {RSP_ANY,      -1, -1, -1,                 -1,-1, ACT_WARN,         NULL},
 400        {RSP_LAST,0,0,0,0,0,0}
 401};
 402
 403static struct reply_t tab_cid[] = /* no dle mode */ //FIXME
 404{
 405        /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
 406
 407        {RSP_ANY,      -1, -1, -1,                 -1,-1, ACT_WARN,         NULL},
 408        {RSP_LAST,0,0,0,0,0,0}
 409};
 410#endif
 411
 412static const struct resp_type_t resp_type[] =
 413{
 414        /*{"",          RSP_EMPTY,      RT_NOTHING},*/
 415        {"OK",          RSP_OK,         RT_NOTHING},
 416        {"ERROR",       RSP_ERROR,      RT_NOTHING},
 417        {"ZSAU",        RSP_ZSAU,       RT_ZSAU},
 418        {"ZCAU",        RSP_ZCAU,       RT_ZCAU},
 419        {"RING",        RSP_RING,       RT_RING},
 420        {"ZGCI",        RSP_ZGCI,       RT_NUMBER},
 421        {"ZVLS",        RSP_ZVLS,       RT_NUMBER},
 422        {"ZCTP",        RSP_ZCTP,       RT_NUMBER},
 423        {"ZDLE",        RSP_ZDLE,       RT_NUMBER},
 424        {"ZCFGT",       RSP_ZCFGT,      RT_NUMBER},
 425        {"ZCCR",        RSP_ZCCR,       RT_NUMBER},
 426        {"ZMWI",        RSP_ZMWI,       RT_NUMBER},
 427        {"ZHLC",        RSP_ZHLC,       RT_STRING},
 428        {"ZBC",         RSP_ZBC,        RT_STRING},
 429        {"NMBR",        RSP_NMBR,       RT_STRING},
 430        {"ZCPN",        RSP_ZCPN,       RT_STRING},
 431        {"ZCON",        RSP_ZCON,       RT_STRING},
 432        {"ZAOC",        RSP_ZAOC,       RT_STRING},
 433        {"ZCSTR",       RSP_ZCSTR,      RT_STRING},
 434        {"ZCFG",        RSP_ZCFG,       RT_HEX},
 435        {"ZLOG",        RSP_ZLOG,       RT_NOTHING},
 436        {"ZABINFO",     RSP_ZABINFO,    RT_NOTHING},
 437        {"ZSMLSTCHG",   RSP_ZSMLSTCHG,  RT_NOTHING},
 438        {NULL,0,0}
 439};
 440
 441/*
 442 * Get integer from char-pointer
 443 */
 444static int isdn_getnum(char *p)
 445{
 446        int v = -1;
 447
 448        gig_dbg(DEBUG_TRANSCMD, "string: %s", p);
 449
 450        while (*p >= '0' && *p <= '9')
 451                v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0');
 452        if (*p)
 453                v = -1; /* invalid Character */
 454        return v;
 455}
 456
 457/*
 458 * Get integer from char-pointer
 459 */
 460static int isdn_gethex(char *p)
 461{
 462        int v = 0;
 463        int c;
 464
 465        gig_dbg(DEBUG_TRANSCMD, "string: %s", p);
 466
 467        if (!*p)
 468                return -1;
 469
 470        do {
 471                if (v > (INT_MAX - 15) / 16)
 472                        return -1;
 473                c = *p;
 474                if (c >= '0' && c <= '9')
 475                        c -= '0';
 476                else if (c >= 'a' && c <= 'f')
 477                        c -= 'a' - 10;
 478                else if (c >= 'A' && c <= 'F')
 479                        c -= 'A' - 10;
 480                else
 481                        return -1;
 482                v = v * 16 + c;
 483        } while (*++p);
 484
 485        return v;
 486}
 487
 488/* retrieve CID from parsed response
 489 * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535
 490 */
 491static int cid_of_response(char *s)
 492{
 493        int cid;
 494
 495        if (s[-1] != ';')
 496                return 0;       /* no CID separator */
 497        cid = isdn_getnum(s);
 498        if (cid < 0)
 499                return 0;       /* CID not numeric */
 500        if (cid < 1 || cid > 65535)
 501                return -1;      /* CID out of range */
 502        return cid;
 503        //FIXME is ;<digit>+ at end of non-CID response really impossible?
 504}
 505
 506/* This function will be called via task queue from the callback handler.
 507 * We received a modem response and have to handle it..
 508 */
 509void gigaset_handle_modem_response(struct cardstate *cs)
 510{
 511        unsigned char *argv[MAX_REC_PARAMS + 1];
 512        int params;
 513        int i, j;
 514        const struct resp_type_t *rt;
 515        int curarg;
 516        unsigned long flags;
 517        unsigned next, tail, head;
 518        struct event_t *event;
 519        int resp_code;
 520        int param_type;
 521        int abort;
 522        size_t len;
 523        int cid;
 524        int rawstring;
 525
 526        len = cs->cbytes;
 527        if (!len) {
 528                /* ignore additional LFs/CRs (M10x config mode or cx100) */
 529                gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]);
 530                return;
 531        }
 532        cs->respdata[len] = 0;
 533        gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata);
 534        argv[0] = cs->respdata;
 535        params = 1;
 536        if (cs->at_state.getstring) {
 537                /* getstring only allowed without cid at the moment */
 538                cs->at_state.getstring = 0;
 539                rawstring = 1;
 540                cid = 0;
 541        } else {
 542                /* parse line */
 543                for (i = 0; i < len; i++)
 544                        switch (cs->respdata[i]) {
 545                        case ';':
 546                        case ',':
 547                        case '=':
 548                                if (params > MAX_REC_PARAMS) {
 549                                        dev_warn(cs->dev,
 550                                           "too many parameters in response\n");
 551                                        /* need last parameter (might be CID) */
 552                                        params--;
 553                                }
 554                                argv[params++] = cs->respdata + i + 1;
 555                        }
 556
 557                rawstring = 0;
 558                cid = params > 1 ? cid_of_response(argv[params-1]) : 0;
 559                if (cid < 0) {
 560                        gigaset_add_event(cs, &cs->at_state, RSP_INVAL,
 561                                          NULL, 0, NULL);
 562                        return;
 563                }
 564
 565                for (j = 1; j < params; ++j)
 566                        argv[j][-1] = 0;
 567
 568                gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]);
 569                if (cid) {
 570                        --params;
 571                        gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]);
 572                }
 573                gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1);
 574                for (j = 1; j < params; j++)
 575                        gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]);
 576        }
 577
 578        spin_lock_irqsave(&cs->ev_lock, flags);
 579        head = cs->ev_head;
 580        tail = cs->ev_tail;
 581
 582        abort = 1;
 583        curarg = 0;
 584        while (curarg < params) {
 585                next = (tail + 1) % MAX_EVENTS;
 586                if (unlikely(next == head)) {
 587                        dev_err(cs->dev, "event queue full\n");
 588                        break;
 589                }
 590
 591                event = cs->events + tail;
 592                event->at_state = NULL;
 593                event->cid = cid;
 594                event->ptr = NULL;
 595                event->arg = NULL;
 596                tail = next;
 597
 598                if (rawstring) {
 599                        resp_code = RSP_STRING;
 600                        param_type = RT_STRING;
 601                } else {
 602                        for (rt = resp_type; rt->response; ++rt)
 603                                if (!strcmp(argv[curarg], rt->response))
 604                                        break;
 605
 606                        if (!rt->response) {
 607                                event->type = RSP_UNKNOWN;
 608                                dev_warn(cs->dev,
 609                                         "unknown modem response: %s\n",
 610                                         argv[curarg]);
 611                                break;
 612                        }
 613
 614                        resp_code = rt->resp_code;
 615                        param_type = rt->type;
 616                        ++curarg;
 617                }
 618
 619                event->type = resp_code;
 620
 621                switch (param_type) {
 622                case RT_NOTHING:
 623                        break;
 624                case RT_RING:
 625                        if (!cid) {
 626                                dev_err(cs->dev,
 627                                        "received RING without CID!\n");
 628                                event->type = RSP_INVAL;
 629                                abort = 1;
 630                        } else {
 631                                event->cid = 0;
 632                                event->parameter = cid;
 633                                abort = 0;
 634                        }
 635                        break;
 636                case RT_ZSAU:
 637                        if (curarg >= params) {
 638                                event->parameter = ZSAU_NONE;
 639                                break;
 640                        }
 641                        if (!strcmp(argv[curarg], "OUTGOING_CALL_PROCEEDING"))
 642                                event->parameter = ZSAU_OUTGOING_CALL_PROCEEDING;
 643                        else if (!strcmp(argv[curarg], "CALL_DELIVERED"))
 644                                event->parameter = ZSAU_CALL_DELIVERED;
 645                        else if (!strcmp(argv[curarg], "ACTIVE"))
 646                                event->parameter = ZSAU_ACTIVE;
 647                        else if (!strcmp(argv[curarg], "DISCONNECT_IND"))
 648                                event->parameter = ZSAU_DISCONNECT_IND;
 649                        else if (!strcmp(argv[curarg], "NULL"))
 650                                event->parameter = ZSAU_NULL;
 651                        else if (!strcmp(argv[curarg], "DISCONNECT_REQ"))
 652                                event->parameter = ZSAU_DISCONNECT_REQ;
 653                        else {
 654                                event->parameter = ZSAU_UNKNOWN;
 655                                dev_warn(cs->dev,
 656                                        "%s: unknown parameter %s after ZSAU\n",
 657                                         __func__, argv[curarg]);
 658                        }
 659                        ++curarg;
 660                        break;
 661                case RT_STRING:
 662                        if (curarg < params) {
 663                                event->ptr = kstrdup(argv[curarg], GFP_ATOMIC);
 664                                if (!event->ptr)
 665                                        dev_err(cs->dev, "out of memory\n");
 666                                ++curarg;
 667                        }
 668#ifdef CONFIG_GIGASET_DEBUG
 669                        if (!event->ptr)
 670                                gig_dbg(DEBUG_CMD, "string==NULL");
 671                        else
 672                                gig_dbg(DEBUG_CMD, "string==%s",
 673                                        (char *) event->ptr);
 674#endif
 675                        break;
 676                case RT_ZCAU:
 677                        event->parameter = -1;
 678                        if (curarg + 1 < params) {
 679                                i = isdn_gethex(argv[curarg]);
 680                                j = isdn_gethex(argv[curarg + 1]);
 681                                if (i >= 0 && i < 256 && j >= 0 && j < 256)
 682                                        event->parameter = (unsigned) i << 8
 683                                                           | j;
 684                                curarg += 2;
 685                        } else
 686                                curarg = params - 1;
 687                        break;
 688                case RT_NUMBER:
 689                case RT_HEX:
 690                        if (curarg < params) {
 691                                if (param_type == RT_HEX)
 692                                        event->parameter =
 693                                                isdn_gethex(argv[curarg]);
 694                                else
 695                                        event->parameter =
 696                                                isdn_getnum(argv[curarg]);
 697                                ++curarg;
 698                        } else
 699                                event->parameter = -1;
 700#ifdef CONFIG_GIGASET_DEBUG
 701                        gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter);
 702#endif
 703                        break;
 704                }
 705
 706                if (resp_code == RSP_ZDLE)
 707                        cs->dle = event->parameter;
 708
 709                if (abort)
 710                        break;
 711        }
 712
 713        cs->ev_tail = tail;
 714        spin_unlock_irqrestore(&cs->ev_lock, flags);
 715
 716        if (curarg != params)
 717                gig_dbg(DEBUG_ANY,
 718                        "invalid number of processed parameters: %d/%d",
 719                        curarg, params);
 720}
 721EXPORT_SYMBOL_GPL(gigaset_handle_modem_response);
 722
 723/* disconnect
 724 * process closing of connection associated with given AT state structure
 725 */
 726static void disconnect(struct at_state_t **at_state_p)
 727{
 728        unsigned long flags;
 729        struct bc_state *bcs = (*at_state_p)->bcs;
 730        struct cardstate *cs = (*at_state_p)->cs;
 731
 732        spin_lock_irqsave(&cs->lock, flags);
 733        ++(*at_state_p)->seq_index;
 734
 735        /* revert to selected idle mode */
 736        if (!cs->cidmode) {
 737                cs->at_state.pending_commands |= PC_UMMODE;
 738                cs->commands_pending = 1;
 739                gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
 740        }
 741        spin_unlock_irqrestore(&cs->lock, flags);
 742
 743        if (bcs) {
 744                /* B channel assigned: invoke hardware specific handler */
 745                cs->ops->close_bchannel(bcs);
 746        } else {
 747                /* no B channel assigned: just deallocate */
 748                spin_lock_irqsave(&cs->lock, flags);
 749                list_del(&(*at_state_p)->list);
 750                kfree(*at_state_p);
 751                *at_state_p = NULL;
 752                spin_unlock_irqrestore(&cs->lock, flags);
 753        }
 754}
 755
 756/* get_free_channel
 757 * get a free AT state structure: either one of those associated with the
 758 * B channels of the Gigaset device, or if none of those is available,
 759 * a newly allocated one with bcs=NULL
 760 * The structure should be freed by calling disconnect() after use.
 761 */
 762static inline struct at_state_t *get_free_channel(struct cardstate *cs,
 763                                                  int cid)
 764/* cids: >0: siemens-cid
 765          0: without cid
 766         -1: no cid assigned yet
 767*/
 768{
 769        unsigned long flags;
 770        int i;
 771        struct at_state_t *ret;
 772
 773        for (i = 0; i < cs->channels; ++i)
 774                if (gigaset_get_channel(cs->bcs + i)) {
 775                        ret = &cs->bcs[i].at_state;
 776                        ret->cid = cid;
 777                        return ret;
 778                }
 779
 780        spin_lock_irqsave(&cs->lock, flags);
 781        ret = kmalloc(sizeof(struct at_state_t), GFP_ATOMIC);
 782        if (ret) {
 783                gigaset_at_init(ret, NULL, cs, cid);
 784                list_add(&ret->list, &cs->temp_at_states);
 785        }
 786        spin_unlock_irqrestore(&cs->lock, flags);
 787        return ret;
 788}
 789
 790static void init_failed(struct cardstate *cs, int mode)
 791{
 792        int i;
 793        struct at_state_t *at_state;
 794
 795        cs->at_state.pending_commands &= ~PC_INIT;
 796        cs->mode = mode;
 797        cs->mstate = MS_UNINITIALIZED;
 798        gigaset_free_channels(cs);
 799        for (i = 0; i < cs->channels; ++i) {
 800                at_state = &cs->bcs[i].at_state;
 801                if (at_state->pending_commands & PC_CID) {
 802                        at_state->pending_commands &= ~PC_CID;
 803                        at_state->pending_commands |= PC_NOCID;
 804                        cs->commands_pending = 1;
 805                }
 806        }
 807}
 808
 809static void schedule_init(struct cardstate *cs, int state)
 810{
 811        if (cs->at_state.pending_commands & PC_INIT) {
 812                gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again");
 813                return;
 814        }
 815        cs->mstate = state;
 816        cs->mode = M_UNKNOWN;
 817        gigaset_block_channels(cs);
 818        cs->at_state.pending_commands |= PC_INIT;
 819        cs->commands_pending = 1;
 820        gig_dbg(DEBUG_CMD, "Scheduling PC_INIT");
 821}
 822
 823/* Add "AT" to a command, add the cid, dle encode it, send the result to the
 824   hardware. */
 825static void send_command(struct cardstate *cs, const char *cmd, int cid,
 826                         int dle, gfp_t kmallocflags)
 827{
 828        size_t cmdlen, buflen;
 829        char *cmdpos, *cmdbuf, *cmdtail;
 830
 831        cmdlen = strlen(cmd);
 832        buflen = 11 + cmdlen;
 833        if (unlikely(buflen <= cmdlen)) {
 834                dev_err(cs->dev, "integer overflow in buflen\n");
 835                return;
 836        }
 837
 838        cmdbuf = kmalloc(buflen, kmallocflags);
 839        if (unlikely(!cmdbuf)) {
 840                dev_err(cs->dev, "out of memory\n");
 841                return;
 842        }
 843
 844        cmdpos = cmdbuf + 9;
 845        cmdtail = cmdpos + cmdlen;
 846        memcpy(cmdpos, cmd, cmdlen);
 847
 848        if (cid > 0 && cid <= 65535) {
 849                do {
 850                        *--cmdpos = '0' + cid % 10;
 851                        cid /= 10;
 852                        ++cmdlen;
 853                } while (cid);
 854        }
 855
 856        cmdlen += 2;
 857        *--cmdpos = 'T';
 858        *--cmdpos = 'A';
 859
 860        if (dle) {
 861                cmdlen += 4;
 862                *--cmdpos = '(';
 863                *--cmdpos = 0x10;
 864                *cmdtail++ = 0x10;
 865                *cmdtail++ = ')';
 866        }
 867
 868        cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL);
 869        kfree(cmdbuf);
 870}
 871
 872static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid)
 873{
 874        struct at_state_t *at_state;
 875        int i;
 876        unsigned long flags;
 877
 878        if (cid == 0)
 879                return &cs->at_state;
 880
 881        for (i = 0; i < cs->channels; ++i)
 882                if (cid == cs->bcs[i].at_state.cid)
 883                        return &cs->bcs[i].at_state;
 884
 885        spin_lock_irqsave(&cs->lock, flags);
 886
 887        list_for_each_entry(at_state, &cs->temp_at_states, list)
 888                if (cid == at_state->cid) {
 889                        spin_unlock_irqrestore(&cs->lock, flags);
 890                        return at_state;
 891                }
 892
 893        spin_unlock_irqrestore(&cs->lock, flags);
 894
 895        return NULL;
 896}
 897
 898static void bchannel_down(struct bc_state *bcs)
 899{
 900        if (bcs->chstate & CHS_B_UP) {
 901                bcs->chstate &= ~CHS_B_UP;
 902                gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP);
 903        }
 904
 905        if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
 906                bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
 907                gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
 908        }
 909
 910        gigaset_free_channel(bcs);
 911
 912        gigaset_bcs_reinit(bcs);
 913}
 914
 915static void bchannel_up(struct bc_state *bcs)
 916{
 917        if (!(bcs->chstate & CHS_D_UP)) {
 918                dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__);
 919                bcs->chstate |= CHS_D_UP;
 920                gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
 921        }
 922
 923        if (bcs->chstate & CHS_B_UP) {
 924                dev_notice(bcs->cs->dev, "%s: B channel already up\n",
 925                           __func__);
 926                return;
 927        }
 928
 929        bcs->chstate |= CHS_B_UP;
 930        gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
 931}
 932
 933static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index)
 934{
 935        struct bc_state *bcs = at_state->bcs;
 936        struct cardstate *cs = at_state->cs;
 937        int retval;
 938        unsigned long flags;
 939
 940        bcs->chstate |= CHS_NOTIFY_LL;
 941
 942        spin_lock_irqsave(&cs->lock, flags);
 943        if (at_state->seq_index != seq_index) {
 944                spin_unlock_irqrestore(&cs->lock, flags);
 945                goto error;
 946        }
 947        spin_unlock_irqrestore(&cs->lock, flags);
 948
 949        retval = gigaset_isdn_setup_dial(at_state, data);
 950        if (retval != 0)
 951                goto error;
 952
 953
 954        at_state->pending_commands |= PC_CID;
 955        gig_dbg(DEBUG_CMD, "Scheduling PC_CID");
 956        cs->commands_pending = 1;
 957        return;
 958
 959error:
 960        at_state->pending_commands |= PC_NOCID;
 961        gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID");
 962        cs->commands_pending = 1;
 963        return;
 964}
 965
 966static void start_accept(struct at_state_t *at_state)
 967{
 968        struct cardstate *cs = at_state->cs;
 969        int retval;
 970
 971        retval = gigaset_isdn_setup_accept(at_state);
 972
 973        if (retval == 0) {
 974                at_state->pending_commands |= PC_ACCEPT;
 975                gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT");
 976                cs->commands_pending = 1;
 977        } else {
 978                /* error reset */
 979                at_state->pending_commands |= PC_HUP;
 980                gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
 981                cs->commands_pending = 1;
 982        }
 983}
 984
 985static void do_start(struct cardstate *cs)
 986{
 987        gigaset_free_channels(cs);
 988
 989        if (cs->mstate != MS_LOCKED)
 990                schedule_init(cs, MS_INIT);
 991
 992        cs->isdn_up = 1;
 993        gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
 994                                        // FIXME: not in locked mode
 995                                        // FIXME 2: only after init sequence
 996
 997        cs->waiting = 0;
 998        wake_up(&cs->waitqueue);
 999}
1000
1001static void finish_shutdown(struct cardstate *cs)
1002{
1003        if (cs->mstate != MS_LOCKED) {
1004                cs->mstate = MS_UNINITIALIZED;
1005                cs->mode = M_UNKNOWN;
1006        }
1007
1008        /* Tell the LL that the device is not available .. */
1009        if (cs->isdn_up) {
1010                cs->isdn_up = 0;
1011                gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
1012        }
1013
1014        /* The rest is done by cleanup_cs () in user mode. */
1015
1016        cs->cmd_result = -ENODEV;
1017        cs->waiting = 0;
1018        wake_up(&cs->waitqueue);
1019}
1020
1021static void do_shutdown(struct cardstate *cs)
1022{
1023        gigaset_block_channels(cs);
1024
1025        if (cs->mstate == MS_READY) {
1026                cs->mstate = MS_SHUTDOWN;
1027                cs->at_state.pending_commands |= PC_SHUTDOWN;
1028                cs->commands_pending = 1;
1029                gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN");
1030        } else
1031                finish_shutdown(cs);
1032}
1033
1034static void do_stop(struct cardstate *cs)
1035{
1036        unsigned long flags;
1037
1038        spin_lock_irqsave(&cs->lock, flags);
1039        cs->connected = 0;
1040        spin_unlock_irqrestore(&cs->lock, flags);
1041
1042        do_shutdown(cs);
1043}
1044
1045/* Entering cid mode or getting a cid failed:
1046 * try to initialize the device and try again.
1047 *
1048 * channel >= 0: getting cid for the channel failed
1049 * channel < 0:  entering cid mode failed
1050 *
1051 * returns 0 on failure
1052 */
1053static int reinit_and_retry(struct cardstate *cs, int channel)
1054{
1055        int i;
1056
1057        if (--cs->retry_count <= 0)
1058                return 0;
1059
1060        for (i = 0; i < cs->channels; ++i)
1061                if (cs->bcs[i].at_state.cid > 0)
1062                        return 0;
1063
1064        if (channel < 0)
1065                dev_warn(cs->dev,
1066                    "Could not enter cid mode. Reinit device and try again.\n");
1067        else {
1068                dev_warn(cs->dev,
1069                    "Could not get a call id. Reinit device and try again.\n");
1070                cs->bcs[channel].at_state.pending_commands |= PC_CID;
1071        }
1072        schedule_init(cs, MS_INIT);
1073        return 1;
1074}
1075
1076static int at_state_invalid(struct cardstate *cs,
1077                            struct at_state_t *test_ptr)
1078{
1079        unsigned long flags;
1080        unsigned channel;
1081        struct at_state_t *at_state;
1082        int retval = 0;
1083
1084        spin_lock_irqsave(&cs->lock, flags);
1085
1086        if (test_ptr == &cs->at_state)
1087                goto exit;
1088
1089        list_for_each_entry(at_state, &cs->temp_at_states, list)
1090                if (at_state == test_ptr)
1091                        goto exit;
1092
1093        for (channel = 0; channel < cs->channels; ++channel)
1094                if (&cs->bcs[channel].at_state == test_ptr)
1095                        goto exit;
1096
1097        retval = 1;
1098exit:
1099        spin_unlock_irqrestore(&cs->lock, flags);
1100        return retval;
1101}
1102
1103static void handle_icall(struct cardstate *cs, struct bc_state *bcs,
1104                         struct at_state_t **p_at_state)
1105{
1106        int retval;
1107        struct at_state_t *at_state = *p_at_state;
1108
1109        retval = gigaset_isdn_icall(at_state);
1110        switch (retval) {
1111        case ICALL_ACCEPT:
1112                break;
1113        default:
1114                dev_err(cs->dev, "internal error: disposition=%d\n", retval);
1115                /* --v-- fall through --v-- */
1116        case ICALL_IGNORE:
1117        case ICALL_REJECT:
1118                /* hang up actively
1119                 * Device doc says that would reject the call.
1120                 * In fact it doesn't.
1121                 */
1122                at_state->pending_commands |= PC_HUP;
1123                cs->commands_pending = 1;
1124                break;
1125        }
1126}
1127
1128static int do_lock(struct cardstate *cs)
1129{
1130        int mode;
1131        int i;
1132
1133        switch (cs->mstate) {
1134        case MS_UNINITIALIZED:
1135        case MS_READY:
1136                if (cs->cur_at_seq || !list_empty(&cs->temp_at_states) ||
1137                    cs->at_state.pending_commands)
1138                        return -EBUSY;
1139
1140                for (i = 0; i < cs->channels; ++i)
1141                        if (cs->bcs[i].at_state.pending_commands)
1142                                return -EBUSY;
1143
1144                if (!gigaset_get_channels(cs))
1145                        return -EBUSY;
1146
1147                break;
1148        case MS_LOCKED:
1149                //retval = -EACCES;
1150                break;
1151        default:
1152                return -EBUSY;
1153        }
1154
1155        mode = cs->mode;
1156        cs->mstate = MS_LOCKED;
1157        cs->mode = M_UNKNOWN;
1158
1159        return mode;
1160}
1161
1162static int do_unlock(struct cardstate *cs)
1163{
1164        if (cs->mstate != MS_LOCKED)
1165                return -EINVAL;
1166
1167        cs->mstate = MS_UNINITIALIZED;
1168        cs->mode = M_UNKNOWN;
1169        gigaset_free_channels(cs);
1170        if (cs->connected)
1171                schedule_init(cs, MS_INIT);
1172
1173        return 0;
1174}
1175
1176static void do_action(int action, struct cardstate *cs,
1177                      struct bc_state *bcs,
1178                      struct at_state_t **p_at_state, char **pp_command,
1179                      int *p_genresp, int *p_resp_code,
1180                      struct event_t *ev)
1181{
1182        struct at_state_t *at_state = *p_at_state;
1183        struct at_state_t *at_state2;
1184        unsigned long flags;
1185
1186        int channel;
1187
1188        unsigned char *s, *e;
1189        int i;
1190        unsigned long val;
1191
1192        switch (action) {
1193        case ACT_NOTHING:
1194                break;
1195        case ACT_TIMEOUT:
1196                at_state->waiting = 1;
1197                break;
1198        case ACT_INIT:
1199                cs->at_state.pending_commands &= ~PC_INIT;
1200                cs->cur_at_seq = SEQ_NONE;
1201                cs->mode = M_UNIMODEM;
1202                spin_lock_irqsave(&cs->lock, flags);
1203                if (!cs->cidmode) {
1204                        spin_unlock_irqrestore(&cs->lock, flags);
1205                        gigaset_free_channels(cs);
1206                        cs->mstate = MS_READY;
1207                        break;
1208                }
1209                spin_unlock_irqrestore(&cs->lock, flags);
1210                cs->at_state.pending_commands |= PC_CIDMODE;
1211                cs->commands_pending = 1;
1212                gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
1213                break;
1214        case ACT_FAILINIT:
1215                dev_warn(cs->dev, "Could not initialize the device.\n");
1216                cs->dle = 0;
1217                init_failed(cs, M_UNKNOWN);
1218                cs->cur_at_seq = SEQ_NONE;
1219                break;
1220        case ACT_CONFIGMODE:
1221                init_failed(cs, M_CONFIG);
1222                cs->cur_at_seq = SEQ_NONE;
1223                break;
1224        case ACT_SETDLE1:
1225                cs->dle = 1;
1226                /* cs->inbuf[0].inputstate |= INS_command | INS_DLE_command; */
1227                cs->inbuf[0].inputstate &=
1228                        ~(INS_command | INS_DLE_command);
1229                break;
1230        case ACT_SETDLE0:
1231                cs->dle = 0;
1232                cs->inbuf[0].inputstate =
1233                        (cs->inbuf[0].inputstate & ~INS_DLE_command)
1234                        | INS_command;
1235                break;
1236        case ACT_CMODESET:
1237                if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) {
1238                        gigaset_free_channels(cs);
1239                        cs->mstate = MS_READY;
1240                }
1241                cs->mode = M_CID;
1242                cs->cur_at_seq = SEQ_NONE;
1243                break;
1244        case ACT_UMODESET:
1245                cs->mode = M_UNIMODEM;
1246                cs->cur_at_seq = SEQ_NONE;
1247                break;
1248        case ACT_FAILCMODE:
1249                cs->cur_at_seq = SEQ_NONE;
1250                if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) {
1251                        init_failed(cs, M_UNKNOWN);
1252                        break;
1253                }
1254                if (!reinit_and_retry(cs, -1))
1255                        schedule_init(cs, MS_RECOVER);
1256                break;
1257        case ACT_FAILUMODE:
1258                cs->cur_at_seq = SEQ_NONE;
1259                schedule_init(cs, MS_RECOVER);
1260                break;
1261        case ACT_HUPMODEM:
1262                /* send "+++" (hangup in unimodem mode) */
1263                if (cs->connected)
1264                        cs->ops->write_cmd(cs, "+++", 3, NULL);
1265                break;
1266        case ACT_RING:
1267                /* get fresh AT state structure for new CID */
1268                at_state2 = get_free_channel(cs, ev->parameter);
1269                if (!at_state2) {
1270                        dev_warn(cs->dev,
1271                        "RING ignored: could not allocate channel structure\n");
1272                        break;
1273                }
1274
1275                /* initialize AT state structure
1276                 * note that bcs may be NULL if no B channel is free
1277                 */
1278                at_state2->ConState = 700;
1279                kfree(at_state2->str_var[STR_NMBR]);
1280                at_state2->str_var[STR_NMBR] = NULL;
1281                kfree(at_state2->str_var[STR_ZCPN]);
1282                at_state2->str_var[STR_ZCPN] = NULL;
1283                kfree(at_state2->str_var[STR_ZBC]);
1284                at_state2->str_var[STR_ZBC] = NULL;
1285                kfree(at_state2->str_var[STR_ZHLC]);
1286                at_state2->str_var[STR_ZHLC] = NULL;
1287                at_state2->int_var[VAR_ZCTP] = -1;
1288
1289                spin_lock_irqsave(&cs->lock, flags);
1290                at_state2->timer_expires = RING_TIMEOUT;
1291                at_state2->timer_active = 1;
1292                spin_unlock_irqrestore(&cs->lock, flags);
1293                break;
1294        case ACT_ICALL:
1295                handle_icall(cs, bcs, p_at_state);
1296                break;
1297        case ACT_FAILSDOWN:
1298                dev_warn(cs->dev, "Could not shut down the device.\n");
1299                /* fall through */
1300        case ACT_FAKESDOWN:
1301        case ACT_SDOWN:
1302                cs->cur_at_seq = SEQ_NONE;
1303                finish_shutdown(cs);
1304                break;
1305        case ACT_CONNECT:
1306                if (cs->onechannel) {
1307                        at_state->pending_commands |= PC_DLE1;
1308                        cs->commands_pending = 1;
1309                        break;
1310                }
1311                bcs->chstate |= CHS_D_UP;
1312                gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
1313                cs->ops->init_bchannel(bcs);
1314                break;
1315        case ACT_DLE1:
1316                cs->cur_at_seq = SEQ_NONE;
1317                bcs = cs->bcs + cs->curchannel;
1318
1319                bcs->chstate |= CHS_D_UP;
1320                gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
1321                cs->ops->init_bchannel(bcs);
1322                break;
1323        case ACT_FAKEHUP:
1324                at_state->int_var[VAR_ZSAU] = ZSAU_NULL;
1325                /* fall through */
1326        case ACT_DISCONNECT:
1327                cs->cur_at_seq = SEQ_NONE;
1328                at_state->cid = -1;
1329                if (bcs && cs->onechannel && cs->dle) {
1330                        /* Check for other open channels not needed:
1331                         * DLE only used for M10x with one B channel.
1332                         */
1333                        at_state->pending_commands |= PC_DLE0;
1334                        cs->commands_pending = 1;
1335                } else
1336                        disconnect(p_at_state);
1337                break;
1338        case ACT_FAKEDLE0:
1339                at_state->int_var[VAR_ZDLE] = 0;
1340                cs->dle = 0;
1341                /* fall through */
1342        case ACT_DLE0:
1343                cs->cur_at_seq = SEQ_NONE;
1344                at_state2 = &cs->bcs[cs->curchannel].at_state;
1345                disconnect(&at_state2);
1346                break;
1347        case ACT_ABORTHUP:
1348                cs->cur_at_seq = SEQ_NONE;
1349                dev_warn(cs->dev, "Could not hang up.\n");
1350                at_state->cid = -1;
1351                if (bcs && cs->onechannel)
1352                        at_state->pending_commands |= PC_DLE0;
1353                else
1354                        disconnect(p_at_state);
1355                schedule_init(cs, MS_RECOVER);
1356                break;
1357        case ACT_FAILDLE0:
1358                cs->cur_at_seq = SEQ_NONE;
1359                dev_warn(cs->dev, "Could not leave DLE mode.\n");
1360                at_state2 = &cs->bcs[cs->curchannel].at_state;
1361                disconnect(&at_state2);
1362                schedule_init(cs, MS_RECOVER);
1363                break;
1364        case ACT_FAILDLE1:
1365                cs->cur_at_seq = SEQ_NONE;
1366                dev_warn(cs->dev,
1367                         "Could not enter DLE mode. Trying to hang up.\n");
1368                channel = cs->curchannel;
1369                cs->bcs[channel].at_state.pending_commands |= PC_HUP;
1370                cs->commands_pending = 1;
1371                break;
1372
1373        case ACT_CID: /* got cid; start dialing */
1374                cs->cur_at_seq = SEQ_NONE;
1375                channel = cs->curchannel;
1376                if (ev->parameter > 0 && ev->parameter <= 65535) {
1377                        cs->bcs[channel].at_state.cid = ev->parameter;
1378                        cs->bcs[channel].at_state.pending_commands |=
1379                                PC_DIAL;
1380                        cs->commands_pending = 1;
1381                        break;
1382                }
1383                /* fall through */
1384        case ACT_FAILCID:
1385                cs->cur_at_seq = SEQ_NONE;
1386                channel = cs->curchannel;
1387                if (!reinit_and_retry(cs, channel)) {
1388                        dev_warn(cs->dev,
1389                                 "Could not get a call ID. Cannot dial.\n");
1390                        at_state2 = &cs->bcs[channel].at_state;
1391                        disconnect(&at_state2);
1392                }
1393                break;
1394        case ACT_ABORTCID:
1395                cs->cur_at_seq = SEQ_NONE;
1396                at_state2 = &cs->bcs[cs->curchannel].at_state;
1397                disconnect(&at_state2);
1398                break;
1399
1400        case ACT_DIALING:
1401        case ACT_ACCEPTED:
1402                cs->cur_at_seq = SEQ_NONE;
1403                break;
1404
1405        case ACT_ABORTACCEPT:   /* hangup/error/timeout during ICALL processing */
1406                disconnect(p_at_state);
1407                break;
1408
1409        case ACT_ABORTDIAL:     /* error/timeout during dial preparation */
1410                cs->cur_at_seq = SEQ_NONE;
1411                at_state->pending_commands |= PC_HUP;
1412                cs->commands_pending = 1;
1413                break;
1414
1415        case ACT_REMOTEREJECT:  /* DISCONNECT_IND after dialling */
1416        case ACT_CONNTIMEOUT:   /* timeout waiting for ZSAU=ACTIVE */
1417        case ACT_REMOTEHUP:     /* DISCONNECT_IND with established connection */
1418                at_state->pending_commands |= PC_HUP;
1419                cs->commands_pending = 1;
1420                break;
1421        case ACT_GETSTRING: /* warning: RING, ZDLE, ...
1422                               are not handled properly anymore */
1423                at_state->getstring = 1;
1424                break;
1425        case ACT_SETVER:
1426                if (!ev->ptr) {
1427                        *p_genresp = 1;
1428                        *p_resp_code = RSP_ERROR;
1429                        break;
1430                }
1431                s = ev->ptr;
1432
1433                if (!strcmp(s, "OK")) {
1434                        *p_genresp = 1;
1435                        *p_resp_code = RSP_ERROR;
1436                        break;
1437                }
1438
1439                for (i = 0; i < 4; ++i) {
1440                        val = simple_strtoul(s, (char **) &e, 10);
1441                        if (val > INT_MAX || e == s)
1442                                break;
1443                        if (i == 3) {
1444                                if (*e)
1445                                        break;
1446                        } else if (*e != '.')
1447                                break;
1448                        else
1449                                s = e + 1;
1450                        cs->fwver[i] = val;
1451                }
1452                if (i != 4) {
1453                        *p_genresp = 1;
1454                        *p_resp_code = RSP_ERROR;
1455                        break;
1456                }
1457                /*at_state->getstring = 1;*/
1458                cs->gotfwver = 0;
1459                break;
1460        case ACT_GOTVER:
1461                if (cs->gotfwver == 0) {
1462                        cs->gotfwver = 1;
1463                        gig_dbg(DEBUG_ANY,
1464                                "firmware version %02d.%03d.%02d.%02d",
1465                                cs->fwver[0], cs->fwver[1],
1466                                cs->fwver[2], cs->fwver[3]);
1467                        break;
1468                }
1469                /* fall through */
1470        case ACT_FAILVER:
1471                cs->gotfwver = -1;
1472                dev_err(cs->dev, "could not read firmware version.\n");
1473                break;
1474#ifdef CONFIG_GIGASET_DEBUG
1475        case ACT_ERROR:
1476                *p_genresp = 1;
1477                *p_resp_code = RSP_ERROR;
1478                break;
1479        case ACT_TEST:
1480                {
1481                        static int count = 3; //2; //1;
1482                        *p_genresp = 1;
1483                        *p_resp_code = count ? RSP_ERROR : RSP_OK;
1484                        if (count > 0)
1485                                --count;
1486                }
1487                break;
1488#endif
1489        case ACT_DEBUG:
1490                gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d",
1491                        __func__, ev->type, at_state->ConState);
1492                break;
1493        case ACT_WARN:
1494                dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n",
1495                         __func__, ev->type, at_state->ConState);
1496                break;
1497        case ACT_ZCAU:
1498                dev_warn(cs->dev, "cause code %04x in connection state %d.\n",
1499                         ev->parameter, at_state->ConState);
1500                break;
1501
1502        /* events from the LL */
1503        case ACT_DIAL:
1504                start_dial(at_state, ev->ptr, ev->parameter);
1505                break;
1506        case ACT_ACCEPT:
1507                start_accept(at_state);
1508                break;
1509        case ACT_PROTO_L2:
1510                gig_dbg(DEBUG_CMD, "set protocol to %u",
1511                        (unsigned) ev->parameter);
1512                at_state->bcs->proto2 = ev->parameter;
1513                break;
1514        case ACT_HUP:
1515                at_state->pending_commands |= PC_HUP;
1516                cs->commands_pending = 1;
1517                gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
1518                break;
1519
1520        /* hotplug events */
1521        case ACT_STOP:
1522                do_stop(cs);
1523                break;
1524        case ACT_START:
1525                do_start(cs);
1526                break;
1527
1528        /* events from the interface */ // FIXME without ACT_xxxx?
1529        case ACT_IF_LOCK:
1530                cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs);
1531                cs->waiting = 0;
1532                wake_up(&cs->waitqueue);
1533                break;
1534        case ACT_IF_VER:
1535                if (ev->parameter != 0)
1536                        cs->cmd_result = -EINVAL;
1537                else if (cs->gotfwver != 1) {
1538                        cs->cmd_result = -ENOENT;
1539                } else {
1540                        memcpy(ev->arg, cs->fwver, sizeof cs->fwver);
1541                        cs->cmd_result = 0;
1542                }
1543                cs->waiting = 0;
1544                wake_up(&cs->waitqueue);
1545                break;
1546
1547        /* events from the proc file system */ // FIXME without ACT_xxxx?
1548        case ACT_PROC_CIDMODE:
1549                spin_lock_irqsave(&cs->lock, flags);
1550                if (ev->parameter != cs->cidmode) {
1551                        cs->cidmode = ev->parameter;
1552                        if (ev->parameter) {
1553                                cs->at_state.pending_commands |= PC_CIDMODE;
1554                                gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
1555                        } else {
1556                                cs->at_state.pending_commands |= PC_UMMODE;
1557                                gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
1558                        }
1559                        cs->commands_pending = 1;
1560                }
1561                spin_unlock_irqrestore(&cs->lock, flags);
1562                cs->waiting = 0;
1563                wake_up(&cs->waitqueue);
1564                break;
1565
1566        /* events from the hardware drivers */
1567        case ACT_NOTIFY_BC_DOWN:
1568                bchannel_down(bcs);
1569                break;
1570        case ACT_NOTIFY_BC_UP:
1571                bchannel_up(bcs);
1572                break;
1573        case ACT_SHUTDOWN:
1574                do_shutdown(cs);
1575                break;
1576
1577
1578        default:
1579                if (action >= ACT_CMD && action < ACT_CMD + AT_NUM) {
1580                        *pp_command = at_state->bcs->commands[action - ACT_CMD];
1581                        if (!*pp_command) {
1582                                *p_genresp = 1;
1583                                *p_resp_code = RSP_NULL;
1584                        }
1585                } else
1586                        dev_err(cs->dev, "%s: action==%d!\n", __func__, action);
1587        }
1588}
1589
1590/* State machine to do the calling and hangup procedure */
1591static void process_event(struct cardstate *cs, struct event_t *ev)
1592{
1593        struct bc_state *bcs;
1594        char *p_command = NULL;
1595        struct reply_t *rep;
1596        int rcode;
1597        int genresp = 0;
1598        int resp_code = RSP_ERROR;
1599        int sendcid;
1600        struct at_state_t *at_state;
1601        int index;
1602        int curact;
1603        unsigned long flags;
1604
1605        if (ev->cid >= 0) {
1606                at_state = at_state_from_cid(cs, ev->cid);
1607                if (!at_state) {
1608                        gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID,
1609                                          NULL, 0, NULL);
1610                        return;
1611                }
1612        } else {
1613                at_state = ev->at_state;
1614                if (at_state_invalid(cs, at_state)) {
1615                        gig_dbg(DEBUG_ANY, "event for invalid at_state %p",
1616                                at_state);
1617                        return;
1618                }
1619        }
1620
1621        gig_dbg(DEBUG_CMD, "connection state %d, event %d",
1622                at_state->ConState, ev->type);
1623
1624        bcs = at_state->bcs;
1625        sendcid = at_state->cid;
1626
1627        /* Setting the pointer to the dial array */
1628        rep = at_state->replystruct;
1629
1630        spin_lock_irqsave(&cs->lock, flags);
1631        if (ev->type == EV_TIMEOUT) {
1632                if (ev->parameter != at_state->timer_index
1633                    || !at_state->timer_active) {
1634                        ev->type = RSP_NONE; /* old timeout */
1635                        gig_dbg(DEBUG_ANY, "old timeout");
1636                } else if (!at_state->waiting)
1637                        gig_dbg(DEBUG_ANY, "timeout occurred");
1638                else
1639                        gig_dbg(DEBUG_ANY, "stopped waiting");
1640        }
1641        spin_unlock_irqrestore(&cs->lock, flags);
1642
1643        /* if the response belongs to a variable in at_state->int_var[VAR_XXXX]
1644           or at_state->str_var[STR_XXXX], set it */
1645        if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) {
1646                index = ev->type - RSP_VAR;
1647                at_state->int_var[index] = ev->parameter;
1648        } else if (ev->type >= RSP_STR && ev->type < RSP_STR + STR_NUM) {
1649                index = ev->type - RSP_STR;
1650                kfree(at_state->str_var[index]);
1651                at_state->str_var[index] = ev->ptr;
1652                ev->ptr = NULL; /* prevent process_events() from
1653                                   deallocating ptr */
1654        }
1655
1656        if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING)
1657                at_state->getstring = 0;
1658
1659        /* Search row in dial array which matches modem response and current
1660           constate */
1661        for (;; rep++) {
1662                rcode = rep->resp_code;
1663                if (rcode == RSP_LAST) {
1664                        /* found nothing...*/
1665                        dev_warn(cs->dev, "%s: rcode=RSP_LAST: "
1666                                        "resp_code %d in ConState %d!\n",
1667                                 __func__, ev->type, at_state->ConState);
1668                        return;
1669                }
1670                if ((rcode == RSP_ANY || rcode == ev->type)
1671                  && ((int) at_state->ConState >= rep->min_ConState)
1672                  && (rep->max_ConState < 0
1673                      || (int) at_state->ConState <= rep->max_ConState)
1674                  && (rep->parameter < 0 || rep->parameter == ev->parameter))
1675                        break;
1676        }
1677
1678        p_command = rep->command;
1679
1680        at_state->waiting = 0;
1681        for (curact = 0; curact < MAXACT; ++curact) {
1682                /* The row tells us what we should do  ..
1683                 */
1684                do_action(rep->action[curact], cs, bcs, &at_state, &p_command, &genresp, &resp_code, ev);
1685                if (!at_state)
1686                        break; /* may be freed after disconnect */
1687        }
1688
1689        if (at_state) {
1690                /* Jump to the next con-state regarding the array */
1691                if (rep->new_ConState >= 0)
1692                        at_state->ConState = rep->new_ConState;
1693
1694                if (genresp) {
1695                        spin_lock_irqsave(&cs->lock, flags);
1696                        at_state->timer_expires = 0; //FIXME
1697                        at_state->timer_active = 0; //FIXME
1698                        spin_unlock_irqrestore(&cs->lock, flags);
1699                        gigaset_add_event(cs, at_state, resp_code, NULL, 0, NULL);
1700                } else {
1701                        /* Send command to modem if not NULL... */
1702                        if (p_command/*rep->command*/) {
1703                                if (cs->connected)
1704                                        send_command(cs, p_command,
1705                                                     sendcid, cs->dle,
1706                                                     GFP_ATOMIC);
1707                                else
1708                                        gigaset_add_event(cs, at_state,
1709                                                          RSP_NODEV,
1710                                                          NULL, 0, NULL);
1711                        }
1712
1713                        spin_lock_irqsave(&cs->lock, flags);
1714                        if (!rep->timeout) {
1715                                at_state->timer_expires = 0;
1716                                at_state->timer_active = 0;
1717                        } else if (rep->timeout > 0) { /* new timeout */
1718                                at_state->timer_expires = rep->timeout * 10;
1719                                at_state->timer_active = 1;
1720                                ++at_state->timer_index;
1721                        }
1722                        spin_unlock_irqrestore(&cs->lock, flags);
1723                }
1724        }
1725}
1726
1727static void schedule_sequence(struct cardstate *cs,
1728                              struct at_state_t *at_state, int sequence)
1729{
1730        cs->cur_at_seq = sequence;
1731        gigaset_add_event(cs, at_state, RSP_INIT, NULL, sequence, NULL);
1732}
1733
1734static void process_command_flags(struct cardstate *cs)
1735{
1736        struct at_state_t *at_state = NULL;
1737        struct bc_state *bcs;
1738        int i;
1739        int sequence;
1740        unsigned long flags;
1741
1742        cs->commands_pending = 0;
1743
1744        if (cs->cur_at_seq) {
1745                gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy");
1746                return;
1747        }
1748
1749        gig_dbg(DEBUG_CMD, "searching scheduled commands");
1750
1751        sequence = SEQ_NONE;
1752
1753        /* clear pending_commands and hangup channels on shutdown */
1754        if (cs->at_state.pending_commands & PC_SHUTDOWN) {
1755                cs->at_state.pending_commands &= ~PC_CIDMODE;
1756                for (i = 0; i < cs->channels; ++i) {
1757                        bcs = cs->bcs + i;
1758                        at_state = &bcs->at_state;
1759                        at_state->pending_commands &=
1760                                ~(PC_DLE1 | PC_ACCEPT | PC_DIAL);
1761                        if (at_state->cid > 0)
1762                                at_state->pending_commands |= PC_HUP;
1763                        if (at_state->pending_commands & PC_CID) {
1764                                at_state->pending_commands |= PC_NOCID;
1765                                at_state->pending_commands &= ~PC_CID;
1766                        }
1767                }
1768        }
1769
1770        /* clear pending_commands and hangup channels on reset */
1771        if (cs->at_state.pending_commands & PC_INIT) {
1772                cs->at_state.pending_commands &= ~PC_CIDMODE;
1773                for (i = 0; i < cs->channels; ++i) {
1774                        bcs = cs->bcs + i;
1775                        at_state = &bcs->at_state;
1776                        at_state->pending_commands &=
1777                                ~(PC_DLE1 | PC_ACCEPT | PC_DIAL);
1778                        if (at_state->cid > 0)
1779                                at_state->pending_commands |= PC_HUP;
1780                        if (cs->mstate == MS_RECOVER) {
1781                                if (at_state->pending_commands & PC_CID) {
1782                                        at_state->pending_commands |= PC_NOCID;
1783                                        at_state->pending_commands &= ~PC_CID;
1784                                }
1785                        }
1786                }
1787        }
1788
1789        /* only switch back to unimodem mode, if no commands are pending and no channels are up */
1790        spin_lock_irqsave(&cs->lock, flags);
1791        if (cs->at_state.pending_commands == PC_UMMODE
1792            && !cs->cidmode
1793            && list_empty(&cs->temp_at_states)
1794            && cs->mode == M_CID) {
1795                sequence = SEQ_UMMODE;
1796                at_state = &cs->at_state;
1797                for (i = 0; i < cs->channels; ++i) {
1798                        bcs = cs->bcs + i;
1799                        if (bcs->at_state.pending_commands ||
1800                            bcs->at_state.cid > 0) {
1801                                sequence = SEQ_NONE;
1802                                break;
1803                        }
1804                }
1805        }
1806        spin_unlock_irqrestore(&cs->lock, flags);
1807        cs->at_state.pending_commands &= ~PC_UMMODE;
1808        if (sequence != SEQ_NONE) {
1809                schedule_sequence(cs, at_state, sequence);
1810                return;
1811        }
1812
1813        for (i = 0; i < cs->channels; ++i) {
1814                bcs = cs->bcs + i;
1815                if (bcs->at_state.pending_commands & PC_HUP) {
1816                        bcs->at_state.pending_commands &= ~PC_HUP;
1817                        if (bcs->at_state.pending_commands & PC_CID) {
1818                                /* not yet dialing: PC_NOCID is sufficient */
1819                                bcs->at_state.pending_commands |= PC_NOCID;
1820                                bcs->at_state.pending_commands &= ~PC_CID;
1821                        } else {
1822                                schedule_sequence(cs, &bcs->at_state, SEQ_HUP);
1823                                return;
1824                        }
1825                }
1826                if (bcs->at_state.pending_commands & PC_NOCID) {
1827                        bcs->at_state.pending_commands &= ~PC_NOCID;
1828                        cs->curchannel = bcs->channel;
1829                        schedule_sequence(cs, &cs->at_state, SEQ_NOCID);
1830                        return;
1831                } else if (bcs->at_state.pending_commands & PC_DLE0) {
1832                        bcs->at_state.pending_commands &= ~PC_DLE0;
1833                        cs->curchannel = bcs->channel;
1834                        schedule_sequence(cs, &cs->at_state, SEQ_DLE0);
1835                        return;
1836                }
1837        }
1838
1839        list_for_each_entry(at_state, &cs->temp_at_states, list)
1840                if (at_state->pending_commands & PC_HUP) {
1841                        at_state->pending_commands &= ~PC_HUP;
1842                        schedule_sequence(cs, at_state, SEQ_HUP);
1843                        return;
1844                }
1845
1846        if (cs->at_state.pending_commands & PC_INIT) {
1847                cs->at_state.pending_commands &= ~PC_INIT;
1848                cs->dle = 0; //FIXME
1849                cs->inbuf->inputstate = INS_command;
1850                //FIXME reset card state (or -> LOCK0)?
1851                schedule_sequence(cs, &cs->at_state, SEQ_INIT);
1852                return;
1853        }
1854        if (cs->at_state.pending_commands & PC_SHUTDOWN) {
1855                cs->at_state.pending_commands &= ~PC_SHUTDOWN;
1856                schedule_sequence(cs, &cs->at_state, SEQ_SHUTDOWN);
1857                return;
1858        }
1859        if (cs->at_state.pending_commands & PC_CIDMODE) {
1860                cs->at_state.pending_commands &= ~PC_CIDMODE;
1861                if (cs->mode == M_UNIMODEM) {
1862                        cs->retry_count = 1;
1863                        schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE);
1864                        return;
1865                }
1866        }
1867
1868        for (i = 0; i < cs->channels; ++i) {
1869                bcs = cs->bcs + i;
1870                if (bcs->at_state.pending_commands & PC_DLE1) {
1871                        bcs->at_state.pending_commands &= ~PC_DLE1;
1872                        cs->curchannel = bcs->channel;
1873                        schedule_sequence(cs, &cs->at_state, SEQ_DLE1);
1874                        return;
1875                }
1876                if (bcs->at_state.pending_commands & PC_ACCEPT) {
1877                        bcs->at_state.pending_commands &= ~PC_ACCEPT;
1878                        schedule_sequence(cs, &bcs->at_state, SEQ_ACCEPT);
1879                        return;
1880                }
1881                if (bcs->at_state.pending_commands & PC_DIAL) {
1882                        bcs->at_state.pending_commands &= ~PC_DIAL;
1883                        schedule_sequence(cs, &bcs->at_state, SEQ_DIAL);
1884                        return;
1885                }
1886                if (bcs->at_state.pending_commands & PC_CID) {
1887                        switch (cs->mode) {
1888                        case M_UNIMODEM:
1889                                cs->at_state.pending_commands |= PC_CIDMODE;
1890                                gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
1891                                cs->commands_pending = 1;
1892                                return;
1893#ifdef GIG_MAYINITONDIAL
1894                        case M_UNKNOWN:
1895                                schedule_init(cs, MS_INIT);
1896                                return;
1897#endif
1898                        }
1899                        bcs->at_state.pending_commands &= ~PC_CID;
1900                        cs->curchannel = bcs->channel;
1901#ifdef GIG_RETRYCID
1902                        cs->retry_count = 2;
1903#else
1904                        cs->retry_count = 1;
1905#endif
1906                        schedule_sequence(cs, &cs->at_state, SEQ_CID);
1907                        return;
1908                }
1909        }
1910}
1911
1912static void process_events(struct cardstate *cs)
1913{
1914        struct event_t *ev;
1915        unsigned head, tail;
1916        int i;
1917        int check_flags = 0;
1918        int was_busy;
1919        unsigned long flags;
1920
1921        spin_lock_irqsave(&cs->ev_lock, flags);
1922        head = cs->ev_head;
1923
1924        for (i = 0; i < 2 * MAX_EVENTS; ++i) {
1925                tail = cs->ev_tail;
1926                if (tail == head) {
1927                        if (!check_flags && !cs->commands_pending)
1928                                break;
1929                        check_flags = 0;
1930                        spin_unlock_irqrestore(&cs->ev_lock, flags);
1931                        process_command_flags(cs);
1932                        spin_lock_irqsave(&cs->ev_lock, flags);
1933                        tail = cs->ev_tail;
1934                        if (tail == head) {
1935                                if (!cs->commands_pending)
1936                                        break;
1937                                continue;
1938                        }
1939                }
1940
1941                ev = cs->events + head;
1942                was_busy = cs->cur_at_seq != SEQ_NONE;
1943                spin_unlock_irqrestore(&cs->ev_lock, flags);
1944                process_event(cs, ev);
1945                spin_lock_irqsave(&cs->ev_lock, flags);
1946                kfree(ev->ptr);
1947                ev->ptr = NULL;
1948                if (was_busy && cs->cur_at_seq == SEQ_NONE)
1949                        check_flags = 1;
1950
1951                head = (head + 1) % MAX_EVENTS;
1952                cs->ev_head = head;
1953        }
1954
1955        spin_unlock_irqrestore(&cs->ev_lock, flags);
1956
1957        if (i == 2 * MAX_EVENTS) {
1958                dev_err(cs->dev,
1959                        "infinite loop in process_events; aborting.\n");
1960        }
1961}
1962
1963/* tasklet scheduled on any event received from the Gigaset device
1964 * parameter:
1965 *      data    ISDN controller state structure
1966 */
1967void gigaset_handle_event(unsigned long data)
1968{
1969        struct cardstate *cs = (struct cardstate *) data;
1970
1971        /* handle incoming data on control/common channel */
1972        if (cs->inbuf->head != cs->inbuf->tail) {
1973                gig_dbg(DEBUG_INTR, "processing new data");
1974                cs->ops->handle_input(cs->inbuf);
1975        }
1976
1977        process_events(cs);
1978}
1979
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.