root/drivers/s390/net/fsm.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. fsm_event
  2. fsm_newstate
  3. fsm_getstate

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _FSM_H_
   3 #define _FSM_H_
   4 
   5 #include <linux/kernel.h>
   6 #include <linux/types.h>
   7 #include <linux/timer.h>
   8 #include <linux/time.h>
   9 #include <linux/slab.h>
  10 #include <linux/sched.h>
  11 #include <linux/string.h>
  12 #include <linux/atomic.h>
  13 
  14 /**
  15  * Define this to get debugging messages.
  16  */
  17 #define FSM_DEBUG         0
  18 
  19 /**
  20  * Define this to get debugging massages for
  21  * timer handling.
  22  */
  23 #define FSM_TIMER_DEBUG   0
  24 
  25 /**
  26  * Define these to record a history of
  27  * Events/Statechanges and print it if a
  28  * action_function is not found.
  29  */
  30 #define FSM_DEBUG_HISTORY 0
  31 #define FSM_HISTORY_SIZE  40
  32 
  33 struct fsm_instance_t;
  34 
  35 /**
  36  * Definition of an action function, called by a FSM
  37  */
  38 typedef void (*fsm_function_t)(struct fsm_instance_t *, int, void *);
  39 
  40 /**
  41  * Internal jump table for a FSM
  42  */
  43 typedef struct {
  44         fsm_function_t *jumpmatrix;
  45         int nr_events;
  46         int nr_states;
  47         const char **event_names;
  48         const char **state_names;
  49 } fsm;
  50 
  51 #if FSM_DEBUG_HISTORY
  52 /**
  53  * Element of State/Event history used for debugging.
  54  */
  55 typedef struct {
  56         int state;
  57         int event;
  58 } fsm_history;
  59 #endif
  60 
  61 /**
  62  * Representation of a FSM
  63  */
  64 typedef struct fsm_instance_t {
  65         fsm *f;
  66         atomic_t state;
  67         char name[16];
  68         void *userdata;
  69         int userint;
  70         wait_queue_head_t wait_q;
  71 #if FSM_DEBUG_HISTORY
  72         int         history_index;
  73         int         history_size;
  74         fsm_history history[FSM_HISTORY_SIZE];
  75 #endif
  76 } fsm_instance;
  77 
  78 /**
  79  * Description of a state-event combination
  80  */
  81 typedef struct {
  82         int cond_state;
  83         int cond_event;
  84         fsm_function_t function;
  85 } fsm_node;
  86 
  87 /**
  88  * Description of a FSM Timer.
  89  */
  90 typedef struct {
  91         fsm_instance *fi;
  92         struct timer_list tl;
  93         int expire_event;
  94         void *event_arg;
  95 } fsm_timer;
  96 
  97 /**
  98  * Creates an FSM
  99  *
 100  * @param name        Name of this instance for logging purposes.
 101  * @param state_names An array of names for all states for logging purposes.
 102  * @param event_names An array of names for all events for logging purposes.
 103  * @param nr_states   Number of states for this instance.
 104  * @param nr_events   Number of events for this instance.
 105  * @param tmpl        An array of fsm_nodes, describing this FSM.
 106  * @param tmpl_len    Length of the describing array.
 107  * @param order       Parameter for allocation of the FSM data structs.
 108  */
 109 extern fsm_instance *
 110 init_fsm(char *name, const char **state_names,
 111          const char **event_names,
 112          int nr_states, int nr_events, const fsm_node *tmpl,
 113          int tmpl_len, gfp_t order);
 114 
 115 /**
 116  * Releases an FSM
 117  *
 118  * @param fi Pointer to an FSM, previously created with init_fsm.
 119  */
 120 extern void kfree_fsm(fsm_instance *fi);
 121 
 122 #if FSM_DEBUG_HISTORY
 123 extern void
 124 fsm_print_history(fsm_instance *fi);
 125 
 126 extern void
 127 fsm_record_history(fsm_instance *fi, int state, int event);
 128 #endif
 129 
 130 /**
 131  * Emits an event to a FSM.
 132  * If an action function is defined for the current state/event combination,
 133  * this function is called.
 134  *
 135  * @param fi    Pointer to FSM which should receive the event.
 136  * @param event The event do be delivered.
 137  * @param arg   A generic argument, handed to the action function.
 138  *
 139  * @return      0  on success,
 140  *              1  if current state or event is out of range
 141  *              !0 if state and event in range, but no action defined.
 142  */
 143 static inline int
 144 fsm_event(fsm_instance *fi, int event, void *arg)
 145 {
 146         fsm_function_t r;
 147         int state = atomic_read(&fi->state);
 148 
 149         if ((state >= fi->f->nr_states) ||
 150             (event >= fi->f->nr_events)       ) {
 151                 printk(KERN_ERR "fsm(%s): Invalid state st(%ld/%ld) ev(%d/%ld)\n",
 152                         fi->name, (long)state,(long)fi->f->nr_states, event,
 153                         (long)fi->f->nr_events);
 154 #if FSM_DEBUG_HISTORY
 155                 fsm_print_history(fi);
 156 #endif
 157                 return 1;
 158         }
 159         r = fi->f->jumpmatrix[fi->f->nr_states * event + state];
 160         if (r) {
 161 #if FSM_DEBUG
 162                 printk(KERN_DEBUG "fsm(%s): state %s event %s\n",
 163                        fi->name, fi->f->state_names[state],
 164                        fi->f->event_names[event]);
 165 #endif
 166 #if FSM_DEBUG_HISTORY
 167                 fsm_record_history(fi, state, event);
 168 #endif
 169                 r(fi, event, arg);
 170                 return 0;
 171         } else {
 172 #if FSM_DEBUG || FSM_DEBUG_HISTORY
 173                 printk(KERN_DEBUG "fsm(%s): no function for event %s in state %s\n",
 174                        fi->name, fi->f->event_names[event],
 175                        fi->f->state_names[state]);
 176 #endif
 177 #if FSM_DEBUG_HISTORY
 178                 fsm_print_history(fi);
 179 #endif
 180                 return !0;
 181         }
 182 }
 183 
 184 /**
 185  * Modifies the state of an FSM.
 186  * This does <em>not</em> trigger an event or calls an action function.
 187  *
 188  * @param fi    Pointer to FSM
 189  * @param state The new state for this FSM.
 190  */
 191 static inline void
 192 fsm_newstate(fsm_instance *fi, int newstate)
 193 {
 194         atomic_set(&fi->state,newstate);
 195 #if FSM_DEBUG_HISTORY
 196         fsm_record_history(fi, newstate, -1);
 197 #endif
 198 #if FSM_DEBUG
 199         printk(KERN_DEBUG "fsm(%s): New state %s\n", fi->name,
 200                 fi->f->state_names[newstate]);
 201 #endif
 202         wake_up(&fi->wait_q);
 203 }
 204 
 205 /**
 206  * Retrieves the state of an FSM
 207  *
 208  * @param fi Pointer to FSM
 209  *
 210  * @return The current state of the FSM.
 211  */
 212 static inline int
 213 fsm_getstate(fsm_instance *fi)
 214 {
 215         return atomic_read(&fi->state);
 216 }
 217 
 218 /**
 219  * Retrieves the name of the state of an FSM
 220  *
 221  * @param fi Pointer to FSM
 222  *
 223  * @return The current state of the FSM in a human readable form.
 224  */
 225 extern const char *fsm_getstate_str(fsm_instance *fi);
 226 
 227 /**
 228  * Initializes a timer for an FSM.
 229  * This prepares an fsm_timer for usage with fsm_addtimer.
 230  *
 231  * @param fi    Pointer to FSM
 232  * @param timer The timer to be initialized.
 233  */
 234 extern void fsm_settimer(fsm_instance *fi, fsm_timer *);
 235 
 236 /**
 237  * Clears a pending timer of an FSM instance.
 238  *
 239  * @param timer The timer to clear.
 240  */
 241 extern void fsm_deltimer(fsm_timer *timer);
 242 
 243 /**
 244  * Adds and starts a timer to an FSM instance.
 245  *
 246  * @param timer    The timer to be added. The field fi of that timer
 247  *                 must have been set to point to the instance.
 248  * @param millisec Duration, after which the timer should expire.
 249  * @param event    Event, to trigger if timer expires.
 250  * @param arg      Generic argument, provided to expiry function.
 251  *
 252  * @return         0 on success, -1 if timer is already active.
 253  */
 254 extern int fsm_addtimer(fsm_timer *timer, int millisec, int event, void *arg);
 255 
 256 /**
 257  * Modifies a timer of an FSM.
 258  *
 259  * @param timer    The timer to modify.
 260  * @param millisec Duration, after which the timer should expire.
 261  * @param event    Event, to trigger if timer expires.
 262  * @param arg      Generic argument, provided to expiry function.
 263  */
 264 extern void fsm_modtimer(fsm_timer *timer, int millisec, int event, void *arg);
 265 
 266 #endif /* _FSM_H_ */

/* [<][>][^][v][top][bottom][index][help] */