aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN/layer1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/layer1.c')
-rw-r--r--drivers/isdn/mISDN/layer1.c36
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;
28struct layer1 { 28struct 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
39static 41static
40struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 42struct 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
303static void 306static void
304release_l1(struct layer1 *l1) { 307release_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;