root/drivers/net/fddi/skfp/smttimer.c

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

DEFINITIONS

This source file includes following definitions.
  1. smt_timer_init
  2. smt_timer_stop
  3. smt_timer_start
  4. smt_force_irq
  5. smt_timer_done
  6. timer_done

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /******************************************************************************
   3  *
   4  *      (C)Copyright 1998,1999 SysKonnect,
   5  *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
   6  *
   7  *      See the file "skfddi.c" for further information.
   8  *
   9  *      The information in this file is provided "AS IS" without warranty.
  10  *
  11  ******************************************************************************/
  12 
  13 /*
  14         SMT timer
  15 */
  16 
  17 #include "h/types.h"
  18 #include "h/fddi.h"
  19 #include "h/smc.h"
  20 
  21 #ifndef lint
  22 static const char ID_sccs[] = "@(#)smttimer.c   2.4 97/08/04 (C) SK " ;
  23 #endif
  24 
  25 static void timer_done(struct s_smc *smc, int restart);
  26 
  27 void smt_timer_init(struct s_smc *smc)
  28 {
  29         smc->t.st_queue = NULL;
  30         smc->t.st_fast.tm_active = FALSE ;
  31         smc->t.st_fast.tm_next = NULL;
  32         hwt_init(smc) ;
  33 }
  34 
  35 void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer)
  36 {
  37         struct smt_timer        **prev ;
  38         struct smt_timer        *tm ;
  39 
  40         /*
  41          * remove timer from queue
  42          */
  43         timer->tm_active = FALSE ;
  44         if (smc->t.st_queue == timer && !timer->tm_next) {
  45                 hwt_stop(smc) ;
  46         }
  47         for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
  48                 if (tm == timer) {
  49                         *prev = tm->tm_next ;
  50                         if (tm->tm_next) {
  51                                 tm->tm_next->tm_delta += tm->tm_delta ;
  52                         }
  53                         return ;
  54                 }
  55         }
  56 }
  57 
  58 void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time,
  59                      u_long token)
  60 {
  61         struct smt_timer        **prev ;
  62         struct smt_timer        *tm ;
  63         u_long                  delta = 0 ;
  64 
  65         time /= 16 ;            /* input is uS, clock ticks are 16uS */
  66         if (!time)
  67                 time = 1 ;
  68         smt_timer_stop(smc,timer) ;
  69         timer->tm_smc = smc ;
  70         timer->tm_token = token ;
  71         timer->tm_active = TRUE ;
  72         if (!smc->t.st_queue) {
  73                 smc->t.st_queue = timer ;
  74                 timer->tm_next = NULL;
  75                 timer->tm_delta = time ;
  76                 hwt_start(smc,time) ;
  77                 return ;
  78         }
  79         /*
  80          * timer correction
  81          */
  82         timer_done(smc,0) ;
  83 
  84         /*
  85          * find position in queue
  86          */
  87         delta = 0 ;
  88         for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
  89                 if (delta + tm->tm_delta > time) {
  90                         break ;
  91                 }
  92                 delta += tm->tm_delta ;
  93         }
  94         /* insert in queue */
  95         *prev = timer ;
  96         timer->tm_next = tm ;
  97         timer->tm_delta = time - delta ;
  98         if (tm)
  99                 tm->tm_delta -= timer->tm_delta ;
 100         /*
 101          * start new with first
 102          */
 103         hwt_start(smc,smc->t.st_queue->tm_delta) ;
 104 }
 105 
 106 void smt_force_irq(struct s_smc *smc)
 107 {
 108         smt_timer_start(smc,&smc->t.st_fast,32L, EV_TOKEN(EVENT_SMT,SM_FAST)); 
 109 }
 110 
 111 void smt_timer_done(struct s_smc *smc)
 112 {
 113         timer_done(smc,1) ;
 114 }
 115 
 116 static void timer_done(struct s_smc *smc, int restart)
 117 {
 118         u_long                  delta ;
 119         struct smt_timer        *tm ;
 120         struct smt_timer        *next ;
 121         struct smt_timer        **last ;
 122         int                     done = 0 ;
 123 
 124         delta = hwt_read(smc) ;
 125         last = &smc->t.st_queue ;
 126         tm = smc->t.st_queue ;
 127         while (tm && !done) {
 128                 if (delta >= tm->tm_delta) {
 129                         tm->tm_active = FALSE ;
 130                         delta -= tm->tm_delta ;
 131                         last = &tm->tm_next ;
 132                         tm = tm->tm_next ;
 133                 }
 134                 else {
 135                         tm->tm_delta -= delta ;
 136                         delta = 0 ;
 137                         done = 1 ;
 138                 }
 139         }
 140         *last = NULL;
 141         next = smc->t.st_queue ;
 142         smc->t.st_queue = tm ;
 143 
 144         for ( tm = next ; tm ; tm = next) {
 145                 next = tm->tm_next ;
 146                 timer_event(smc,tm->tm_token) ;
 147         }
 148 
 149         if (restart && smc->t.st_queue)
 150                 hwt_start(smc,smc->t.st_queue->tm_delta) ;
 151 }
 152 

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