sktimer.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Name: sktimer.c
  4.  * Project: PCI Gigabit Ethernet Adapter
  5.  * Version: $Revision: 1.11 $
  6.  * Date: $Date: 1998/12/17 13:24:13 $
  7.  * Purpose: High level timer functions.
  8.  *
  9.  ******************************************************************************/
  10. /******************************************************************************
  11.  *
  12.  * (C)Copyright 1989-1998 SysKonnect,
  13.  * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  14.  * All Rights Reserved
  15.  *
  16.  * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT
  17.  * The copyright notice above does not evidence any
  18.  * actual or intended publication of such source code.
  19.  *
  20.  * This Module contains Proprietary Information of SysKonnect
  21.  * and should be treated as Confidential.
  22.  *
  23.  * The information in this file is provided for the exclusive use of
  24.  * the licensees of SysKonnect.
  25.  * Such users have the right to use, modify, and incorporate this code
  26.  * into products for purposes authorized by the license agreement
  27.  * provided they include this notice and the associated copyright notice
  28.  * with any such product.
  29.  * The information in this file is provided "AS IS" without warranty.
  30.  *
  31.  ******************************************************************************/
  32. /******************************************************************************
  33.  *
  34.  * History:
  35.  *
  36.  * $Log: sktimer.c,v $
  37.  * Revision 1.11  1998/12/17 13:24:13  gklug
  38.  * fix: restart problem: do NOT destroy timer queue if init 1 is done
  39.  *
  40.  * Revision 1.10  1998/10/15 15:11:36  gklug
  41.  * fix: ID_sccs to SysKonnectFileId
  42.  *
  43.  * Revision 1.9  1998/09/15 15:15:04  cgoos
  44.  * Changed TRUE/FALSE to SK_TRUE/SK_FALSE
  45.  *
  46.  * Revision 1.8  1998/09/08 08:47:55  gklug
  47.  * add: init level handling
  48.  *
  49.  * Revision 1.7  1998/08/19 09:50:53  gklug
  50.  * fix: remove struct keyword from c-code (see CCC) add typedefs
  51.  *
  52.  * Revision 1.6  1998/08/17 13:43:13  gklug
  53.  * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
  54.  *
  55.  * Revision 1.5  1998/08/14 07:09:14  gklug
  56.  * fix: chg pAc -> pAC
  57.  *
  58.  * Revision 1.4  1998/08/07 12:53:46  gklug
  59.  * fix: first compiled version
  60.  *
  61.  * Revision 1.3  1998/08/07 09:31:53  gklug
  62.  * fix: delta spelling
  63.  *
  64.  * Revision 1.2  1998/08/07 09:31:02  gklug
  65.  * adapt functions to new c coding conventions
  66.  * rmv: "fast" handling
  67.  * chg: inserting of new timer in queue.
  68.  * chg: event queue generation when timer runs out
  69.  *
  70.  * Revision 1.1  1998/08/05 11:27:55  gklug
  71.  * first version: adapted from SMT
  72.  *
  73.  *
  74.  *
  75.  *
  76.  ******************************************************************************/
  77. /*
  78. Event queue and dispatcher
  79. */
  80. static const char SysKonnectFileId[] =
  81. "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.11 1998/12/17 13:24:13 gklug Exp $" ;
  82. #include "h/skdrv1st.h" /* Driver Specific Definitions */
  83. #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
  84. #ifdef __C2MAN__
  85. /*
  86. Event queue management.
  87. General Description:
  88.  */
  89. intro()
  90. {}
  91. #endif
  92. /* Forward declaration */
  93. static void timer_done(SK_AC *pAC,SK_IOC Ioc,int Restart);
  94. /*
  95.  * Inits the software timer
  96.  *
  97.  * needs to be called during Init level 1.
  98.  */
  99. void SkTimerInit(
  100. SK_AC *pAC, /* Adapters context */
  101. SK_IOC Ioc, /* IoContext */
  102. int Level) /* Init Level */
  103. {
  104. switch (Level) {
  105. case SK_INIT_DATA:
  106. pAC->Tim.StQueue = 0 ;
  107. break;
  108. case SK_INIT_IO:
  109. SkHwtInit(pAC,Ioc) ;
  110. SkTimerDone(pAC, Ioc);
  111. break;
  112. default:
  113. break;
  114. }
  115. }
  116. /*
  117.  * Stops a high level timer
  118.  * - If a timer is not in the queue the function returns normally, too.
  119.  */
  120. void SkTimerStop(
  121. SK_AC *pAC, /* Adapters context */
  122. SK_IOC Ioc, /* IoContext */
  123. SK_TIMER *pTimer) /* Timer Pointer to be started */
  124. {
  125. SK_TIMER **ppTimPrev ;
  126. SK_TIMER *pTm ;
  127. /*
  128.  * remove timer from queue
  129.  */
  130. pTimer->TmActive = SK_FALSE ;
  131. if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) {
  132. SkHwtStop(pAC,Ioc) ;
  133. }
  134. for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
  135. ppTimPrev = &pTm->TmNext ) {
  136. if (pTm == pTimer) {
  137. /*
  138.  * Timer found in queue
  139.  * - dequeue it and
  140.  * - correct delta of the next timer
  141.  */
  142. *ppTimPrev = pTm->TmNext ;
  143. if (pTm->TmNext) {
  144. /* correct delta of next timer in queue */
  145. pTm->TmNext->TmDelta += pTm->TmDelta ;
  146. }
  147. return ;
  148. }
  149. }
  150. }
  151. /*
  152.  * Start a high level software timer
  153.  */
  154. void SkTimerStart(
  155. SK_AC *pAC, /* Adapters context */
  156. SK_IOC Ioc, /* IoContext */
  157. SK_TIMER *pTimer, /* Timer Pointer to be started */
  158. SK_U32 Time, /* Time value */
  159. SK_U32 Class, /* Event Class for this timer */
  160. SK_U32 Event, /* Event Value for this timer */
  161. SK_EVPARA Para) /* Event Parameter for this timer */
  162. {
  163. SK_TIMER **ppTimPrev ;
  164. SK_TIMER *pTm ;
  165. SK_U32 Delta ;
  166. Time /= 16 ; /* input is uS, clock ticks are 16uS */
  167. if (!Time)
  168. Time = 1 ;
  169. SkTimerStop(pAC,Ioc,pTimer) ;
  170. pTimer->TmClass = Class ;
  171. pTimer->TmEvent = Event ;
  172. pTimer->TmPara = Para ;
  173. pTimer->TmActive = SK_TRUE ;
  174. if (!pAC->Tim.StQueue) {
  175. /* First Timer to be started */
  176. pAC->Tim.StQueue = pTimer ;
  177. pTimer->TmNext = 0 ;
  178. pTimer->TmDelta = Time ;
  179. SkHwtStart(pAC,Ioc,Time) ;
  180. return ;
  181. }
  182. /*
  183.  * timer correction
  184.  */
  185. timer_done(pAC,Ioc,0) ;
  186. /*
  187.  * find position in queue
  188.  */
  189. Delta = 0 ;
  190. for (ppTimPrev = &pAC->Tim.StQueue ; (pTm = *ppTimPrev) ;
  191. ppTimPrev = &pTm->TmNext ) {
  192. if (Delta + pTm->TmDelta > Time) {
  193. /* Position found */
  194. /* Here the timer needs to be inserted. */
  195. break ;
  196. }
  197. Delta += pTm->TmDelta ;
  198. }
  199. /* insert in queue */
  200. *ppTimPrev = pTimer ;
  201. pTimer->TmNext = pTm ;
  202. pTimer->TmDelta = Time - Delta ;
  203. if (pTm) {
  204. /* There is a next timer
  205.  * -> correct its Delta value.
  206.  */
  207. pTm->TmDelta -= pTimer->TmDelta ;
  208. }
  209. /*
  210.  * start new with first
  211.  */
  212. SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
  213. }
  214. void SkTimerDone(
  215. SK_AC *pAC, /* Adapters context */
  216. SK_IOC Ioc) /* IoContext */
  217. {
  218. timer_done(pAC,Ioc,1) ;
  219. }
  220. static void timer_done(
  221. SK_AC *pAC, /* Adapters context */
  222. SK_IOC Ioc, /* IoContext */
  223. int Restart) /* Do we need to restart the Hardware timer ? */
  224. {
  225. SK_U32 Delta ;
  226. SK_TIMER *pTm ;
  227. SK_TIMER *pTComp ; /* Timer completed now now */
  228. SK_TIMER **ppLast ; /* Next field of Last timer to be deq */
  229. int Done = 0 ;
  230. Delta = SkHwtRead(pAC,Ioc) ;
  231. ppLast = &pAC->Tim.StQueue ;
  232. pTm = pAC->Tim.StQueue ;
  233. while (pTm && !Done) {
  234. if (Delta >= pTm->TmDelta) {
  235. /* Timer ran out */
  236. pTm->TmActive = SK_FALSE ;
  237. Delta -= pTm->TmDelta ;
  238. ppLast = &pTm->TmNext ;
  239. pTm = pTm->TmNext ;
  240. } else {
  241. /* We found the first timer that did not run out */
  242. pTm->TmDelta -= Delta ;
  243. Delta = 0 ;
  244. Done = 1 ;
  245. }
  246. }
  247. *ppLast = 0 ;
  248. /*
  249.  * pTm points to the first Timer that did not run out.
  250.  * StQueue points to the first Timer that run out.
  251.  */
  252. for ( pTComp = pAC->Tim.StQueue ; pTComp ; pTComp = pTComp->TmNext) {
  253. SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent,
  254. pTComp->TmPara) ;
  255. }
  256. /* Set head of timer queue to the first timer that did not run out */
  257. pAC->Tim.StQueue = pTm ;
  258. if (Restart && pAC->Tim.StQueue) {
  259. /* Restart HW timer */
  260. SkHwtStart(pAC,Ioc,pAC->Tim.StQueue->TmDelta) ;
  261. }
  262. }
  263. /* End of file */