File: /usr/src/linux/drivers/isdn/hisax/isdnl1.c

1     /* $Id: isdnl1.c,v 2.41.6.4 2001/08/23 19:44:23 kai Exp $
2      *
3      * isdnl1.c     common low level stuff for Siemens Chipsetbased isdn cards
4      *              based on the teles driver from Jan den Ouden
5      *
6      * Author       Karsten Keil (keil@isdn4linux.de)
7      *
8      *		This file is (c) under GNU General Public License
9      *		For changes and modifications please read
10      *		../../../Documentation/isdn/HiSax.cert
11      *
12      * Thanks to    Jan den Ouden
13      *              Fritz Elfert
14      *              Beat Doebeli
15      *
16      */
17     
18     const char *l1_revision = "$Revision: 2.41.6.4 $";
19     
20     #define __NO_VERSION__
21     #include <linux/init.h>
22     #include "hisax.h"
23     #include "isdnl1.h"
24     
25     #define TIMER3_VALUE 7000
26     
27     static struct Fsm l1fsm_b;
28     static struct Fsm l1fsm_s;
29     
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,
38     };
39     
40     #define L1S_STATE_COUNT (ST_L1_F8+1)
41     
42     static char *strL1SState[] =
43     {
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",
51     };
52     
53     #ifdef HISAX_UINTERFACE
54     static
55     struct Fsm l1fsm_u =
56     {NULL, 0, 0, NULL, NULL};
57     
58     enum {
59     	ST_L1_RESET,
60     	ST_L1_DEACT,
61     	ST_L1_SYNC2,
62     	ST_L1_TRANS,
63     };
64     
65     #define L1U_STATE_COUNT (ST_L1_TRANS+1)
66     
67     static char *strL1UState[] =
68     {
69     	"ST_L1_RESET",
70     	"ST_L1_DEACT",
71     	"ST_L1_SYNC2",
72     	"ST_L1_TRANS",
73     };
74     #endif
75     
76     enum {
77     	ST_L1_NULL,
78     	ST_L1_WAIT_ACT,
79     	ST_L1_WAIT_DEACT,
80     	ST_L1_ACTIV,
81     };
82     
83     #define L1B_STATE_COUNT (ST_L1_ACTIV+1)
84     
85     static char *strL1BState[] =
86     {
87     	"ST_L1_NULL",
88     	"ST_L1_WAIT_ACT",
89     	"ST_L1_WAIT_DEACT",
90     	"ST_L1_ACTIV",
91     };
92     
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,
106     };
107     
108     #define L1_EVENT_COUNT (EV_TIMER3 + 1)
109     
110     static char *strL1Event[] =
111     {
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",
124     };
125     
126     void
127     debugl1(struct IsdnCardState *cs, char *fmt, ...)
128     {
129     	va_list args;
130     	char tmp[8];
131     	
132     	va_start(args, fmt);
133     	sprintf(tmp, "Card%d ", cs->cardnr + 1);
134     	VHiSax_putstatus(cs, tmp, fmt, args);
135     	va_end(args);
136     }
137     
138     static void
139     l1m_debug(struct FsmInst *fi, char *fmt, ...)
140     {
141     	va_list args;
142     	struct PStack *st = fi->userdata;
143     	struct IsdnCardState *cs = st->l1.hardware;
144     	char tmp[8];
145     	
146     	va_start(args, fmt);
147     	sprintf(tmp, "Card%d ", cs->cardnr + 1);
148     	VHiSax_putstatus(cs, tmp, fmt, args);
149     	va_end(args);
150     }
151     
152     void
153     L1activated(struct IsdnCardState *cs)
154     {
155     	struct PStack *st;
156     
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;
164     	}
165     }
166     
167     void
168     L1deactivated(struct IsdnCardState *cs)
169     {
170     	struct PStack *st;
171     
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;
178     	}
179     	test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags);
180     }
181     
182     void
183     DChannel_proc_xmt(struct IsdnCardState *cs)
184     {
185     	struct PStack *stptr;
186     
187     	if (cs->tx_skb)
188     		return;
189     
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;
197     }
198     
199     void
200     DChannel_proc_rcv(struct IsdnCardState *cs)
201     {
202     	struct sk_buff *skb, *nskb;
203     	struct PStack *stptr = cs->stlist;
204     	int found, tei, sapi;
205     
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;
219     		}
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;
224     		}
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;
239     				}
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;
247     				}
248     			}
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);
263     	}
264     }
265     
266     static void
267     BChannel_proc_xmt(struct BCState *bcs)
268     {
269     	struct PStack *st = bcs->st;
270     
271     	if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
272     		debugl1(bcs->cs, "BC_BUSY Error");
273     		return;
274     	}
275     
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);
281     		}
282     	}
283     }
284     
285     static void
286     BChannel_proc_rcv(struct BCState *bcs)
287     {
288     	struct sk_buff *skb;
289     
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);
293     	}
294     	while ((skb = skb_dequeue(&bcs->rqueue))) {
295     		bcs->st->l1.l1l2(bcs->st, PH_DATA | INDICATION, skb);
296     	}
297     }
298     
299     void
300     BChannel_bh(struct BCState *bcs)
301     {
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);
308     }
309     
310     void
311     HiSax_addlist(struct IsdnCardState *cs,
312     	      struct PStack *st)
313     {
314     	st->next = cs->stlist;
315     	cs->stlist = st;
316     }
317     
318     void
319     HiSax_rmlist(struct IsdnCardState *cs,
320     	     struct PStack *st)
321     {
322     	struct PStack *p;
323     
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;
335     	}
336     }
337     
338     void
339     init_bcstate(struct IsdnCardState *cs,
340     	     int bc)
341     {
342     	struct BCState *bcs = cs->bcs + bc;
343     
344     	bcs->cs = cs;
345     	bcs->channel = bc;
346     	bcs->tqueue.sync = 0;
347     	bcs->tqueue.routine = (void *) (void *) BChannel_bh;
348     	bcs->tqueue.data = bcs;
349     	bcs->BC_SetStack = NULL;
350     	bcs->BC_Close = NULL;
351     	bcs->Flag = 0;
352     }
353     
354     #ifdef L2FRAME_DEBUG		/* psa */
355     
356     char *
357     l2cmd(u_char cmd)
358     {
359     	switch (cmd & ~0x10) {
360     		case 1:
361     			return "RR";
362     		case 5:
363     			return "RNR";
364     		case 9:
365     			return "REJ";
366     		case 0x6f:
367     			return "SABME";
368     		case 0x0f:
369     			return "DM";
370     		case 3:
371     			return "UI";
372     		case 0x43:
373     			return "DISC";
374     		case 0x63:
375     			return "UA";
376     		case 0x87:
377     			return "FRMR";
378     		case 0xaf:
379     			return "XID";
380     		default:
381     			if (!(cmd & 1))
382     				return "I";
383     			else
384     				return "invalid command";
385     	}
386     }
387     
388     static char tmpdeb[32];
389     
390     char *
391     l2frames(u_char * ptr)
392     {
393     	switch (ptr[2] & ~0x10) {
394     		case 1:
395     		case 5:
396     		case 9:
397     			sprintf(tmpdeb, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1);
398     			break;
399     		case 0x6f:
400     		case 0x0f:
401     		case 3:
402     		case 0x43:
403     		case 0x63:
404     		case 0x87:
405     		case 0xaf:
406     			sprintf(tmpdeb, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4);
407     			break;
408     		default:
409     			if (!(ptr[2] & 1)) {
410     				sprintf(tmpdeb, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1);
411     				break;
412     			} else
413     				return "invalid command";
414     	}
415     
416     
417     	return tmpdeb;
418     }
419     
420     void
421     Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir)
422     {
423     	u_char *ptr;
424     
425     	ptr = skb->data;
426     
427     	if (ptr[0] & 1 || !(ptr[1] & 1))
428     		debugl1(cs, "Address not LAPD");
429     	else
430     		debugl1(cs, "%s %s: %s%c (sapi %d, tei %d)",
431     			(dir ? "<-" : "->"), buf, l2frames(ptr),
432     			((ptr[0] & 2) >> 1) == dir ? 'C' : 'R', ptr[0] >> 2, ptr[1] >> 1);
433     }
434     #endif
435     
436     static void
437     l1_reset(struct FsmInst *fi, int event, void *arg)
438     {
439     	FsmChangeState(fi, ST_L1_F3);
440     }
441     
442     static void
443     l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
444     {
445     	struct PStack *st = fi->userdata;
446     
447     	FsmChangeState(fi, ST_L1_F3);
448     	if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
449     		st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
450     }
451     
452     static void
453     l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
454     {
455     	struct PStack *st = fi->userdata;
456     
457     	FsmChangeState(fi, ST_L1_F3);
458     	FsmRestartTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2);
459     	test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
460     }
461     
462     static void
463     l1_power_up_s(struct FsmInst *fi, int event, void *arg)
464     {
465     	struct PStack *st = fi->userdata;
466     
467     	if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) {
468     		FsmChangeState(fi, ST_L1_F4);
469     		st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
470     		FsmRestartTimer(&st->l1.timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
471     		test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags);
472     	} else
473     		FsmChangeState(fi, ST_L1_F3);
474     }
475     
476     static void
477     l1_go_F5(struct FsmInst *fi, int event, void *arg)
478     {
479     	FsmChangeState(fi, ST_L1_F5);
480     }
481     
482     static void
483     l1_go_F8(struct FsmInst *fi, int event, void *arg)
484     {
485     	FsmChangeState(fi, ST_L1_F8);
486     }
487     
488     static void
489     l1_info2_ind(struct FsmInst *fi, int event, void *arg)
490     {
491     	struct PStack *st = fi->userdata;
492     
493     #ifdef HISAX_UINTERFACE
494     	if (test_bit(FLG_L1_UINT, &st->l1.Flags))
495     		FsmChangeState(fi, ST_L1_SYNC2);
496     	else
497     #endif
498     		FsmChangeState(fi, ST_L1_F6);
499     	st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
500     }
501     
502     static void
503     l1_info4_ind(struct FsmInst *fi, int event, void *arg)
504     {
505     	struct PStack *st = fi->userdata;
506     
507     #ifdef HISAX_UINTERFACE
508     	if (test_bit(FLG_L1_UINT, &st->l1.Flags))
509     		FsmChangeState(fi, ST_L1_TRANS);
510     	else
511     #endif
512     		FsmChangeState(fi, ST_L1_F7);
513     	st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
514     	if (test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags))
515     		FsmDelTimer(&st->l1.timer, 4);
516     	if (!test_bit(FLG_L1_ACTIVATED, &st->l1.Flags)) {
517     		if (test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags))
518     			FsmDelTimer(&st->l1.timer, 3);
519     		FsmRestartTimer(&st->l1.timer, 110, EV_TIMER_ACT, NULL, 2);
520     		test_and_set_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
521     	}
522     }
523     
524     static void
525     l1_timer3(struct FsmInst *fi, int event, void *arg)
526     {
527     	struct PStack *st = fi->userdata;
528     
529     	test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags);	
530     	if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
531     		L1deactivated(st->l1.hardware);
532     
533     #ifdef HISAX_UINTERFACE
534     	if (!test_bit(FLG_L1_UINT, &st->l1.Flags))
535     #endif
536     	if (st->l1.l1m.state != ST_L1_F6) {
537     		FsmChangeState(fi, ST_L1_F3);
538     		st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
539     	}
540     }
541     
542     static void
543     l1_timer_act(struct FsmInst *fi, int event, void *arg)
544     {
545     	struct PStack *st = fi->userdata;
546     	
547     	test_and_clear_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
548     	test_and_set_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
549     	L1activated(st->l1.hardware);
550     }
551     
552     static void
553     l1_timer_deact(struct FsmInst *fi, int event, void *arg)
554     {
555     	struct PStack *st = fi->userdata;
556     	
557     	test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
558     	test_and_clear_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
559     	L1deactivated(st->l1.hardware);
560     	st->l1.l1hw(st, HW_DEACTIVATE | RESPONSE, NULL);
561     }
562     
563     static void
564     l1_activate_s(struct FsmInst *fi, int event, void *arg)
565     {
566     	struct PStack *st = fi->userdata;
567                     
568     	st->l1.l1hw(st, HW_RESET | REQUEST, NULL);
569     }
570     
571     static void
572     l1_activate_no(struct FsmInst *fi, int event, void *arg)
573     {
574     	struct PStack *st = fi->userdata;
575     
576     	if ((!test_bit(FLG_L1_DEACTTIMER, &st->l1.Flags)) && (!test_bit(FLG_L1_T3RUN, &st->l1.Flags))) {
577     		test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
578     		L1deactivated(st->l1.hardware);
579     	}
580     }
581     
582     static struct FsmNode L1SFnList[] __initdata =
583     {
584     	{ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s},
585     	{ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no},
586     	{ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no},
587     	{ST_L1_F3, EV_RESET_IND, l1_reset},
588     	{ST_L1_F4, EV_RESET_IND, l1_reset},
589     	{ST_L1_F5, EV_RESET_IND, l1_reset},
590     	{ST_L1_F6, EV_RESET_IND, l1_reset},
591     	{ST_L1_F7, EV_RESET_IND, l1_reset},
592     	{ST_L1_F8, EV_RESET_IND, l1_reset},
593     	{ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf},
594     	{ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf},
595     	{ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf},
596     	{ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf},
597     	{ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf},
598     	{ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf},
599     	{ST_L1_F6, EV_DEACT_IND, l1_deact_req_s},
600     	{ST_L1_F7, EV_DEACT_IND, l1_deact_req_s},
601     	{ST_L1_F8, EV_DEACT_IND, l1_deact_req_s},
602     	{ST_L1_F3, EV_POWER_UP, l1_power_up_s},
603     	{ST_L1_F4, EV_RSYNC_IND, l1_go_F5},
604     	{ST_L1_F6, EV_RSYNC_IND, l1_go_F8},
605     	{ST_L1_F7, EV_RSYNC_IND, l1_go_F8},
606     	{ST_L1_F3, EV_INFO2_IND, l1_info2_ind},
607     	{ST_L1_F4, EV_INFO2_IND, l1_info2_ind},
608     	{ST_L1_F5, EV_INFO2_IND, l1_info2_ind},
609     	{ST_L1_F7, EV_INFO2_IND, l1_info2_ind},
610     	{ST_L1_F8, EV_INFO2_IND, l1_info2_ind},
611     	{ST_L1_F3, EV_INFO4_IND, l1_info4_ind},
612     	{ST_L1_F4, EV_INFO4_IND, l1_info4_ind},
613     	{ST_L1_F5, EV_INFO4_IND, l1_info4_ind},
614     	{ST_L1_F6, EV_INFO4_IND, l1_info4_ind},
615     	{ST_L1_F8, EV_INFO4_IND, l1_info4_ind},
616     	{ST_L1_F3, EV_TIMER3, l1_timer3},
617     	{ST_L1_F4, EV_TIMER3, l1_timer3},
618     	{ST_L1_F5, EV_TIMER3, l1_timer3},
619     	{ST_L1_F6, EV_TIMER3, l1_timer3},
620     	{ST_L1_F8, EV_TIMER3, l1_timer3},
621     	{ST_L1_F7, EV_TIMER_ACT, l1_timer_act},
622     	{ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact},
623     	{ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact},
624     	{ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact},
625     	{ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact},
626     	{ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact},
627     	{ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
628     };
629     
630     #define L1S_FN_COUNT (sizeof(L1SFnList)/sizeof(struct FsmNode))
631     
632     #ifdef HISAX_UINTERFACE
633     static void
634     l1_deact_req_u(struct FsmInst *fi, int event, void *arg)
635     {
636     	struct PStack *st = fi->userdata;
637     
638     	FsmChangeState(fi, ST_L1_RESET);
639     	FsmRestartTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2);
640     	test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
641     	st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
642     }
643     
644     static void
645     l1_power_up_u(struct FsmInst *fi, int event, void *arg)
646     {
647     	struct PStack *st = fi->userdata;
648     
649     	FsmRestartTimer(&st->l1.timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
650     	test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags);
651     }
652     
653     static void
654     l1_info0_ind(struct FsmInst *fi, int event, void *arg)
655     {
656     	FsmChangeState(fi, ST_L1_DEACT);
657     }
658     
659     static void
660     l1_activate_u(struct FsmInst *fi, int event, void *arg)
661     {
662     	struct PStack *st = fi->userdata;
663                     
664     	st->l1.l1hw(st, HW_INFO1 | REQUEST, NULL);
665     }
666     
667     static struct FsmNode L1UFnList[] __initdata =
668     {
669     	{ST_L1_RESET, EV_DEACT_IND, l1_deact_req_u},
670     	{ST_L1_DEACT, EV_DEACT_IND, l1_deact_req_u},
671     	{ST_L1_SYNC2, EV_DEACT_IND, l1_deact_req_u},
672     	{ST_L1_TRANS, EV_DEACT_IND, l1_deact_req_u},
673     	{ST_L1_DEACT, EV_PH_ACTIVATE, l1_activate_u},
674     	{ST_L1_DEACT, EV_POWER_UP, l1_power_up_u},
675     	{ST_L1_DEACT, EV_INFO2_IND, l1_info2_ind},
676     	{ST_L1_TRANS, EV_INFO2_IND, l1_info2_ind},
677     	{ST_L1_RESET, EV_DEACT_CNF, l1_info0_ind},
678     	{ST_L1_DEACT, EV_INFO4_IND, l1_info4_ind},
679     	{ST_L1_SYNC2, EV_INFO4_IND, l1_info4_ind},
680     	{ST_L1_RESET, EV_INFO4_IND, l1_info4_ind},
681     	{ST_L1_DEACT, EV_TIMER3, l1_timer3},
682     	{ST_L1_SYNC2, EV_TIMER3, l1_timer3},
683     	{ST_L1_TRANS, EV_TIMER_ACT, l1_timer_act},
684     	{ST_L1_DEACT, EV_TIMER_DEACT, l1_timer_deact},
685     	{ST_L1_SYNC2, EV_TIMER_DEACT, l1_timer_deact},
686     	{ST_L1_RESET, EV_TIMER_DEACT, l1_timer_deact},
687     };
688     
689     #define L1U_FN_COUNT (sizeof(L1UFnList)/sizeof(struct FsmNode))
690     
691     #endif
692     
693     static void
694     l1b_activate(struct FsmInst *fi, int event, void *arg)
695     {
696     	struct PStack *st = fi->userdata;
697     
698     	FsmChangeState(fi, ST_L1_WAIT_ACT);
699     	FsmRestartTimer(&st->l1.timer, st->l1.delay, EV_TIMER_ACT, NULL, 2);
700     }
701     
702     static void
703     l1b_deactivate(struct FsmInst *fi, int event, void *arg)
704     {
705     	struct PStack *st = fi->userdata;
706     
707     	FsmChangeState(fi, ST_L1_WAIT_DEACT);
708     	FsmRestartTimer(&st->l1.timer, 10, EV_TIMER_DEACT, NULL, 2);
709     }
710     
711     static void
712     l1b_timer_act(struct FsmInst *fi, int event, void *arg)
713     {
714     	struct PStack *st = fi->userdata;
715     
716     	FsmChangeState(fi, ST_L1_ACTIV);
717     	st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
718     }
719     
720     static void
721     l1b_timer_deact(struct FsmInst *fi, int event, void *arg)
722     {
723     	struct PStack *st = fi->userdata;
724     
725     	FsmChangeState(fi, ST_L1_NULL);
726     	st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL);
727     }
728     
729     static struct FsmNode L1BFnList[] __initdata =
730     {
731     	{ST_L1_NULL, EV_PH_ACTIVATE, l1b_activate},
732     	{ST_L1_WAIT_ACT, EV_TIMER_ACT, l1b_timer_act},
733     	{ST_L1_ACTIV, EV_PH_DEACTIVATE, l1b_deactivate},
734     	{ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact},
735     };
736     
737     #define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
738     
739     int __init 
740     Isdnl1New(void)
741     {
742     	int retval;
743     
744     	l1fsm_s.state_count = L1S_STATE_COUNT;
745     	l1fsm_s.event_count = L1_EVENT_COUNT;
746     	l1fsm_s.strEvent = strL1Event;
747     	l1fsm_s.strState = strL1SState;
748     	retval = FsmNew(&l1fsm_s, L1SFnList, L1S_FN_COUNT);
749     	if (retval)
750     		return retval;
751     
752     	l1fsm_b.state_count = L1B_STATE_COUNT;
753     	l1fsm_b.event_count = L1_EVENT_COUNT;
754     	l1fsm_b.strEvent = strL1Event;
755     	l1fsm_b.strState = strL1BState;
756     	retval = FsmNew(&l1fsm_b, L1BFnList, L1B_FN_COUNT);
757     	if (retval) {
758     		FsmFree(&l1fsm_s);
759     		return retval;
760     	}
761     #ifdef HISAX_UINTERFACE
762     	l1fsm_u.state_count = L1U_STATE_COUNT;
763     	l1fsm_u.event_count = L1_EVENT_COUNT;
764     	l1fsm_u.strEvent = strL1Event;
765     	l1fsm_u.strState = strL1UState;
766     	retval = FsmNew(&l1fsm_u, L1UFnList, L1U_FN_COUNT);
767     	if (retval) {
768     		FsmFree(&l1fsm_s);
769     		FsmFree(&l1fsm_b);
770     		return retval;
771     	}
772     #endif
773     	return 0;
774     }
775     
776     void Isdnl1Free(void)
777     {
778     #ifdef HISAX_UINTERFACE
779     	FsmFree(&l1fsm_u);
780     #endif
781     	FsmFree(&l1fsm_s);
782     	FsmFree(&l1fsm_b);
783     }
784     
785     static void
786     dch_l2l1(struct PStack *st, int pr, void *arg)
787     {
788     	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
789     
790     	switch (pr) {
791     		case (PH_DATA | REQUEST):
792     		case (PH_PULL | REQUEST):
793     		case (PH_PULL |INDICATION):
794     			st->l1.l1hw(st, pr, arg);
795     			break;
796     		case (PH_ACTIVATE | REQUEST):
797     			if (cs->debug)
798     				debugl1(cs, "PH_ACTIVATE_REQ %s",
799     					st->l1.l1m.fsm->strState[st->l1.l1m.state]);
800     			if (test_bit(FLG_L1_ACTIVATED, &st->l1.Flags))
801     				st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
802     			else {
803     				test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
804     				FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg);
805     			}
806     			break;
807     		case (PH_TESTLOOP | REQUEST):
808     			if (1 & (long) arg)
809     				debugl1(cs, "PH_TEST_LOOP B1");
810     			if (2 & (long) arg)
811     				debugl1(cs, "PH_TEST_LOOP B2");
812     			if (!(3 & (long) arg))
813     				debugl1(cs, "PH_TEST_LOOP DISABLED");
814     			st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
815     			break;
816     		default:
817     			if (cs->debug)
818     				debugl1(cs, "dch_l2l1 msg %04X unhandled", pr);
819     			break;
820     	}
821     }
822     
823     void
824     l1_msg(struct IsdnCardState *cs, int pr, void *arg) {
825     	struct PStack *st;
826     
827     	st = cs->stlist;
828     	
829     	while (st) {
830     		switch(pr) {
831     			case (HW_RESET | INDICATION):
832     				FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
833     				break;
834     			case (HW_DEACTIVATE | CONFIRM):
835     				FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
836     				break;
837     			case (HW_DEACTIVATE | INDICATION):
838     				FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
839     				break;
840     			case (HW_POWERUP | CONFIRM):
841     				FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
842     				break;
843     			case (HW_RSYNC | INDICATION):
844     				FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
845     				break;
846     			case (HW_INFO2 | INDICATION):
847     				FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
848     				break;
849     			case (HW_INFO4_P8 | INDICATION):
850     			case (HW_INFO4_P10 | INDICATION):
851     				FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
852     				break;
853     			default:
854     				if (cs->debug)
855     					debugl1(cs, "l1msg %04X unhandled", pr);
856     				break;
857     		}
858     		st = st->next;
859     	}
860     }
861     
862     void
863     l1_msg_b(struct PStack *st, int pr, void *arg) {
864     	switch(pr) {
865     		case (PH_ACTIVATE | REQUEST):
866     			FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, NULL);
867     			break;
868     		case (PH_DEACTIVATE | REQUEST):
869     			FsmEvent(&st->l1.l1m, EV_PH_DEACTIVATE, NULL);
870     			break;
871     	}
872     }
873     
874     void
875     setstack_HiSax(struct PStack *st, struct IsdnCardState *cs)
876     {
877     	st->l1.hardware = cs;
878     	st->protocol = cs->protocol;
879     	st->l1.l1m.fsm = &l1fsm_s;
880     	st->l1.l1m.state = ST_L1_F3;
881     	st->l1.Flags = 0;
882     #ifdef HISAX_UINTERFACE
883     	if (test_bit(FLG_HW_L1_UINT, &cs->HW_Flags)) {
884     		st->l1.l1m.fsm = &l1fsm_u;
885     		st->l1.l1m.state = ST_L1_RESET;
886     		st->l1.Flags = FLG_L1_UINT;
887     	}
888     #endif
889     	st->l1.l1m.debug = cs->debug;
890     	st->l1.l1m.userdata = st;
891     	st->l1.l1m.userint = 0;
892     	st->l1.l1m.printdebug = l1m_debug;
893     	FsmInitTimer(&st->l1.l1m, &st->l1.timer);
894     	setstack_tei(st);
895     	setstack_manager(st);
896     	st->l1.stlistp = &(cs->stlist);
897     	st->l2.l2l1  = dch_l2l1;
898     	if (cs->setstack_d)
899     		cs->setstack_d(st, cs);
900     }
901     
902     void
903     setstack_l1_B(struct PStack *st)
904     {
905     	struct IsdnCardState *cs = st->l1.hardware;
906     
907     	st->l1.l1m.fsm = &l1fsm_b;
908     	st->l1.l1m.state = ST_L1_NULL;
909     	st->l1.l1m.debug = cs->debug;
910     	st->l1.l1m.userdata = st;
911     	st->l1.l1m.userint = 0;
912     	st->l1.l1m.printdebug = l1m_debug;
913     	st->l1.Flags = 0;
914     	FsmInitTimer(&st->l1.l1m, &st->l1.timer);
915     }
916