fsm.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* $Id: fsm.c,v 1.14.6.4 2001/09/23 22:24:47 kai Exp $
  2. *
  3. * Finite state machine
  4. *
  5. * Author Karsten Keil
  6. * Copyright by Karsten Keil <keil@isdn4linux.de>
  7. * by Kai Germaschewski <kai.germaschewski@gmx.de>
  8. *
  9. * This software may be used and distributed according to the terms
  10. * of the GNU General Public License, incorporated herein by reference.
  11. *
  12. * Thanks to Jan den Ouden
  13. * Fritz Elfert
  14. *
  15. */
  16. #include <linux/module.h>
  17. #include <linux/init.h>
  18. #include "hisax.h"
  19. #define FSM_TIMER_DEBUG 0
  20. int
  21. FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
  22. {
  23. int i;
  24. fsm->jumpmatrix = (FSMFNPTR *)
  25. kzalloc(sizeof (FSMFNPTR) * fsm->state_count * fsm->event_count, GFP_KERNEL);
  26. if (!fsm->jumpmatrix)
  27. return -ENOMEM;
  28. for (i = 0; i < fncount; i++)
  29. if ((fnlist[i].state>=fsm->state_count) || (fnlist[i].event>=fsm->event_count)) {
  30. printk(KERN_ERR "FsmNew Error line %d st(%ld/%ld) ev(%ld/%ld)\n",
  31. i,(long)fnlist[i].state,(long)fsm->state_count,
  32. (long)fnlist[i].event,(long)fsm->event_count);
  33. } else
  34. fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
  35. fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
  36. return 0;
  37. }
  38. void
  39. FsmFree(struct Fsm *fsm)
  40. {
  41. kfree((void *) fsm->jumpmatrix);
  42. }
  43. int
  44. FsmEvent(struct FsmInst *fi, int event, void *arg)
  45. {
  46. FSMFNPTR r;
  47. if ((fi->state>=fi->fsm->state_count) || (event >= fi->fsm->event_count)) {
  48. printk(KERN_ERR "FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
  49. (long)fi->state,(long)fi->fsm->state_count,event,(long)fi->fsm->event_count);
  50. return(1);
  51. }
  52. r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state];
  53. if (r) {
  54. if (fi->debug)
  55. fi->printdebug(fi, "State %s Event %s",
  56. fi->fsm->strState[fi->state],
  57. fi->fsm->strEvent[event]);
  58. r(fi, event, arg);
  59. return (0);
  60. } else {
  61. if (fi->debug)
  62. fi->printdebug(fi, "State %s Event %s no routine",
  63. fi->fsm->strState[fi->state],
  64. fi->fsm->strEvent[event]);
  65. return (!0);
  66. }
  67. }
  68. void
  69. FsmChangeState(struct FsmInst *fi, int newstate)
  70. {
  71. fi->state = newstate;
  72. if (fi->debug)
  73. fi->printdebug(fi, "ChangeState %s",
  74. fi->fsm->strState[newstate]);
  75. }
  76. static void
  77. FsmExpireTimer(struct FsmTimer *ft)
  78. {
  79. #if FSM_TIMER_DEBUG
  80. if (ft->fi->debug)
  81. ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft);
  82. #endif
  83. FsmEvent(ft->fi, ft->event, ft->arg);
  84. }
  85. void
  86. FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft)
  87. {
  88. ft->fi = fi;
  89. ft->tl.function = (void *) FsmExpireTimer;
  90. ft->tl.data = (long) ft;
  91. #if FSM_TIMER_DEBUG
  92. if (ft->fi->debug)
  93. ft->fi->printdebug(ft->fi, "FsmInitTimer %lx", (long) ft);
  94. #endif
  95. init_timer(&ft->tl);
  96. }
  97. void
  98. FsmDelTimer(struct FsmTimer *ft, int where)
  99. {
  100. #if FSM_TIMER_DEBUG
  101. if (ft->fi->debug)
  102. ft->fi->printdebug(ft->fi, "FsmDelTimer %lx %d", (long) ft, where);
  103. #endif
  104. del_timer(&ft->tl);
  105. }
  106. int
  107. FsmAddTimer(struct FsmTimer *ft,
  108. int millisec, int event, void *arg, int where)
  109. {
  110. #if FSM_TIMER_DEBUG
  111. if (ft->fi->debug)
  112. ft->fi->printdebug(ft->fi, "FsmAddTimer %lx %d %d",
  113. (long) ft, millisec, where);
  114. #endif
  115. if (timer_pending(&ft->tl)) {
  116. printk(KERN_WARNING "FsmAddTimer: timer already active!\n");
  117. ft->fi->printdebug(ft->fi, "FsmAddTimer already active!");
  118. return -1;
  119. }
  120. init_timer(&ft->tl);
  121. ft->event = event;
  122. ft->arg = arg;
  123. ft->tl.expires = jiffies + (millisec * HZ) / 1000;
  124. add_timer(&ft->tl);
  125. return 0;
  126. }
  127. void
  128. FsmRestartTimer(struct FsmTimer *ft,
  129. int millisec, int event, void *arg, int where)
  130. {
  131. #if FSM_TIMER_DEBUG
  132. if (ft->fi->debug)
  133. ft->fi->printdebug(ft->fi, "FsmRestartTimer %lx %d %d",
  134. (long) ft, millisec, where);
  135. #endif
  136. if (timer_pending(&ft->tl))
  137. del_timer(&ft->tl);
  138. init_timer(&ft->tl);
  139. ft->event = event;
  140. ft->arg = arg;
  141. ft->tl.expires = jiffies + (millisec * HZ) / 1000;
  142. add_timer(&ft->tl);
  143. }