No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / ic / isic_l1fsm.c
blobf29035e7a95217b424decb3499b83031e9ffcb8d
1 /*
2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
25 *---------------------------------------------------------------------------
27 * i4b_l1fsm.c - isdn4bsd layer 1 I.430 state machine
28 * --------------------------------------------------
30 * $Id: isic_l1fsm.c,v 1.13 2007/10/19 11:59:54 ad Exp $
32 * last edit-date: [Fri Jan 5 11:36:11 2001]
34 *---------------------------------------------------------------------------*/
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: isic_l1fsm.c,v 1.12 2005/12/11 12:21:27 christos Exp $");
39 #include <sys/param.h>
40 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
41 #include <sys/ioccom.h>
42 #else
43 #include <sys/ioctl.h>
44 #endif
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/mbuf.h>
49 #include <machine/stdarg.h>
51 #ifdef __FreeBSD__
52 #include <machine/clock.h>
53 #include <i386/isa/isa_device.h>
54 #else
55 #ifndef __bsdi__
56 #include <sys/bus.h>
57 #endif
58 #include <sys/device.h>
59 #endif
61 #include <sys/socket.h>
62 #include <net/if.h>
64 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
65 #include <sys/callout.h>
66 #endif
68 #ifdef __FreeBSD__
69 #include <machine/i4b_debug.h>
70 #include <machine/i4b_ioctl.h>
71 #else
72 #include <netisdn/i4b_debug.h>
73 #include <netisdn/i4b_ioctl.h>
74 #endif
76 #include <netisdn/i4b_global.h>
77 #include <netisdn/i4b_trace.h>
78 #include <netisdn/i4b_l2.h>
79 #include <netisdn/i4b_l1l2.h>
80 #include <netisdn/i4b_mbuf.h>
82 #include <dev/ic/isic_l1.h>
83 #include <dev/ic/isac.h>
84 #include <dev/ic/hscx.h>
86 #include "nisac.h"
87 #include "nisacsx.h"
89 #if DO_I4B_DEBUG
90 static const char *state_text[N_STATES] = {
91 "F3 Deactivated",
92 "F4 Awaiting Signal",
93 "F5 Identifying Input",
94 "F6 Synchronized",
95 "F7 Activated",
96 "F8 Lost Framing",
97 "Illegal State"
100 static const char *event_text[N_EVENTS] = {
101 "EV_PHAR PH_ACT_REQ",
102 "EV_T3 Timer 3 expired",
103 "EV_INFO0 INFO0 received",
104 "EV_RSY Level Detected",
105 "EV_INFO2 INFO2 received",
106 "EV_INFO48 INFO4 received",
107 "EV_INFO410 INFO4 received",
108 "EV_DR Deactivate Req",
109 "EV_PU Power UP",
110 "EV_DIS Disconnected",
111 "EV_EI Error Ind",
112 "Illegal Event"
114 #endif
116 /* Function prototypes */
118 static void timer3_expired (struct isic_softc *sc);
119 static void T3_start (struct isic_softc *sc);
120 static void T3_stop (struct isic_softc *sc);
121 static void F_T3ex (struct isic_softc *sc);
122 static void timer4_expired (struct isic_softc *sc);
123 static void T4_start (struct isic_softc *sc);
124 static void T4_stop (struct isic_softc *sc);
125 static void F_AI8 (struct isic_softc *sc);
126 static void F_AI10 (struct isic_softc *sc);
127 static void F_I01 (struct isic_softc *sc);
128 static void F_I02 (struct isic_softc *sc);
129 static void F_I03 (struct isic_softc *sc);
130 static void F_I2 (struct isic_softc *sc);
131 static void F_ill (struct isic_softc *sc);
132 static void F_NULL (struct isic_softc *sc);
134 /*---------------------------------------------------------------------------*
135 * I.430 Timer T3 expire function
136 *---------------------------------------------------------------------------*/
137 static void
138 timer3_expired(struct isic_softc *sc)
140 if(sc->sc_I430T3)
142 NDBGL1(L1_T_ERR, "state = %s", isic_printstate(sc));
143 sc->sc_I430T3 = 0;
145 /* XXX try some recovery here XXX */
146 switch(sc->sc_cardtyp) {
147 #if NNISACSX > 0
148 case CARD_TYPEP_AVMA1PCIV2:
149 isic_isacsx_recover(sc);
150 break;
151 #endif /* NNISACSX > 0 */
152 default:
153 #if NNISAC > 0
154 isic_recover(sc);
155 #endif /* NNISAC > 0 */
156 break;
159 sc->sc_init_tries++; /* increment retry count */
161 /*XXX*/ if(sc->sc_init_tries > 4)
163 int s = splnet();
165 sc->sc_init_tries = 0;
167 if(sc->sc_obuf2 != NULL)
169 i4b_Dfreembuf(sc->sc_obuf2);
170 sc->sc_obuf2 = NULL;
172 if(sc->sc_obuf != NULL)
174 i4b_Dfreembuf(sc->sc_obuf);
175 sc->sc_obuf = NULL;
176 sc->sc_freeflag = 0;
177 sc->sc_op = NULL;
178 sc->sc_ol = 0;
181 splx(s);
183 isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_NOL1ACC, 0);
186 isic_next_state(sc, EV_T3);
188 else
190 NDBGL1(L1_T_ERR, "expired without starting it ....");
194 /*---------------------------------------------------------------------------*
195 * I.430 Timer T3 start
196 *---------------------------------------------------------------------------*/
197 static void
198 T3_start(struct isic_softc *sc)
200 NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
201 sc->sc_I430T3 = 1;
203 START_TIMER(sc->sc_T3_callout, timer3_expired, sc, 2*hz);
206 /*---------------------------------------------------------------------------*
207 * I.430 Timer T3 stop
208 *---------------------------------------------------------------------------*/
209 static void
210 T3_stop(struct isic_softc *sc)
212 NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
214 sc->sc_init_tries = 0; /* init connect retry count */
216 if(sc->sc_I430T3)
218 sc->sc_I430T3 = 0;
219 STOP_TIMER(sc->sc_T3_callout, timer3_expired, sc);
223 /*---------------------------------------------------------------------------*
224 * I.430 Timer T3 expiry
225 *---------------------------------------------------------------------------*/
226 static void
227 F_T3ex(struct isic_softc *sc)
229 NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
230 if(((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S)
231 isdn_layer2_activate_ind(&sc->sc_l2, sc->sc_l3token, 0);
234 /*---------------------------------------------------------------------------*
235 * Timer T4 expire function
236 *---------------------------------------------------------------------------*/
237 static void
238 timer4_expired(struct isic_softc *sc)
240 if(sc->sc_I430T4)
242 NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
243 sc->sc_I430T4 = 0;
244 isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_PDEACT, 0);
246 else
248 NDBGL1(L1_T_ERR, "expired without starting it ....");
252 /*---------------------------------------------------------------------------*
253 * Timer T4 start
254 *---------------------------------------------------------------------------*/
255 static void
256 T4_start(struct isic_softc *sc)
258 NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
259 sc->sc_I430T4 = 1;
261 START_TIMER(sc->sc_T4_callout, timer4_expired, sc, hz);
264 /*---------------------------------------------------------------------------*
265 * Timer T4 stop
266 *---------------------------------------------------------------------------*/
267 static void
268 T4_stop(struct isic_softc *sc)
270 NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
272 if(sc->sc_I430T4)
274 sc->sc_I430T4 = 0;
275 STOP_TIMER(sc->sc_T4_callout, timer4_expired, sc);
279 /*---------------------------------------------------------------------------*
280 * FSM function: received AI8
281 *---------------------------------------------------------------------------*/
282 static void
283 F_AI8(struct isic_softc *sc)
285 T4_stop(sc);
287 NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
289 if(((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S)
290 isdn_layer2_activate_ind(&sc->sc_l2, sc->sc_l3token, 1);
292 T3_stop(sc);
294 if(sc->sc_trace & TRACE_I)
296 i4b_trace_hdr hdr;
297 char info = INFO4_8;
299 hdr.type = TRC_CH_I;
300 hdr.dir = FROM_NT;
301 hdr.count = 0;
302 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
306 /*---------------------------------------------------------------------------*
307 * FSM function: received AI10
308 *---------------------------------------------------------------------------*/
309 static void
310 F_AI10(struct isic_softc *sc)
312 T4_stop(sc);
314 NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
316 if(((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S)
317 isdn_layer2_activate_ind(&sc->sc_l2, sc->sc_l3token, 1);
319 T3_stop(sc);
321 if(sc->sc_trace & TRACE_I)
323 i4b_trace_hdr hdr;
324 char info = INFO4_10;
326 hdr.type = TRC_CH_I;
327 hdr.dir = FROM_NT;
328 hdr.count = 0;
329 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
333 /*---------------------------------------------------------------------------*
334 * FSM function: received INFO 0 in states F3 .. F5
335 *---------------------------------------------------------------------------*/
336 static void
337 F_I01(struct isic_softc *sc)
339 NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
341 if(sc->sc_trace & TRACE_I)
343 i4b_trace_hdr hdr;
344 char info = INFO0;
346 hdr.type = TRC_CH_I;
347 hdr.dir = FROM_NT;
348 hdr.count = 0;
349 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
353 /*---------------------------------------------------------------------------*
354 * FSM function: received INFO 0 in state F6
355 *---------------------------------------------------------------------------*/
356 static void
357 F_I02(struct isic_softc *sc)
359 NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
361 if(((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S)
362 isdn_layer2_activate_ind(&sc->sc_l2, sc->sc_l3token, 0);
364 if(sc->sc_trace & TRACE_I)
366 i4b_trace_hdr hdr;
367 char info = INFO0;
369 hdr.type = TRC_CH_I;
370 hdr.dir = FROM_NT;
371 hdr.count = 0;
372 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
376 /*---------------------------------------------------------------------------*
377 * FSM function: received INFO 0 in state F7 or F8
378 *---------------------------------------------------------------------------*/
379 static void
380 F_I03(struct isic_softc *sc)
382 NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
384 if(((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S)
385 isdn_layer2_activate_ind(&sc->sc_l2, sc->sc_l3token, 0);
387 T4_start(sc);
389 if(sc->sc_trace & TRACE_I)
391 i4b_trace_hdr hdr;
392 char info = INFO0;
394 hdr.type = TRC_CH_I;
395 hdr.dir = FROM_NT;
396 hdr.count = 0;
397 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
401 /*---------------------------------------------------------------------------*
402 * FSM function: activate request
403 *---------------------------------------------------------------------------*/
404 static void
405 F_AR(struct isic_softc *sc)
407 NDBGL1(L1_F_MSG, "FSM function F_AR executing");
409 if(sc->sc_trace & TRACE_I)
411 i4b_trace_hdr hdr;
412 char info = INFO1_8;
414 hdr.type = TRC_CH_I;
415 hdr.dir = FROM_TE;
416 hdr.count = 0;
417 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
420 switch(sc->sc_cardtyp) {
421 #if NNISACSX > 0
422 case CARD_TYPEP_AVMA1PCIV2:
423 isic_isacsx_l1_cmd(sc, CMD_AR8);
424 break;
425 #endif /* NNISACSX > 0 */
426 default:
427 #if NNISAC > 0
428 isic_isac_l1_cmd(sc, CMD_AR8);
429 #endif /* NNISAC > 0 */
430 break;
433 T3_start(sc);
436 /*---------------------------------------------------------------------------*
437 * FSM function: received INFO2
438 *---------------------------------------------------------------------------*/
439 static void
440 F_I2(struct isic_softc *sc)
442 NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
444 if(sc->sc_trace & TRACE_I)
446 i4b_trace_hdr hdr;
447 char info = INFO2;
449 hdr.type = TRC_CH_I;
450 hdr.dir = FROM_NT;
451 hdr.count = 0;
452 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, 1, &info);
456 /*---------------------------------------------------------------------------*
457 * illegal state default action
458 *---------------------------------------------------------------------------*/
459 static void
460 F_ill(struct isic_softc *sc)
462 NDBGL1(L1_F_ERR, "FSM function F_ill executing");
465 /*---------------------------------------------------------------------------*
466 * No action
467 *---------------------------------------------------------------------------*/
468 static void
469 F_NULL(struct isic_softc *sc)
471 NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
475 /*---------------------------------------------------------------------------*
476 * layer 1 state transition table
477 *---------------------------------------------------------------------------*/
478 struct isic_state_tab {
479 void (*func) (struct isic_softc *sc); /* function to execute */
480 int newstate; /* next state */
481 } isic_state_tab[N_EVENTS][N_STATES] = {
483 /* STATE: F3 F4 F5 F6 F7 F8 ILLEGAL STATE */
484 /* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
485 /* EV_PHAR x*/ {{F_AR, ST_F4}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_ill, ST_ILL}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
486 /* EV_T3 x*/ {{F_NULL, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_T3ex, ST_F3}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
487 /* EV_INFO0 */ {{F_I01, ST_F3}, {F_I01, ST_F4}, {F_I01, ST_F5}, {F_I02, ST_F3}, {F_I03, ST_F3}, {F_I03, ST_F3}, {F_ill, ST_ILL}},
488 /* EV_RSY x*/ {{F_NULL, ST_F3}, {F_NULL, ST_F5}, {F_NULL, ST_F5}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
489 /* EV_INFO2 */ {{F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_I2, ST_F6}, {F_ill, ST_ILL}},
490 /* EV_INFO48*/ {{F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_AI8, ST_F7}, {F_NULL, ST_F7}, {F_AI8, ST_F7}, {F_ill, ST_ILL}},
491 /* EV_INFO41*/ {{F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_AI10, ST_F7}, {F_NULL, ST_F7}, {F_AI10, ST_F7}, {F_ill, ST_ILL}},
492 /* EV_DR */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
493 /* EV_PU */ {{F_NULL, ST_F3}, {F_NULL, ST_F4}, {F_NULL, ST_F5}, {F_NULL, ST_F6}, {F_NULL, ST_F7}, {F_NULL, ST_F8}, {F_ill, ST_ILL}},
494 /* EV_DIS */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}},
495 /* EV_EI */ {{F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_NULL, ST_F3}, {F_ill, ST_ILL}},
496 /* EV_ILL */ {{F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}, {F_ill, ST_ILL}}
499 /*---------------------------------------------------------------------------*
500 * event handler
501 *---------------------------------------------------------------------------*/
502 void
503 isic_next_state(struct isic_softc *sc, int event)
505 int currstate, newstate;
507 if(event >= N_EVENTS)
508 panic("i4b_l1fsm.c: event >= N_EVENTS");
510 currstate = sc->sc_I430state;
512 if(currstate >= N_STATES)
513 panic("i4b_l1fsm.c: currstate >= N_STATES");
515 newstate = isic_state_tab[event][currstate].newstate;
517 if(newstate >= N_STATES)
518 panic("i4b_l1fsm.c: newstate >= N_STATES");
520 NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
521 state_text[currstate],
522 state_text[newstate]);
524 (*isic_state_tab[event][currstate].func)(sc);
526 if(newstate == ST_ILL)
528 newstate = ST_F3;
529 NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
530 state_text[currstate],
531 state_text[newstate],
532 event_text[event]);
535 sc->sc_I430state = newstate;
538 #if DO_I4B_DEBUG
539 /*---------------------------------------------------------------------------*
540 * return pointer to current state description
541 *---------------------------------------------------------------------------*/
542 const char *
543 isic_printstate(struct isic_softc *sc)
545 return(state_text[sc->sc_I430state]);
547 #endif