1 /* $Id: fsm.c,v 1.10 1998/11/15 23:54:39 keil Exp $
3 * Author Karsten Keil (keil@temic-ech.spacenet.de)
4 * based on the teles driver from Jan den Ouden
6 * Thanks to Jan den Ouden
10 * Revision 1.10 1998/11/15 23:54:39 keil
13 * Revision 1.9 1998/03/26 07:10:02 paul
14 * The jumpmatrix table in struct Fsm was an array of "int". This is not
15 * large enough for pointers to functions on Linux/Alpha (instant crash
16 * on "insmod hisax). Now there is a typedef for the pointer to function.
17 * This also prevents warnings about "incompatible pointer types".
19 * Revision 1.8 1998/03/07 22:56:59 tsbogend
20 * made HiSax working on Linux/Alpha
22 * Revision 1.7 1997/11/06 17:09:13 keil
25 * Revision 1.6 1997/07/27 21:42:25 keil
28 * Revision 1.5 1997/06/26 11:10:05 keil
29 * Restart timer function added
31 * Revision 1.4 1997/04/06 22:56:42 keil
32 * Some cosmetic changes
34 * Revision 1.3 1997/02/16 01:04:08 fritz
35 * Bugfix: Changed timer handling caused hang with 2.1.X
37 * Revision 1.2 1997/01/09 20:57:27 keil
38 * cleanup & FSM_TIMER_DEBUG
40 * Revision 1.1 1996/10/13 20:04:52 keil
45 #define __NO_VERSION__
48 #define FSM_TIMER_DEBUG 0
51 FsmNew(struct Fsm
*fsm
,
52 struct FsmNode
*fnlist
, int fncount
))
56 fsm
->jumpmatrix
= (FSMFNPTR
*)
57 kmalloc(sizeof (FSMFNPTR
) * fsm
->state_count
* fsm
->event_count
, GFP_KERNEL
);
58 memset(fsm
->jumpmatrix
, 0, sizeof (FSMFNPTR
) * fsm
->state_count
* fsm
->event_count
);
60 for (i
= 0; i
< fncount
; i
++)
61 if ((fnlist
[i
].state
>=fsm
->state_count
) || (fnlist
[i
].event
>=fsm
->event_count
)) {
62 printk(KERN_ERR
"FsmNew Error line %d st(%ld/%ld) ev(%ld/%ld)\n",
63 i
,(long)fnlist
[i
].state
,(long)fsm
->state_count
,
64 (long)fnlist
[i
].event
,(long)fsm
->event_count
);
66 fsm
->jumpmatrix
[fsm
->state_count
* fnlist
[i
].event
+
67 fnlist
[i
].state
] = (FSMFNPTR
) fnlist
[i
].routine
;
71 FsmFree(struct Fsm
*fsm
)
73 kfree((void *) fsm
->jumpmatrix
);
77 FsmEvent(struct FsmInst
*fi
, int event
, void *arg
)
81 if ((fi
->state
>=fi
->fsm
->state_count
) || (event
>= fi
->fsm
->event_count
)) {
82 printk(KERN_ERR
"FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
83 (long)fi
->state
,(long)fi
->fsm
->state_count
,event
,(long)fi
->fsm
->event_count
);
86 r
= fi
->fsm
->jumpmatrix
[fi
->fsm
->state_count
* event
+ fi
->state
];
89 fi
->printdebug(fi
, "State %s Event %s",
90 fi
->fsm
->strState
[fi
->state
],
91 fi
->fsm
->strEvent
[event
]);
96 fi
->printdebug(fi
, "State %s Event %s no routine",
97 fi
->fsm
->strState
[fi
->state
],
98 fi
->fsm
->strEvent
[event
]);
104 FsmChangeState(struct FsmInst
*fi
, int newstate
)
106 fi
->state
= newstate
;
108 fi
->printdebug(fi
, "ChangeState %s",
109 fi
->fsm
->strState
[newstate
]);
113 FsmExpireTimer(struct FsmTimer
*ft
)
117 ft
->fi
->printdebug(ft
->fi
, "FsmExpireTimer %lx", (long) ft
);
119 FsmEvent(ft
->fi
, ft
->event
, ft
->arg
);
123 FsmInitTimer(struct FsmInst
*fi
, struct FsmTimer
*ft
)
126 ft
->tl
.function
= (void *) FsmExpireTimer
;
127 ft
->tl
.data
= (long) ft
;
130 ft
->fi
->printdebug(ft
->fi
, "FsmInitTimer %lx", (long) ft
);
136 FsmDelTimer(struct FsmTimer
*ft
, int where
)
140 ft
->fi
->printdebug(ft
->fi
, "FsmDelTimer %lx %d", (long) ft
, where
);
146 FsmAddTimer(struct FsmTimer
*ft
,
147 int millisec
, int event
, void *arg
, int where
)
152 ft
->fi
->printdebug(ft
->fi
, "FsmAddTimer %lx %d %d",
153 (long) ft
, millisec
, where
);
156 if (ft
->tl
.next
|| ft
->tl
.prev
) {
157 printk(KERN_WARNING
"FsmAddTimer: timer already active!\n");
158 ft
->fi
->printdebug(ft
->fi
, "FsmAddTimer already active!");
164 ft
->tl
.expires
= jiffies
+ (millisec
* HZ
) / 1000;
170 FsmRestartTimer(struct FsmTimer
*ft
,
171 int millisec
, int event
, void *arg
, int where
)
176 ft
->fi
->printdebug(ft
->fi
, "FsmRestartTimer %lx %d %d",
177 (long) ft
, millisec
, where
);
180 if (ft
->tl
.next
|| ft
->tl
.prev
)
185 ft
->tl
.expires
= jiffies
+ (millisec
* HZ
) / 1000;