aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKarsten Keil <isdn@linux-pingi.de>2012-05-04 00:15:34 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-04 11:55:39 -0400
commit1ea52fbda1629216182a0b0fbee9d65e8bcedd1e (patch)
tree798dcc87b7ac3c8683fa73e6eb06ee0c5f8c7e77 /drivers
parentc626c127279b265ab293348763e043864d58d42c (diff)
mISDN: Layer1 statemachine fix
The timer3 and the activation delay timer need to be independent. If timer3 fires do not reqest power up we have to send only INFO 0. Now layer1 pass TBR3 again. Signed-off-by: Karsten Keil <kkeil@linux-pingi.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/isdn/mISDN/layer1.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index ff0515323c8..bebc57b7213 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -28,7 +28,8 @@ 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;
33 int t3_value; 34 int t3_value;
34 struct dchannel *dch; 35 struct dchannel *dch;
@@ -135,7 +136,7 @@ l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
135 struct layer1 *l1 = fi->userdata; 136 struct layer1 *l1 = fi->userdata;
136 137
137 mISDN_FsmChangeState(fi, ST_L1_F3); 138 mISDN_FsmChangeState(fi, ST_L1_F3);
138 mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2); 139 mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2);
139 test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 140 test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags);
140} 141}
141 142
@@ -180,11 +181,11 @@ l1_info4_ind(struct FsmInst *fi, int event, void *arg)
180 mISDN_FsmChangeState(fi, ST_L1_F7); 181 mISDN_FsmChangeState(fi, ST_L1_F7);
181 l1->dcb(l1->dch, INFO3_P8); 182 l1->dcb(l1->dch, INFO3_P8);
182 if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 183 if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags))
183 mISDN_FsmDelTimer(&l1->timer, 4); 184 mISDN_FsmDelTimer(&l1->timerX, 4);
184 if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 185 if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) {
185 if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 186 if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags))
186 mISDN_FsmDelTimer(&l1->timer, 3); 187 mISDN_FsmDelTimer(&l1->timer3, 3);
187 mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2); 188 mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2);
188 test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 189 test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags);
189 } 190 }
190} 191}
@@ -202,7 +203,7 @@ l1_timer3(struct FsmInst *fi, int event, void *arg)
202 } 203 }
203 if (l1->l1m.state != ST_L1_F6) { 204 if (l1->l1m.state != ST_L1_F6) {
204 mISDN_FsmChangeState(fi, ST_L1_F3); 205 mISDN_FsmChangeState(fi, ST_L1_F3);
205 l1->dcb(l1->dch, HW_POWERUP_REQ); 206 /* do not force anything here, we need send INFO 0 */
206 } 207 }
207} 208}
208 209
@@ -234,8 +235,9 @@ l1_activate_s(struct FsmInst *fi, int event, void *arg)
234{ 235{
235 struct layer1 *l1 = fi->userdata; 236 struct layer1 *l1 = fi->userdata;
236 237
237 mISDN_FsmRestartTimer(&l1->timer, l1->t3_value, EV_TIMER3, NULL, 2); 238 mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2);
238 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 */
239 l1->dcb(l1->dch, HW_RESET_REQ); 241 l1->dcb(l1->dch, HW_RESET_REQ);
240} 242}
241 243
@@ -303,7 +305,8 @@ static struct FsmNode L1SFnList[] =
303 305
304static void 306static void
305release_l1(struct layer1 *l1) { 307release_l1(struct layer1 *l1) {
306 mISDN_FsmDelTimer(&l1->timer, 0); 308 mISDN_FsmDelTimer(&l1->timerX, 0);
309 mISDN_FsmDelTimer(&l1->timer3, 0);
307 if (l1->dch) 310 if (l1->dch)
308 l1->dch->l1 = NULL; 311 l1->dch->l1 = NULL;
309 module_put(THIS_MODULE); 312 module_put(THIS_MODULE);
@@ -395,7 +398,8 @@ create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
395 nl1->l1m.printdebug = l1m_debug; 398 nl1->l1m.printdebug = l1m_debug;
396 nl1->dch = dch; 399 nl1->dch = dch;
397 nl1->dcb = dcb; 400 nl1->dcb = dcb;
398 mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); 401 mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3);
402 mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX);
399 __module_get(THIS_MODULE); 403 __module_get(THIS_MODULE);
400 dch->l1 = nl1; 404 dch->l1 = nl1;
401 return 0; 405 return 0;