diff options
Diffstat (limited to 'drivers/isdn/gigaset/ev-layer.c')
-rw-r--r-- | drivers/isdn/gigaset/ev-layer.c | 667 |
1 files changed, 333 insertions, 334 deletions
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index fdcb80bb21c7..1ba3424a286b 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? */ |
@@ -393,7 +389,7 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | |||
393 | 389 | ||
394 | 390 | ||
395 | #if 0 | 391 | #if 0 |
396 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen uebernehmen | 392 | static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME |
397 | { | 393 | { |
398 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 394 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
399 | 395 | ||
@@ -401,7 +397,7 @@ static struct reply_t tab_nocid[]= /* no dle mode */ //FIXME aenderungen ueberne | |||
401 | {RSP_LAST,0,0,0,0,0,0} | 397 | {RSP_LAST,0,0,0,0,0,0} |
402 | }; | 398 | }; |
403 | 399 | ||
404 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen uebernehmen | 400 | static struct reply_t tab_cid[] = /* no dle mode */ //FIXME |
405 | { | 401 | { |
406 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 402 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
407 | 403 | ||
@@ -412,30 +408,30 @@ static struct reply_t tab_cid[] = /* no dle mode */ //FIXME aenderungen ueberneh | |||
412 | 408 | ||
413 | static struct resp_type_t resp_type[]= | 409 | static struct resp_type_t resp_type[]= |
414 | { | 410 | { |
415 | /*{"", RSP_EMPTY, RT_NOTHING},*/ | 411 | /*{"", RSP_EMPTY, RT_NOTHING},*/ |
416 | {"OK", RSP_OK, RT_NOTHING}, | 412 | {"OK", RSP_OK, RT_NOTHING}, |
417 | {"ERROR", RSP_ERROR, RT_NOTHING}, | 413 | {"ERROR", RSP_ERROR, RT_NOTHING}, |
418 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, | 414 | {"ZSAU", RSP_ZSAU, RT_ZSAU}, |
419 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, | 415 | {"ZCAU", RSP_ZCAU, RT_ZCAU}, |
420 | {"RING", RSP_RING, RT_RING}, | 416 | {"RING", RSP_RING, RT_RING}, |
421 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, | 417 | {"ZGCI", RSP_ZGCI, RT_NUMBER}, |
422 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, | 418 | {"ZVLS", RSP_ZVLS, RT_NUMBER}, |
423 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, | 419 | {"ZCTP", RSP_ZCTP, RT_NUMBER}, |
424 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, | 420 | {"ZDLE", RSP_ZDLE, RT_NUMBER}, |
425 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, | 421 | {"ZCFGT", RSP_ZCFGT, RT_NUMBER}, |
426 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, | 422 | {"ZCCR", RSP_ZCCR, RT_NUMBER}, |
427 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, | 423 | {"ZMWI", RSP_ZMWI, RT_NUMBER}, |
428 | {"ZHLC", RSP_ZHLC, RT_STRING}, | 424 | {"ZHLC", RSP_ZHLC, RT_STRING}, |
429 | {"ZBC", RSP_ZBC, RT_STRING}, | 425 | {"ZBC", RSP_ZBC, RT_STRING}, |
430 | {"NMBR", RSP_NMBR, RT_STRING}, | 426 | {"NMBR", RSP_NMBR, RT_STRING}, |
431 | {"ZCPN", RSP_ZCPN, RT_STRING}, | 427 | {"ZCPN", RSP_ZCPN, RT_STRING}, |
432 | {"ZCON", RSP_ZCON, RT_STRING}, | 428 | {"ZCON", RSP_ZCON, RT_STRING}, |
433 | {"ZAOC", RSP_ZAOC, RT_STRING}, | 429 | {"ZAOC", RSP_ZAOC, RT_STRING}, |
434 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, | 430 | {"ZCSTR", RSP_ZCSTR, RT_STRING}, |
435 | {"ZCFG", RSP_ZCFG, RT_HEX}, | 431 | {"ZCFG", RSP_ZCFG, RT_HEX}, |
436 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, | 432 | {"ZLOG", RSP_ZLOG, RT_NOTHING}, |
437 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, | 433 | {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, |
438 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, | 434 | {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, |
439 | {NULL,0,0} | 435 | {NULL,0,0} |
440 | }; | 436 | }; |
441 | 437 | ||
@@ -446,9 +442,7 @@ static int isdn_getnum(char *p) | |||
446 | { | 442 | { |
447 | int v = -1; | 443 | int v = -1; |
448 | 444 | ||
449 | IFNULLRETVAL(p, -1); | 445 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
450 | |||
451 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
452 | 446 | ||
453 | while (*p >= '0' && *p <= '9') | 447 | while (*p >= '0' && *p <= '9') |
454 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); | 448 | v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); |
@@ -465,9 +459,7 @@ static int isdn_gethex(char *p) | |||
465 | int v = 0; | 459 | int v = 0; |
466 | int c; | 460 | int c; |
467 | 461 | ||
468 | IFNULLRETVAL(p, -1); | 462 | gig_dbg(DEBUG_TRANSCMD, "string: %s", p); |
469 | |||
470 | dbg(DEBUG_TRANSCMD, "string: %s", p); | ||
471 | 463 | ||
472 | if (!*p) | 464 | if (!*p) |
473 | return -1; | 465 | return -1; |
@@ -490,14 +482,6 @@ static int isdn_gethex(char *p) | |||
490 | return v; | 482 | return v; |
491 | } | 483 | } |
492 | 484 | ||
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 | 485 | /* retrieve CID from parsed response |
502 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 | 486 | * returns 0 if no CID, -1 if invalid CID, or CID value 1..65535 |
503 | */ | 487 | */ |
@@ -536,16 +520,14 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
536 | int cid; | 520 | int cid; |
537 | int rawstring; | 521 | int rawstring; |
538 | 522 | ||
539 | IFNULLRET(cs); | ||
540 | |||
541 | len = cs->cbytes; | 523 | len = cs->cbytes; |
542 | if (!len) { | 524 | if (!len) { |
543 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ | 525 | /* ignore additional LFs/CRs (M10x config mode or cx100) */ |
544 | dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); | 526 | gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); |
545 | return; | 527 | return; |
546 | } | 528 | } |
547 | cs->respdata[len] = 0; | 529 | cs->respdata[len] = 0; |
548 | dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); | 530 | gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata); |
549 | argv[0] = cs->respdata; | 531 | argv[0] = cs->respdata; |
550 | params = 1; | 532 | params = 1; |
551 | if (cs->at_state.getstring) { | 533 | if (cs->at_state.getstring) { |
@@ -561,7 +543,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
561 | case ',': | 543 | case ',': |
562 | case '=': | 544 | case '=': |
563 | if (params > MAX_REC_PARAMS) { | 545 | if (params > MAX_REC_PARAMS) { |
564 | warn("too many parameters in response"); | 546 | dev_warn(cs->dev, |
547 | "too many parameters in response\n"); | ||
565 | /* need last parameter (might be CID) */ | 548 | /* need last parameter (might be CID) */ |
566 | params--; | 549 | params--; |
567 | } | 550 | } |
@@ -572,33 +555,33 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
572 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; | 555 | cid = params > 1 ? cid_of_response(argv[params-1]) : 0; |
573 | if (cid < 0) { | 556 | if (cid < 0) { |
574 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, | 557 | gigaset_add_event(cs, &cs->at_state, RSP_INVAL, |
575 | NULL, 0, NULL); | 558 | NULL, 0, NULL); |
576 | return; | 559 | return; |
577 | } | 560 | } |
578 | 561 | ||
579 | for (j = 1; j < params; ++j) | 562 | for (j = 1; j < params; ++j) |
580 | argv[j][-1] = 0; | 563 | argv[j][-1] = 0; |
581 | 564 | ||
582 | dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); | 565 | gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); |
583 | if (cid) { | 566 | if (cid) { |
584 | --params; | 567 | --params; |
585 | dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); | 568 | gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); |
586 | } | 569 | } |
587 | dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); | 570 | gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); |
588 | for (j = 1; j < params; j++) | 571 | for (j = 1; j < params; j++) |
589 | dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); | 572 | gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); |
590 | } | 573 | } |
591 | 574 | ||
592 | spin_lock_irqsave(&cs->ev_lock, flags); | 575 | spin_lock_irqsave(&cs->ev_lock, flags); |
593 | head = atomic_read(&cs->ev_head); | 576 | head = cs->ev_head; |
594 | tail = atomic_read(&cs->ev_tail); | 577 | tail = cs->ev_tail; |
595 | 578 | ||
596 | abort = 1; | 579 | abort = 1; |
597 | curarg = 0; | 580 | curarg = 0; |
598 | while (curarg < params) { | 581 | while (curarg < params) { |
599 | next = (tail + 1) % MAX_EVENTS; | 582 | next = (tail + 1) % MAX_EVENTS; |
600 | if (unlikely(next == head)) { | 583 | if (unlikely(next == head)) { |
601 | err("event queue full"); | 584 | dev_err(cs->dev, "event queue full\n"); |
602 | break; | 585 | break; |
603 | } | 586 | } |
604 | 587 | ||
@@ -619,8 +602,9 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
619 | 602 | ||
620 | if (!rt->response) { | 603 | if (!rt->response) { |
621 | event->type = RSP_UNKNOWN; | 604 | event->type = RSP_UNKNOWN; |
622 | warn("unknown modem response: %s", | 605 | dev_warn(cs->dev, |
623 | argv[curarg]); | 606 | "unknown modem response: %s\n", |
607 | argv[curarg]); | ||
624 | break; | 608 | break; |
625 | } | 609 | } |
626 | 610 | ||
@@ -636,7 +620,8 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
636 | break; | 620 | break; |
637 | case RT_RING: | 621 | case RT_RING: |
638 | if (!cid) { | 622 | if (!cid) { |
639 | err("received RING without CID!"); | 623 | dev_err(cs->dev, |
624 | "received RING without CID!\n"); | ||
640 | event->type = RSP_INVAL; | 625 | event->type = RSP_INVAL; |
641 | abort = 1; | 626 | abort = 1; |
642 | } else { | 627 | } else { |
@@ -664,27 +649,25 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
664 | event->parameter = ZSAU_DISCONNECT_REQ; | 649 | event->parameter = ZSAU_DISCONNECT_REQ; |
665 | else { | 650 | else { |
666 | event->parameter = ZSAU_UNKNOWN; | 651 | event->parameter = ZSAU_UNKNOWN; |
667 | warn("%s: unknown parameter %s after ZSAU", | 652 | dev_warn(cs->dev, |
668 | __func__, argv[curarg]); | 653 | "%s: unknown parameter %s after ZSAU\n", |
654 | __func__, argv[curarg]); | ||
669 | } | 655 | } |
670 | ++curarg; | 656 | ++curarg; |
671 | break; | 657 | break; |
672 | case RT_STRING: | 658 | case RT_STRING: |
673 | if (curarg < params) { | 659 | if (curarg < params) { |
674 | len = strlen(argv[curarg]) + 1; | 660 | event->ptr = kstrdup(argv[curarg], GFP_ATOMIC); |
675 | event->ptr = kmalloc(len, GFP_ATOMIC); | 661 | if (!event->ptr) |
676 | if (event->ptr) | 662 | 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; | 663 | ++curarg; |
681 | } | 664 | } |
682 | #ifdef CONFIG_GIGASET_DEBUG | 665 | #ifdef CONFIG_GIGASET_DEBUG |
683 | if (!event->ptr) | 666 | if (!event->ptr) |
684 | dbg(DEBUG_CMD, "string==NULL"); | 667 | gig_dbg(DEBUG_CMD, "string==NULL"); |
685 | else | 668 | else |
686 | dbg(DEBUG_CMD, | 669 | gig_dbg(DEBUG_CMD, "string==%s", |
687 | "string==%s", (char *) event->ptr); | 670 | (char *) event->ptr); |
688 | #endif | 671 | #endif |
689 | break; | 672 | break; |
690 | case RT_ZCAU: | 673 | case RT_ZCAU: |
@@ -694,7 +677,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
694 | j = isdn_gethex(argv[curarg + 1]); | 677 | j = isdn_gethex(argv[curarg + 1]); |
695 | if (i >= 0 && i < 256 && j >= 0 && j < 256) | 678 | if (i >= 0 && i < 256 && j >= 0 && j < 256) |
696 | event->parameter = (unsigned) i << 8 | 679 | event->parameter = (unsigned) i << 8 |
697 | | j; | 680 | | j; |
698 | curarg += 2; | 681 | curarg += 2; |
699 | } else | 682 | } else |
700 | curarg = params - 1; | 683 | curarg = params - 1; |
@@ -712,7 +695,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
712 | } else | 695 | } else |
713 | event->parameter = -1; | 696 | event->parameter = -1; |
714 | #ifdef CONFIG_GIGASET_DEBUG | 697 | #ifdef CONFIG_GIGASET_DEBUG |
715 | dbg(DEBUG_CMD, "parameter==%d", event->parameter); | 698 | gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); |
716 | #endif | 699 | #endif |
717 | break; | 700 | break; |
718 | } | 701 | } |
@@ -724,12 +707,13 @@ void gigaset_handle_modem_response(struct cardstate *cs) | |||
724 | break; | 707 | break; |
725 | } | 708 | } |
726 | 709 | ||
727 | atomic_set(&cs->ev_tail, tail); | 710 | cs->ev_tail = tail; |
728 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 711 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
729 | 712 | ||
730 | if (curarg != params) | 713 | if (curarg != params) |
731 | dbg(DEBUG_ANY, "invalid number of processed parameters: %d/%d", | 714 | gig_dbg(DEBUG_ANY, |
732 | curarg, params); | 715 | "invalid number of processed parameters: %d/%d", |
716 | curarg, params); | ||
733 | } | 717 | } |
734 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | 718 | EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); |
735 | 719 | ||
@@ -739,23 +723,19 @@ EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); | |||
739 | static void disconnect(struct at_state_t **at_state_p) | 723 | static void disconnect(struct at_state_t **at_state_p) |
740 | { | 724 | { |
741 | unsigned long flags; | 725 | unsigned long flags; |
742 | struct bc_state *bcs; | 726 | struct bc_state *bcs = (*at_state_p)->bcs; |
743 | struct cardstate *cs; | 727 | struct cardstate *cs = (*at_state_p)->cs; |
744 | 728 | ||
745 | IFNULLRET(at_state_p); | 729 | spin_lock_irqsave(&cs->lock, flags); |
746 | IFNULLRET(*at_state_p); | 730 | ++(*at_state_p)->seq_index; |
747 | bcs = (*at_state_p)->bcs; | ||
748 | cs = (*at_state_p)->cs; | ||
749 | IFNULLRET(cs); | ||
750 | |||
751 | new_index(&(*at_state_p)->seq_index, MAX_SEQ_INDEX); | ||
752 | 731 | ||
753 | /* revert to selected idle mode */ | 732 | /* revert to selected idle mode */ |
754 | if (!atomic_read(&cs->cidmode)) { | 733 | if (!cs->cidmode) { |
755 | cs->at_state.pending_commands |= PC_UMMODE; | 734 | cs->at_state.pending_commands |= PC_UMMODE; |
756 | atomic_set(&cs->commands_pending, 1); //FIXME | 735 | atomic_set(&cs->commands_pending, 1); //FIXME |
757 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 736 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
758 | } | 737 | } |
738 | spin_unlock_irqrestore(&cs->lock, flags); | ||
759 | 739 | ||
760 | if (bcs) { | 740 | if (bcs) { |
761 | /* B channel assigned: invoke hardware specific handler */ | 741 | /* B channel assigned: invoke hardware specific handler */ |
@@ -777,7 +757,7 @@ static void disconnect(struct at_state_t **at_state_p) | |||
777 | * The structure should be freed by calling disconnect() after use. | 757 | * The structure should be freed by calling disconnect() after use. |
778 | */ | 758 | */ |
779 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, | 759 | static inline struct at_state_t *get_free_channel(struct cardstate *cs, |
780 | int cid) | 760 | int cid) |
781 | /* cids: >0: siemens-cid | 761 | /* cids: >0: siemens-cid |
782 | 0: without cid | 762 | 0: without cid |
783 | -1: no cid assigned yet | 763 | -1: no cid assigned yet |
@@ -826,7 +806,7 @@ static void init_failed(struct cardstate *cs, int mode) | |||
826 | static void schedule_init(struct cardstate *cs, int state) | 806 | static void schedule_init(struct cardstate *cs, int state) |
827 | { | 807 | { |
828 | if (cs->at_state.pending_commands & PC_INIT) { | 808 | if (cs->at_state.pending_commands & PC_INIT) { |
829 | dbg(DEBUG_CMD, "not scheduling PC_INIT again"); | 809 | gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); |
830 | return; | 810 | return; |
831 | } | 811 | } |
832 | atomic_set(&cs->mstate, state); | 812 | atomic_set(&cs->mstate, state); |
@@ -834,52 +814,56 @@ static void schedule_init(struct cardstate *cs, int state) | |||
834 | gigaset_block_channels(cs); | 814 | gigaset_block_channels(cs); |
835 | cs->at_state.pending_commands |= PC_INIT; | 815 | cs->at_state.pending_commands |= PC_INIT; |
836 | atomic_set(&cs->commands_pending, 1); | 816 | atomic_set(&cs->commands_pending, 1); |
837 | dbg(DEBUG_CMD, "Scheduling PC_INIT"); | 817 | gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); |
838 | } | 818 | } |
839 | 819 | ||
840 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the hardware. */ | 820 | /* Add "AT" to a command, add the cid, dle encode it, send the result to the |
821 | hardware. */ | ||
841 | static void send_command(struct cardstate *cs, const char *cmd, int cid, | 822 | static void send_command(struct cardstate *cs, const char *cmd, int cid, |
842 | int dle, gfp_t kmallocflags) | 823 | int dle, gfp_t kmallocflags) |
843 | { | 824 | { |
844 | size_t cmdlen, buflen; | 825 | size_t cmdlen, buflen; |
845 | char *cmdpos, *cmdbuf, *cmdtail; | 826 | char *cmdpos, *cmdbuf, *cmdtail; |
846 | 827 | ||
847 | cmdlen = strlen(cmd); | 828 | cmdlen = strlen(cmd); |
848 | buflen = 11 + cmdlen; | 829 | buflen = 11 + cmdlen; |
830 | if (unlikely(buflen <= cmdlen)) { | ||
831 | dev_err(cs->dev, "integer overflow in buflen\n"); | ||
832 | return; | ||
833 | } | ||
849 | 834 | ||
850 | if (likely(buflen > cmdlen)) { | 835 | cmdbuf = kmalloc(buflen, kmallocflags); |
851 | cmdbuf = kmalloc(buflen, kmallocflags); | 836 | if (unlikely(!cmdbuf)) { |
852 | if (likely(cmdbuf != NULL)) { | 837 | dev_err(cs->dev, "out of memory\n"); |
853 | cmdpos = cmdbuf + 9; | 838 | return; |
854 | cmdtail = cmdpos + cmdlen; | 839 | } |
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 | 840 | ||
865 | cmdlen += 2; | 841 | cmdpos = cmdbuf + 9; |
866 | *--cmdpos = 'T'; | 842 | cmdtail = cmdpos + cmdlen; |
867 | *--cmdpos = 'A'; | 843 | memcpy(cmdpos, cmd, cmdlen); |
868 | 844 | ||
869 | if (dle) { | 845 | if (cid > 0 && cid <= 65535) { |
870 | cmdlen += 4; | 846 | do { |
871 | *--cmdpos = '('; | 847 | *--cmdpos = '0' + cid % 10; |
872 | *--cmdpos = 0x10; | 848 | cid /= 10; |
873 | *cmdtail++ = 0x10; | 849 | ++cmdlen; |
874 | *cmdtail++ = ')'; | 850 | } while (cid); |
875 | } | 851 | } |
876 | 852 | ||
877 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | 853 | cmdlen += 2; |
878 | kfree(cmdbuf); | 854 | *--cmdpos = 'T'; |
879 | } else | 855 | *--cmdpos = 'A'; |
880 | err("no memory for command buffer"); | 856 | |
881 | } else | 857 | if (dle) { |
882 | err("overflow in buflen"); | 858 | cmdlen += 4; |
859 | *--cmdpos = '('; | ||
860 | *--cmdpos = 0x10; | ||
861 | *cmdtail++ = 0x10; | ||
862 | *cmdtail++ = ')'; | ||
863 | } | ||
864 | |||
865 | cs->ops->write_cmd(cs, cmdpos, cmdlen, NULL); | ||
866 | kfree(cmdbuf); | ||
883 | } | 867 | } |
884 | 868 | ||
885 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | 869 | static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) |
@@ -910,9 +894,6 @@ static struct at_state_t *at_state_from_cid(struct cardstate *cs, int cid) | |||
910 | 894 | ||
911 | static void bchannel_down(struct bc_state *bcs) | 895 | static void bchannel_down(struct bc_state *bcs) |
912 | { | 896 | { |
913 | IFNULLRET(bcs); | ||
914 | IFNULLRET(bcs->cs); | ||
915 | |||
916 | if (bcs->chstate & CHS_B_UP) { | 897 | if (bcs->chstate & CHS_B_UP) { |
917 | bcs->chstate &= ~CHS_B_UP; | 898 | bcs->chstate &= ~CHS_B_UP; |
918 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); | 899 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); |
@@ -930,16 +911,15 @@ static void bchannel_down(struct bc_state *bcs) | |||
930 | 911 | ||
931 | static void bchannel_up(struct bc_state *bcs) | 912 | static void bchannel_up(struct bc_state *bcs) |
932 | { | 913 | { |
933 | IFNULLRET(bcs); | ||
934 | |||
935 | if (!(bcs->chstate & CHS_D_UP)) { | 914 | if (!(bcs->chstate & CHS_D_UP)) { |
936 | notice("%s: D channel not up", __func__); | 915 | dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__); |
937 | bcs->chstate |= CHS_D_UP; | 916 | bcs->chstate |= CHS_D_UP; |
938 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); | 917 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); |
939 | } | 918 | } |
940 | 919 | ||
941 | if (bcs->chstate & CHS_B_UP) { | 920 | if (bcs->chstate & CHS_B_UP) { |
942 | notice("%s: B channel already up", __func__); | 921 | dev_notice(bcs->cs->dev, "%s: B channel already up\n", |
922 | __func__); | ||
943 | return; | 923 | return; |
944 | } | 924 | } |
945 | 925 | ||
@@ -947,17 +927,21 @@ static void bchannel_up(struct bc_state *bcs) | |||
947 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); | 927 | gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); |
948 | } | 928 | } |
949 | 929 | ||
950 | static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | 930 | static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) |
951 | { | 931 | { |
952 | struct bc_state *bcs = at_state->bcs; | 932 | struct bc_state *bcs = at_state->bcs; |
953 | struct cardstate *cs = at_state->cs; | 933 | struct cardstate *cs = at_state->cs; |
954 | int retval; | 934 | int retval; |
935 | unsigned long flags; | ||
955 | 936 | ||
956 | bcs->chstate |= CHS_NOTIFY_LL; | 937 | bcs->chstate |= CHS_NOTIFY_LL; |
957 | //atomic_set(&bcs->status, BCS_INIT); | ||
958 | 938 | ||
959 | if (atomic_read(&at_state->seq_index) != seq_index) | 939 | spin_lock_irqsave(&cs->lock, flags); |
940 | if (at_state->seq_index != seq_index) { | ||
941 | spin_unlock_irqrestore(&cs->lock, flags); | ||
960 | goto error; | 942 | goto error; |
943 | } | ||
944 | spin_unlock_irqrestore(&cs->lock, flags); | ||
961 | 945 | ||
962 | retval = gigaset_isdn_setup_dial(at_state, data); | 946 | retval = gigaset_isdn_setup_dial(at_state, data); |
963 | if (retval != 0) | 947 | if (retval != 0) |
@@ -965,20 +949,14 @@ static void start_dial(struct at_state_t *at_state, void *data, int seq_index) | |||
965 | 949 | ||
966 | 950 | ||
967 | at_state->pending_commands |= PC_CID; | 951 | at_state->pending_commands |= PC_CID; |
968 | dbg(DEBUG_CMD, "Scheduling PC_CID"); | 952 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); |
969 | //#ifdef GIG_MAYINITONDIAL | 953 | 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; | 954 | return; |
977 | 955 | ||
978 | error: | 956 | error: |
979 | at_state->pending_commands |= PC_NOCID; | 957 | at_state->pending_commands |= PC_NOCID; |
980 | dbg(DEBUG_CMD, "Scheduling PC_NOCID"); | 958 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); |
981 | atomic_set(&cs->commands_pending, 1); //FIXME | 959 | atomic_set(&cs->commands_pending, 1); |
982 | return; | 960 | return; |
983 | } | 961 | } |
984 | 962 | ||
@@ -991,13 +969,13 @@ static void start_accept(struct at_state_t *at_state) | |||
991 | 969 | ||
992 | if (retval == 0) { | 970 | if (retval == 0) { |
993 | at_state->pending_commands |= PC_ACCEPT; | 971 | at_state->pending_commands |= PC_ACCEPT; |
994 | dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | 972 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); |
995 | atomic_set(&cs->commands_pending, 1); //FIXME | 973 | atomic_set(&cs->commands_pending, 1); |
996 | } else { | 974 | } else { |
997 | //FIXME | 975 | //FIXME |
998 | at_state->pending_commands |= PC_HUP; | 976 | at_state->pending_commands |= PC_HUP; |
999 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 977 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1000 | atomic_set(&cs->commands_pending, 1); //FIXME | 978 | atomic_set(&cs->commands_pending, 1); |
1001 | } | 979 | } |
1002 | } | 980 | } |
1003 | 981 | ||
@@ -1008,9 +986,10 @@ static void do_start(struct cardstate *cs) | |||
1008 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 986 | if (atomic_read(&cs->mstate) != MS_LOCKED) |
1009 | schedule_init(cs, MS_INIT); | 987 | schedule_init(cs, MS_INIT); |
1010 | 988 | ||
989 | cs->isdn_up = 1; | ||
1011 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); | 990 | gigaset_i4l_cmd(cs, ISDN_STAT_RUN); |
1012 | // FIXME: not in locked mode | 991 | // FIXME: not in locked mode |
1013 | // FIXME 2: only after init sequence | 992 | // FIXME 2: only after init sequence |
1014 | 993 | ||
1015 | cs->waiting = 0; | 994 | cs->waiting = 0; |
1016 | wake_up(&cs->waitqueue); | 995 | wake_up(&cs->waitqueue); |
@@ -1023,6 +1002,12 @@ static void finish_shutdown(struct cardstate *cs) | |||
1023 | atomic_set(&cs->mode, M_UNKNOWN); | 1002 | atomic_set(&cs->mode, M_UNKNOWN); |
1024 | } | 1003 | } |
1025 | 1004 | ||
1005 | /* Tell the LL that the device is not available .. */ | ||
1006 | if (cs->isdn_up) { | ||
1007 | cs->isdn_up = 0; | ||
1008 | gigaset_i4l_cmd(cs, ISDN_STAT_STOP); | ||
1009 | } | ||
1010 | |||
1026 | /* The rest is done by cleanup_cs () in user mode. */ | 1011 | /* The rest is done by cleanup_cs () in user mode. */ |
1027 | 1012 | ||
1028 | cs->cmd_result = -ENODEV; | 1013 | cs->cmd_result = -ENODEV; |
@@ -1037,15 +1022,20 @@ static void do_shutdown(struct cardstate *cs) | |||
1037 | if (atomic_read(&cs->mstate) == MS_READY) { | 1022 | if (atomic_read(&cs->mstate) == MS_READY) { |
1038 | atomic_set(&cs->mstate, MS_SHUTDOWN); | 1023 | atomic_set(&cs->mstate, MS_SHUTDOWN); |
1039 | cs->at_state.pending_commands |= PC_SHUTDOWN; | 1024 | cs->at_state.pending_commands |= PC_SHUTDOWN; |
1040 | atomic_set(&cs->commands_pending, 1); //FIXME | 1025 | atomic_set(&cs->commands_pending, 1); |
1041 | dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); //FIXME | 1026 | gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); |
1042 | //gigaset_schedule_event(cs); //FIXME | ||
1043 | } else | 1027 | } else |
1044 | finish_shutdown(cs); | 1028 | finish_shutdown(cs); |
1045 | } | 1029 | } |
1046 | 1030 | ||
1047 | static void do_stop(struct cardstate *cs) | 1031 | static void do_stop(struct cardstate *cs) |
1048 | { | 1032 | { |
1033 | unsigned long flags; | ||
1034 | |||
1035 | spin_lock_irqsave(&cs->lock, flags); | ||
1036 | cs->connected = 0; | ||
1037 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1038 | |||
1049 | do_shutdown(cs); | 1039 | do_shutdown(cs); |
1050 | } | 1040 | } |
1051 | 1041 | ||
@@ -1069,9 +1059,11 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1069 | return 0; | 1059 | return 0; |
1070 | 1060 | ||
1071 | if (channel < 0) | 1061 | if (channel < 0) |
1072 | warn("Could not enter cid mode. Reinit device and try again."); | 1062 | dev_warn(cs->dev, |
1063 | "Could not enter cid mode. Reinit device and try again.\n"); | ||
1073 | else { | 1064 | else { |
1074 | warn("Could not get a call id. Reinit device and try again."); | 1065 | dev_warn(cs->dev, |
1066 | "Could not get a call id. Reinit device and try again.\n"); | ||
1075 | cs->bcs[channel].at_state.pending_commands |= PC_CID; | 1067 | cs->bcs[channel].at_state.pending_commands |= PC_CID; |
1076 | } | 1068 | } |
1077 | schedule_init(cs, MS_INIT); | 1069 | schedule_init(cs, MS_INIT); |
@@ -1079,7 +1071,7 @@ static int reinit_and_retry(struct cardstate *cs, int channel) | |||
1079 | } | 1071 | } |
1080 | 1072 | ||
1081 | static int at_state_invalid(struct cardstate *cs, | 1073 | static int at_state_invalid(struct cardstate *cs, |
1082 | struct at_state_t *test_ptr) | 1074 | struct at_state_t *test_ptr) |
1083 | { | 1075 | { |
1084 | unsigned long flags; | 1076 | unsigned long flags; |
1085 | unsigned channel; | 1077 | unsigned channel; |
@@ -1116,7 +1108,7 @@ static void handle_icall(struct cardstate *cs, struct bc_state *bcs, | |||
1116 | case ICALL_ACCEPT: | 1108 | case ICALL_ACCEPT: |
1117 | break; | 1109 | break; |
1118 | default: | 1110 | default: |
1119 | err("internal error: disposition=%d", retval); | 1111 | dev_err(cs->dev, "internal error: disposition=%d\n", retval); |
1120 | /* --v-- fall through --v-- */ | 1112 | /* --v-- fall through --v-- */ |
1121 | case ICALL_IGNORE: | 1113 | case ICALL_IGNORE: |
1122 | case ICALL_REJECT: | 1114 | case ICALL_REJECT: |
@@ -1160,7 +1152,6 @@ static int do_lock(struct cardstate *cs) | |||
1160 | mode = atomic_read(&cs->mode); | 1152 | mode = atomic_read(&cs->mode); |
1161 | atomic_set(&cs->mstate, MS_LOCKED); | 1153 | atomic_set(&cs->mstate, MS_LOCKED); |
1162 | atomic_set(&cs->mode, M_UNKNOWN); | 1154 | atomic_set(&cs->mode, M_UNKNOWN); |
1163 | //FIXME reset card state / at states / bcs states | ||
1164 | 1155 | ||
1165 | return mode; | 1156 | return mode; |
1166 | } | 1157 | } |
@@ -1173,8 +1164,7 @@ static int do_unlock(struct cardstate *cs) | |||
1173 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 1164 | atomic_set(&cs->mstate, MS_UNINITIALIZED); |
1174 | atomic_set(&cs->mode, M_UNKNOWN); | 1165 | atomic_set(&cs->mode, M_UNKNOWN); |
1175 | gigaset_free_channels(cs); | 1166 | gigaset_free_channels(cs); |
1176 | //FIXME reset card state / at states / bcs states | 1167 | if (cs->connected) |
1177 | if (atomic_read(&cs->connected)) | ||
1178 | schedule_init(cs, MS_INIT); | 1168 | schedule_init(cs, MS_INIT); |
1179 | 1169 | ||
1180 | return 0; | 1170 | return 0; |
@@ -1203,21 +1193,23 @@ static void do_action(int action, struct cardstate *cs, | |||
1203 | at_state->waiting = 1; | 1193 | at_state->waiting = 1; |
1204 | break; | 1194 | break; |
1205 | case ACT_INIT: | 1195 | case ACT_INIT: |
1206 | //FIXME setup everything | ||
1207 | cs->at_state.pending_commands &= ~PC_INIT; | 1196 | cs->at_state.pending_commands &= ~PC_INIT; |
1208 | cs->cur_at_seq = SEQ_NONE; | 1197 | cs->cur_at_seq = SEQ_NONE; |
1209 | atomic_set(&cs->mode, M_UNIMODEM); | 1198 | atomic_set(&cs->mode, M_UNIMODEM); |
1210 | if (!atomic_read(&cs->cidmode)) { | 1199 | spin_lock_irqsave(&cs->lock, flags); |
1200 | if (!cs->cidmode) { | ||
1201 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1211 | gigaset_free_channels(cs); | 1202 | gigaset_free_channels(cs); |
1212 | atomic_set(&cs->mstate, MS_READY); | 1203 | atomic_set(&cs->mstate, MS_READY); |
1213 | break; | 1204 | break; |
1214 | } | 1205 | } |
1206 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1215 | cs->at_state.pending_commands |= PC_CIDMODE; | 1207 | cs->at_state.pending_commands |= PC_CIDMODE; |
1216 | atomic_set(&cs->commands_pending, 1); //FIXME | 1208 | atomic_set(&cs->commands_pending, 1); |
1217 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1209 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1218 | break; | 1210 | break; |
1219 | case ACT_FAILINIT: | 1211 | case ACT_FAILINIT: |
1220 | warn("Could not initialize the device."); | 1212 | dev_warn(cs->dev, "Could not initialize the device.\n"); |
1221 | cs->dle = 0; | 1213 | cs->dle = 0; |
1222 | init_failed(cs, M_UNKNOWN); | 1214 | init_failed(cs, M_UNKNOWN); |
1223 | cs->cur_at_seq = SEQ_NONE; | 1215 | cs->cur_at_seq = SEQ_NONE; |
@@ -1273,8 +1265,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1273 | /* get fresh AT state structure for new CID */ | 1265 | /* get fresh AT state structure for new CID */ |
1274 | at_state2 = get_free_channel(cs, ev->parameter); | 1266 | at_state2 = get_free_channel(cs, ev->parameter); |
1275 | if (!at_state2) { | 1267 | if (!at_state2) { |
1276 | warn("RING ignored: " | 1268 | dev_warn(cs->dev, |
1277 | "could not allocate channel structure"); | 1269 | "RING ignored: could not allocate channel structure\n"); |
1278 | break; | 1270 | break; |
1279 | } | 1271 | } |
1280 | 1272 | ||
@@ -1302,7 +1294,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1302 | at_state = *p_at_state; | 1294 | at_state = *p_at_state; |
1303 | break; | 1295 | break; |
1304 | case ACT_FAILSDOWN: | 1296 | case ACT_FAILSDOWN: |
1305 | warn("Could not shut down the device."); | 1297 | dev_warn(cs->dev, "Could not shut down the device.\n"); |
1306 | /* fall through */ | 1298 | /* fall through */ |
1307 | case ACT_FAKESDOWN: | 1299 | case ACT_FAKESDOWN: |
1308 | case ACT_SDOWN: | 1300 | case ACT_SDOWN: |
@@ -1355,7 +1347,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1355 | break; | 1347 | break; |
1356 | case ACT_ABORTHUP: | 1348 | case ACT_ABORTHUP: |
1357 | cs->cur_at_seq = SEQ_NONE; | 1349 | cs->cur_at_seq = SEQ_NONE; |
1358 | warn("Could not hang up."); | 1350 | dev_warn(cs->dev, "Could not hang up.\n"); |
1359 | at_state->cid = -1; | 1351 | at_state->cid = -1; |
1360 | if (bcs && cs->onechannel) | 1352 | if (bcs && cs->onechannel) |
1361 | at_state->pending_commands |= PC_DLE0; | 1353 | at_state->pending_commands |= PC_DLE0; |
@@ -1367,14 +1359,15 @@ static void do_action(int action, struct cardstate *cs, | |||
1367 | break; | 1359 | break; |
1368 | case ACT_FAILDLE0: | 1360 | case ACT_FAILDLE0: |
1369 | cs->cur_at_seq = SEQ_NONE; | 1361 | cs->cur_at_seq = SEQ_NONE; |
1370 | warn("Could not leave DLE mode."); | 1362 | dev_warn(cs->dev, "Could not leave DLE mode.\n"); |
1371 | at_state2 = &cs->bcs[cs->curchannel].at_state; | 1363 | at_state2 = &cs->bcs[cs->curchannel].at_state; |
1372 | disconnect(&at_state2); | 1364 | disconnect(&at_state2); |
1373 | schedule_init(cs, MS_RECOVER); | 1365 | schedule_init(cs, MS_RECOVER); |
1374 | break; | 1366 | break; |
1375 | case ACT_FAILDLE1: | 1367 | case ACT_FAILDLE1: |
1376 | cs->cur_at_seq = SEQ_NONE; | 1368 | cs->cur_at_seq = SEQ_NONE; |
1377 | warn("Could not enter DLE mode. Try to hang up."); | 1369 | dev_warn(cs->dev, |
1370 | "Could not enter DLE mode. Trying to hang up.\n"); | ||
1378 | channel = cs->curchannel; | 1371 | channel = cs->curchannel; |
1379 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; | 1372 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; |
1380 | atomic_set(&cs->commands_pending, 1); | 1373 | atomic_set(&cs->commands_pending, 1); |
@@ -1395,7 +1388,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1395 | cs->cur_at_seq = SEQ_NONE; | 1388 | cs->cur_at_seq = SEQ_NONE; |
1396 | channel = cs->curchannel; | 1389 | channel = cs->curchannel; |
1397 | if (!reinit_and_retry(cs, channel)) { | 1390 | if (!reinit_and_retry(cs, channel)) { |
1398 | warn("Could not get a call id. Dialing not possible"); | 1391 | dev_warn(cs->dev, |
1392 | "Could not get a call ID. Cannot dial.\n"); | ||
1399 | at_state2 = &cs->bcs[channel].at_state; | 1393 | at_state2 = &cs->bcs[channel].at_state; |
1400 | disconnect(&at_state2); | 1394 | disconnect(&at_state2); |
1401 | } | 1395 | } |
@@ -1428,7 +1422,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1428 | at_state->pending_commands |= PC_HUP; | 1422 | at_state->pending_commands |= PC_HUP; |
1429 | atomic_set(&cs->commands_pending, 1); | 1423 | atomic_set(&cs->commands_pending, 1); |
1430 | break; | 1424 | break; |
1431 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... are not handled properly any more */ | 1425 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... |
1426 | are not handled properly anymore */ | ||
1432 | at_state->getstring = 1; | 1427 | at_state->getstring = 1; |
1433 | break; | 1428 | break; |
1434 | case ACT_SETVER: | 1429 | case ACT_SETVER: |
@@ -1469,16 +1464,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1469 | case ACT_GOTVER: | 1464 | case ACT_GOTVER: |
1470 | if (cs->gotfwver == 0) { | 1465 | if (cs->gotfwver == 0) { |
1471 | cs->gotfwver = 1; | 1466 | cs->gotfwver = 1; |
1472 | dbg(DEBUG_ANY, | 1467 | gig_dbg(DEBUG_ANY, |
1473 | "firmware version %02d.%03d.%02d.%02d", | 1468 | "firmware version %02d.%03d.%02d.%02d", |
1474 | cs->fwver[0], cs->fwver[1], | 1469 | cs->fwver[0], cs->fwver[1], |
1475 | cs->fwver[2], cs->fwver[3]); | 1470 | cs->fwver[2], cs->fwver[3]); |
1476 | break; | 1471 | break; |
1477 | } | 1472 | } |
1478 | /* fall through */ | 1473 | /* fall through */ |
1479 | case ACT_FAILVER: | 1474 | case ACT_FAILVER: |
1480 | cs->gotfwver = -1; | 1475 | cs->gotfwver = -1; |
1481 | err("could not read firmware version."); | 1476 | dev_err(cs->dev, "could not read firmware version.\n"); |
1482 | break; | 1477 | break; |
1483 | #ifdef CONFIG_GIGASET_DEBUG | 1478 | #ifdef CONFIG_GIGASET_DEBUG |
1484 | case ACT_ERROR: | 1479 | case ACT_ERROR: |
@@ -1496,16 +1491,16 @@ static void do_action(int action, struct cardstate *cs, | |||
1496 | break; | 1491 | break; |
1497 | #endif | 1492 | #endif |
1498 | case ACT_DEBUG: | 1493 | case ACT_DEBUG: |
1499 | dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", | 1494 | gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", |
1500 | __func__, ev->type, at_state->ConState); | 1495 | __func__, ev->type, at_state->ConState); |
1501 | break; | 1496 | break; |
1502 | case ACT_WARN: | 1497 | case ACT_WARN: |
1503 | warn("%s: resp_code %d in ConState %d!", | 1498 | dev_warn(cs->dev, "%s: resp_code %d in ConState %d!\n", |
1504 | __func__, ev->type, at_state->ConState); | 1499 | __func__, ev->type, at_state->ConState); |
1505 | break; | 1500 | break; |
1506 | case ACT_ZCAU: | 1501 | case ACT_ZCAU: |
1507 | warn("cause code %04x in connection state %d.", | 1502 | dev_warn(cs->dev, "cause code %04x in connection state %d.\n", |
1508 | ev->parameter, at_state->ConState); | 1503 | ev->parameter, at_state->ConState); |
1509 | break; | 1504 | break; |
1510 | 1505 | ||
1511 | /* events from the LL */ | 1506 | /* events from the LL */ |
@@ -1516,14 +1511,14 @@ static void do_action(int action, struct cardstate *cs, | |||
1516 | start_accept(at_state); | 1511 | start_accept(at_state); |
1517 | break; | 1512 | break; |
1518 | case ACT_PROTO_L2: | 1513 | case ACT_PROTO_L2: |
1519 | dbg(DEBUG_CMD, | 1514 | gig_dbg(DEBUG_CMD, "set protocol to %u", |
1520 | "set protocol to %u", (unsigned) ev->parameter); | 1515 | (unsigned) ev->parameter); |
1521 | at_state->bcs->proto2 = ev->parameter; | 1516 | at_state->bcs->proto2 = ev->parameter; |
1522 | break; | 1517 | break; |
1523 | case ACT_HUP: | 1518 | case ACT_HUP: |
1524 | at_state->pending_commands |= PC_HUP; | 1519 | at_state->pending_commands |= PC_HUP; |
1525 | atomic_set(&cs->commands_pending, 1); //FIXME | 1520 | atomic_set(&cs->commands_pending, 1); |
1526 | dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 1521 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1527 | break; | 1522 | break; |
1528 | 1523 | ||
1529 | /* hotplug events */ | 1524 | /* hotplug events */ |
@@ -1555,17 +1550,19 @@ static void do_action(int action, struct cardstate *cs, | |||
1555 | 1550 | ||
1556 | /* events from the proc file system */ // FIXME without ACT_xxxx? | 1551 | /* events from the proc file system */ // FIXME without ACT_xxxx? |
1557 | case ACT_PROC_CIDMODE: | 1552 | case ACT_PROC_CIDMODE: |
1558 | if (ev->parameter != atomic_read(&cs->cidmode)) { | 1553 | spin_lock_irqsave(&cs->lock, flags); |
1559 | atomic_set(&cs->cidmode, ev->parameter); | 1554 | if (ev->parameter != cs->cidmode) { |
1555 | cs->cidmode = ev->parameter; | ||
1560 | if (ev->parameter) { | 1556 | if (ev->parameter) { |
1561 | cs->at_state.pending_commands |= PC_CIDMODE; | 1557 | cs->at_state.pending_commands |= PC_CIDMODE; |
1562 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1558 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1563 | } else { | 1559 | } else { |
1564 | cs->at_state.pending_commands |= PC_UMMODE; | 1560 | cs->at_state.pending_commands |= PC_UMMODE; |
1565 | dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 1561 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
1566 | } | 1562 | } |
1567 | atomic_set(&cs->commands_pending, 1); | 1563 | atomic_set(&cs->commands_pending, 1); |
1568 | } | 1564 | } |
1565 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1569 | cs->waiting = 0; | 1566 | cs->waiting = 0; |
1570 | wake_up(&cs->waitqueue); | 1567 | wake_up(&cs->waitqueue); |
1571 | break; | 1568 | break; |
@@ -1590,7 +1587,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1590 | *p_resp_code = RSP_NULL; | 1587 | *p_resp_code = RSP_NULL; |
1591 | } | 1588 | } |
1592 | } else | 1589 | } else |
1593 | err("%s: action==%d!", __func__, action); | 1590 | dev_err(cs->dev, "%s: action==%d!\n", __func__, action); |
1594 | } | 1591 | } |
1595 | } | 1592 | } |
1596 | 1593 | ||
@@ -1609,47 +1606,46 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1609 | int curact; | 1606 | int curact; |
1610 | unsigned long flags; | 1607 | unsigned long flags; |
1611 | 1608 | ||
1612 | IFNULLRET(cs); | ||
1613 | IFNULLRET(ev); | ||
1614 | |||
1615 | if (ev->cid >= 0) { | 1609 | if (ev->cid >= 0) { |
1616 | at_state = at_state_from_cid(cs, ev->cid); | 1610 | at_state = at_state_from_cid(cs, ev->cid); |
1617 | if (!at_state) { | 1611 | if (!at_state) { |
1618 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, | 1612 | gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, |
1619 | NULL, 0, NULL); | 1613 | NULL, 0, NULL); |
1620 | return; | 1614 | return; |
1621 | } | 1615 | } |
1622 | } else { | 1616 | } else { |
1623 | at_state = ev->at_state; | 1617 | at_state = ev->at_state; |
1624 | if (at_state_invalid(cs, at_state)) { | 1618 | if (at_state_invalid(cs, at_state)) { |
1625 | dbg(DEBUG_ANY, | 1619 | gig_dbg(DEBUG_ANY, "event for invalid at_state %p", |
1626 | "event for invalid at_state %p", at_state); | 1620 | at_state); |
1627 | return; | 1621 | return; |
1628 | } | 1622 | } |
1629 | } | 1623 | } |
1630 | 1624 | ||
1631 | dbg(DEBUG_CMD, | 1625 | gig_dbg(DEBUG_CMD, "connection state %d, event %d", |
1632 | "connection state %d, event %d", at_state->ConState, ev->type); | 1626 | at_state->ConState, ev->type); |
1633 | 1627 | ||
1634 | bcs = at_state->bcs; | 1628 | bcs = at_state->bcs; |
1635 | sendcid = at_state->cid; | 1629 | sendcid = at_state->cid; |
1636 | 1630 | ||
1637 | /* Setting the pointer to the dial array */ | 1631 | /* Setting the pointer to the dial array */ |
1638 | rep = at_state->replystruct; | 1632 | rep = at_state->replystruct; |
1639 | IFNULLRET(rep); | ||
1640 | 1633 | ||
1634 | spin_lock_irqsave(&cs->lock, flags); | ||
1641 | if (ev->type == EV_TIMEOUT) { | 1635 | if (ev->type == EV_TIMEOUT) { |
1642 | if (ev->parameter != atomic_read(&at_state->timer_index) | 1636 | if (ev->parameter != at_state->timer_index |
1643 | || !at_state->timer_active) { | 1637 | || !at_state->timer_active) { |
1644 | ev->type = RSP_NONE; /* old timeout */ | 1638 | ev->type = RSP_NONE; /* old timeout */ |
1645 | dbg(DEBUG_ANY, "old timeout"); | 1639 | gig_dbg(DEBUG_ANY, "old timeout"); |
1646 | } else if (!at_state->waiting) | 1640 | } else if (!at_state->waiting) |
1647 | dbg(DEBUG_ANY, "timeout occured"); | 1641 | gig_dbg(DEBUG_ANY, "timeout occurred"); |
1648 | else | 1642 | else |
1649 | dbg(DEBUG_ANY, "stopped waiting"); | 1643 | gig_dbg(DEBUG_ANY, "stopped waiting"); |
1650 | } | 1644 | } |
1645 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1651 | 1646 | ||
1652 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] or at_state->str_var[STR_XXXX], set it */ | 1647 | /* if the response belongs to a variable in at_state->int_var[VAR_XXXX] |
1648 | or at_state->str_var[STR_XXXX], set it */ | ||
1653 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { | 1649 | if (ev->type >= RSP_VAR && ev->type < RSP_VAR + VAR_NUM) { |
1654 | index = ev->type - RSP_VAR; | 1650 | index = ev->type - RSP_VAR; |
1655 | at_state->int_var[index] = ev->parameter; | 1651 | at_state->int_var[index] = ev->parameter; |
@@ -1657,20 +1653,22 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1657 | index = ev->type - RSP_STR; | 1653 | index = ev->type - RSP_STR; |
1658 | kfree(at_state->str_var[index]); | 1654 | kfree(at_state->str_var[index]); |
1659 | at_state->str_var[index] = ev->ptr; | 1655 | at_state->str_var[index] = ev->ptr; |
1660 | ev->ptr = NULL; /* prevent process_events() from deallocating ptr */ | 1656 | ev->ptr = NULL; /* prevent process_events() from |
1657 | deallocating ptr */ | ||
1661 | } | 1658 | } |
1662 | 1659 | ||
1663 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) | 1660 | if (ev->type == EV_TIMEOUT || ev->type == RSP_STRING) |
1664 | at_state->getstring = 0; | 1661 | at_state->getstring = 0; |
1665 | 1662 | ||
1666 | /* Search row in dial array which matches modem response and current constate */ | 1663 | /* Search row in dial array which matches modem response and current |
1664 | constate */ | ||
1667 | for (;; rep++) { | 1665 | for (;; rep++) { |
1668 | rcode = rep->resp_code; | 1666 | rcode = rep->resp_code; |
1669 | /* dbg (DEBUG_ANY, "rcode %d", rcode); */ | ||
1670 | if (rcode == RSP_LAST) { | 1667 | if (rcode == RSP_LAST) { |
1671 | /* found nothing...*/ | 1668 | /* found nothing...*/ |
1672 | warn("%s: rcode=RSP_LAST: resp_code %d in ConState %d!", | 1669 | dev_warn(cs->dev, "%s: rcode=RSP_LAST: " |
1673 | __func__, ev->type, at_state->ConState); | 1670 | "resp_code %d in ConState %d!\n", |
1671 | __func__, ev->type, at_state->ConState); | ||
1674 | return; | 1672 | return; |
1675 | } | 1673 | } |
1676 | if ((rcode == RSP_ANY || rcode == ev->type) | 1674 | if ((rcode == RSP_ANY || rcode == ev->type) |
@@ -1706,14 +1704,14 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1706 | } else { | 1704 | } else { |
1707 | /* Send command to modem if not NULL... */ | 1705 | /* Send command to modem if not NULL... */ |
1708 | if (p_command/*rep->command*/) { | 1706 | if (p_command/*rep->command*/) { |
1709 | if (atomic_read(&cs->connected)) | 1707 | if (cs->connected) |
1710 | send_command(cs, p_command, | 1708 | send_command(cs, p_command, |
1711 | sendcid, cs->dle, | 1709 | sendcid, cs->dle, |
1712 | GFP_ATOMIC); | 1710 | GFP_ATOMIC); |
1713 | else | 1711 | else |
1714 | gigaset_add_event(cs, at_state, | 1712 | gigaset_add_event(cs, at_state, |
1715 | RSP_NODEV, | 1713 | RSP_NODEV, |
1716 | NULL, 0, NULL); | 1714 | NULL, 0, NULL); |
1717 | } | 1715 | } |
1718 | 1716 | ||
1719 | spin_lock_irqsave(&cs->lock, flags); | 1717 | spin_lock_irqsave(&cs->lock, flags); |
@@ -1723,8 +1721,7 @@ static void process_event(struct cardstate *cs, struct event_t *ev) | |||
1723 | } else if (rep->timeout > 0) { /* new timeout */ | 1721 | } else if (rep->timeout > 0) { /* new timeout */ |
1724 | at_state->timer_expires = rep->timeout * 10; | 1722 | at_state->timer_expires = rep->timeout * 10; |
1725 | at_state->timer_active = 1; | 1723 | at_state->timer_active = 1; |
1726 | new_index(&at_state->timer_index, | 1724 | ++at_state->timer_index; |
1727 | MAX_TIMER_INDEX); | ||
1728 | } | 1725 | } |
1729 | spin_unlock_irqrestore(&cs->lock, flags); | 1726 | spin_unlock_irqrestore(&cs->lock, flags); |
1730 | } | 1727 | } |
@@ -1744,17 +1741,16 @@ static void process_command_flags(struct cardstate *cs) | |||
1744 | struct bc_state *bcs; | 1741 | struct bc_state *bcs; |
1745 | int i; | 1742 | int i; |
1746 | int sequence; | 1743 | int sequence; |
1747 | 1744 | unsigned long flags; | |
1748 | IFNULLRET(cs); | ||
1749 | 1745 | ||
1750 | atomic_set(&cs->commands_pending, 0); | 1746 | atomic_set(&cs->commands_pending, 0); |
1751 | 1747 | ||
1752 | if (cs->cur_at_seq) { | 1748 | if (cs->cur_at_seq) { |
1753 | dbg(DEBUG_CMD, "not searching scheduled commands: busy"); | 1749 | gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); |
1754 | return; | 1750 | return; |
1755 | } | 1751 | } |
1756 | 1752 | ||
1757 | dbg(DEBUG_CMD, "searching scheduled commands"); | 1753 | gig_dbg(DEBUG_CMD, "searching scheduled commands"); |
1758 | 1754 | ||
1759 | sequence = SEQ_NONE; | 1755 | sequence = SEQ_NONE; |
1760 | 1756 | ||
@@ -1795,8 +1791,9 @@ static void process_command_flags(struct cardstate *cs) | |||
1795 | } | 1791 | } |
1796 | 1792 | ||
1797 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ | 1793 | /* only switch back to unimodem mode, if no commands are pending and no channels are up */ |
1794 | spin_lock_irqsave(&cs->lock, flags); | ||
1798 | if (cs->at_state.pending_commands == PC_UMMODE | 1795 | if (cs->at_state.pending_commands == PC_UMMODE |
1799 | && !atomic_read(&cs->cidmode) | 1796 | && !cs->cidmode |
1800 | && list_empty(&cs->temp_at_states) | 1797 | && list_empty(&cs->temp_at_states) |
1801 | && atomic_read(&cs->mode) == M_CID) { | 1798 | && atomic_read(&cs->mode) == M_CID) { |
1802 | sequence = SEQ_UMMODE; | 1799 | sequence = SEQ_UMMODE; |
@@ -1810,6 +1807,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1810 | } | 1807 | } |
1811 | } | 1808 | } |
1812 | } | 1809 | } |
1810 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1813 | cs->at_state.pending_commands &= ~PC_UMMODE; | 1811 | cs->at_state.pending_commands &= ~PC_UMMODE; |
1814 | if (sequence != SEQ_NONE) { | 1812 | if (sequence != SEQ_NONE) { |
1815 | schedule_sequence(cs, at_state, sequence); | 1813 | schedule_sequence(cs, at_state, sequence); |
@@ -1865,11 +1863,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1865 | if (cs->at_state.pending_commands & PC_CIDMODE) { | 1863 | if (cs->at_state.pending_commands & PC_CIDMODE) { |
1866 | cs->at_state.pending_commands &= ~PC_CIDMODE; | 1864 | cs->at_state.pending_commands &= ~PC_CIDMODE; |
1867 | if (atomic_read(&cs->mode) == M_UNIMODEM) { | 1865 | if (atomic_read(&cs->mode) == M_UNIMODEM) { |
1868 | #if 0 | ||
1869 | cs->retry_count = 2; | ||
1870 | #else | ||
1871 | cs->retry_count = 1; | 1866 | cs->retry_count = 1; |
1872 | #endif | ||
1873 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); | 1867 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); |
1874 | return; | 1868 | return; |
1875 | } | 1869 | } |
@@ -1897,7 +1891,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1897 | switch (atomic_read(&cs->mode)) { | 1891 | switch (atomic_read(&cs->mode)) { |
1898 | case M_UNIMODEM: | 1892 | case M_UNIMODEM: |
1899 | cs->at_state.pending_commands |= PC_CIDMODE; | 1893 | cs->at_state.pending_commands |= PC_CIDMODE; |
1900 | dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1894 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1901 | atomic_set(&cs->commands_pending, 1); | 1895 | atomic_set(&cs->commands_pending, 1); |
1902 | return; | 1896 | return; |
1903 | #ifdef GIG_MAYINITONDIAL | 1897 | #ifdef GIG_MAYINITONDIAL |
@@ -1926,18 +1920,21 @@ static void process_events(struct cardstate *cs) | |||
1926 | int i; | 1920 | int i; |
1927 | int check_flags = 0; | 1921 | int check_flags = 0; |
1928 | int was_busy; | 1922 | int was_busy; |
1923 | unsigned long flags; | ||
1929 | 1924 | ||
1930 | /* no locking needed (only one reader) */ | 1925 | spin_lock_irqsave(&cs->ev_lock, flags); |
1931 | head = atomic_read(&cs->ev_head); | 1926 | head = cs->ev_head; |
1932 | 1927 | ||
1933 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { | 1928 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { |
1934 | tail = atomic_read(&cs->ev_tail); | 1929 | tail = cs->ev_tail; |
1935 | if (tail == head) { | 1930 | if (tail == head) { |
1936 | if (!check_flags && !atomic_read(&cs->commands_pending)) | 1931 | if (!check_flags && !atomic_read(&cs->commands_pending)) |
1937 | break; | 1932 | break; |
1938 | check_flags = 0; | 1933 | check_flags = 0; |
1934 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1939 | process_command_flags(cs); | 1935 | process_command_flags(cs); |
1940 | tail = atomic_read(&cs->ev_tail); | 1936 | spin_lock_irqsave(&cs->ev_lock, flags); |
1937 | tail = cs->ev_tail; | ||
1941 | if (tail == head) { | 1938 | if (tail == head) { |
1942 | if (!atomic_read(&cs->commands_pending)) | 1939 | if (!atomic_read(&cs->commands_pending)) |
1943 | break; | 1940 | break; |
@@ -1947,18 +1944,23 @@ static void process_events(struct cardstate *cs) | |||
1947 | 1944 | ||
1948 | ev = cs->events + head; | 1945 | ev = cs->events + head; |
1949 | was_busy = cs->cur_at_seq != SEQ_NONE; | 1946 | was_busy = cs->cur_at_seq != SEQ_NONE; |
1947 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1950 | process_event(cs, ev); | 1948 | process_event(cs, ev); |
1949 | spin_lock_irqsave(&cs->ev_lock, flags); | ||
1951 | kfree(ev->ptr); | 1950 | kfree(ev->ptr); |
1952 | ev->ptr = NULL; | 1951 | ev->ptr = NULL; |
1953 | if (was_busy && cs->cur_at_seq == SEQ_NONE) | 1952 | if (was_busy && cs->cur_at_seq == SEQ_NONE) |
1954 | check_flags = 1; | 1953 | check_flags = 1; |
1955 | 1954 | ||
1956 | head = (head + 1) % MAX_EVENTS; | 1955 | head = (head + 1) % MAX_EVENTS; |
1957 | atomic_set(&cs->ev_head, head); | 1956 | cs->ev_head = head; |
1958 | } | 1957 | } |
1959 | 1958 | ||
1959 | spin_unlock_irqrestore(&cs->ev_lock, flags); | ||
1960 | |||
1960 | if (i == 2 * MAX_EVENTS) { | 1961 | if (i == 2 * MAX_EVENTS) { |
1961 | err("infinite loop in process_events; aborting."); | 1962 | dev_err(cs->dev, |
1963 | "infinite loop in process_events; aborting.\n"); | ||
1962 | } | 1964 | } |
1963 | } | 1965 | } |
1964 | 1966 | ||
@@ -1970,12 +1972,9 @@ void gigaset_handle_event(unsigned long data) | |||
1970 | { | 1972 | { |
1971 | struct cardstate *cs = (struct cardstate *) data; | 1973 | struct cardstate *cs = (struct cardstate *) data; |
1972 | 1974 | ||
1973 | IFNULLRET(cs); | ||
1974 | IFNULLRET(cs->inbuf); | ||
1975 | |||
1976 | /* handle incoming data on control/common channel */ | 1975 | /* handle incoming data on control/common channel */ |
1977 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { | 1976 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { |
1978 | dbg(DEBUG_INTR, "processing new data"); | 1977 | gig_dbg(DEBUG_INTR, "processing new data"); |
1979 | cs->ops->handle_input(cs->inbuf); | 1978 | cs->ops->handle_input(cs->inbuf); |
1980 | } | 1979 | } |
1981 | 1980 | ||