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