mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
6a57a21943
Found with git grep 'MODULE_AUTHOR(".*([^)]*@' Fixed with sed -i '/MODULE_AUTHOR(".*([^)]*@/{s/ (/ </g;s/)"/>"/;s/)and/> and/}' \ $(git grep -l 'MODULE_AUTHOR(".*([^)]*@') Also: in drivers/media/usb/siano/smsusb.c normalise ", INC" to ", Inc"; this is what every other MODULE_AUTHOR for this company says, and it's what the header says in drivers/sbus/char/openprom.c normalise a double-spaced separator; this is clearly copied from the copyright header, where the names are aligned on consecutive lines thusly: * Linux/SPARC PROM Configuration Driver * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) but the authorship branding is single-line Link: https://lkml.kernel.org/r/mk3geln4azm5binjjlfsgjepow4o73domjv6ajybws3tz22vb3@tarta.nabijaczleweli.xyz Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz> Cc: Joe Perches <joe@perches.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
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;
|
|
}
|
|
strscpy(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
|