1 /* $Id: isdnl1.c,v 2.41 2000/11/24 17:05:37 kai Exp $
3 * isdnl1.c common low level stuff for Siemens Chipsetbased isdn cards
4 * based on the teles driver from Jan den Ouden
6 * Author Karsten Keil (keil@isdn4linux.de)
8 * This file is (c) under GNU PUBLIC LICENSE
9 * For changes and modifications please read
10 * ../../../Documentation/isdn/HiSax.cert
12 * Thanks to Jan den Ouden
18 const char *l1_revision
= "$Revision: 2.41 $";
20 #define __NO_VERSION__
21 #include <linux/init.h>
25 #define TIMER3_VALUE 7000
27 static struct Fsm l1fsm_b
;
28 static struct Fsm l1fsm_s
;
40 #define L1S_STATE_COUNT (ST_L1_F8+1)
42 static char *strL1SState
[] =
53 #ifdef HISAX_UINTERFACE
56 {NULL
, 0, 0, NULL
, NULL
};
65 #define L1U_STATE_COUNT (ST_L1_TRANS+1)
67 static char *strL1UState
[] =
83 #define L1B_STATE_COUNT (ST_L1_ACTIV+1)
85 static char *strL1BState
[] =
108 #define L1_EVENT_COUNT (EV_TIMER3 + 1)
110 static char *strL1Event
[] =
127 debugl1(struct IsdnCardState
*cs
, char *fmt
, ...)
133 sprintf(tmp
, "Card%d ", cs
->cardnr
+ 1);
134 VHiSax_putstatus(cs
, tmp
, fmt
, args
);
139 l1m_debug(struct FsmInst
*fi
, char *fmt
, ...)
142 struct PStack
*st
= fi
->userdata
;
143 struct IsdnCardState
*cs
= st
->l1
.hardware
;
147 sprintf(tmp
, "Card%d ", cs
->cardnr
+ 1);
148 VHiSax_putstatus(cs
, tmp
, fmt
, args
);
153 L1activated(struct IsdnCardState
*cs
)
159 if (test_and_clear_bit(FLG_L1_ACTIVATING
, &st
->l1
.Flags
))
160 st
->l1
.l1l2(st
, PH_ACTIVATE
| CONFIRM
, NULL
);
162 st
->l1
.l1l2(st
, PH_ACTIVATE
| INDICATION
, NULL
);
168 L1deactivated(struct IsdnCardState
*cs
)
174 if (test_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
))
175 st
->l1
.l1l2(st
, PH_PAUSE
| CONFIRM
, NULL
);
176 st
->l1
.l1l2(st
, PH_DEACTIVATE
| INDICATION
, NULL
);
179 test_and_clear_bit(FLG_L1_DBUSY
, &cs
->HW_Flags
);
183 DChannel_proc_xmt(struct IsdnCardState
*cs
)
185 struct PStack
*stptr
;
191 while (stptr
!= NULL
)
192 if (test_and_clear_bit(FLG_L1_PULL_REQ
, &stptr
->l1
.Flags
)) {
193 stptr
->l1
.l1l2(stptr
, PH_PULL
| CONFIRM
, NULL
);
200 DChannel_proc_rcv(struct IsdnCardState
*cs
)
202 struct sk_buff
*skb
, *nskb
;
203 struct PStack
*stptr
= cs
->stlist
;
204 int found
, tei
, sapi
;
207 if (test_bit(FLG_L1_ACTTIMER
, &stptr
->l1
.Flags
))
208 FsmEvent(&stptr
->l1
.l1m
, EV_TIMER_ACT
, NULL
);
209 while ((skb
= skb_dequeue(&cs
->rq
))) {
210 #ifdef L2FRAME_DEBUG /* psa */
211 if (cs
->debug
& L1_DEB_LAPD
)
212 Logl2Frame(cs
, skb
, "PH_DATA", 1);
216 debugl1(cs
, "D-channel frame too short(%d)",skb
->len
);
220 if ((skb
->data
[0] & 1) || !(skb
->data
[1] &1)) {
221 debugl1(cs
, "D-channel frame wrong EA0/EA1");
225 sapi
= skb
->data
[0] >> 2;
226 tei
= skb
->data
[1] >> 1;
227 if (cs
->debug
& DEB_DLOG_HEX
)
228 LogFrame(cs
, skb
->data
, skb
->len
);
229 if (cs
->debug
& DEB_DLOG_VERBOSE
)
230 dlogframe(cs
, skb
, 1);
231 if (tei
== GROUP_TEI
) {
232 if (sapi
== CTRL_SAPI
) { /* sapi 0 */
233 while (stptr
!= NULL
) {
234 if ((nskb
= skb_clone(skb
, GFP_ATOMIC
)))
235 stptr
->l1
.l1l2(stptr
, PH_DATA
| INDICATION
, nskb
);
237 printk(KERN_WARNING
"HiSax: isdn broadcast buffer shortage\n");
240 } else if (sapi
== TEI_SAPI
) {
241 while (stptr
!= NULL
) {
242 if ((nskb
= skb_clone(skb
, GFP_ATOMIC
)))
243 stptr
->l1
.l1tei(stptr
, PH_DATA
| INDICATION
, nskb
);
245 printk(KERN_WARNING
"HiSax: tei broadcast buffer shortage\n");
250 } else if (sapi
== CTRL_SAPI
) { /* sapi 0 */
252 while (stptr
!= NULL
)
253 if (tei
== stptr
->l2
.tei
) {
254 stptr
->l1
.l1l2(stptr
, PH_DATA
| INDICATION
, skb
);
267 BChannel_proc_xmt(struct BCState
*bcs
)
269 struct PStack
*st
= bcs
->st
;
271 if (test_bit(BC_FLG_BUSY
, &bcs
->Flag
)) {
272 debugl1(bcs
->cs
, "BC_BUSY Error");
276 if (test_and_clear_bit(FLG_L1_PULL_REQ
, &st
->l1
.Flags
))
277 st
->l1
.l1l2(st
, PH_PULL
| CONFIRM
, NULL
);
278 if (!test_bit(BC_FLG_ACTIV
, &bcs
->Flag
)) {
279 if (!test_bit(BC_FLG_BUSY
, &bcs
->Flag
) && (!skb_queue_len(&bcs
->squeue
))) {
280 st
->l2
.l2l1(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
286 BChannel_proc_rcv(struct BCState
*bcs
)
290 if (bcs
->st
->l1
.l1m
.state
== ST_L1_WAIT_ACT
) {
291 FsmDelTimer(&bcs
->st
->l1
.timer
, 4);
292 FsmEvent(&bcs
->st
->l1
.l1m
, EV_TIMER_ACT
, NULL
);
294 while ((skb
= skb_dequeue(&bcs
->rqueue
))) {
295 bcs
->st
->l1
.l1l2(bcs
->st
, PH_DATA
| INDICATION
, skb
);
300 BChannel_bh(struct BCState
*bcs
)
304 if (test_and_clear_bit(B_RCVBUFREADY
, &bcs
->event
))
305 BChannel_proc_rcv(bcs
);
306 if (test_and_clear_bit(B_XMTBUFREADY
, &bcs
->event
))
307 BChannel_proc_xmt(bcs
);
311 HiSax_addlist(struct IsdnCardState
*cs
,
314 st
->next
= cs
->stlist
;
319 HiSax_rmlist(struct IsdnCardState
*cs
,
324 FsmDelTimer(&st
->l1
.timer
, 0);
325 if (cs
->stlist
== st
)
326 cs
->stlist
= st
->next
;
339 init_bcstate(struct IsdnCardState
*cs
,
342 struct BCState
*bcs
= cs
->bcs
+ bc
;
346 INIT_LIST_HEAD(&bcs
->tqueue
.list
);
347 bcs
->tqueue
.sync
= 0;
348 bcs
->tqueue
.routine
= (void *) (void *) BChannel_bh
;
349 bcs
->tqueue
.data
= bcs
;
350 bcs
->BC_SetStack
= NULL
;
351 bcs
->BC_Close
= NULL
;
355 #ifdef L2FRAME_DEBUG /* psa */
360 switch (cmd
& ~0x10) {
385 return "invalid command";
389 static char tmpdeb
[32];
392 l2frames(u_char
* ptr
)
394 switch (ptr
[2] & ~0x10) {
398 sprintf(tmpdeb
, "%s[%d](nr %d)", l2cmd(ptr
[2]), ptr
[3] & 1, ptr
[3] >> 1);
407 sprintf(tmpdeb
, "%s[%d]", l2cmd(ptr
[2]), (ptr
[2] & 0x10) >> 4);
411 sprintf(tmpdeb
, "I[%d](ns %d, nr %d)", ptr
[3] & 1, ptr
[2] >> 1, ptr
[3] >> 1);
414 return "invalid command";
422 Logl2Frame(struct IsdnCardState
*cs
, struct sk_buff
*skb
, char *buf
, int dir
)
428 if (ptr
[0] & 1 || !(ptr
[1] & 1))
429 debugl1(cs
, "Address not LAPD");
431 debugl1(cs
, "%s %s: %s%c (sapi %d, tei %d)",
432 (dir
? "<-" : "->"), buf
, l2frames(ptr
),
433 ((ptr
[0] & 2) >> 1) == dir
? 'C' : 'R', ptr
[0] >> 2, ptr
[1] >> 1);
438 l1_reset(struct FsmInst
*fi
, int event
, void *arg
)
440 FsmChangeState(fi
, ST_L1_F3
);
444 l1_deact_cnf(struct FsmInst
*fi
, int event
, void *arg
)
446 struct PStack
*st
= fi
->userdata
;
448 FsmChangeState(fi
, ST_L1_F3
);
449 if (test_bit(FLG_L1_ACTIVATING
, &st
->l1
.Flags
))
450 st
->l1
.l1hw(st
, HW_ENABLE
| REQUEST
, NULL
);
454 l1_deact_req_s(struct FsmInst
*fi
, int event
, void *arg
)
456 struct PStack
*st
= fi
->userdata
;
458 FsmChangeState(fi
, ST_L1_F3
);
459 FsmRestartTimer(&st
->l1
.timer
, 550, EV_TIMER_DEACT
, NULL
, 2);
460 test_and_set_bit(FLG_L1_DEACTTIMER
, &st
->l1
.Flags
);
464 l1_power_up_s(struct FsmInst
*fi
, int event
, void *arg
)
466 struct PStack
*st
= fi
->userdata
;
468 if (test_bit(FLG_L1_ACTIVATING
, &st
->l1
.Flags
)) {
469 FsmChangeState(fi
, ST_L1_F4
);
470 st
->l1
.l1hw(st
, HW_INFO3
| REQUEST
, NULL
);
471 FsmRestartTimer(&st
->l1
.timer
, TIMER3_VALUE
, EV_TIMER3
, NULL
, 2);
472 test_and_set_bit(FLG_L1_T3RUN
, &st
->l1
.Flags
);
474 FsmChangeState(fi
, ST_L1_F3
);
478 l1_go_F5(struct FsmInst
*fi
, int event
, void *arg
)
480 FsmChangeState(fi
, ST_L1_F5
);
484 l1_go_F8(struct FsmInst
*fi
, int event
, void *arg
)
486 FsmChangeState(fi
, ST_L1_F8
);
490 l1_info2_ind(struct FsmInst
*fi
, int event
, void *arg
)
492 struct PStack
*st
= fi
->userdata
;
494 #ifdef HISAX_UINTERFACE
495 if (test_bit(FLG_L1_UINT
, &st
->l1
.Flags
))
496 FsmChangeState(fi
, ST_L1_SYNC2
);
499 FsmChangeState(fi
, ST_L1_F6
);
500 st
->l1
.l1hw(st
, HW_INFO3
| REQUEST
, NULL
);
504 l1_info4_ind(struct FsmInst
*fi
, int event
, void *arg
)
506 struct PStack
*st
= fi
->userdata
;
508 #ifdef HISAX_UINTERFACE
509 if (test_bit(FLG_L1_UINT
, &st
->l1
.Flags
))
510 FsmChangeState(fi
, ST_L1_TRANS
);
513 FsmChangeState(fi
, ST_L1_F7
);
514 st
->l1
.l1hw(st
, HW_INFO3
| REQUEST
, NULL
);
515 if (test_and_clear_bit(FLG_L1_DEACTTIMER
, &st
->l1
.Flags
))
516 FsmDelTimer(&st
->l1
.timer
, 4);
517 if (!test_bit(FLG_L1_ACTIVATED
, &st
->l1
.Flags
)) {
518 if (test_and_clear_bit(FLG_L1_T3RUN
, &st
->l1
.Flags
))
519 FsmDelTimer(&st
->l1
.timer
, 3);
520 FsmRestartTimer(&st
->l1
.timer
, 110, EV_TIMER_ACT
, NULL
, 2);
521 test_and_set_bit(FLG_L1_ACTTIMER
, &st
->l1
.Flags
);
526 l1_timer3(struct FsmInst
*fi
, int event
, void *arg
)
528 struct PStack
*st
= fi
->userdata
;
530 test_and_clear_bit(FLG_L1_T3RUN
, &st
->l1
.Flags
);
531 if (test_and_clear_bit(FLG_L1_ACTIVATING
, &st
->l1
.Flags
))
532 L1deactivated(st
->l1
.hardware
);
534 #ifdef HISAX_UINTERFACE
535 if (!test_bit(FLG_L1_UINT
, &st
->l1
.Flags
))
537 if (st
->l1
.l1m
.state
!= ST_L1_F6
) {
538 FsmChangeState(fi
, ST_L1_F3
);
539 st
->l1
.l1hw(st
, HW_ENABLE
| REQUEST
, NULL
);
544 l1_timer_act(struct FsmInst
*fi
, int event
, void *arg
)
546 struct PStack
*st
= fi
->userdata
;
548 test_and_clear_bit(FLG_L1_ACTTIMER
, &st
->l1
.Flags
);
549 test_and_set_bit(FLG_L1_ACTIVATED
, &st
->l1
.Flags
);
550 L1activated(st
->l1
.hardware
);
554 l1_timer_deact(struct FsmInst
*fi
, int event
, void *arg
)
556 struct PStack
*st
= fi
->userdata
;
558 test_and_clear_bit(FLG_L1_DEACTTIMER
, &st
->l1
.Flags
);
559 test_and_clear_bit(FLG_L1_ACTIVATED
, &st
->l1
.Flags
);
560 L1deactivated(st
->l1
.hardware
);
561 st
->l1
.l1hw(st
, HW_DEACTIVATE
| RESPONSE
, NULL
);
565 l1_activate_s(struct FsmInst
*fi
, int event
, void *arg
)
567 struct PStack
*st
= fi
->userdata
;
569 st
->l1
.l1hw(st
, HW_RESET
| REQUEST
, NULL
);
573 l1_activate_no(struct FsmInst
*fi
, int event
, void *arg
)
575 struct PStack
*st
= fi
->userdata
;
577 if ((!test_bit(FLG_L1_DEACTTIMER
, &st
->l1
.Flags
)) && (!test_bit(FLG_L1_T3RUN
, &st
->l1
.Flags
))) {
578 test_and_clear_bit(FLG_L1_ACTIVATING
, &st
->l1
.Flags
);
579 L1deactivated(st
->l1
.hardware
);
583 static struct FsmNode L1SFnList
[] __initdata
=
585 {ST_L1_F3
, EV_PH_ACTIVATE
, l1_activate_s
},
586 {ST_L1_F6
, EV_PH_ACTIVATE
, l1_activate_no
},
587 {ST_L1_F8
, EV_PH_ACTIVATE
, l1_activate_no
},
588 {ST_L1_F3
, EV_RESET_IND
, l1_reset
},
589 {ST_L1_F4
, EV_RESET_IND
, l1_reset
},
590 {ST_L1_F5
, EV_RESET_IND
, l1_reset
},
591 {ST_L1_F6
, EV_RESET_IND
, l1_reset
},
592 {ST_L1_F7
, EV_RESET_IND
, l1_reset
},
593 {ST_L1_F8
, EV_RESET_IND
, l1_reset
},
594 {ST_L1_F3
, EV_DEACT_CNF
, l1_deact_cnf
},
595 {ST_L1_F4
, EV_DEACT_CNF
, l1_deact_cnf
},
596 {ST_L1_F5
, EV_DEACT_CNF
, l1_deact_cnf
},
597 {ST_L1_F6
, EV_DEACT_CNF
, l1_deact_cnf
},
598 {ST_L1_F7
, EV_DEACT_CNF
, l1_deact_cnf
},
599 {ST_L1_F8
, EV_DEACT_CNF
, l1_deact_cnf
},
600 {ST_L1_F6
, EV_DEACT_IND
, l1_deact_req_s
},
601 {ST_L1_F7
, EV_DEACT_IND
, l1_deact_req_s
},
602 {ST_L1_F8
, EV_DEACT_IND
, l1_deact_req_s
},
603 {ST_L1_F3
, EV_POWER_UP
, l1_power_up_s
},
604 {ST_L1_F4
, EV_RSYNC_IND
, l1_go_F5
},
605 {ST_L1_F6
, EV_RSYNC_IND
, l1_go_F8
},
606 {ST_L1_F7
, EV_RSYNC_IND
, l1_go_F8
},
607 {ST_L1_F3
, EV_INFO2_IND
, l1_info2_ind
},
608 {ST_L1_F4
, EV_INFO2_IND
, l1_info2_ind
},
609 {ST_L1_F5
, EV_INFO2_IND
, l1_info2_ind
},
610 {ST_L1_F7
, EV_INFO2_IND
, l1_info2_ind
},
611 {ST_L1_F8
, EV_INFO2_IND
, l1_info2_ind
},
612 {ST_L1_F3
, EV_INFO4_IND
, l1_info4_ind
},
613 {ST_L1_F4
, EV_INFO4_IND
, l1_info4_ind
},
614 {ST_L1_F5
, EV_INFO4_IND
, l1_info4_ind
},
615 {ST_L1_F6
, EV_INFO4_IND
, l1_info4_ind
},
616 {ST_L1_F8
, EV_INFO4_IND
, l1_info4_ind
},
617 {ST_L1_F3
, EV_TIMER3
, l1_timer3
},
618 {ST_L1_F4
, EV_TIMER3
, l1_timer3
},
619 {ST_L1_F5
, EV_TIMER3
, l1_timer3
},
620 {ST_L1_F6
, EV_TIMER3
, l1_timer3
},
621 {ST_L1_F8
, EV_TIMER3
, l1_timer3
},
622 {ST_L1_F7
, EV_TIMER_ACT
, l1_timer_act
},
623 {ST_L1_F3
, EV_TIMER_DEACT
, l1_timer_deact
},
624 {ST_L1_F4
, EV_TIMER_DEACT
, l1_timer_deact
},
625 {ST_L1_F5
, EV_TIMER_DEACT
, l1_timer_deact
},
626 {ST_L1_F6
, EV_TIMER_DEACT
, l1_timer_deact
},
627 {ST_L1_F7
, EV_TIMER_DEACT
, l1_timer_deact
},
628 {ST_L1_F8
, EV_TIMER_DEACT
, l1_timer_deact
},
631 #define L1S_FN_COUNT (sizeof(L1SFnList)/sizeof(struct FsmNode))
633 #ifdef HISAX_UINTERFACE
635 l1_deact_req_u(struct FsmInst
*fi
, int event
, void *arg
)
637 struct PStack
*st
= fi
->userdata
;
639 FsmChangeState(fi
, ST_L1_RESET
);
640 FsmRestartTimer(&st
->l1
.timer
, 550, EV_TIMER_DEACT
, NULL
, 2);
641 test_and_set_bit(FLG_L1_DEACTTIMER
, &st
->l1
.Flags
);
642 st
->l1
.l1hw(st
, HW_ENABLE
| REQUEST
, NULL
);
646 l1_power_up_u(struct FsmInst
*fi
, int event
, void *arg
)
648 struct PStack
*st
= fi
->userdata
;
650 FsmRestartTimer(&st
->l1
.timer
, TIMER3_VALUE
, EV_TIMER3
, NULL
, 2);
651 test_and_set_bit(FLG_L1_T3RUN
, &st
->l1
.Flags
);
655 l1_info0_ind(struct FsmInst
*fi
, int event
, void *arg
)
657 FsmChangeState(fi
, ST_L1_DEACT
);
661 l1_activate_u(struct FsmInst
*fi
, int event
, void *arg
)
663 struct PStack
*st
= fi
->userdata
;
665 st
->l1
.l1hw(st
, HW_INFO1
| REQUEST
, NULL
);
668 static struct FsmNode L1UFnList
[] __initdata
=
670 {ST_L1_RESET
, EV_DEACT_IND
, l1_deact_req_u
},
671 {ST_L1_DEACT
, EV_DEACT_IND
, l1_deact_req_u
},
672 {ST_L1_SYNC2
, EV_DEACT_IND
, l1_deact_req_u
},
673 {ST_L1_TRANS
, EV_DEACT_IND
, l1_deact_req_u
},
674 {ST_L1_DEACT
, EV_PH_ACTIVATE
, l1_activate_u
},
675 {ST_L1_DEACT
, EV_POWER_UP
, l1_power_up_u
},
676 {ST_L1_DEACT
, EV_INFO2_IND
, l1_info2_ind
},
677 {ST_L1_TRANS
, EV_INFO2_IND
, l1_info2_ind
},
678 {ST_L1_RESET
, EV_DEACT_CNF
, l1_info0_ind
},
679 {ST_L1_DEACT
, EV_INFO4_IND
, l1_info4_ind
},
680 {ST_L1_SYNC2
, EV_INFO4_IND
, l1_info4_ind
},
681 {ST_L1_RESET
, EV_INFO4_IND
, l1_info4_ind
},
682 {ST_L1_DEACT
, EV_TIMER3
, l1_timer3
},
683 {ST_L1_SYNC2
, EV_TIMER3
, l1_timer3
},
684 {ST_L1_TRANS
, EV_TIMER_ACT
, l1_timer_act
},
685 {ST_L1_DEACT
, EV_TIMER_DEACT
, l1_timer_deact
},
686 {ST_L1_SYNC2
, EV_TIMER_DEACT
, l1_timer_deact
},
687 {ST_L1_RESET
, EV_TIMER_DEACT
, l1_timer_deact
},
690 #define L1U_FN_COUNT (sizeof(L1UFnList)/sizeof(struct FsmNode))
695 l1b_activate(struct FsmInst
*fi
, int event
, void *arg
)
697 struct PStack
*st
= fi
->userdata
;
699 FsmChangeState(fi
, ST_L1_WAIT_ACT
);
700 FsmRestartTimer(&st
->l1
.timer
, st
->l1
.delay
, EV_TIMER_ACT
, NULL
, 2);
704 l1b_deactivate(struct FsmInst
*fi
, int event
, void *arg
)
706 struct PStack
*st
= fi
->userdata
;
708 FsmChangeState(fi
, ST_L1_WAIT_DEACT
);
709 FsmRestartTimer(&st
->l1
.timer
, 10, EV_TIMER_DEACT
, NULL
, 2);
713 l1b_timer_act(struct FsmInst
*fi
, int event
, void *arg
)
715 struct PStack
*st
= fi
->userdata
;
717 FsmChangeState(fi
, ST_L1_ACTIV
);
718 st
->l1
.l1l2(st
, PH_ACTIVATE
| CONFIRM
, NULL
);
722 l1b_timer_deact(struct FsmInst
*fi
, int event
, void *arg
)
724 struct PStack
*st
= fi
->userdata
;
726 FsmChangeState(fi
, ST_L1_NULL
);
727 st
->l2
.l2l1(st
, PH_DEACTIVATE
| CONFIRM
, NULL
);
730 static struct FsmNode L1BFnList
[] __initdata
=
732 {ST_L1_NULL
, EV_PH_ACTIVATE
, l1b_activate
},
733 {ST_L1_WAIT_ACT
, EV_TIMER_ACT
, l1b_timer_act
},
734 {ST_L1_ACTIV
, EV_PH_DEACTIVATE
, l1b_deactivate
},
735 {ST_L1_WAIT_DEACT
, EV_TIMER_DEACT
, l1b_timer_deact
},
738 #define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
743 #ifdef HISAX_UINTERFACE
744 l1fsm_u
.state_count
= L1U_STATE_COUNT
;
745 l1fsm_u
.event_count
= L1_EVENT_COUNT
;
746 l1fsm_u
.strEvent
= strL1Event
;
747 l1fsm_u
.strState
= strL1UState
;
748 FsmNew(&l1fsm_u
, L1UFnList
, L1U_FN_COUNT
);
750 l1fsm_s
.state_count
= L1S_STATE_COUNT
;
751 l1fsm_s
.event_count
= L1_EVENT_COUNT
;
752 l1fsm_s
.strEvent
= strL1Event
;
753 l1fsm_s
.strState
= strL1SState
;
754 FsmNew(&l1fsm_s
, L1SFnList
, L1S_FN_COUNT
);
755 l1fsm_b
.state_count
= L1B_STATE_COUNT
;
756 l1fsm_b
.event_count
= L1_EVENT_COUNT
;
757 l1fsm_b
.strEvent
= strL1Event
;
758 l1fsm_b
.strState
= strL1BState
;
759 FsmNew(&l1fsm_b
, L1BFnList
, L1B_FN_COUNT
);
762 void Isdnl1Free(void)
764 #ifdef HISAX_UINTERFACE
772 dch_l2l1(struct PStack
*st
, int pr
, void *arg
)
774 struct IsdnCardState
*cs
= (struct IsdnCardState
*) st
->l1
.hardware
;
777 case (PH_DATA
| REQUEST
):
778 case (PH_PULL
| REQUEST
):
779 case (PH_PULL
|INDICATION
):
780 st
->l1
.l1hw(st
, pr
, arg
);
782 case (PH_ACTIVATE
| REQUEST
):
784 debugl1(cs
, "PH_ACTIVATE_REQ %s",
785 st
->l1
.l1m
.fsm
->strState
[st
->l1
.l1m
.state
]);
786 if (test_bit(FLG_L1_ACTIVATED
, &st
->l1
.Flags
))
787 st
->l1
.l1l2(st
, PH_ACTIVATE
| CONFIRM
, NULL
);
789 test_and_set_bit(FLG_L1_ACTIVATING
, &st
->l1
.Flags
);
790 FsmEvent(&st
->l1
.l1m
, EV_PH_ACTIVATE
, arg
);
793 case (PH_TESTLOOP
| REQUEST
):
795 debugl1(cs
, "PH_TEST_LOOP B1");
797 debugl1(cs
, "PH_TEST_LOOP B2");
798 if (!(3 & (long) arg
))
799 debugl1(cs
, "PH_TEST_LOOP DISABLED");
800 st
->l1
.l1hw(st
, HW_TESTLOOP
| REQUEST
, arg
);
804 debugl1(cs
, "dch_l2l1 msg %04X unhandled", pr
);
810 l1_msg(struct IsdnCardState
*cs
, int pr
, void *arg
) {
817 case (HW_RESET
| INDICATION
):
818 FsmEvent(&st
->l1
.l1m
, EV_RESET_IND
, arg
);
820 case (HW_DEACTIVATE
| CONFIRM
):
821 FsmEvent(&st
->l1
.l1m
, EV_DEACT_CNF
, arg
);
823 case (HW_DEACTIVATE
| INDICATION
):
824 FsmEvent(&st
->l1
.l1m
, EV_DEACT_IND
, arg
);
826 case (HW_POWERUP
| CONFIRM
):
827 FsmEvent(&st
->l1
.l1m
, EV_POWER_UP
, arg
);
829 case (HW_RSYNC
| INDICATION
):
830 FsmEvent(&st
->l1
.l1m
, EV_RSYNC_IND
, arg
);
832 case (HW_INFO2
| INDICATION
):
833 FsmEvent(&st
->l1
.l1m
, EV_INFO2_IND
, arg
);
835 case (HW_INFO4_P8
| INDICATION
):
836 case (HW_INFO4_P10
| INDICATION
):
837 FsmEvent(&st
->l1
.l1m
, EV_INFO4_IND
, arg
);
841 debugl1(cs
, "l1msg %04X unhandled", pr
);
849 l1_msg_b(struct PStack
*st
, int pr
, void *arg
) {
851 case (PH_ACTIVATE
| REQUEST
):
852 FsmEvent(&st
->l1
.l1m
, EV_PH_ACTIVATE
, NULL
);
854 case (PH_DEACTIVATE
| REQUEST
):
855 FsmEvent(&st
->l1
.l1m
, EV_PH_DEACTIVATE
, NULL
);
861 setstack_HiSax(struct PStack
*st
, struct IsdnCardState
*cs
)
863 st
->l1
.hardware
= cs
;
864 st
->protocol
= cs
->protocol
;
865 st
->l1
.l1m
.fsm
= &l1fsm_s
;
866 st
->l1
.l1m
.state
= ST_L1_F3
;
868 #ifdef HISAX_UINTERFACE
869 if (test_bit(FLG_HW_L1_UINT
, &cs
->HW_Flags
)) {
870 st
->l1
.l1m
.fsm
= &l1fsm_u
;
871 st
->l1
.l1m
.state
= ST_L1_RESET
;
872 st
->l1
.Flags
= FLG_L1_UINT
;
875 st
->l1
.l1m
.debug
= cs
->debug
;
876 st
->l1
.l1m
.userdata
= st
;
877 st
->l1
.l1m
.userint
= 0;
878 st
->l1
.l1m
.printdebug
= l1m_debug
;
879 FsmInitTimer(&st
->l1
.l1m
, &st
->l1
.timer
);
881 setstack_manager(st
);
882 st
->l1
.stlistp
= &(cs
->stlist
);
883 st
->l2
.l2l1
= dch_l2l1
;
884 cs
->setstack_d(st
, cs
);
888 setstack_l1_B(struct PStack
*st
)
890 struct IsdnCardState
*cs
= st
->l1
.hardware
;
892 st
->l1
.l1m
.fsm
= &l1fsm_b
;
893 st
->l1
.l1m
.state
= ST_L1_NULL
;
894 st
->l1
.l1m
.debug
= cs
->debug
;
895 st
->l1
.l1m
.userdata
= st
;
896 st
->l1
.l1m
.userint
= 0;
897 st
->l1
.l1m
.printdebug
= l1m_debug
;
899 FsmInitTimer(&st
->l1
.l1m
, &st
->l1
.timer
);