patch-2.4.2 linux/drivers/s390/net/fsm.c
Next file: linux/drivers/s390/net/fsm.h
Previous file: linux/drivers/s390/net/ctcmain.c
Back to the patch index
Back to the overall index
- Lines: 231
- Date:
Tue Feb 13 14:13:44 2001
- Orig file:
v2.4.1/linux/drivers/s390/net/fsm.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.1/linux/drivers/s390/net/fsm.c linux/drivers/s390/net/fsm.c
@@ -0,0 +1,230 @@
+/**
+ * $Id: fsm.c,v 1.1 2000/11/30 11:21:08 bird Exp $
+ *
+ * A generic FSM based on fsm used in isdn4linux
+ *
+ * $Log: fsm.c,v $
+ * Revision 1.1 2000/11/30 11:21:08 bird
+ * Support for new ctc driver
+ *
+ * Revision 1.2 2000/11/10 17:25:11 felfert
+ * Changes for kernel 2.4
+ *
+ * Revision 1.1 2000/11/03 16:58:45 felfert
+ * Initial import
+ *
+ *
+ */
+
+#include "fsm.h"
+#include <linux/version.h>
+
+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, int order)
+{
+ int i;
+ fsm_instance *this;
+ fsm_function_t *m;
+ fsm *f;
+
+ this = (fsm_instance *)kmalloc(sizeof(fsm_instance), order);
+ if (this == NULL) {
+ printk(KERN_WARNING
+ "fsm(%s): init_fsm: Couldn't alloc instance\n", name);
+ return NULL;
+ }
+ memset(this, 0, sizeof(fsm_instance));
+ strncpy(this->name, name, sizeof(this->name));
+
+ f = (fsm *)kmalloc(sizeof(fsm), order);
+ if (f == NULL) {
+ printk(KERN_WARNING
+ "fsm(%s): init_fsm: Couldn't alloc fsm\n", name);
+ kfree_fsm(this);
+ return NULL;
+ }
+ memset(f, 0, sizeof(fsm));
+ f->nr_events = nr_events;
+ f->nr_states = nr_states;
+ f->event_names = event_names;
+ f->state_names = state_names;
+ this->f = f;
+
+ m = (fsm_function_t *)kmalloc(
+ sizeof(fsm_function_t) * nr_states * nr_events, order);
+ if (m == NULL) {
+ printk(KERN_WARNING
+ "fsm(%s): init_fsm: Couldn't alloc jumptable\n", name);
+ kfree_fsm(this);
+ return NULL;
+ }
+ memset(m, 0, sizeof(fsm_function_t) * f->nr_states * f->nr_events);
+ 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) {
+ if (this->f->jumpmatrix)
+ 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(fsm_timer *this)
+{
+#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;
+ this->tl.function = (void *)fsm_expire_timer;
+ this->tl.data = (long)this;
+#if FSM_TIMER_DEBUG
+ printk(KERN_DEBUG "fsm(%s): Create timer %p\n", fi->name,
+ this);
+#endif
+ init_timer(&this->tl);
+}
+
+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
+
+#if LINUX_VERSION_CODE >= 0x020300
+ if (this->tl.list.next || this->tl.list.prev) {
+ printk(KERN_WARNING "fsm(%s): timer already active!\n",
+ this->fi->name);
+ return -1;
+ }
+#else
+ if (this->tl.next || this->tl.prev) {
+ printk(KERN_WARNING "fsm(%s): timer already active!\n",
+ this->fi->name);
+ return -1;
+ }
+#endif
+ init_timer(&this->tl);
+ this->tl.function = (void *)fsm_expire_timer;
+ this->tl.data = (long)this;
+ this->expire_event = event;
+ this->event_arg = arg;
+ this->tl.expires = jiffies + (millisec * HZ) / 1000;
+ add_timer(&this->tl);
+ return 0;
+}
+
+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
+
+#if LINUX_VERSION_CODE >= 0x020300
+ if (this->tl.list.next || this->tl.list.prev)
+ del_timer(&this->tl);
+#else
+ if (this->tl.next || this->tl.prev)
+ del_timer(&this->tl);
+#endif
+ init_timer(&this->tl);
+ this->tl.function = (void *)fsm_expire_timer;
+ this->tl.data = (long)this;
+ this->expire_event = event;
+ this->event_arg = arg;
+ this->tl.expires = jiffies + (millisec * HZ) / 1000;
+ add_timer(&this->tl);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)