diff options
Diffstat (limited to 'drivers/isdn/mISDN/layer1.c')
-rw-r--r-- | drivers/isdn/mISDN/layer1.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c index 0fc49b375514..bebc57b72138 100644 --- a/drivers/isdn/mISDN/layer1.c +++ b/drivers/isdn/mISDN/layer1.c | |||
@@ -28,13 +28,15 @@ static u_int *debug; | |||
28 | struct layer1 { | 28 | struct layer1 { |
29 | u_long Flags; | 29 | u_long Flags; |
30 | struct FsmInst l1m; | 30 | struct FsmInst l1m; |
31 | struct FsmTimer timer; | 31 | struct FsmTimer timer3; |
32 | struct FsmTimer timerX; | ||
32 | int delay; | 33 | int delay; |
34 | int t3_value; | ||
33 | struct dchannel *dch; | 35 | struct dchannel *dch; |
34 | dchannel_l1callback *dcb; | 36 | dchannel_l1callback *dcb; |
35 | }; | 37 | }; |
36 | 38 | ||
37 | #define TIMER3_VALUE 7000 | 39 | #define TIMER3_DEFAULT_VALUE 7000 |
38 | 40 | ||
39 | static | 41 | static |
40 | struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; | 42 | struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; |
@@ -134,7 +136,7 @@ l1_deact_req_s(struct FsmInst *fi, int event, void *arg) | |||
134 | struct layer1 *l1 = fi->userdata; | 136 | struct layer1 *l1 = fi->userdata; |
135 | 137 | ||
136 | mISDN_FsmChangeState(fi, ST_L1_F3); | 138 | mISDN_FsmChangeState(fi, ST_L1_F3); |
137 | mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2); | 139 | mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2); |
138 | test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); | 140 | test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); |
139 | } | 141 | } |
140 | 142 | ||
@@ -179,11 +181,11 @@ l1_info4_ind(struct FsmInst *fi, int event, void *arg) | |||
179 | mISDN_FsmChangeState(fi, ST_L1_F7); | 181 | mISDN_FsmChangeState(fi, ST_L1_F7); |
180 | l1->dcb(l1->dch, INFO3_P8); | 182 | l1->dcb(l1->dch, INFO3_P8); |
181 | if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) | 183 | if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) |
182 | mISDN_FsmDelTimer(&l1->timer, 4); | 184 | mISDN_FsmDelTimer(&l1->timerX, 4); |
183 | if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { | 185 | if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { |
184 | if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) | 186 | if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) |
185 | mISDN_FsmDelTimer(&l1->timer, 3); | 187 | mISDN_FsmDelTimer(&l1->timer3, 3); |
186 | mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2); | 188 | mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2); |
187 | test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); | 189 | test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); |
188 | } | 190 | } |
189 | } | 191 | } |
@@ -201,7 +203,7 @@ l1_timer3(struct FsmInst *fi, int event, void *arg) | |||
201 | } | 203 | } |
202 | if (l1->l1m.state != ST_L1_F6) { | 204 | if (l1->l1m.state != ST_L1_F6) { |
203 | mISDN_FsmChangeState(fi, ST_L1_F3); | 205 | mISDN_FsmChangeState(fi, ST_L1_F3); |
204 | l1->dcb(l1->dch, HW_POWERUP_REQ); | 206 | /* do not force anything here, we need send INFO 0 */ |
205 | } | 207 | } |
206 | } | 208 | } |
207 | 209 | ||
@@ -233,8 +235,9 @@ l1_activate_s(struct FsmInst *fi, int event, void *arg) | |||
233 | { | 235 | { |
234 | struct layer1 *l1 = fi->userdata; | 236 | struct layer1 *l1 = fi->userdata; |
235 | 237 | ||
236 | mISDN_FsmRestartTimer(&l1->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); | 238 | mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2); |
237 | test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); | 239 | test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); |
240 | /* Tell HW to send INFO 1 */ | ||
238 | l1->dcb(l1->dch, HW_RESET_REQ); | 241 | l1->dcb(l1->dch, HW_RESET_REQ); |
239 | } | 242 | } |
240 | 243 | ||
@@ -302,7 +305,8 @@ static struct FsmNode L1SFnList[] = | |||
302 | 305 | ||
303 | static void | 306 | static void |
304 | release_l1(struct layer1 *l1) { | 307 | release_l1(struct layer1 *l1) { |
305 | mISDN_FsmDelTimer(&l1->timer, 0); | 308 | mISDN_FsmDelTimer(&l1->timerX, 0); |
309 | mISDN_FsmDelTimer(&l1->timer3, 0); | ||
306 | if (l1->dch) | 310 | if (l1->dch) |
307 | l1->dch->l1 = NULL; | 311 | l1->dch->l1 = NULL; |
308 | module_put(THIS_MODULE); | 312 | module_put(THIS_MODULE); |
@@ -356,6 +360,16 @@ l1_event(struct layer1 *l1, u_int event) | |||
356 | release_l1(l1); | 360 | release_l1(l1); |
357 | break; | 361 | break; |
358 | default: | 362 | default: |
363 | if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { | ||
364 | int val = event & HW_TIMER3_VMASK; | ||
365 | |||
366 | if (val < 5) | ||
367 | val = 5; | ||
368 | if (val > 30) | ||
369 | val = 30; | ||
370 | l1->t3_value = val; | ||
371 | break; | ||
372 | } | ||
359 | if (*debug & DEBUG_L1) | 373 | if (*debug & DEBUG_L1) |
360 | printk(KERN_DEBUG "%s %x unhandled\n", | 374 | printk(KERN_DEBUG "%s %x unhandled\n", |
361 | __func__, event); | 375 | __func__, event); |
@@ -377,13 +391,15 @@ create_l1(struct dchannel *dch, dchannel_l1callback *dcb) { | |||
377 | nl1->l1m.fsm = &l1fsm_s; | 391 | nl1->l1m.fsm = &l1fsm_s; |
378 | nl1->l1m.state = ST_L1_F3; | 392 | nl1->l1m.state = ST_L1_F3; |
379 | nl1->Flags = 0; | 393 | nl1->Flags = 0; |
394 | nl1->t3_value = TIMER3_DEFAULT_VALUE; | ||
380 | nl1->l1m.debug = *debug & DEBUG_L1_FSM; | 395 | nl1->l1m.debug = *debug & DEBUG_L1_FSM; |
381 | nl1->l1m.userdata = nl1; | 396 | nl1->l1m.userdata = nl1; |
382 | nl1->l1m.userint = 0; | 397 | nl1->l1m.userint = 0; |
383 | nl1->l1m.printdebug = l1m_debug; | 398 | nl1->l1m.printdebug = l1m_debug; |
384 | nl1->dch = dch; | 399 | nl1->dch = dch; |
385 | nl1->dcb = dcb; | 400 | nl1->dcb = dcb; |
386 | mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); | 401 | mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3); |
402 | mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX); | ||
387 | __module_get(THIS_MODULE); | 403 | __module_get(THIS_MODULE); |
388 | dch->l1 = nl1; | 404 | dch->l1 = nl1; |
389 | return 0; | 405 | return 0; |