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