1 /* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
7 * by Kai Germaschewski <kai.germaschewski@gmx.de>
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
12 * Thanks to Jan den Ouden
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/init.h>
22 #define FSM_TIMER_DEBUG 0
25 FsmNew(struct Fsm
*fsm
, struct FsmNode
*fnlist
, int fncount
)
30 kzalloc(array3_size(sizeof(FSMFNPTR
), fsm
->state_count
,
36 for (i
= 0; i
< fncount
; i
++)
37 if ((fnlist
[i
].state
>= fsm
->state_count
) || (fnlist
[i
].event
>= fsm
->event_count
)) {
38 printk(KERN_ERR
"FsmNew Error line %d st(%ld/%ld) ev(%ld/%ld)\n",
39 i
, (long)fnlist
[i
].state
, (long)fsm
->state_count
,
40 (long)fnlist
[i
].event
, (long)fsm
->event_count
);
42 fsm
->jumpmatrix
[fsm
->state_count
* fnlist
[i
].event
+
43 fnlist
[i
].state
] = (FSMFNPTR
)fnlist
[i
].routine
;
48 FsmFree(struct Fsm
*fsm
)
50 kfree((void *) fsm
->jumpmatrix
);
54 FsmEvent(struct FsmInst
*fi
, int event
, void *arg
)
58 if ((fi
->state
>= fi
->fsm
->state_count
) || (event
>= fi
->fsm
->event_count
)) {
59 printk(KERN_ERR
"FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
60 (long)fi
->state
, (long)fi
->fsm
->state_count
, event
, (long)fi
->fsm
->event_count
);
63 r
= fi
->fsm
->jumpmatrix
[fi
->fsm
->state_count
* event
+ fi
->state
];
66 fi
->printdebug(fi
, "State %s Event %s",
67 fi
->fsm
->strState
[fi
->state
],
68 fi
->fsm
->strEvent
[event
]);
73 fi
->printdebug(fi
, "State %s Event %s no routine",
74 fi
->fsm
->strState
[fi
->state
],
75 fi
->fsm
->strEvent
[event
]);
81 FsmChangeState(struct FsmInst
*fi
, int newstate
)
85 fi
->printdebug(fi
, "ChangeState %s",
86 fi
->fsm
->strState
[newstate
]);
90 FsmExpireTimer(struct timer_list
*t
)
92 struct FsmTimer
*ft
= from_timer(ft
, t
, tl
);
95 ft
->fi
->printdebug(ft
->fi
, "FsmExpireTimer %lx", (long) ft
);
97 FsmEvent(ft
->fi
, ft
->event
, ft
->arg
);
101 FsmInitTimer(struct FsmInst
*fi
, struct FsmTimer
*ft
)
106 ft
->fi
->printdebug(ft
->fi
, "FsmInitTimer %lx", (long) ft
);
108 timer_setup(&ft
->tl
, FsmExpireTimer
, 0);
112 FsmDelTimer(struct FsmTimer
*ft
, int where
)
116 ft
->fi
->printdebug(ft
->fi
, "FsmDelTimer %lx %d", (long) ft
, where
);
122 FsmAddTimer(struct FsmTimer
*ft
,
123 int millisec
, int event
, void *arg
, int where
)
128 ft
->fi
->printdebug(ft
->fi
, "FsmAddTimer %lx %d %d",
129 (long) ft
, millisec
, where
);
132 if (timer_pending(&ft
->tl
)) {
133 printk(KERN_WARNING
"FsmAddTimer: timer already active!\n");
134 ft
->fi
->printdebug(ft
->fi
, "FsmAddTimer already active!");
139 ft
->tl
.expires
= jiffies
+ (millisec
* HZ
) / 1000;
145 FsmRestartTimer(struct FsmTimer
*ft
,
146 int millisec
, int event
, void *arg
, int where
)
151 ft
->fi
->printdebug(ft
->fi
, "FsmRestartTimer %lx %d %d",
152 (long) ft
, millisec
, where
);
155 if (timer_pending(&ft
->tl
))
159 ft
->tl
.expires
= jiffies
+ (millisec
* HZ
) / 1000;