Merge branch 'linus' into irq/genirq
[linux-2.6] / drivers / staging / epl / EplTimeruLinuxKernel.c
1 /****************************************************************************
2
3   (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4       www.systec-electronic.com
5
6   Project:      openPOWERLINK
7
8   Description:  source file for EPL User Timermodule for Linux kernel module
9
10   License:
11
12     Redistribution and use in source and binary forms, with or without
13     modification, are permitted provided that the following conditions
14     are met:
15
16     1. Redistributions of source code must retain the above copyright
17        notice, this list of conditions and the following disclaimer.
18
19     2. Redistributions in binary form must reproduce the above copyright
20        notice, this list of conditions and the following disclaimer in the
21        documentation and/or other materials provided with the distribution.
22
23     3. Neither the name of SYSTEC electronic GmbH nor the names of its
24        contributors may be used to endorse or promote products derived
25        from this software without prior written permission. For written
26        permission, please contact info@systec-electronic.com.
27
28     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32     COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39     POSSIBILITY OF SUCH DAMAGE.
40
41     Severability Clause:
42
43         If a provision of this License is or becomes illegal, invalid or
44         unenforceable in any jurisdiction, that shall not affect:
45         1. the validity or enforceability in that jurisdiction of any other
46            provision of this License; or
47         2. the validity or enforceability in other jurisdictions of that or
48            any other provision of this License.
49
50   -------------------------------------------------------------------------
51
52                 $RCSfile: EplTimeruLinuxKernel.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                 KEIL uVision 2
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/09/12 d.k.:   start of the implementation
68
69 ****************************************************************************/
70
71 #include "user/EplTimeru.h"
72 #include <linux/timer.h>
73
74 /***************************************************************************/
75 /*                                                                         */
76 /*                                                                         */
77 /*          G L O B A L   D E F I N I T I O N S                            */
78 /*                                                                         */
79 /*                                                                         */
80 /***************************************************************************/
81
82 //---------------------------------------------------------------------------
83 // const defines
84 //---------------------------------------------------------------------------
85
86 //---------------------------------------------------------------------------
87 // local types
88 //---------------------------------------------------------------------------
89 typedef struct {
90         struct timer_list m_Timer;
91         tEplTimerArg TimerArgument;
92
93 } tEplTimeruData;
94
95 //---------------------------------------------------------------------------
96 // modul globale vars
97 //---------------------------------------------------------------------------
98
99 //---------------------------------------------------------------------------
100 // local function prototypes
101 //---------------------------------------------------------------------------
102 static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
103
104 /***************************************************************************/
105 /*                                                                         */
106 /*                                                                         */
107 /*          C L A S S  <Epl Userspace-Timermodule for Linux Kernel>              */
108 /*                                                                         */
109 /*                                                                         */
110 /***************************************************************************/
111 //
112 // Description: Epl Userspace-Timermodule for Linux Kernel
113 //
114 //
115 /***************************************************************************/
116
117 //=========================================================================//
118 //                                                                         //
119 //          P U B L I C   F U N C T I O N S                                //
120 //                                                                         //
121 //=========================================================================//
122
123 //---------------------------------------------------------------------------
124 //
125 // Function:    EplTimeruInit
126 //
127 // Description: function inits first instance
128 //
129 // Parameters:  void
130 //
131 // Returns:     tEplKernel  = errorcode
132 //
133 // State:
134 //
135 //---------------------------------------------------------------------------
136
137 tEplKernel PUBLIC EplTimeruInit()
138 {
139         tEplKernel Ret;
140
141         Ret = EplTimeruAddInstance();
142
143         return Ret;
144 }
145
146 //---------------------------------------------------------------------------
147 //
148 // Function:    EplTimeruAddInstance
149 //
150 // Description: function inits additional instance
151 //
152 // Parameters:  void
153 //
154 // Returns:     tEplKernel  = errorcode
155 //
156 // State:
157 //
158 //---------------------------------------------------------------------------
159
160 tEplKernel PUBLIC EplTimeruAddInstance()
161 {
162         tEplKernel Ret;
163
164         Ret = kEplSuccessful;
165
166         return Ret;
167 }
168
169 //---------------------------------------------------------------------------
170 //
171 // Function:    EplTimeruDelInstance
172 //
173 // Description: function deletes instance
174 //              -> under Linux nothing to do
175 //              -> no instance table needed
176 //
177 // Parameters:  void
178 //
179 // Returns:     tEplKernel  = errorcode
180 //
181 // State:
182 //
183 //---------------------------------------------------------------------------
184
185 tEplKernel PUBLIC EplTimeruDelInstance()
186 {
187         tEplKernel Ret;
188
189         Ret = kEplSuccessful;
190
191         return Ret;
192 }
193
194 //---------------------------------------------------------------------------
195 //
196 // Function:    EplTimeruSetTimerMs
197 //
198 // Description: function creates a timer and returns the corresponding handle
199 //
200 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
201 //              ulTime_p    = time for timer in ms
202 //              Argument_p  = argument for timer
203 //
204 // Returns:     tEplKernel  = errorcode
205 //
206 // State:
207 //
208 //---------------------------------------------------------------------------
209
210 tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
211                                       unsigned long ulTime_p,
212                                       tEplTimerArg Argument_p)
213 {
214         tEplKernel Ret = kEplSuccessful;
215         tEplTimeruData *pData;
216
217         // check pointer to handle
218         if (pTimerHdl_p == NULL) {
219                 Ret = kEplTimerInvalidHandle;
220                 goto Exit;
221         }
222
223         pData = (tEplTimeruData *) EPL_MALLOC(sizeof(tEplTimeruData));
224         if (pData == NULL) {
225                 Ret = kEplNoResource;
226                 goto Exit;
227         }
228
229         init_timer(&pData->m_Timer);
230         pData->m_Timer.function = EplTimeruCbMs;
231         pData->m_Timer.data = (unsigned long)pData;
232         pData->m_Timer.expires = jiffies + ulTime_p * HZ / 1000;
233
234         EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
235
236         add_timer(&pData->m_Timer);
237
238         *pTimerHdl_p = (tEplTimerHdl) pData;
239
240       Exit:
241         return Ret;
242 }
243
244 //---------------------------------------------------------------------------
245 //
246 // Function:    EplTimeruModifyTimerMs
247 //
248 // Description: function changes a timer and returns the corresponding handle
249 //
250 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
251 //              ulTime_p    = time for timer in ms
252 //              Argument_p  = argument for timer
253 //
254 // Returns:     tEplKernel  = errorcode
255 //
256 // State:
257 //
258 //---------------------------------------------------------------------------
259
260 tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
261                                          unsigned long ulTime_p,
262                                          tEplTimerArg Argument_p)
263 {
264         tEplKernel Ret = kEplSuccessful;
265         tEplTimeruData *pData;
266
267         // check pointer to handle
268         if (pTimerHdl_p == NULL) {
269                 Ret = kEplTimerInvalidHandle;
270                 goto Exit;
271         }
272         // check handle itself, i.e. was the handle initialized before
273         if (*pTimerHdl_p == 0) {
274                 Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p);
275                 goto Exit;
276         }
277         pData = (tEplTimeruData *) * pTimerHdl_p;
278         if ((tEplTimeruData *) pData->m_Timer.data != pData) {
279                 Ret = kEplTimerInvalidHandle;
280                 goto Exit;
281         }
282
283         mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));
284
285         // copy the TimerArg after the timer is restarted,
286         // so that a timer occured immediately before mod_timer
287         // won't use the new TimerArg and
288         // therefore the old timer cannot be distinguished from the new one.
289         // But if the new timer is too fast, it may get lost.
290         EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
291
292         // check if timer is really running
293         if (timer_pending(&pData->m_Timer) == 0) {      // timer is not running
294                 // retry starting it
295                 add_timer(&pData->m_Timer);
296         }
297         // set handle to pointer of tEplTimeruData
298 //    *pTimerHdl_p = (tEplTimerHdl) pData;
299
300       Exit:
301         return Ret;
302 }
303
304 //---------------------------------------------------------------------------
305 //
306 // Function:    EplTimeruDeleteTimer
307 //
308 // Description: function deletes a timer
309 //
310 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
311 //
312 // Returns:     tEplKernel  = errorcode
313 //
314 // State:
315 //
316 //---------------------------------------------------------------------------
317
318 tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
319 {
320         tEplKernel Ret = kEplSuccessful;
321         tEplTimeruData *pData;
322
323         // check pointer to handle
324         if (pTimerHdl_p == NULL) {
325                 Ret = kEplTimerInvalidHandle;
326                 goto Exit;
327         }
328         // check handle itself, i.e. was the handle initialized before
329         if (*pTimerHdl_p == 0) {
330                 Ret = kEplSuccessful;
331                 goto Exit;
332         }
333         pData = (tEplTimeruData *) * pTimerHdl_p;
334         if ((tEplTimeruData *) pData->m_Timer.data != pData) {
335                 Ret = kEplTimerInvalidHandle;
336                 goto Exit;
337         }
338
339 /*    if (del_timer(&pData->m_Timer) == 1)
340     {
341         kfree(pData);
342     }
343 */
344         // try to delete the timer
345         del_timer(&pData->m_Timer);
346         // free memory in any case
347         kfree(pData);
348
349         // uninitialize handle
350         *pTimerHdl_p = 0;
351
352       Exit:
353         return Ret;
354
355 }
356
357 //---------------------------------------------------------------------------
358 //
359 // Function:    EplTimeruIsTimerActive
360 //
361 // Description: checks if the timer referenced by the handle is currently
362 //              active.
363 //
364 // Parameters:  TimerHdl_p  = handle of the timer to check
365 //
366 // Returns:     BOOL        = TRUE, if active;
367 //                            FALSE, otherwise
368 //
369 // State:
370 //
371 //---------------------------------------------------------------------------
372
373 BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
374 {
375         BOOL fActive = FALSE;
376         tEplTimeruData *pData;
377
378         // check handle itself, i.e. was the handle initialized before
379         if (TimerHdl_p == 0) {  // timer was not created yet, so it is not active
380                 goto Exit;
381         }
382         pData = (tEplTimeruData *) TimerHdl_p;
383         if ((tEplTimeruData *) pData->m_Timer.data != pData) {  // invalid timer
384                 goto Exit;
385         }
386         // check if timer is running
387         if (timer_pending(&pData->m_Timer) == 0) {      // timer is not running
388                 goto Exit;
389         }
390
391         fActive = TRUE;
392
393       Exit:
394         return fActive;
395 }
396
397 //=========================================================================//
398 //                                                                         //
399 //          P R I V A T E   F U N C T I O N S                              //
400 //                                                                         //
401 //=========================================================================//
402
403 //---------------------------------------------------------------------------
404 //
405 // Function:    EplTimeruCbMs
406 //
407 // Description: function to process timer
408 //
409 //
410 //
411 // Parameters:  lpParameter = pointer to structur of type tEplTimeruData
412 //
413 //
414 // Returns:     (none)
415 //
416 //
417 // State:
418 //
419 //---------------------------------------------------------------------------
420 static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
421 {
422         tEplKernel Ret = kEplSuccessful;
423         tEplTimeruData *pData;
424         tEplEvent EplEvent;
425         tEplTimerEventArg TimerEventArg;
426
427         pData = (tEplTimeruData *) ulParameter_p;
428
429         // call event function
430         TimerEventArg.m_TimerHdl = (tEplTimerHdl) pData;
431         TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg;
432
433         EplEvent.m_EventSink = pData->TimerArgument.m_EventSink;
434         EplEvent.m_EventType = kEplEventTypeTimer;
435         EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
436         EplEvent.m_pArg = &TimerEventArg;
437         EplEvent.m_uiSize = sizeof(TimerEventArg);
438
439         Ret = EplEventuPost(&EplEvent);
440
441         // d.k. do not free memory, user has to call EplTimeruDeleteTimer()
442         //kfree(pData);
443
444 }
445
446 // EOF