- David Miller: sparc and net updates. Fix merge_segments.
[davej-history.git] / drivers / isdn / hisax / isdnl1.c
blobcda9e422c7349d15d21f2753265a6d6200f015c9
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
13 * Fritz Elfert
14 * Beat Doebeli
18 const char *l1_revision = "$Revision: 2.41 $";
20 #define __NO_VERSION__
21 #include <linux/init.h>
22 #include "hisax.h"
23 #include "isdnl1.h"
25 #define TIMER3_VALUE 7000
27 static struct Fsm l1fsm_b;
28 static struct Fsm l1fsm_s;
30 enum {
31 ST_L1_F2,
32 ST_L1_F3,
33 ST_L1_F4,
34 ST_L1_F5,
35 ST_L1_F6,
36 ST_L1_F7,
37 ST_L1_F8,
40 #define L1S_STATE_COUNT (ST_L1_F8+1)
42 static char *strL1SState[] =
44 "ST_L1_F2",
45 "ST_L1_F3",
46 "ST_L1_F4",
47 "ST_L1_F5",
48 "ST_L1_F6",
49 "ST_L1_F7",
50 "ST_L1_F8",
53 #ifdef HISAX_UINTERFACE
54 static
55 struct Fsm l1fsm_u =
56 {NULL, 0, 0, NULL, NULL};
58 enum {
59 ST_L1_RESET,
60 ST_L1_DEACT,
61 ST_L1_SYNC2,
62 ST_L1_TRANS,
65 #define L1U_STATE_COUNT (ST_L1_TRANS+1)
67 static char *strL1UState[] =
69 "ST_L1_RESET",
70 "ST_L1_DEACT",
71 "ST_L1_SYNC2",
72 "ST_L1_TRANS",
74 #endif
76 enum {
77 ST_L1_NULL,
78 ST_L1_WAIT_ACT,
79 ST_L1_WAIT_DEACT,
80 ST_L1_ACTIV,
83 #define L1B_STATE_COUNT (ST_L1_ACTIV+1)
85 static char *strL1BState[] =
87 "ST_L1_NULL",
88 "ST_L1_WAIT_ACT",
89 "ST_L1_WAIT_DEACT",
90 "ST_L1_ACTIV",
93 enum {
94 EV_PH_ACTIVATE,
95 EV_PH_DEACTIVATE,
96 EV_RESET_IND,
97 EV_DEACT_CNF,
98 EV_DEACT_IND,
99 EV_POWER_UP,
100 EV_RSYNC_IND,
101 EV_INFO2_IND,
102 EV_INFO4_IND,
103 EV_TIMER_DEACT,
104 EV_TIMER_ACT,
105 EV_TIMER3,
108 #define L1_EVENT_COUNT (EV_TIMER3 + 1)
110 static char *strL1Event[] =
112 "EV_PH_ACTIVATE",
113 "EV_PH_DEACTIVATE",
114 "EV_RESET_IND",
115 "EV_DEACT_CNF",
116 "EV_DEACT_IND",
117 "EV_POWER_UP",
118 "EV_RSYNC_IND",
119 "EV_INFO2_IND",
120 "EV_INFO4_IND",
121 "EV_TIMER_DEACT",
122 "EV_TIMER_ACT",
123 "EV_TIMER3",
126 void
127 debugl1(struct IsdnCardState *cs, char *fmt, ...)
129 va_list args;
130 char tmp[8];
132 va_start(args, fmt);
133 sprintf(tmp, "Card%d ", cs->cardnr + 1);
134 VHiSax_putstatus(cs, tmp, fmt, args);
135 va_end(args);
138 static void
139 l1m_debug(struct FsmInst *fi, char *fmt, ...)
141 va_list args;
142 struct PStack *st = fi->userdata;
143 struct IsdnCardState *cs = st->l1.hardware;
144 char tmp[8];
146 va_start(args, fmt);
147 sprintf(tmp, "Card%d ", cs->cardnr + 1);
148 VHiSax_putstatus(cs, tmp, fmt, args);
149 va_end(args);
152 void
153 L1activated(struct IsdnCardState *cs)
155 struct PStack *st;
157 st = cs->stlist;
158 while (st) {
159 if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
160 st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
161 else
162 st->l1.l1l2(st, PH_ACTIVATE | INDICATION, NULL);
163 st = st->next;
167 void
168 L1deactivated(struct IsdnCardState *cs)
170 struct PStack *st;
172 st = cs->stlist;
173 while (st) {
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);
177 st = st->next;
179 test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags);
182 void
183 DChannel_proc_xmt(struct IsdnCardState *cs)
185 struct PStack *stptr;
187 if (cs->tx_skb)
188 return;
190 stptr = cs->stlist;
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);
194 break;
195 } else
196 stptr = stptr->next;
199 void
200 DChannel_proc_rcv(struct IsdnCardState *cs)
202 struct sk_buff *skb, *nskb;
203 struct PStack *stptr = cs->stlist;
204 int found, tei, sapi;
206 if (stptr)
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);
213 #endif
214 stptr = cs->stlist;
215 if (skb->len<3) {
216 debugl1(cs, "D-channel frame too short(%d)",skb->len);
217 dev_kfree_skb(skb);
218 return;
220 if ((skb->data[0] & 1) || !(skb->data[1] &1)) {
221 debugl1(cs, "D-channel frame wrong EA0/EA1");
222 dev_kfree_skb(skb);
223 return;
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);
236 else
237 printk(KERN_WARNING "HiSax: isdn broadcast buffer shortage\n");
238 stptr = stptr->next;
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);
244 else
245 printk(KERN_WARNING "HiSax: tei broadcast buffer shortage\n");
246 stptr = stptr->next;
249 dev_kfree_skb(skb);
250 } else if (sapi == CTRL_SAPI) { /* sapi 0 */
251 found = 0;
252 while (stptr != NULL)
253 if (tei == stptr->l2.tei) {
254 stptr->l1.l1l2(stptr, PH_DATA | INDICATION, skb);
255 found = !0;
256 break;
257 } else
258 stptr = stptr->next;
259 if (!found)
260 dev_kfree_skb(skb);
261 } else
262 dev_kfree_skb(skb);
266 static void
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");
273 return;
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);
285 static void
286 BChannel_proc_rcv(struct BCState *bcs)
288 struct sk_buff *skb;
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);
299 void
300 BChannel_bh(struct BCState *bcs)
302 if (!bcs)
303 return;
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);
310 void
311 HiSax_addlist(struct IsdnCardState *cs,
312 struct PStack *st)
314 st->next = cs->stlist;
315 cs->stlist = st;
318 void
319 HiSax_rmlist(struct IsdnCardState *cs,
320 struct PStack *st)
322 struct PStack *p;
324 FsmDelTimer(&st->l1.timer, 0);
325 if (cs->stlist == st)
326 cs->stlist = st->next;
327 else {
328 p = cs->stlist;
329 while (p)
330 if (p->next == st) {
331 p->next = st->next;
332 return;
333 } else
334 p = p->next;
338 void
339 init_bcstate(struct IsdnCardState *cs,
340 int bc)
342 struct BCState *bcs = cs->bcs + bc;
344 bcs->cs = cs;
345 bcs->channel = 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;
352 bcs->Flag = 0;
355 #ifdef L2FRAME_DEBUG /* psa */
357 char *
358 l2cmd(u_char cmd)
360 switch (cmd & ~0x10) {
361 case 1:
362 return "RR";
363 case 5:
364 return "RNR";
365 case 9:
366 return "REJ";
367 case 0x6f:
368 return "SABME";
369 case 0x0f:
370 return "DM";
371 case 3:
372 return "UI";
373 case 0x43:
374 return "DISC";
375 case 0x63:
376 return "UA";
377 case 0x87:
378 return "FRMR";
379 case 0xaf:
380 return "XID";
381 default:
382 if (!(cmd & 1))
383 return "I";
384 else
385 return "invalid command";
389 static char tmpdeb[32];
391 char *
392 l2frames(u_char * ptr)
394 switch (ptr[2] & ~0x10) {
395 case 1:
396 case 5:
397 case 9:
398 sprintf(tmpdeb, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1);
399 break;
400 case 0x6f:
401 case 0x0f:
402 case 3:
403 case 0x43:
404 case 0x63:
405 case 0x87:
406 case 0xaf:
407 sprintf(tmpdeb, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4);
408 break;
409 default:
410 if (!(ptr[2] & 1)) {
411 sprintf(tmpdeb, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1);
412 break;
413 } else
414 return "invalid command";
418 return tmpdeb;
421 void
422 Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir)
424 u_char *ptr;
426 ptr = skb->data;
428 if (ptr[0] & 1 || !(ptr[1] & 1))
429 debugl1(cs, "Address not LAPD");
430 else
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);
435 #endif
437 static void
438 l1_reset(struct FsmInst *fi, int event, void *arg)
440 FsmChangeState(fi, ST_L1_F3);
443 static void
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);
453 static void
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);
463 static void
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);
473 } else
474 FsmChangeState(fi, ST_L1_F3);
477 static void
478 l1_go_F5(struct FsmInst *fi, int event, void *arg)
480 FsmChangeState(fi, ST_L1_F5);
483 static void
484 l1_go_F8(struct FsmInst *fi, int event, void *arg)
486 FsmChangeState(fi, ST_L1_F8);
489 static void
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);
497 else
498 #endif
499 FsmChangeState(fi, ST_L1_F6);
500 st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
503 static void
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);
511 else
512 #endif
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);
525 static void
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))
536 #endif
537 if (st->l1.l1m.state != ST_L1_F6) {
538 FsmChangeState(fi, ST_L1_F3);
539 st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
543 static void
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);
553 static void
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);
564 static void
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);
572 static void
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
634 static void
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);
645 static void
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);
654 static void
655 l1_info0_ind(struct FsmInst *fi, int event, void *arg)
657 FsmChangeState(fi, ST_L1_DEACT);
660 static void
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))
692 #endif
694 static void
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);
703 static void
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);
712 static void
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);
721 static void
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))
740 void __init
741 Isdnl1New(void)
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);
749 #endif
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
765 FsmFree(&l1fsm_u);
766 #endif
767 FsmFree(&l1fsm_s);
768 FsmFree(&l1fsm_b);
771 static void
772 dch_l2l1(struct PStack *st, int pr, void *arg)
774 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
776 switch (pr) {
777 case (PH_DATA | REQUEST):
778 case (PH_PULL | REQUEST):
779 case (PH_PULL |INDICATION):
780 st->l1.l1hw(st, pr, arg);
781 break;
782 case (PH_ACTIVATE | REQUEST):
783 if (cs->debug)
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);
788 else {
789 test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
790 FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg);
792 break;
793 case (PH_TESTLOOP | REQUEST):
794 if (1 & (long) arg)
795 debugl1(cs, "PH_TEST_LOOP B1");
796 if (2 & (long) arg)
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);
801 break;
802 default:
803 if (cs->debug)
804 debugl1(cs, "dch_l2l1 msg %04X unhandled", pr);
805 break;
809 void
810 l1_msg(struct IsdnCardState *cs, int pr, void *arg) {
811 struct PStack *st;
813 st = cs->stlist;
815 while (st) {
816 switch(pr) {
817 case (HW_RESET | INDICATION):
818 FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
819 break;
820 case (HW_DEACTIVATE | CONFIRM):
821 FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
822 break;
823 case (HW_DEACTIVATE | INDICATION):
824 FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
825 break;
826 case (HW_POWERUP | CONFIRM):
827 FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
828 break;
829 case (HW_RSYNC | INDICATION):
830 FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
831 break;
832 case (HW_INFO2 | INDICATION):
833 FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
834 break;
835 case (HW_INFO4_P8 | INDICATION):
836 case (HW_INFO4_P10 | INDICATION):
837 FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
838 break;
839 default:
840 if (cs->debug)
841 debugl1(cs, "l1msg %04X unhandled", pr);
842 break;
844 st = st->next;
848 void
849 l1_msg_b(struct PStack *st, int pr, void *arg) {
850 switch(pr) {
851 case (PH_ACTIVATE | REQUEST):
852 FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, NULL);
853 break;
854 case (PH_DEACTIVATE | REQUEST):
855 FsmEvent(&st->l1.l1m, EV_PH_DEACTIVATE, NULL);
856 break;
860 void
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;
867 st->l1.Flags = 0;
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;
874 #endif
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);
880 setstack_tei(st);
881 setstack_manager(st);
882 st->l1.stlistp = &(cs->stlist);
883 st->l2.l2l1 = dch_l2l1;
884 cs->setstack_d(st, cs);
887 void
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;
898 st->l1.Flags = 0;
899 FsmInitTimer(&st->l1.l1m, &st->l1.timer);