diff options
Diffstat (limited to 'drivers/isdn/gigaset/ev-layer.c')
-rw-r--r-- | drivers/isdn/gigaset/ev-layer.c | 670 |
1 files changed, 336 insertions, 334 deletions
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index fdcb80bb21c7..18e05c09b71c 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Stuff used by all variants of the driver | 2 | * Stuff used by all variants of the driver |
3 | * | 3 | * |
4 | * Copyright (c) 2001 by Stefan Eilers <Eilers.Stefan@epost.de>, | 4 | * Copyright (c) 2001 by Stefan Eilers, |
5 | * Hansjoerg Lipp <hjlipp@web.de>, | 5 | * Hansjoerg Lipp <hjlipp@web.de>, |
6 | * Tilman Schmidt <tilman@imap.cc>. | 6 | * Tilman Schmidt <tilman@imap.cc>. |
7 | * | 7 | * |
@@ -11,82 +11,78 @@ | |||
11 | * published by the Free Software Foundation; either version 2 of | 11 | * published by the Free Software Foundation; either version 2 of |
12 | * the License, or (at your option) any later version. | 12 | * the License, or (at your option) any later version. |
13 | * ===================================================================== | 13 | * ===================================================================== |
14 | * ToDo: ... | ||
15 | * ===================================================================== | ||
16 | * Version: $Id: ev-layer.c,v 1.4.2.18 2006/02/04 18:28:16 hjlipp Exp $ | ||
17 | * ===================================================================== | ||
18 | */ | 14 | */ |
19 | 15 | ||
20 | #include "gigaset.h" | 16 | #include "gigaset.h" |
21 | 17 | ||
22 | /* ========================================================== */ | 18 | /* ========================================================== */ |
23 | /* bit masks for pending commands */ | 19 | /* bit masks for pending commands */ |
24 | #define PC_INIT 0x004 | 20 | #define PC_DIAL 0x001 |
25 | #define PC_DLE0 0x008 | 21 | #define PC_HUP 0x002 |
26 | #define PC_DLE1 0x010 | 22 | #define PC_INIT 0x004 |
27 | #define PC_CID 0x080 | 23 | #define PC_DLE0 0x008 |
28 | #define PC_NOCID 0x100 | 24 | #define PC_DLE1 0x010 |
29 | #define PC_HUP 0x002 | 25 | #define PC_SHUTDOWN 0x020 |
30 | #define PC_DIAL 0x001 | 26 | #define PC_ACCEPT 0x040 |
31 | #define PC_ACCEPT 0x040 | 27 | #define PC_CID 0x080 |
32 | #define PC_SHUTDOWN 0x020 | 28 | #define PC_NOCID 0x100 |
33 | #define PC_CIDMODE 0x200 | 29 | #define PC_CIDMODE 0x200 |
34 | #define PC_UMMODE 0x400 | 30 | #define PC_UMMODE 0x400 |
35 | 31 | ||
36 | /* types of modem responses */ | 32 | /* types of modem responses */ |
37 | #define RT_NOTHING 0 | 33 | #define RT_NOTHING 0 |
38 | #define RT_ZSAU 1 | 34 | #define RT_ZSAU 1 |
39 | #define RT_RING 2 | 35 | #define RT_RING 2 |
40 | #define RT_NUMBER 3 | 36 | #define RT_NUMBER 3 |
41 | #define RT_STRING 4 | 37 | #define RT_STRING 4 |
42 | #define RT_HEX 5 | 38 | #define RT_HEX 5 |
43 | #define RT_ZCAU 6 | 39 | #define RT_ZCAU 6 |
44 | 40 | ||
45 | /* Possible ASCII responses */ | 41 | /* Possible ASCII responses */ |
46 | #define RSP_OK 0 | 42 | #define RSP_OK 0 |
47 | //#define RSP_BUSY 1 | 43 | //#define RSP_BUSY 1 |
48 | //#define RSP_CONNECT 2 | 44 | //#define RSP_CONNECT 2 |
49 | #define RSP_ZGCI 3 | 45 | #define RSP_ZGCI 3 |
50 | #define RSP_RING 4 | 46 | #define RSP_RING 4 |
51 | #define RSP_ZAOC 5 | 47 | #define RSP_ZAOC 5 |
52 | #define RSP_ZCSTR 6 | 48 | #define RSP_ZCSTR 6 |
53 | #define RSP_ZCFGT 7 | 49 | #define RSP_ZCFGT 7 |
54 | #define RSP_ZCFG 8 | 50 | #define RSP_ZCFG 8 |
55 | #define RSP_ZCCR 9 | 51 | #define RSP_ZCCR 9 |
56 | #define RSP_EMPTY 10 | 52 | #define RSP_EMPTY 10 |
57 | #define RSP_ZLOG 11 | 53 | #define RSP_ZLOG 11 |
58 | #define RSP_ZCAU 12 | 54 | #define RSP_ZCAU 12 |
59 | #define RSP_ZMWI 13 | 55 | #define RSP_ZMWI 13 |
60 | #define RSP_ZABINFO 14 | 56 | #define RSP_ZABINFO 14 |
61 | #define RSP_ZSMLSTCHG 15 | 57 | #define RSP_ZSMLSTCHG 15 |
62 | #define RSP_VAR 100 | 58 | #define RSP_VAR 100 |
63 | #define RSP_ZSAU (RSP_VAR + VAR_ZSAU) | 59 | #define RSP_ZSAU (RSP_VAR + VAR_ZSAU) |
64 | #define RSP_ZDLE (RSP_VAR + VAR_ZDLE) | 60 | #define RSP_ZDLE (RSP_VAR + VAR_ZDLE) |
65 | #define RSP_ZVLS (RSP_VAR + VAR_ZVLS) | 61 | #define RSP_ZVLS (RSP_VAR + VAR_ZVLS) |
66 | #define RSP_ZCTP (RSP_VAR + VAR_ZCTP) | 62 | #define RSP_ZCTP (RSP_VAR + VAR_ZCTP) |
67 | #define RSP_STR (RSP_VAR + VAR_NUM) | 63 | #define RSP_STR (RSP_VAR + VAR_NUM) |
68 | #define RSP_NMBR (RSP_STR + STR_NMBR) | 64 | #define RSP_NMBR (RSP_STR + STR_NMBR) |
69 | #define RSP_ZCPN (RSP_STR + STR_ZCPN) | 65 | #define RSP_ZCPN (RSP_STR + STR_ZCPN) |
70 | #define RSP_ZCON (RSP_STR + STR_ZCON) | 66 | #define RSP_ZCON (RSP_STR + STR_ZCON) |
71 | #define RSP_ZBC (RSP_STR + STR_ZBC) | 67 | #define RSP_ZBC (RSP_STR + STR_ZBC) |
72 | #define RSP_ZHLC (RSP_STR + STR_ZHLC) | 68 | #define RSP_ZHLC (RSP_STR + STR_ZHLC) |
73 | #define RSP_ERROR -1 /* ERROR */ | 69 | #define RSP_ERROR -1 /* ERROR */ |
74 | #define RSP_WRONG_CID -2 /* unknown cid in cmd */ | 70 | #define RSP_WRONG_CID -2 /* unknown cid in cmd */ |
75 | //#define RSP_EMPTY -3 | 71 | //#define RSP_EMPTY -3 |
76 | #define RSP_UNKNOWN -4 /* unknown response */ | 72 | #define RSP_UNKNOWN -4 /* unknown response */ |
77 | #define RSP_FAIL -5 /* internal error */ | 73 | #define RSP_FAIL -5 /* internal error */ |
78 | #define RSP_INVAL -6 /* invalid response */ | 74 | #define RSP_INVAL -6 /* invalid response */ |
79 | 75 | ||
80 | #define RSP_NONE -19 | 76 | #define RSP_NONE -19 |
81 | #define RSP_STRING -20 | 77 | #define RSP_STRING -20 |
82 | #define RSP_NULL -21 | 78 | #define RSP_NULL -21 |
83 | //#define RSP_RETRYFAIL -22 | 79 | //#define RSP_RETRYFAIL -22 |
84 | //#define RSP_RETRY -23 | 80 | //#define RSP_RETRY -23 |
85 | //#define RSP_SKIP -24 | 81 | //#define RSP_SKIP -24 |
86 | #define RSP_INIT -27 | 82 | #define RSP_INIT -27 |
87 | #define RSP_ANY -26 | 83 | #define RSP_ANY -26 |
88 | #define RSP_LAST -28 | 84 | #define RSP_LAST -28 |
89 | #define RSP_NODEV -9 | 85 | #define RSP_NODEV -9 |
90 | 86 | ||
91 | /* actions for process_response */ | 87 | /* actions for process_response */ |
92 | #define ACT_NOTHING 0 | 88 | #define ACT_NOTHING 0 |
@@ -112,7 +108,7 @@ | |||
112 | #define ACT_DISCONNECT 20 | 108 | #define ACT_DISCONNECT 20 |
113 | #define ACT_CONNECT 21 | 109 | #define ACT_CONNECT 21 |
114 | #define ACT_REMOTEREJECT 22 | 110 | #define ACT_REMOTEREJECT 22 |
115 | #define ACT_CONNTIMEOUT 23 | 111 | #define ACT_CONNTIMEOUT 23 |
116 | #define ACT_REMOTEHUP 24 | 112 | #define ACT_REMOTEHUP 24 |
117 | #define ACT_ABORTHUP 25 | 113 | #define ACT_ABORTHUP 25 |
118 | #define ACT_ICALL 26 | 114 | #define ACT_ICALL 26 |
@@ -127,40 +123,40 @@ | |||
127 | #define ACT_ERROR 35 | 123 | #define ACT_ERROR 35 |
128 | #define ACT_ABORTCID 36 | 124 | #define ACT_ABORTCID 36 |
129 | #define ACT_ZCAU 37 | 125 | #define ACT_ZCAU 37 |
130 | #define ACT_NOTIFY_BC_DOWN 38 | 126 | #define ACT_NOTIFY_BC_DOWN 38 |
131 | #define ACT_NOTIFY_BC_UP 39 | 127 | #define ACT_NOTIFY_BC_UP 39 |
132 | #define ACT_DIAL 40 | 128 | #define ACT_DIAL 40 |
133 | #define ACT_ACCEPT 41 | 129 | #define ACT_ACCEPT 41 |
134 | #define ACT_PROTO_L2 42 | 130 | #define ACT_PROTO_L2 42 |
135 | #define ACT_HUP 43 | 131 | #define ACT_HUP 43 |
136 | #define ACT_IF_LOCK 44 | 132 | #define ACT_IF_LOCK 44 |
137 | #define ACT_START 45 | 133 | #define ACT_START 45 |
138 | #define ACT_STOP 46 | 134 | #define ACT_STOP 46 |
139 | #define ACT_FAKEDLE0 47 | 135 | #define ACT_FAKEDLE0 47 |
140 | #define ACT_FAKEHUP 48 | 136 | #define ACT_FAKEHUP 48 |
141 | #define ACT_FAKESDOWN 49 | 137 | #define ACT_FAKESDOWN 49 |
142 | #define ACT_SHUTDOWN 50 | 138 | #define ACT_SHUTDOWN 50 |
143 | #define ACT_PROC_CIDMODE 51 | 139 | #define ACT_PROC_CIDMODE 51 |
144 | #define ACT_UMODESET 52 | 140 | #define ACT_UMODESET 52 |
145 | #define ACT_FAILUMODE 53 | 141 | #define ACT_FAILUMODE 53 |
146 | #define ACT_CMODESET 54 | 142 | #define ACT_CMODESET 54 |
147 | #define ACT_FAILCMODE 55 | 143 | #define ACT_FAILCMODE 55 |
148 | #define ACT_IF_VER 56 | 144 | #define ACT_IF_VER 56 |
149 | #define ACT_CMD 100 | 145 | #define ACT_CMD 100 |
150 | 146 | ||
151 | /* at command sequences */ | 147 | /* at command sequences */ |
152 | #define SEQ_NONE 0 | 148 | #define SEQ_NONE 0 |
153 | #define SEQ_INIT 100 | 149 | #define SEQ_INIT 100 |
154 | #define SEQ_DLE0 200 | 150 | #define SEQ_DLE0 200 |
155 | #define SEQ_DLE1 250 | 151 | #define SEQ_DLE1 250 |
156 | #define SEQ_CID 300 | 152 | #define SEQ_CID 300 |
157 | #define SEQ_NOCID 350 | 153 | #define SEQ_NOCID 350 |
158 | #define SEQ_HUP 400 | 154 | #define SEQ_HUP 400 |
159 | #define SEQ_DIAL 600 | 155 | #define SEQ_DIAL 600 |
160 | #define SEQ_ACCEPT 720 | 156 | #define SEQ_ACCEPT 720 |
161 | #define SEQ_SHUTDOWN 500 | 157 | #define SEQ_SHUTDOWN 500 |
162 | #define SEQ_CIDMODE 10 | 158 | #define SEQ_CIDMODE 10 |
163 | #define SEQ_UMMODE 11 | 159 | #define SEQ_UMMODE 11 |
164 | 160 | ||
165 | 161 | ||
166 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring | 162 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring |
@@ -175,7 +171,7 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
175 | // {ACT_TIMEOUT}}, | 171 | // {ACT_TIMEOUT}}, |
176 | 172 | ||
177 | {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, | 173 | {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, |
178 | {ACT_TIMEOUT}}, /* wait until device is ready */ | 174 | {ACT_TIMEOUT}}, /* wait until device is ready */ |
179 | 175 | ||
180 | {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ | 176 | {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ |
181 | {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ | 177 | {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ |
@@ -190,8 +186,8 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
190 | {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, | 186 | {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, |
191 | 187 | ||
192 | {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, | 188 | {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, |
193 | ACT_HUPMODEM, | 189 | ACT_HUPMODEM, |
194 | ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ | 190 | ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ |
195 | {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, | 191 | {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, |
196 | 192 | ||
197 | {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ | 193 | {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ |
@@ -377,6 +373,9 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | |||
377 | 373 | ||
378 | {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, | 374 | {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, |
379 | 375 | ||
376 | /* B channel closed (general case) */ | ||
377 | {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME | ||
378 | |||
380 | /* misc. */ | 379 | /* misc. */ |
381 | {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME | 380 | {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME |
382 | 381 | ||
@@ -393,7 +392,7 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | |||
393 | 392 | ||
394 | 393 | ||
395 | #if 0 | 394 | #if 0 |
396 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen uebernehmen | 395 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME |
397 | { | 396 | { |
398 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 397 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
399 | 398 | ||
@@ -401,7 +400,7 @@ static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen ueberne | |||
401 | {RSP_LAST,0,0,0,0,0,0} | 400 | {RSP_LAST,0,0,0,0,0,0} |
402 | }; | 401 | }; |
403 | 402 | ||
404 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen uebernehmen | 403 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME |
405 | { | 404 | { |
406 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 405 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
407 | 406 | ||
@@ -412,30 +411,30 @@ static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen ueberneh | |||
412 | 411 | ||
413 | static struct resp_type_t resp_type[]= | 412 | static struct resp_type_t resp_type[]= |
414 | { | 413 | { |
415 | /*{"", RSP_EMPTY, RT_NOTHING},*/ | 414 | /*{"", RSP_EMPTY, RT_NOTHING},*/ |
416 | {"OK", RSP_OK, RT_NOTHING}, | 415 | {"OK", RSP_OK, RT_NOTHING}, |
417 | {"ERROR", RSP_ERROR, RT_NOTHING}, | 416 | {"ERROR", RSP_ERROR, RT_NOTHING}, |
418 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, | 417 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, |
419 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, | 418 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, |
420 | {"RING", RSP_RING, RT_RING}, | 419 | {"RING", RSP_RING, RT_RING}, |
421 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, | 420 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, |
422 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, | 421 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, |
423 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, | 422 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, |
424 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, | 423 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, |
425 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, | 424 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, |
426 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, | 425 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, |
427 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, | 426 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, |
428 | {"ZHLC", RSP_ZHLC, RT_STRING}, | 427 | {"ZHLC", RSP_ZHLC, RT_STRING}, |
429 | {"ZBC", RSP_ZBC, RT_STRING}, | 428 | {"ZBC", RSP_ZBC, RT_STRING}, |
430 | {"NMBR", RSP_NMBR, RT_STRING}, | 429 | {"NMBR", RSP_NMBR, RT_STRING}, |
431 | {"ZCPN", RSP_ZCPN, RT_STRING}, | 430 | {"ZCPN", RSP_ZCPN, RT_STRING}, |
432 | {"ZCON", RSP_ZCON, RT_STRING}, | 431 | {"ZCON", RSP_ZCON, RT_STRING}, |
433 | {"ZAOC", RSP_ZAOC, RT_STRING}, | 432 | {"ZAOC", RSP_ZAOC, RT_STRING}, |
434 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, | 433 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, |
435 | {"ZCFG", RSP_ZCFG, RT_HEX}, | 434 | {"ZCFG", RSP_ZCFG, RT_HEX}, |
436 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, | 435 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, |
437 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, | 436 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, |
438 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, | 437 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, |
439 | {NULL,0,0} | 438 | {NULL,0,0} |
440 | }; | 439 | }; |
441 | 440 | ||
@@ -446,9 +445,7 @@ static int isdn_getnum(char *p) | |||
446 | { | 445 | { |
447 | int v = -1; | 446 | int v = -1; |
448 | 447 | ||
449 | IFNULLRETVAL(p, -1); | 448 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
450 | |||
451 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
452 | 449 | ||
453 | while (*p >= '0' && *p <= '9') | 450 | while (*p >= '0' && *p <= '9') |
454 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); | 451 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); |
@@ -465,9 +462,7 @@ static int isdn_gethex(char *p) | |||
465 | int v = 0; | 462 | int v = 0; |
466 | int c; | 463 | int c; |
467 | 464 | ||
468 | IFNULLRETVAL(p, -1); | 465 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
469 | |||
470 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
471 | 466 | ||
472 | if (!*p) | 467 | if (!*p) |
473 | return -1; | 468 | return -1; |
@@ -490,14 +485,6 @@ static int isdn_gethex(char *p) | |||
490 | return v; | 485 | return v; |
491 | } | 486 | } |
492 | 487 | ||
493 | static inline void new_index(atomic_t *index, int max) | ||
494 | { | ||
495 | if (atomic_read(index) == max) //FIXME race? | ||
496 | atomic_set(index, 0); | ||
497 | else | ||
498 | atomic_inc(index); | ||
499 | } | ||
500 | |||
501 | /* retrieve CID from parsed response | 488 | /* retrieve CID from parsed response |
502 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 | 489 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 |
503 | */ | 490 | */ |
@@ -536,16 +523,14 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
536 | int cid; | 523 | int cid; |
537 | int rawstring; | 524 | int rawstring; |
538 | 525 | ||
539 | IFNULLRET(cs); | ||
540 | |||
541 | len = cs->cbytes; | 526 | len = cs->cbytes; |
542 | if (!len) { | 527 | if (!len) { |
543 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ | 528 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ |
544 | dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); | 529 | gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); |
545 | return; | 530 | return; |
546 | } | 531 | } |
547 | cs->respdata[len] = 0; | 532 | cs->respdata[len] = 0; |
548 | dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); | 533 | gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); |
549 | argv[0] = cs->respdata; | 534 | argv[0] = cs->respdata; |
550 | params = 1; | 535 | params = 1; |
551 | if (cs->at_state.getstring) { | 536 | if (cs->at_state.getstring) { |
@@ -561,7 +546,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
561 | case ',': | 546 | case ',': |
562 | case '=': | 547 | case '=': |
563 | if (params > MAX_REC_PARAMS) { | 548 | if (params > MAX_REC_PARAMS) { |
564 | warn("too many parameters in response"); | 549 | dev_warn(cs->dev, |
550 | "too many parameters in response\n"); | ||
565 | /* need last parameter (might be CID) */ | 551 | /* need last parameter (might be CID) */ |
566 | params--; | 552 | params--; |
567 | } | 553 | } |
@@ -572,33 +558,33 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
572 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; | 558 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; |
573 | if (cid < 0) { | 559 | if (cid < 0) { |
574 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, | 560 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, |
575 | NULL, 0, NULL); | 561 | NULL, 0, NULL); |
576 | return; | 562 | return; |
577 | } | 563 | } |
578 | 564 | ||
579 | for (j = 1; j < params; ++j) | 565 | for (j = 1; j < params; ++j) |
580 | argv[j][-1] = 0; | 566 | argv[j][-1] = 0; |
581 | 567 | ||
582 | dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); | 568 | gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); |
583 | if (cid) { | 569 | if (cid) { |
584 | --params; | 570 | --params; |
585 | dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); | 571 | gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); |
586 | } | 572 | } |
587 | dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); | 573 | gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); |
588 | for (j = 1; j < params; j++) | 574 | for (j = 1; j < params; j++) |
589 | dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); | 575 | gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); |
590 | } | 576 | } |
591 | 577 | ||
592 | spin_lock_irqsave(&cs->ev_lock, flags); | 578 | spin_lock_irqsave(&cs->ev_lock, flags); |
593 | head = atomic_read(&cs->ev_head); | 579 | head = cs->ev_head; |
594 | tail = atomic_read(&cs->ev_tail); | 580 | tail = cs->ev_tail; |
595 | 581 | ||
596 | abort = 1; | 582 | abort = 1; |
597 | curarg = 0; | 583 | curarg = 0; |
598 | while (curarg < params) { | 584 | while (curarg < params) { |
599 | next = (tail + 1) % MAX_EVENTS; | 585 | next = (tail + 1) % MAX_EVENTS; |
600 | if (unlikely(next == head)) { | 586 | if (unlikely(next == head)) { |
601 | err("event queue full"); | 587 | dev_err(cs->dev, "event queue full\n"); |
602 | break; | 588 | break; |
603 | } | 589 | } |
604 | 590 | ||
@@ -619,8 +605,9 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
619 | 605 | ||
620 | if (!rt->response) { | 606 | if (!rt->response) { |
621 | event->type = RSP_UNKNOWN; | 607 | event->type = RSP_UNKNOWN; |
622 | warn("unknown modem response: %s", | 608 | dev_warn(cs->dev, |
623 | argv[curarg]); | 609 | "unknown modem response: %s\n", |
610 | argv[curarg]); | ||
624 | break; | 611 | break; |
625 | } | 612 | } |
626 | 613 | ||
@@ -636,7 +623,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
636 | break; | 623 | break; |
637 | case RT_RING: | 624 | case RT_RING: |
638 | if (!cid) { | 625 | if (!cid) { |
639 | err("received RING without CID!"); | 626 | dev_err(cs->dev, |
627 | "received RING without CID!\n"); | ||
640 | event->type = RSP_INVAL; | 628 | event->type = RSP_INVAL; |
641 | abort = 1; | 629 | abort = 1; |
642 | } else { | 630 | } else { |
@@ -664,27 +652,25 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
664 | event->parameter = ZSAU_DISCONNECT_REQ; | 652 | event->parameter = ZSAU_DISCONNECT_REQ; |
665 | else { | 653 | else { |
666 | event->parameter = ZSAU_UNKNOWN; | 654 | event->parameter = ZSAU_UNKNOWN; |
667 | warn("%s: unknown parameter %s after ZSAU", | 655 | dev_warn(cs->dev, |
668 | __func__, argv[curarg]); | 656 | "%s: unknown parameter %s after ZSAU\n", |
657 | __func__, argv[curarg]); | ||
669 | } | 658 | } |
670 | ++curarg; | 659 | ++curarg; |
671 | break; | 660 | break; |
672 | case RT_STRING: | 661 | case RT_STRING: |
673 | if (curarg < params) { | 662 | if (curarg < params) { |
674 | len = strlen(argv[curarg]) + 1; | 663 | event->ptr = kstrdup(argv[curarg], GFP_ATOMIC); |
675 | event->ptr = kmalloc(len, GFP_ATOMIC); | 664 | if (!event->ptr) |
676 | if (event->ptr) | 665 | dev_err(cs->dev, "out of memory\n"); |
677 | memcpy(event->ptr, argv[curarg], len); | ||
678 | else | ||
679 | err("no memory for string!"); | ||
680 | ++curarg; | 666 | ++curarg; |
681 | } | 667 | } |
682 | #ifdef CONFIG_GIGASET_DEBUG | 668 | #ifdef CONFIG_GIGASET_DEBUG |
683 | if (!event->ptr) | 669 | if (!event->ptr) |
684 | dbg(DEBUG_CMD, "string==NULL"); | 670 | gig_dbg(DEBUG_CMD, "string==NULL"); |
685 | else | 671 | else |
686 | dbg(DEBUG_CMD, | 672 | gig_dbg(DEBUG_CMD, "string==%s", |
687 | "string==%s", (char *) event->ptr); | 673 | (char *) event->ptr); |
688 | #endif | 674 | #endif |
689 | break; | 675 | break; |
690 | case RT_ZCAU: | 676 | case RT_ZCAU: |
@@ -694,7 +680,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
694 | j = isdn_gethex(argv[curarg + 1]); | 680 | j = isdn_gethex(argv[curarg + 1]); |
695 | if (i >= 0 && i < 256 && j >= 0 && j < 256) | 681 | if (i >= 0 && i < 256 && j >= 0 && j < 256) |
696 | event->parameter = (unsigned) i << 8 | 682 | event->parameter = (unsigned) i << 8 |
697 | | j; | 683 | | j; |
698 | curarg += 2; | 684 | curarg += 2; |
699 | } else | 685 | } else |
700 | curarg = params - 1; | 686 | curarg = params - 1; |
@@ -712,7 +698,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
712 | } else | 698 | } else |
713 | event->parameter = -1; | 699 | event->parameter = -1; |
714 | #ifdef CONFIG_GIGASET_DEBUG | 700 | #ifdef CONFIG_GIGASET_DEBUG |
715 | dbg(DEBUG_CMD, "parameter==%d", event->parameter); | 701 | gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); |
716 | #endif | 702 | #endif |
717 | break; | 703 | break; |
718 | } | 704 | } |
@@ -724,12 +710,13 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
724 | break; | 710 | break; |
725 | } | 711 | } |
726 | 712 | ||
727 | atomic_set(&cs->ev_tail, tail); | 713 | cs->ev_tail = tail; |
728 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 714 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
729 | 715 | ||
730 | if (curarg != params) | 716 | if (curarg != params) |
731 | dbg(DEBUG_ANY, "invalid number of processed parameters: %d/%d", | 717 | gig_dbg(DEBUG_ANY, |
732 | curarg, params); | 718 | "invalid number of processed parameters: %d/%d", |
719 | curarg, params); | ||
733 | } | 720 | } |
734 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | 721 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); |
735 | 722 | ||
@@ -739,23 +726,19 @@ EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | |||
739 | static void disconnect(struct at_state_t **at_state_p) | 726 | static void disconnect(struct at_state_t **at_state_p) |
740 | { | 727 | { |
741 | unsigned long flags; | 728 | unsigned long flags; |
742 | struct bc_state *bcs; | 729 | struct bc_state *bcs = (*at_state_p)->bcs; |
743 | struct cardstate *cs; | 730 | struct cardstate *cs = (*at_state_p)->cs; |
744 | |||
745 | IFNULLRET(at_state_p); | ||
746 | IFNULLRET(*at_state_p); | ||
747 | bcs = (*at_state_p)->bcs; | ||
748 | cs = (*at_state_p)->cs; | ||
749 | IFNULLRET(cs); | ||
750 | 731 | ||
751 | new_index(&(*at_state_p)->seq_index, MAX_SEQ_INDEX); | 732 | spin_lock_irqsave(&cs->lock, flags); |
733 | ++(*at_state_p)->seq_index; | ||
752 | 734 | ||
753 | /* revert to selected idle mode */ | 735 | /* revert to selected idle mode */ |
754 | if (!atomic_read(&cs->cidmode)) { | 736 | if (!cs->cidmode) { |
755 | cs->at_state.pending_commands |= PC_UMMODE; | 737 | cs->at_state.pending_commands |= PC_UMMODE; |
756 | atomic_set(&cs->commands_pending, 1); //FIXME | 738 | atomic_set(&cs->commands_pending, 1); //FIXME |
757 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 739 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
758 | } | 740 | } |
741 | spin_unlock_irqrestore(&cs->lock, flags); | ||
759 | 742 | ||
760 | if (bcs) { | 743 | if (bcs) { |
761 | /* B channel assigned: invoke hardware specific handler */ | 744 | /* B channel assigned: invoke hardware specific handler */ |
@@ -777,7 +760,7 @@ static void disconnect(struct at_state_t **at_state_p) | |||
777 | * The structure should be freed by calling disconnect() after use. | 760 | * The structure should be freed by calling disconnect() after use. |
778 | */ | 761 | */ |
779 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, | 762 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, |
780 | int cid) | 763 | int cid) |
781 | /* cids: >0: siemens-cid | 764 | /* cids: >0: siemens-cid |
782 | 0: without cid | 765 | 0: without cid |
783 | -1: no cid assigned yet | 766 | -1: no cid assigned yet |
@@ -826,7 +809,7 @@ static void init_failed(struct cardstate *cs, int mode) | |||
826 | static void schedule_init(struct cardstate *cs, int state) | 809 | static void schedule_init(struct cardstate *cs, int state) |
827 | { | 810 | { |
828 | if (cs->at_state.pending_commands & PC_INIT) { | 811 | if (cs->at_state.pending_commands & PC_INIT) { |
829 | dbg(DEBUG_CMD, "not scheduling PC_INIT again"); | 812 | gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); |
830 | return; | 813 | return; |
831 | } | 814 | } |
832 | atomic_set(&cs->mstate, state); | 815 | atomic_set(&cs->mstate, state); |
@@ -834,52 +817,56 @@ static void schedule_init(struct cardstate *cs, int state) | |||
834 | gigaset_block_channels(cs); | 817 | gigaset_block_channels(cs); |
835 | cs->at_state.pending_commands |= PC_INIT; | 818 | cs->at_state.pending_commands |= PC_INIT; |
836 | atomic_set(&cs->commands_pending, 1); | 819 | atomic_set(&cs->commands_pending, 1); |
837 | dbg(DEBUG_CMD, "Scheduling PC_INIT"); | 820 | gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); |
838 | } | 821 | } |
839 | 822 | ||
840 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the hardware. */ | 823 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the |
824 | hardware. */ | ||
841 | static void send_command(struct cardstate *cs, const char *cmd, int cid, | 825 | static void send_command(struct cardstate *cs, const char *cmd, int cid, |
842 | int dle, gfp_t kmallocflags) | 826 | int dle, gfp_t kmallocflags) |
843 | { | 827 | { |
844 | size_t cmdlen, buflen; | 828 | size_t cmdlen, buflen; |
845 | char *cmdpos, *cmdbuf, *cmdtail; | 829 | char *cmdpos, *cmdbuf, *cmdtail; |
846 | 830 | ||
847 | cmdlen = strlen(cmd); | 831 | cmdlen = strlen(cmd); |
848 | buflen = 11 + cmdlen; | 832 | buflen = 11 + cmdlen; |
833 | if (unlikely(buflen <= cmdlen)) { | ||
834 | dev_err(cs->dev, "integer overflow in buflen\n"); | ||
835 | return; | ||
836 | } | ||
849 | 837 | ||
850 | if (likely(buflen > cmdlen)) { | 838 | cmdbuf = kmalloc(buflen, kmallocflags); |
851 | cmdbuf = kmalloc(buflen, kmallocflags); | 839 | if (unlikely(!cmdbuf)) { |
852 | if (likely(cmdbuf != NULL)) { | 840 | dev_err(cs->dev, "out of memory\n"); |
853 | cmdpos = cmdbuf + 9; | 841 | return; |
854 | cmdtail = cmdpos + cmdlen; | 842 | } |
855 | memcpy(cmdpos, cmd, cmdlen); | ||
856 | |||
857 | if (cid > 0 && cid <= 65535) { | ||
858 | do { | ||
859 | *--cmdpos = '0' + cid % 10; | ||
860 | cid /= 10; | ||
861 | ++cmdlen; | ||
862 | } while (cid); | ||
863 | } | ||
864 | 843 | ||
865 | cmdlen += 2; | 844 | cmdpos = cmdbuf + 9; |
866 | *--cmdpos = 'T'; | 845 | cmdtail = cmdpos + cmdlen; |
867 | *--cmdpos = 'A'; | 846 | memcpy(cmdpos, cmd, cmdlen); |
868 | 847 | ||
869 | if (dle) { | 848 | if (cid > 0 && cid <= 65535) { |
870 | cmdlen += 4; | 849 | do { |
871 | *--cmdpos = '('; | 850 | *--cmdpos = '0' + cid % 10; |
872 | *--cmdpos = 0x10; | 851 | cid /= 10; |
873 | *cmdtail++ = 0x10; | 852 | ++cmdlen; |
874 | *cmdtail++ = ')'; | 853 | } while (cid); |
875 | } | 854 | } |
876 | 855 | ||
877 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | 856 | cmdlen += 2; |
878 | kfree(cmdbuf); | 857 | *--cmdpos = 'T'; |
879 | } else | 858 | *--cmdpos = 'A'; |
880 | err("no memory for command buffer"); | 859 | |
881 | } else | 860 | if (dle) { |
882 | err("overflow in buflen"); | 861 | cmdlen += 4; |
862 | *--cmdpos = '('; | ||
863 | *--cmdpos = 0x10; | ||
864 | *cmdtail++ = 0x10; | ||
865 | *cmdtail++ = ')'; | ||
866 | } | ||
867 | |||
868 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | ||
869 | kfree(cmdbuf); | ||
883 | } | 870 | } |
884 | 871 | ||
885 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | 872 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) |
@@ -910,9 +897,6 @@ static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | |||
910 | 897 | ||
911 | static void bchannel_down(struct bc_state *bcs) | 898 | static void bchannel_down(struct bc_state *bcs) |
912 | { | 899 | { |
913 | IFNULLRET(bcs); | ||
914 | IFNULLRET(bcs->cs); | ||
915 | |||
916 | if (bcs->chstate & CHS_B_UP) { | 900 | if (bcs->chstate & CHS_B_UP) { |
917 | bcs->chstate &= ~CHS_B_UP; | 901 | bcs->chstate &= ~CHS_B_UP; |
918 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); | 902 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); |
@@ -930,16 +914,15 @@ static void bchannel_down(struct bc_state *bcs) | |||
930 | 914 | ||
931 | static void bchannel_up(struct bc_state *bcs) | 915 | static void bchannel_up(struct bc_state *bcs) |
932 | { | 916 | { |
933 | IFNULLRET(bcs); | ||
934 | |||
935 | if (!(bcs->chstate & CHS_D_UP)) { | 917 | if (!(bcs->chstate & CHS_D_UP)) { |
936 | notice("%s: D channel not up", __func__); | 918 | dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__); |
937 | bcs->chstate |= CHS_D_UP; | 919 | bcs->chstate |= CHS_D_UP; |
938 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | 920 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); |
939 | } | 921 | } |
940 | 922 | ||
941 | if (bcs->chstate & CHS_B_UP) { | 923 | if (bcs->chstate & CHS_B_UP) { |
942 | notice("%s: B channel already up", __func__); | 924 | dev_notice(bcs->cs->dev, "%s: B channel already up\n", |
925 | __func__); | ||
943 | return; | 926 | return; |
944 | } | 927 | } |
945 | 928 | ||
@@ -947,17 +930,21 @@ static void bchannel_up(struct bc_state *bcs) | |||
947 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); | 930 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); |
948 | } | 931 | } |
949 | 932 | ||
950 | static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | 933 | static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) |
951 | { | 934 | { |
952 | struct bc_state *bcs = at_state->bcs; | 935 | struct bc_state *bcs = at_state->bcs; |
953 | struct cardstate *cs = at_state->cs; | 936 | struct cardstate *cs = at_state->cs; |
954 | int retval; | 937 | int retval; |
938 | unsigned long flags; | ||
955 | 939 | ||
956 | bcs->chstate |= CHS_NOTIFY_LL; | 940 | bcs->chstate |= CHS_NOTIFY_LL; |
957 | //atomic_set(&bcs->status, BCS_INIT); | ||
958 | 941 | ||
959 | if (atomic_read(&at_state->seq_index) != seq_index) | 942 | spin_lock_irqsave(&cs->lock, flags); |
943 | if (at_state->seq_index != seq_index) { | ||
944 | spin_unlock_irqrestore(&cs->lock, flags); | ||
960 | goto error; | 945 | goto error; |
946 | } | ||
947 | spin_unlock_irqrestore(&cs->lock, flags); | ||
961 | 948 | ||
962 | retval = gigaset_isdn_setup_dial(at_state, data); | 949 | retval = gigaset_isdn_setup_dial(at_state, data); |
963 | if (retval != 0) | 950 | if (retval != 0) |
@@ -965,20 +952,14 @@ static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | |||
965 | 952 | ||
966 | 953 | ||
967 | at_state->pending_commands |= PC_CID; | 954 | at_state->pending_commands |= PC_CID; |
968 | dbg(DEBUG_CMD, "Scheduling PC_CID"); | 955 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); |
969 | //#ifdef GIG_MAYINITONDIAL | 956 | atomic_set(&cs->commands_pending, 1); |
970 | // if (atomic_read(&cs->MState) == MS_UNKNOWN) { | ||
971 | // cs->at_state.pending_commands |= PC_INIT; | ||
972 | // dbg(DEBUG_CMD, "Scheduling PC_INIT"); | ||
973 | // } | ||
974 | //#endif | ||
975 | atomic_set(&cs->commands_pending, 1); //FIXME | ||
976 | return; | 957 | return; |
977 | 958 | ||
978 | error: | 959 | error: |
979 | at_state->pending_commands |= PC_NOCID; | 960 | at_state->pending_commands |= PC_NOCID; |
980 | dbg(DEBUG_CMD, "Scheduling PC_NOCID"); | 961 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); |
981 | atomic_set(&cs->commands_pending, 1); //FIXME | 962 | atomic_set(&cs->commands_pending, 1); |
982 | return; | 963 | return; |
983 | } | 964 | } |
984 | 965 | ||
@@ -991,13 +972,13 @@ static void start_accept(struct at_state_t *at_state) | |||
991 | 972 | ||
992 | if (retval == 0) { | 973 | if (retval == 0) { |
993 | at_state->pending_commands |= PC_ACCEPT; | 974 | at_state->pending_commands |= PC_ACCEPT; |
994 | dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | 975 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); |
995 | atomic_set(&cs->commands_pending, 1); //FIXME | 976 | atomic_set(&cs->commands_pending, 1); |
996 | } else { | 977 | } else { |
997 | //FIXME | 978 | //FIXME |
998 | at_state->pending_commands |= PC_HUP; | 979 | at_state->pending_commands |= PC_HUP; |
999 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 980 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1000 | atomic_set(&cs->commands_pending, 1); //FIXME | 981 | atomic_set(&cs->commands_pending, 1); |
1001 | } | 982 | } |
1002 | } | 983 | } |
1003 | 984 | ||
@@ -1008,9 +989,10 @@ static void do_start(struct cardstate *cs) | |||
1008 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 989 | if (atomic_read(&cs->mstate) != MS_LOCKED) |
1009 | schedule_init(cs, MS_INIT); | 990 | schedule_init(cs, MS_INIT); |
1010 | 991 | ||
992 | cs->isdn_up = 1; | ||
1011 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); | 993 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); |
1012 | // FIXME: not in locked mode | 994 | // FIXME: not in locked mode |
1013 | // FIXME 2: only after init sequence | 995 | // FIXME 2: only after init sequence |
1014 | 996 | ||
1015 | cs->waiting = 0; | 997 | cs->waiting = 0; |
1016 | wake_up(&cs->waitqueue); | 998 | wake_up(&cs->waitqueue); |
@@ -1023,6 +1005,12 @@ static void finish_shutdown(struct cardstate *cs) | |||
1023 | atomic_set(&cs->mode, M_UNKNOWN); | 1005 | atomic_set(&cs->mode, M_UNKNOWN); |
1024 | } | 1006 | } |
1025 | 1007 | ||
1008 | /* Tell the LL that the device is not available .. */ | ||
1009 | if (cs->isdn_up) { | ||
1010 | cs->isdn_up = 0; | ||
1011 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); | ||
1012 | } | ||
1013 | |||
1026 | /* The rest is done by cleanup_cs () in user mode. */ | 1014 | /* The rest is done by cleanup_cs () in user mode. */ |
1027 | 1015 | ||
1028 | cs->cmd_result = -ENODEV; | 1016 | cs->cmd_result = -ENODEV; |
@@ -1037,15 +1025,20 @@ static void do_shutdown(struct cardstate *cs) | |||
1037 | if (atomic_read(&cs->mstate) == MS_READY) { | 1025 | if (atomic_read(&cs->mstate) == MS_READY) { |
1038 | atomic_set(&cs->mstate, MS_SHUTDOWN); | 1026 | atomic_set(&cs->mstate, MS_SHUTDOWN); |
1039 | cs->at_state.pending_commands |= PC_SHUTDOWN; | 1027 | cs->at_state.pending_commands |= PC_SHUTDOWN; |
1040 | atomic_set(&cs->commands_pending, 1); //FIXME | 1028 | atomic_set(&cs->commands_pending, 1); |
1041 | dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); //FIXME | 1029 | gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); |
1042 | //gigaset_schedule_event(cs); //FIXME | ||
1043 | } else | 1030 | } else |
1044 | finish_shutdown(cs); | 1031 | finish_shutdown(cs); |
1045 | } | 1032 | } |
1046 | 1033 | ||
1047 | static void do_stop(struct cardstate *cs) | 1034 | static void do_stop(struct cardstate *cs) |
1048 | { | 1035 | { |
1036 | unsigned long flags; | ||
1037 | |||
1038 | spin_lock_irqsave(&cs->lock, flags); | ||
1039 | cs->connected = 0; | ||
1040 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1041 | |||
1049 | do_shutdown(cs); | 1042 | do_shutdown(cs); |
1050 | } | 1043 | } |
1051 | 1044 | ||
@@ -1069,9 +1062,11 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1069 | return 0; | 1062 | return 0; |
1070 | 1063 | ||
1071 | if (channel < 0) | 1064 | if (channel < 0) |
1072 | warn("Could not enter cid mode. Reinit device and try again."); | 1065 | dev_warn(cs->dev, |
1066 | "Could not enter cid mode. Reinit device and try again.\n"); | ||
1073 | else { | 1067 | else { |
1074 | warn("Could not get a call id. Reinit device and try again."); | 1068 | dev_warn(cs->dev, |
1069 | "Could not get a call id. Reinit device and try again.\n"); | ||
1075 | cs->bcs[channel].at_state.pending_commands |= PC_CID; | 1070 | cs->bcs[channel].at_state.pending_commands |= PC_CID; |
1076 | } | 1071 | } |
1077 | schedule_init(cs, MS_INIT); | 1072 | schedule_init(cs, MS_INIT); |
@@ -1079,7 +1074,7 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1079 | } | 1074 | } |
1080 | 1075 | ||
1081 | static int at_state_invalid(struct cardstate *cs, | 1076 | static int at_state_invalid(struct cardstate *cs, |
1082 | struct at_state_t *test_ptr) | 1077 | struct at_state_t *test_ptr) |
1083 | { | 1078 | { |
1084 | unsigned long flags; | 1079 | unsigned long flags; |
1085 | unsigned channel; | 1080 | unsigned channel; |
@@ -1116,7 +1111,7 @@ static void handle_icall(struct cardstate *cs, struct bc_state *bcs, | |||
1116 | case ICALL_ACCEPT: | 1111 | case ICALL_ACCEPT: |
1117 | break; | 1112 | break; |
1118 | default: | 1113 | default: |
1119 | err("internal error: disposition=%d", retval); | 1114 | dev_err(cs->dev, "internal error: disposition=%d\n", retval); |
1120 | /* --v-- fall through --v-- */ | 1115 | /* --v-- fall through --v-- */ |
1121 | case ICALL_IGNORE: | 1116 | case ICALL_IGNORE: |
1122 | case ICALL_REJECT: | 1117 | case ICALL_REJECT: |
@@ -1160,7 +1155,6 @@ static int do_lock(struct cardstate *cs) | |||
1160 | mode = atomic_read(&cs->mode); | 1155 | mode = atomic_read(&cs->mode); |
1161 | atomic_set(&cs->mstate, MS_LOCKED); | 1156 | atomic_set(&cs->mstate, MS_LOCKED); |
1162 | atomic_set(&cs->mode, M_UNKNOWN); | 1157 | atomic_set(&cs->mode, M_UNKNOWN); |
1163 | //FIXME reset card state / at states / bcs states | ||
1164 | 1158 | ||
1165 | return mode; | 1159 | return mode; |
1166 | } | 1160 | } |
@@ -1173,8 +1167,7 @@ static int do_unlock(struct cardstate *cs) | |||
1173 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 1167 | atomic_set(&cs->mstate, MS_UNINITIALIZED); |
1174 | atomic_set(&cs->mode, M_UNKNOWN); | 1168 | atomic_set(&cs->mode, M_UNKNOWN); |
1175 | gigaset_free_channels(cs); | 1169 | gigaset_free_channels(cs); |
1176 | //FIXME reset card state / at states / bcs states | 1170 | if (cs->connected) |
1177 | if (atomic_read(&cs->connected)) | ||
1178 | schedule_init(cs, MS_INIT); | 1171 | schedule_init(cs, MS_INIT); |
1179 | 1172 | ||
1180 | return 0; | 1173 | return 0; |
@@ -1203,21 +1196,23 @@ static void do_action(int action, struct cardstate *cs, | |||
1203 | at_state->waiting = 1; | 1196 | at_state->waiting = 1; |
1204 | break; | 1197 | break; |
1205 | case ACT_INIT: | 1198 | case ACT_INIT: |
1206 | //FIXME setup everything | ||
1207 | cs->at_state.pending_commands &= ~PC_INIT; | 1199 | cs->at_state.pending_commands &= ~PC_INIT; |
1208 | cs->cur_at_seq = SEQ_NONE; | 1200 | cs->cur_at_seq = SEQ_NONE; |
1209 | atomic_set(&cs->mode, M_UNIMODEM); | 1201 | atomic_set(&cs->mode, M_UNIMODEM); |
1210 | if (!atomic_read(&cs->cidmode)) { | 1202 | spin_lock_irqsave(&cs->lock, flags); |
1203 | if (!cs->cidmode) { | ||
1204 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1211 | gigaset_free_channels(cs); | 1205 | gigaset_free_channels(cs); |
1212 | atomic_set(&cs->mstate, MS_READY); | 1206 | atomic_set(&cs->mstate, MS_READY); |
1213 | break; | 1207 | break; |
1214 | } | 1208 | } |
1209 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1215 | cs->at_state.pending_commands |= PC_CIDMODE; | 1210 | cs->at_state.pending_commands |= PC_CIDMODE; |
1216 | atomic_set(&cs->commands_pending, 1); //FIXME | 1211 | atomic_set(&cs->commands_pending, 1); |
1217 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1212 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1218 | break; | 1213 | break; |
1219 | case ACT_FAILINIT: | 1214 | case ACT_FAILINIT: |
1220 | warn("Could not initialize the device."); | 1215 | dev_warn(cs->dev, "Could not initialize the device.\n"); |
1221 | cs->dle = 0; | 1216 | cs->dle = 0; |
1222 | init_failed(cs, M_UNKNOWN); | 1217 | init_failed(cs, M_UNKNOWN); |
1223 | cs->cur_at_seq = SEQ_NONE; | 1218 | cs->cur_at_seq = SEQ_NONE; |
@@ -1273,8 +1268,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1273 | /* get fresh AT state structure for new CID */ | 1268 | /* get fresh AT state structure for new CID */ |
1274 | at_state2 = get_free_channel(cs, ev->parameter); | 1269 | at_state2 = get_free_channel(cs, ev->parameter); |
1275 | if (!at_state2) { | 1270 | if (!at_state2) { |
1276 | warn("RING ignored: " | 1271 | dev_warn(cs->dev, |
1277 | "could not allocate channel structure"); | 1272 | "RING ignored: could not allocate channel structure\n"); |
1278 | break; | 1273 | break; |
1279 | } | 1274 | } |
1280 | 1275 | ||
@@ -1302,7 +1297,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1302 | at_state = *p_at_state; | 1297 | at_state = *p_at_state; |
1303 | break; | 1298 | break; |
1304 | case ACT_FAILSDOWN: | 1299 | case ACT_FAILSDOWN: |
1305 | warn("Could not shut down the device."); | 1300 | dev_warn(cs->dev, "Could not shut down the device.\n"); |
1306 | /* fall through */ | 1301 | /* fall through */ |
1307 | case ACT_FAKESDOWN: | 1302 | case ACT_FAKESDOWN: |
1308 | case ACT_SDOWN: | 1303 | case ACT_SDOWN: |
@@ -1355,7 +1350,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1355 | break; | 1350 | break; |
1356 | case ACT_ABORTHUP: | 1351 | case ACT_ABORTHUP: |
1357 | cs->cur_at_seq = SEQ_NONE; | 1352 | cs->cur_at_seq = SEQ_NONE; |
1358 | warn("Could not hang up."); | 1353 | dev_warn(cs->dev, "Could not hang up.\n"); |
1359 | at_state->cid = -1; | 1354 | at_state->cid = -1; |
1360 | if (bcs && cs->onechannel) | 1355 | if (bcs && cs->onechannel) |
1361 | at_state->pending_commands |= PC_DLE0; | 1356 | at_state->pending_commands |= PC_DLE0; |
@@ -1367,14 +1362,15 @@ static void do_action(int action, struct cardstate *cs, | |||
1367 | break; | 1362 | break; |
1368 | case ACT_FAILDLE0: | 1363 | case ACT_FAILDLE0: |
1369 | cs->cur_at_seq = SEQ_NONE; | 1364 | cs->cur_at_seq = SEQ_NONE; |
1370 | warn("Could not leave DLE mode."); | 1365 | dev_warn(cs->dev, "Could not leave DLE mode.\n"); |
1371 | at_state2 = &cs->bcs[cs->curchannel].at_state; | 1366 | at_state2 = &cs->bcs[cs->curchannel].at_state; |
1372 | disconnect(&at_state2); | 1367 | disconnect(&at_state2); |
1373 | schedule_init(cs, MS_RECOVER); | 1368 | schedule_init(cs, MS_RECOVER); |
1374 | break; | 1369 | break; |
1375 | case ACT_FAILDLE1: | 1370 | case ACT_FAILDLE1: |
1376 | cs->cur_at_seq = SEQ_NONE; | 1371 | cs->cur_at_seq = SEQ_NONE; |
1377 | warn("Could not enter DLE mode. Try to hang up."); | 1372 | dev_warn(cs->dev, |
1373 | "Could not enter DLE mode. Trying to hang up.\n"); | ||
1378 | channel = cs->curchannel; | 1374 | channel = cs->curchannel; |
1379 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; | 1375 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; |
1380 | atomic_set(&cs->commands_pending, 1); | 1376 | atomic_set(&cs->commands_pending, 1); |
@@ -1395,7 +1391,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1395 | cs->cur_at_seq = SEQ_NONE; | 1391 | cs->cur_at_seq = SEQ_NONE; |
1396 | channel = cs->curchannel; | 1392 | channel = cs->curchannel; |
1397 | if (!reinit_and_retry(cs, channel)) { | 1393 | if (!reinit_and_retry(cs, channel)) { |
1398 | warn("Could not get a call id. Dialing not possible"); | 1394 | dev_warn(cs->dev, |
1395 | "Could not get a call ID. Cannot dial.\n"); | ||
1399 | at_state2 = &cs->bcs[channel].at_state; | 1396 | at_state2 = &cs->bcs[channel].at_state; |
1400 | disconnect(&at_state2); | 1397 | disconnect(&at_state2); |
1401 | } | 1398 | } |
@@ -1428,7 +1425,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1428 | at_state->pending_commands |= PC_HUP; | 1425 | at_state->pending_commands |= PC_HUP; |
1429 | atomic_set(&cs->commands_pending, 1); | 1426 | atomic_set(&cs->commands_pending, 1); |
1430 | break; | 1427 | break; |
1431 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... are not handled properly any more */ | 1428 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... |
1429 | are not handled properly anymore */ | ||
1432 | at_state->getstring = 1; | 1430 | at_state->getstring = 1; |
1433 | break; | 1431 | break; |
1434 | case ACT_SETVER: | 1432 | case ACT_SETVER: |
@@ -1469,16 +1467,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1469 | case ACT_GOTVER: | 1467 | case ACT_GOTVER: |
1470 | if (cs->gotfwver == 0) { | 1468 | if (cs->gotfwver == 0) { |
1471 | cs->gotfwver = 1; | 1469 | cs->gotfwver = 1; |
1472 | dbg(DEBUG_ANY, | 1470 | gig_dbg(DEBUG_ANY, |
1473 | "firmware version %02d.%03d.%02d.%02d", | 1471 | "firmware version %02d.%03d.%02d.%02d", |
1474 | cs->fwver[0], cs->fwver[1], | 1472 | cs->fwver[0], cs->fwver[1], |
1475 | cs->fwver[2], cs->fwver[3]); | 1473 | cs->fwver[2], cs->fwver[3]); |
1476 | break; | 1474 | break; |
1477 | } | 1475 | } |
1478 | /* fall through */ | 1476 | /* fall through */ |
1479 | case ACT_FAILVER: | 1477 | case ACT_FAILVER: |
1480 | cs->gotfwver = -1; | 1478 | cs->gotfwver = -1; |
1481 | err("could not read firmware version."); | 1479 | dev_err(cs->dev, "could not read firmware version.\n"); |
1482 | break; | 1480 | break; |
1483 | #ifdef CONFIG_GIGASET_DEBUG | 1481 | #ifdef CONFIG_GIGASET_DEBUG |
1484 | case ACT_ERROR: | 1482 | case ACT_ERROR: |
@@ -1496,16 +1494,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1496 | break; | 1494 | break; |
1497 | #endif | 1495 | #endif |
1498 | case ACT_DEBUG: | 1496 | case ACT_DEBUG: |
1499 | dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", | 1497 | gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", |
1500 | __func__, ev->type, at_state->ConState); | 1498 | __func__, ev->type, at_state->ConState); |
1501 | break; | 1499 | break; |
1502 | case ACT_WARN: | 1500 | case ACT_WARN: |
1503 | warn("%s: resp_code %d in ConState %d!", | 1501 | dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n", |
1504 | __func__, ev->type, at_state->ConState); | 1502 | __func__, ev->type, at_state->ConState); |
1505 | break; | 1503 | break; |
1506 | case ACT_ZCAU: | 1504 | case ACT_ZCAU: |
1507 | warn("cause code %04x in connection state %d.", | 1505 | dev_warn(cs->dev, "cause code %04x in connection state %d.\n", |
1508 | ev->parameter, at_state->ConState); | 1506 | ev->parameter, at_state->ConState); |
1509 | break; | 1507 | break; |
1510 | 1508 | ||
1511 | /* events from the LL */ | 1509 | /* events from the LL */ |
@@ -1516,14 +1514,14 @@ static void do_action(int action, struct cardstate *cs, | |||
1516 | start_accept(at_state); | 1514 | start_accept(at_state); |
1517 | break; | 1515 | break; |
1518 | case ACT_PROTO_L2: | 1516 | case ACT_PROTO_L2: |
1519 | dbg(DEBUG_CMD, | 1517 | gig_dbg(DEBUG_CMD, "set protocol to %u", |
1520 | "set protocol to %u", (unsigned) ev->parameter); | 1518 | (unsigned) ev->parameter); |
1521 | at_state->bcs->proto2 = ev->parameter; | 1519 | at_state->bcs->proto2 = ev->parameter; |
1522 | break; | 1520 | break; |
1523 | case ACT_HUP: | 1521 | case ACT_HUP: |
1524 | at_state->pending_commands |= PC_HUP; | 1522 | at_state->pending_commands |= PC_HUP; |
1525 | atomic_set(&cs->commands_pending, 1); //FIXME | 1523 | atomic_set(&cs->commands_pending, 1); |
1526 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 1524 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1527 | break; | 1525 | break; |
1528 | 1526 | ||
1529 | /* hotplug events */ | 1527 | /* hotplug events */ |
@@ -1555,17 +1553,19 @@ static void do_action(int action, struct cardstate *cs, | |||
1555 | 1553 | ||
1556 | /* events from the proc file system */ // FIXME without ACT_xxxx? | 1554 | /* events from the proc file system */ // FIXME without ACT_xxxx? |
1557 | case ACT_PROC_CIDMODE: | 1555 | case ACT_PROC_CIDMODE: |
1558 | if (ev->parameter != atomic_read(&cs->cidmode)) { | 1556 | spin_lock_irqsave(&cs->lock, flags); |
1559 | atomic_set(&cs->cidmode, ev->parameter); | 1557 | if (ev->parameter != cs->cidmode) { |
1558 | cs->cidmode = ev->parameter; | ||
1560 | if (ev->parameter) { | 1559 | if (ev->parameter) { |
1561 | cs->at_state.pending_commands |= PC_CIDMODE; | 1560 | cs->at_state.pending_commands |= PC_CIDMODE; |
1562 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1561 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1563 | } else { | 1562 | } else { |
1564 | cs->at_state.pending_commands |= PC_UMMODE; | 1563 | cs->at_state.pending_commands |= PC_UMMODE; |
1565 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 1564 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
1566 | } | 1565 | } |
1567 | atomic_set(&cs->commands_pending, 1); | 1566 | atomic_set(&cs->commands_pending, 1); |
1568 | } | 1567 | } |
1568 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1569 | cs->waiting = 0; | 1569 | cs->waiting = 0; |
1570 | wake_up(&cs->waitqueue); | 1570 | wake_up(&cs->waitqueue); |
1571 | break; | 1571 | break; |
@@ -1590,7 +1590,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1590 | *p_resp_code = RSP_NULL; | 1590 | *p_resp_code = RSP_NULL; |
1591 | } | 1591 | } |
1592 | } else | 1592 | } else |
1593 | err("%s: action==%d!", __func__, action); | 1593 | dev_err(cs->dev, "%s: action==%d!\n", __func__, action); |
1594 | } | 1594 | } |
1595 | } | 1595 | } |
1596 | 1596 | ||
@@ -1609,47 +1609,46 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1609 | int curact; | 1609 | int curact; |
1610 | unsigned long flags; | 1610 | unsigned long flags; |
1611 | 1611 | ||
1612 | IFNULLRET(cs); | ||
1613 | IFNULLRET(ev); | ||
1614 | |||
1615 | if (ev->cid >= 0) { | 1612 | if (ev->cid >= 0) { |
1616 | at_state = at_state_from_cid(cs, ev->cid); | 1613 | at_state = at_state_from_cid(cs, ev->cid); |
1617 | if (!at_state) { | 1614 | if (!at_state) { |
1618 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, | 1615 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, |
1619 | NULL, 0, NULL); | 1616 | NULL, 0, NULL); |
1620 | return; | 1617 | return; |
1621 | } | 1618 | } |
1622 | } else { | 1619 | } else { |
1623 | at_state = ev->at_state; | 1620 | at_state = ev->at_state; |
1624 | if (at_state_invalid(cs, at_state)) { | 1621 | if (at_state_invalid(cs, at_state)) { |
1625 | dbg(DEBUG_ANY, | 1622 | gig_dbg(DEBUG_ANY, "event for invalid at_state %p", |
1626 | "event for invalid at_state %p", at_state); | 1623 | at_state); |
1627 | return; | 1624 | return; |
1628 | } | 1625 | } |
1629 | } | 1626 | } |
1630 | 1627 | ||
1631 | dbg(DEBUG_CMD, | 1628 | gig_dbg(DEBUG_CMD, "connection state %d, event %d", |
1632 | "connection state %d, event %d", at_state->ConState, ev->type); | 1629 | at_state->ConState, ev->type); |
1633 | 1630 | ||
1634 | bcs = at_state->bcs; | 1631 | bcs = at_state->bcs; |
1635 | sendcid = at_state->cid; | 1632 | sendcid = at_state->cid; |
1636 | 1633 | ||
1637 | /* Setting the pointer to the dial array */ | 1634 | /* Setting the pointer to the dial array */ |
1638 | rep = at_state->replystruct; | 1635 | rep = at_state->replystruct; |
1639 | IFNULLRET(rep); | ||
1640 | 1636 | ||
1637 | spin_lock_irqsave(&cs->lock, flags); | ||
1641 | if (ev->type == EV_TIMEOUT) { | 1638 | if (ev->type == EV_TIMEOUT) { |
1642 | if (ev->parameter != atomic_read(&at_state->timer_index) | 1639 | if (ev->parameter != at_state->timer_index |
1643 | || !at_state->timer_active) { | 1640 | || !at_state->timer_active) { |
1644 | ev->type = RSP_NONE; /* old timeout */ | 1641 | ev->type = RSP_NONE; /* old timeout */ |
1645 | dbg(DEBUG_ANY, "old timeout"); | 1642 | gig_dbg(DEBUG_ANY, "old timeout"); |
1646 | } else if (!at_state->waiting) | 1643 | } else if (!at_state->waiting) |
1647 | dbg(DEBUG_ANY, "timeout occured"); | 1644 | gig_dbg(DEBUG_ANY, "timeout occurred"); |
1648 | else | 1645 | else |
1649 | dbg(DEBUG_ANY, "stopped waiting"); | 1646 | gig_dbg(DEBUG_ANY, "stopped waiting"); |
1650 | } | 1647 | } |
1648 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1651 | 1649 | ||
1652 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] or at_state->str_var[STR_XXXX], set it */ | 1650 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] |
1651 | or at_state->str_var[STR_XXXX], set it */ | ||
1653 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { | 1652 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { |
1654 | index = ev->type - RSP_VAR; | 1653 | index = ev->type - RSP_VAR; |
1655 | at_state->int_var[index] = ev->parameter; | 1654 | at_state->int_var[index] = ev->parameter; |
@@ -1657,20 +1656,22 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1657 | index = ev->type - RSP_STR; | 1656 | index = ev->type - RSP_STR; |
1658 | kfree(at_state->str_var[index]); | 1657 | kfree(at_state->str_var[index]); |
1659 | at_state->str_var[index] = ev->ptr; | 1658 | at_state->str_var[index] = ev->ptr; |
1660 | ev->ptr = NULL; /* prevent process_events() from deallocating ptr */ | 1659 | ev->ptr = NULL; /* prevent process_events() from |
1660 | deallocating ptr */ | ||
1661 | } | 1661 | } |
1662 | 1662 | ||
1663 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) | 1663 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) |
1664 | at_state->getstring = 0; | 1664 | at_state->getstring = 0; |
1665 | 1665 | ||
1666 | /* Search row in dial array which matches modem response and current constate */ | 1666 | /* Search row in dial array which matches modem response and current |
1667 | constate */ | ||
1667 | for (;; rep++) { | 1668 | for (;; rep++) { |
1668 | rcode = rep->resp_code; | 1669 | rcode = rep->resp_code; |
1669 | /* dbg (DEBUG_ANY, "rcode %d", rcode); */ | ||
1670 | if (rcode == RSP_LAST) { | 1670 | if (rcode == RSP_LAST) { |
1671 | /* found nothing...*/ | 1671 | /* found nothing...*/ |
1672 | warn("%s: rcode=RSP_LAST: resp_code %d in ConState %d!", | 1672 | dev_warn(cs->dev, "%s: rcode=RSP_LAST: " |
1673 | __func__, ev->type, at_state->ConState); | 1673 | "resp_code %d in ConState %d!\n", |
1674 | __func__, ev->type, at_state->ConState); | ||
1674 | return; | 1675 | return; |
1675 | } | 1676 | } |
1676 | if ((rcode == RSP_ANY || rcode == ev->type) | 1677 | if ((rcode == RSP_ANY || rcode == ev->type) |
@@ -1706,14 +1707,14 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1706 | } else { | 1707 | } else { |
1707 | /* Send command to modem if not NULL... */ | 1708 | /* Send command to modem if not NULL... */ |
1708 | if (p_command/*rep->command*/) { | 1709 | if (p_command/*rep->command*/) { |
1709 | if (atomic_read(&cs->connected)) | 1710 | if (cs->connected) |
1710 | send_command(cs, p_command, | 1711 | send_command(cs, p_command, |
1711 | sendcid, cs->dle, | 1712 | sendcid, cs->dle, |
1712 | GFP_ATOMIC); | 1713 | GFP_ATOMIC); |
1713 | else | 1714 | else |
1714 | gigaset_add_event(cs, at_state, | 1715 | gigaset_add_event(cs, at_state, |
1715 | RSP_NODEV, | 1716 | RSP_NODEV, |
1716 | NULL, 0, NULL); | 1717 | NULL, 0, NULL); |
1717 | } | 1718 | } |
1718 | 1719 | ||
1719 | spin_lock_irqsave(&cs->lock, flags); | 1720 | spin_lock_irqsave(&cs->lock, flags); |
@@ -1723,8 +1724,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1723 | } else if (rep->timeout > 0) { /* new timeout */ | 1724 | } else if (rep->timeout > 0) { /* new timeout */ |
1724 | at_state->timer_expires = rep->timeout * 10; | 1725 | at_state->timer_expires = rep->timeout * 10; |
1725 | at_state->timer_active = 1; | 1726 | at_state->timer_active = 1; |
1726 | new_index(&at_state->timer_index, | 1727 | ++at_state->timer_index; |
1727 | MAX_TIMER_INDEX); | ||
1728 | } | 1728 | } |
1729 | spin_unlock_irqrestore(&cs->lock, flags); | 1729 | spin_unlock_irqrestore(&cs->lock, flags); |
1730 | } | 1730 | } |
@@ -1744,17 +1744,16 @@ static void process_command_flags(struct cardstate *cs) | |||
1744 | struct bc_state *bcs; | 1744 | struct bc_state *bcs; |
1745 | int i; | 1745 | int i; |
1746 | int sequence; | 1746 | int sequence; |
1747 | 1747 | unsigned long flags; | |
1748 | IFNULLRET(cs); | ||
1749 | 1748 | ||
1750 | atomic_set(&cs->commands_pending, 0); | 1749 | atomic_set(&cs->commands_pending, 0); |
1751 | 1750 | ||
1752 | if (cs->cur_at_seq) { | 1751 | if (cs->cur_at_seq) { |
1753 | dbg(DEBUG_CMD, "not searching scheduled commands: busy"); | 1752 | gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); |
1754 | return; | 1753 | return; |
1755 | } | 1754 | } |
1756 | 1755 | ||
1757 | dbg(DEBUG_CMD, "searching scheduled commands"); | 1756 | gig_dbg(DEBUG_CMD, "searching scheduled commands"); |
1758 | 1757 | ||
1759 | sequence = SEQ_NONE; | 1758 | sequence = SEQ_NONE; |
1760 | 1759 | ||
@@ -1795,8 +1794,9 @@ static void process_command_flags(struct cardstate *cs) | |||
1795 | } | 1794 | } |
1796 | 1795 | ||
1797 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ | 1796 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ |
1797 | spin_lock_irqsave(&cs->lock, flags); | ||
1798 | if (cs->at_state.pending_commands == PC_UMMODE | 1798 | if (cs->at_state.pending_commands == PC_UMMODE |
1799 | && !atomic_read(&cs->cidmode) | 1799 | && !cs->cidmode |
1800 | && list_empty(&cs->temp_at_states) | 1800 | && list_empty(&cs->temp_at_states) |
1801 | && atomic_read(&cs->mode) == M_CID) { | 1801 | && atomic_read(&cs->mode) == M_CID) { |
1802 | sequence = SEQ_UMMODE; | 1802 | sequence = SEQ_UMMODE; |
@@ -1810,6 +1810,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1810 | } | 1810 | } |
1811 | } | 1811 | } |
1812 | } | 1812 | } |
1813 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1813 | cs->at_state.pending_commands &= ~PC_UMMODE; | 1814 | cs->at_state.pending_commands &= ~PC_UMMODE; |
1814 | if (sequence != SEQ_NONE) { | 1815 | if (sequence != SEQ_NONE) { |
1815 | schedule_sequence(cs, at_state, sequence); | 1816 | schedule_sequence(cs, at_state, sequence); |
@@ -1865,11 +1866,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1865 | if (cs->at_state.pending_commands & PC_CIDMODE) { | 1866 | if (cs->at_state.pending_commands & PC_CIDMODE) { |
1866 | cs->at_state.pending_commands &= ~PC_CIDMODE; | 1867 | cs->at_state.pending_commands &= ~PC_CIDMODE; |
1867 | if (atomic_read(&cs->mode) == M_UNIMODEM) { | 1868 | if (atomic_read(&cs->mode) == M_UNIMODEM) { |
1868 | #if 0 | ||
1869 | cs->retry_count = 2; | ||
1870 | #else | ||
1871 | cs->retry_count = 1; | 1869 | cs->retry_count = 1; |
1872 | #endif | ||
1873 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); | 1870 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); |
1874 | return; | 1871 | return; |
1875 | } | 1872 | } |
@@ -1897,7 +1894,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1897 | switch (atomic_read(&cs->mode)) { | 1894 | switch (atomic_read(&cs->mode)) { |
1898 | case M_UNIMODEM: | 1895 | case M_UNIMODEM: |
1899 | cs->at_state.pending_commands |= PC_CIDMODE; | 1896 | cs->at_state.pending_commands |= PC_CIDMODE; |
1900 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1897 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1901 | atomic_set(&cs->commands_pending, 1); | 1898 | atomic_set(&cs->commands_pending, 1); |
1902 | return; | 1899 | return; |
1903 | #ifdef GIG_MAYINITONDIAL | 1900 | #ifdef GIG_MAYINITONDIAL |
@@ -1926,18 +1923,21 @@ static void process_events(struct cardstate *cs) | |||
1926 | int i; | 1923 | int i; |
1927 | int check_flags = 0; | 1924 | int check_flags = 0; |
1928 | int was_busy; | 1925 | int was_busy; |
1926 | unsigned long flags; | ||
1929 | 1927 | ||
1930 | /* no locking needed (only one reader) */ | 1928 | spin_lock_irqsave(&cs->ev_lock, flags); |
1931 | head = atomic_read(&cs->ev_head); | 1929 | head = cs->ev_head; |
1932 | 1930 | ||
1933 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { | 1931 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { |
1934 | tail = atomic_read(&cs->ev_tail); | 1932 | tail = cs->ev_tail; |
1935 | if (tail == head) { | 1933 | if (tail == head) { |
1936 | if (!check_flags && !atomic_read(&cs->commands_pending)) | 1934 | if (!check_flags && !atomic_read(&cs->commands_pending)) |
1937 | break; | 1935 | break; |
1938 | check_flags = 0; | 1936 | check_flags = 0; |
1937 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1939 | process_command_flags(cs); | 1938 | process_command_flags(cs); |
1940 | tail = atomic_read(&cs->ev_tail); | 1939 | spin_lock_irqsave(&cs->ev_lock, flags); |
1940 | tail = cs->ev_tail; | ||
1941 | if (tail == head) { | 1941 | if (tail == head) { |
1942 | if (!atomic_read(&cs->commands_pending)) | 1942 | if (!atomic_read(&cs->commands_pending)) |
1943 | break; | 1943 | break; |
@@ -1947,18 +1947,23 @@ static void process_events(struct cardstate *cs) | |||
1947 | 1947 | ||
1948 | ev = cs->events + head; | 1948 | ev = cs->events + head; |
1949 | was_busy = cs->cur_at_seq != SEQ_NONE; | 1949 | was_busy = cs->cur_at_seq != SEQ_NONE; |
1950 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1950 | process_event(cs, ev); | 1951 | process_event(cs, ev); |
1952 | spin_lock_irqsave(&cs->ev_lock, flags); | ||
1951 | kfree(ev->ptr); | 1953 | kfree(ev->ptr); |
1952 | ev->ptr = NULL; | 1954 | ev->ptr = NULL; |
1953 | if (was_busy && cs->cur_at_seq == SEQ_NONE) | 1955 | if (was_busy && cs->cur_at_seq == SEQ_NONE) |
1954 | check_flags = 1; | 1956 | check_flags = 1; |
1955 | 1957 | ||
1956 | head = (head + 1) % MAX_EVENTS; | 1958 | head = (head + 1) % MAX_EVENTS; |
1957 | atomic_set(&cs->ev_head, head); | 1959 | cs->ev_head = head; |
1958 | } | 1960 | } |
1959 | 1961 | ||
1962 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1963 | |||
1960 | if (i == 2 * MAX_EVENTS) { | 1964 | if (i == 2 * MAX_EVENTS) { |
1961 | err("infinite loop in process_events; aborting."); | 1965 | dev_err(cs->dev, |
1966 | "infinite loop in process_events; aborting.\n"); | ||
1962 | } | 1967 | } |
1963 | } | 1968 | } |
1964 | 1969 | ||
@@ -1970,12 +1975,9 @@ void gigaset_handle_event(unsigned long data) | |||
1970 | { | 1975 | { |
1971 | struct cardstate *cs = (struct cardstate *) data; | 1976 | struct cardstate *cs = (struct cardstate *) data; |
1972 | 1977 | ||
1973 | IFNULLRET(cs); | ||
1974 | IFNULLRET(cs->inbuf); | ||
1975 | |||
1976 | /* handle incoming data on control/common channel */ | 1978 | /* handle incoming data on control/common channel */ |
1977 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { | 1979 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { |
1978 | dbg(DEBUG_INTR, "processing new data"); | 1980 | gig_dbg(DEBUG_INTR, "processing new data"); |
1979 | cs->ops->handle_input(cs->inbuf); | 1981 | cs->ops->handle_input(cs->inbuf); |
1980 | } | 1982 | } |
1981 | 1983 | ||