]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/net/sk98lin/sktimer.c
1 /******************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.12 $
6 * Date: $Date: 1999/11/22 13:38:51 $
7 * Purpose: High level timer functions.
9 ******************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998,1999 SysKonnect,
14 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * The information in this file is provided "AS IS" without warranty.
23 ******************************************************************************/
25 /******************************************************************************
30 * Revision 1.12 1999/11/22 13:38:51 cgoos
31 * Changed license header to GPL.
33 * Revision 1.11 1998/12/17 13:24:13 gklug
34 * fix: restart problem: do NOT destroy timer queue if init 1 is done
36 * Revision 1.10 1998/10/15 15:11:36 gklug
37 * fix: ID_sccs to SysKonnectFileId
39 * Revision 1.9 1998/09/15 15:15:04 cgoos
40 * Changed TRUE/FALSE to SK_TRUE/SK_FALSE
42 * Revision 1.8 1998/09/08 08:47:55 gklug
43 * add: init level handling
45 * Revision 1.7 1998/08/19 09:50:53 gklug
46 * fix: remove struct keyword from c-code (see CCC) add typedefs
48 * Revision 1.6 1998/08/17 13:43:13 gklug
49 * chg: Parameter will be union of 64bit para, 2 times SK_U32 or SK_PTR
51 * Revision 1.5 1998/08/14 07:09:14 gklug
54 * Revision 1.4 1998/08/07 12:53:46 gklug
55 * fix: first compiled version
57 * Revision 1.3 1998/08/07 09:31:53 gklug
60 * Revision 1.2 1998/08/07 09:31:02 gklug
61 * adapt functions to new c coding conventions
62 * rmv: "fast" handling
63 * chg: inserting of new timer in queue.
64 * chg: event queue generation when timer runs out
66 * Revision 1.1 1998/08/05 11:27:55 gklug
67 * first version: adapted from SMT
72 ******************************************************************************/
80 Event queue and dispatcher
82 static const char SysKonnectFileId
[] =
83 "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.12 1999/11/22 13:38:51 cgoos Exp $" ;
85 #include "h/skdrv1st.h" /* Driver Specific Definitions */
86 #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
90 Event queue management.
100 /* Forward declaration */
101 static void timer_done(SK_AC
*pAC
,SK_IOC Ioc
,int Restart
);
105 * Inits the software timer
107 * needs to be called during Init level 1.
110 SK_AC
*pAC
, /* Adapters context */
111 SK_IOC Ioc
, /* IoContext */
112 int Level
) /* Init Level */
116 pAC
->Tim
.StQueue
= 0 ;
120 SkTimerDone(pAC
, Ioc
);
128 * Stops a high level timer
129 * - If a timer is not in the queue the function returns normally, too.
132 SK_AC
*pAC
, /* Adapters context */
133 SK_IOC Ioc
, /* IoContext */
134 SK_TIMER
*pTimer
) /* Timer Pointer to be started */
136 SK_TIMER
**ppTimPrev
;
140 * remove timer from queue
142 pTimer
->TmActive
= SK_FALSE
;
143 if (pAC
->Tim
.StQueue
== pTimer
&& !pTimer
->TmNext
) {
146 for (ppTimPrev
= &pAC
->Tim
.StQueue
; (pTm
= *ppTimPrev
) ;
147 ppTimPrev
= &pTm
->TmNext
) {
150 * Timer found in queue
152 * - correct delta of the next timer
154 *ppTimPrev
= pTm
->TmNext
;
157 /* correct delta of next timer in queue */
158 pTm
->TmNext
->TmDelta
+= pTm
->TmDelta
;
166 * Start a high level software timer
169 SK_AC
*pAC
, /* Adapters context */
170 SK_IOC Ioc
, /* IoContext */
171 SK_TIMER
*pTimer
, /* Timer Pointer to be started */
172 SK_U32 Time
, /* Time value */
173 SK_U32 Class
, /* Event Class for this timer */
174 SK_U32 Event
, /* Event Value for this timer */
175 SK_EVPARA Para
) /* Event Parameter for this timer */
177 SK_TIMER
**ppTimPrev
;
181 Time
/= 16 ; /* input is uS, clock ticks are 16uS */
185 SkTimerStop(pAC
,Ioc
,pTimer
) ;
187 pTimer
->TmClass
= Class
;
188 pTimer
->TmEvent
= Event
;
189 pTimer
->TmPara
= Para
;
190 pTimer
->TmActive
= SK_TRUE
;
192 if (!pAC
->Tim
.StQueue
) {
193 /* First Timer to be started */
194 pAC
->Tim
.StQueue
= pTimer
;
196 pTimer
->TmDelta
= Time
;
197 SkHwtStart(pAC
,Ioc
,Time
) ;
204 timer_done(pAC
,Ioc
,0) ;
207 * find position in queue
210 for (ppTimPrev
= &pAC
->Tim
.StQueue
; (pTm
= *ppTimPrev
) ;
211 ppTimPrev
= &pTm
->TmNext
) {
212 if (Delta
+ pTm
->TmDelta
> Time
) {
214 /* Here the timer needs to be inserted. */
217 Delta
+= pTm
->TmDelta
;
220 /* insert in queue */
221 *ppTimPrev
= pTimer
;
222 pTimer
->TmNext
= pTm
;
223 pTimer
->TmDelta
= Time
- Delta
;
226 /* There is a next timer
227 * -> correct its Delta value.
229 pTm
->TmDelta
-= pTimer
->TmDelta
;
233 * start new with first
235 SkHwtStart(pAC
,Ioc
,pAC
->Tim
.StQueue
->TmDelta
) ;
240 SK_AC
*pAC
, /* Adapters context */
241 SK_IOC Ioc
) /* IoContext */
243 timer_done(pAC
,Ioc
,1) ;
247 static void timer_done(
248 SK_AC
*pAC
, /* Adapters context */
249 SK_IOC Ioc
, /* IoContext */
250 int Restart
) /* Do we need to restart the Hardware timer ? */
254 SK_TIMER
*pTComp
; /* Timer completed now now */
255 SK_TIMER
**ppLast
; /* Next field of Last timer to be deq */
258 Delta
= SkHwtRead(pAC
,Ioc
) ;
259 ppLast
= &pAC
->Tim
.StQueue
;
260 pTm
= pAC
->Tim
.StQueue
;
261 while (pTm
&& !Done
) {
262 if (Delta
>= pTm
->TmDelta
) {
264 pTm
->TmActive
= SK_FALSE
;
265 Delta
-= pTm
->TmDelta
;
266 ppLast
= &pTm
->TmNext
;
269 /* We found the first timer that did not run out */
270 pTm
->TmDelta
-= Delta
;
277 * pTm points to the first Timer that did not run out.
278 * StQueue points to the first Timer that run out.
281 for ( pTComp
= pAC
->Tim
.StQueue
; pTComp
; pTComp
= pTComp
->TmNext
) {
282 SkEventQueue(pAC
,pTComp
->TmClass
, pTComp
->TmEvent
,
286 /* Set head of timer queue to the first timer that did not run out */
287 pAC
->Tim
.StQueue
= pTm
;
289 if (Restart
&& pAC
->Tim
.StQueue
) {
290 /* Restart HW timer */
291 SkHwtStart(pAC
,Ioc
,pAC
->Tim
.StQueue
->TmDelta
) ;
295 #endif /* CONFIG_SK98 */