0001
0002 #ifndef _FSM_H_
0003 #define _FSM_H_
0004
0005 #include <linux/kernel.h>
0006 #include <linux/types.h>
0007 #include <linux/timer.h>
0008 #include <linux/time.h>
0009 #include <linux/slab.h>
0010 #include <linux/sched.h>
0011 #include <linux/string.h>
0012 #include <linux/atomic.h>
0013
0014
0015
0016
0017 #define FSM_DEBUG 0
0018
0019
0020
0021
0022
0023 #define FSM_TIMER_DEBUG 0
0024
0025
0026
0027
0028
0029
0030 #define FSM_DEBUG_HISTORY 0
0031 #define FSM_HISTORY_SIZE 40
0032
0033 struct fsm_instance_t;
0034
0035
0036
0037
0038 typedef void (*fsm_function_t)(struct fsm_instance_t *, int, void *);
0039
0040
0041
0042
0043 typedef struct {
0044 fsm_function_t *jumpmatrix;
0045 int nr_events;
0046 int nr_states;
0047 const char **event_names;
0048 const char **state_names;
0049 } fsm;
0050
0051 #if FSM_DEBUG_HISTORY
0052
0053
0054
0055 typedef struct {
0056 int state;
0057 int event;
0058 } fsm_history;
0059 #endif
0060
0061
0062
0063
0064 typedef struct fsm_instance_t {
0065 fsm *f;
0066 atomic_t state;
0067 char name[16];
0068 void *userdata;
0069 int userint;
0070 wait_queue_head_t wait_q;
0071 #if FSM_DEBUG_HISTORY
0072 int history_index;
0073 int history_size;
0074 fsm_history history[FSM_HISTORY_SIZE];
0075 #endif
0076 } fsm_instance;
0077
0078
0079
0080
0081 typedef struct {
0082 int cond_state;
0083 int cond_event;
0084 fsm_function_t function;
0085 } fsm_node;
0086
0087
0088
0089
0090 typedef struct {
0091 fsm_instance *fi;
0092 struct timer_list tl;
0093 int expire_event;
0094 void *event_arg;
0095 } fsm_timer;
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 extern fsm_instance *
0110 init_fsm(char *name, const char **state_names,
0111 const char **event_names,
0112 int nr_states, int nr_events, const fsm_node *tmpl,
0113 int tmpl_len, gfp_t order);
0114
0115
0116
0117
0118
0119
0120 extern void kfree_fsm(fsm_instance *fi);
0121
0122 #if FSM_DEBUG_HISTORY
0123 extern void
0124 fsm_print_history(fsm_instance *fi);
0125
0126 extern void
0127 fsm_record_history(fsm_instance *fi, int state, int event);
0128 #endif
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 static inline int
0144 fsm_event(fsm_instance *fi, int event, void *arg)
0145 {
0146 fsm_function_t r;
0147 int state = atomic_read(&fi->state);
0148
0149 if ((state >= fi->f->nr_states) ||
0150 (event >= fi->f->nr_events) ) {
0151 printk(KERN_ERR "fsm(%s): Invalid state st(%ld/%ld) ev(%d/%ld)\n",
0152 fi->name, (long)state,(long)fi->f->nr_states, event,
0153 (long)fi->f->nr_events);
0154 #if FSM_DEBUG_HISTORY
0155 fsm_print_history(fi);
0156 #endif
0157 return 1;
0158 }
0159 r = fi->f->jumpmatrix[fi->f->nr_states * event + state];
0160 if (r) {
0161 #if FSM_DEBUG
0162 printk(KERN_DEBUG "fsm(%s): state %s event %s\n",
0163 fi->name, fi->f->state_names[state],
0164 fi->f->event_names[event]);
0165 #endif
0166 #if FSM_DEBUG_HISTORY
0167 fsm_record_history(fi, state, event);
0168 #endif
0169 r(fi, event, arg);
0170 return 0;
0171 } else {
0172 #if FSM_DEBUG || FSM_DEBUG_HISTORY
0173 printk(KERN_DEBUG "fsm(%s): no function for event %s in state %s\n",
0174 fi->name, fi->f->event_names[event],
0175 fi->f->state_names[state]);
0176 #endif
0177 #if FSM_DEBUG_HISTORY
0178 fsm_print_history(fi);
0179 #endif
0180 return !0;
0181 }
0182 }
0183
0184
0185
0186
0187
0188
0189
0190
0191 static inline void
0192 fsm_newstate(fsm_instance *fi, int newstate)
0193 {
0194 atomic_set(&fi->state,newstate);
0195 #if FSM_DEBUG_HISTORY
0196 fsm_record_history(fi, newstate, -1);
0197 #endif
0198 #if FSM_DEBUG
0199 printk(KERN_DEBUG "fsm(%s): New state %s\n", fi->name,
0200 fi->f->state_names[newstate]);
0201 #endif
0202 wake_up(&fi->wait_q);
0203 }
0204
0205
0206
0207
0208
0209
0210
0211
0212 static inline int
0213 fsm_getstate(fsm_instance *fi)
0214 {
0215 return atomic_read(&fi->state);
0216 }
0217
0218
0219
0220
0221
0222
0223
0224
0225 extern const char *fsm_getstate_str(fsm_instance *fi);
0226
0227
0228
0229
0230
0231
0232
0233
0234 extern void fsm_settimer(fsm_instance *fi, fsm_timer *);
0235
0236
0237
0238
0239
0240
0241 extern void fsm_deltimer(fsm_timer *timer);
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 extern int fsm_addtimer(fsm_timer *timer, int millisec, int event, void *arg);
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 extern void fsm_modtimer(fsm_timer *timer, int millisec, int event, void *arg);
0265
0266 #endif