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