forked from Qortal/Brooklyn
04c1822c0a
Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey! Ring the door. Take your seat moosey!
211 lines
4.7 KiB
C
211 lines
4.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/**
|
|
* A generic FSM based on fsm used in isdn4linux
|
|
*
|
|
*/
|
|
|
|
#include "fsm.h"
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/timer.h>
|
|
|
|
MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)");
|
|
MODULE_DESCRIPTION("Finite state machine helper functions");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
fsm_instance *
|
|
init_fsm(char *name, const char **state_names, const char **event_names, int nr_states,
|
|
int nr_events, const fsm_node *tmpl, int tmpl_len, gfp_t order)
|
|
{
|
|
int i;
|
|
fsm_instance *this;
|
|
fsm_function_t *m;
|
|
fsm *f;
|
|
|
|
this = kzalloc(sizeof(fsm_instance), order);
|
|
if (this == NULL) {
|
|
printk(KERN_WARNING
|
|
"fsm(%s): init_fsm: Couldn't alloc instance\n", name);
|
|
return NULL;
|
|
}
|
|
strlcpy(this->name, name, sizeof(this->name));
|
|
init_waitqueue_head(&this->wait_q);
|
|
|
|
f = kzalloc(sizeof(fsm), order);
|
|
if (f == NULL) {
|
|
printk(KERN_WARNING
|
|
"fsm(%s): init_fsm: Couldn't alloc fsm\n", name);
|
|
kfree_fsm(this);
|
|
return NULL;
|
|
}
|
|
f->nr_events = nr_events;
|
|
f->nr_states = nr_states;
|
|
f->event_names = event_names;
|
|
f->state_names = state_names;
|
|
this->f = f;
|
|
|
|
m = kcalloc(nr_states*nr_events, sizeof(fsm_function_t), order);
|
|
if (m == NULL) {
|
|
printk(KERN_WARNING
|
|
"fsm(%s): init_fsm: Couldn't alloc jumptable\n", name);
|
|
kfree_fsm(this);
|
|
return NULL;
|
|
}
|
|
f->jumpmatrix = m;
|
|
|
|
for (i = 0; i < tmpl_len; i++) {
|
|
if ((tmpl[i].cond_state >= nr_states) ||
|
|
(tmpl[i].cond_event >= nr_events) ) {
|
|
printk(KERN_ERR
|
|
"fsm(%s): init_fsm: Bad template l=%d st(%ld/%ld) ev(%ld/%ld)\n",
|
|
name, i, (long)tmpl[i].cond_state, (long)f->nr_states,
|
|
(long)tmpl[i].cond_event, (long)f->nr_events);
|
|
kfree_fsm(this);
|
|
return NULL;
|
|
} else
|
|
m[nr_states * tmpl[i].cond_event + tmpl[i].cond_state] =
|
|
tmpl[i].function;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
void
|
|
kfree_fsm(fsm_instance *this)
|
|
{
|
|
if (this) {
|
|
if (this->f) {
|
|
kfree(this->f->jumpmatrix);
|
|
kfree(this->f);
|
|
}
|
|
kfree(this);
|
|
} else
|
|
printk(KERN_WARNING
|
|
"fsm: kfree_fsm called with NULL argument\n");
|
|
}
|
|
|
|
#if FSM_DEBUG_HISTORY
|
|
void
|
|
fsm_print_history(fsm_instance *fi)
|
|
{
|
|
int idx = 0;
|
|
int i;
|
|
|
|
if (fi->history_size >= FSM_HISTORY_SIZE)
|
|
idx = fi->history_index;
|
|
|
|
printk(KERN_DEBUG "fsm(%s): History:\n", fi->name);
|
|
for (i = 0; i < fi->history_size; i++) {
|
|
int e = fi->history[idx].event;
|
|
int s = fi->history[idx++].state;
|
|
idx %= FSM_HISTORY_SIZE;
|
|
if (e == -1)
|
|
printk(KERN_DEBUG " S=%s\n",
|
|
fi->f->state_names[s]);
|
|
else
|
|
printk(KERN_DEBUG " S=%s E=%s\n",
|
|
fi->f->state_names[s],
|
|
fi->f->event_names[e]);
|
|
}
|
|
fi->history_size = fi->history_index = 0;
|
|
}
|
|
|
|
void
|
|
fsm_record_history(fsm_instance *fi, int state, int event)
|
|
{
|
|
fi->history[fi->history_index].state = state;
|
|
fi->history[fi->history_index++].event = event;
|
|
fi->history_index %= FSM_HISTORY_SIZE;
|
|
if (fi->history_size < FSM_HISTORY_SIZE)
|
|
fi->history_size++;
|
|
}
|
|
#endif
|
|
|
|
const char *
|
|
fsm_getstate_str(fsm_instance *fi)
|
|
{
|
|
int st = atomic_read(&fi->state);
|
|
if (st >= fi->f->nr_states)
|
|
return "Invalid";
|
|
return fi->f->state_names[st];
|
|
}
|
|
|
|
static void
|
|
fsm_expire_timer(struct timer_list *t)
|
|
{
|
|
fsm_timer *this = from_timer(this, t, tl);
|
|
#if FSM_TIMER_DEBUG
|
|
printk(KERN_DEBUG "fsm(%s): Timer %p expired\n",
|
|
this->fi->name, this);
|
|
#endif
|
|
fsm_event(this->fi, this->expire_event, this->event_arg);
|
|
}
|
|
|
|
void
|
|
fsm_settimer(fsm_instance *fi, fsm_timer *this)
|
|
{
|
|
this->fi = fi;
|
|
#if FSM_TIMER_DEBUG
|
|
printk(KERN_DEBUG "fsm(%s): Create timer %p\n", fi->name,
|
|
this);
|
|
#endif
|
|
timer_setup(&this->tl, fsm_expire_timer, 0);
|
|
}
|
|
|
|
void
|
|
fsm_deltimer(fsm_timer *this)
|
|
{
|
|
#if FSM_TIMER_DEBUG
|
|
printk(KERN_DEBUG "fsm(%s): Delete timer %p\n", this->fi->name,
|
|
this);
|
|
#endif
|
|
del_timer(&this->tl);
|
|
}
|
|
|
|
int
|
|
fsm_addtimer(fsm_timer *this, int millisec, int event, void *arg)
|
|
{
|
|
|
|
#if FSM_TIMER_DEBUG
|
|
printk(KERN_DEBUG "fsm(%s): Add timer %p %dms\n",
|
|
this->fi->name, this, millisec);
|
|
#endif
|
|
|
|
timer_setup(&this->tl, fsm_expire_timer, 0);
|
|
this->expire_event = event;
|
|
this->event_arg = arg;
|
|
this->tl.expires = jiffies + (millisec * HZ) / 1000;
|
|
add_timer(&this->tl);
|
|
return 0;
|
|
}
|
|
|
|
/* FIXME: this function is never used, why */
|
|
void
|
|
fsm_modtimer(fsm_timer *this, int millisec, int event, void *arg)
|
|
{
|
|
|
|
#if FSM_TIMER_DEBUG
|
|
printk(KERN_DEBUG "fsm(%s): Restart timer %p %dms\n",
|
|
this->fi->name, this, millisec);
|
|
#endif
|
|
|
|
del_timer(&this->tl);
|
|
timer_setup(&this->tl, fsm_expire_timer, 0);
|
|
this->expire_event = event;
|
|
this->event_arg = arg;
|
|
this->tl.expires = jiffies + (millisec * HZ) / 1000;
|
|
add_timer(&this->tl);
|
|
}
|
|
|
|
EXPORT_SYMBOL(init_fsm);
|
|
EXPORT_SYMBOL(kfree_fsm);
|
|
EXPORT_SYMBOL(fsm_settimer);
|
|
EXPORT_SYMBOL(fsm_deltimer);
|
|
EXPORT_SYMBOL(fsm_addtimer);
|
|
EXPORT_SYMBOL(fsm_modtimer);
|
|
EXPORT_SYMBOL(fsm_getstate_str);
|
|
|
|
#if FSM_DEBUG_HISTORY
|
|
EXPORT_SYMBOL(fsm_print_history);
|
|
EXPORT_SYMBOL(fsm_record_history);
|
|
#endif
|