Staging: add epl stack
[firefly-linux-kernel-4.4.55.git] / 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 {
91     struct timer_list   m_Timer;
92     tEplTimerArg        TimerArgument;
93
94 } tEplTimeruData;
95
96 //---------------------------------------------------------------------------
97 // modul globale vars
98 //---------------------------------------------------------------------------
99
100 //---------------------------------------------------------------------------
101 // local function prototypes
102 //---------------------------------------------------------------------------
103 static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
104
105 /***************************************************************************/
106 /*                                                                         */
107 /*                                                                         */
108 /*          C L A S S  <Epl Userspace-Timermodule for Linux Kernel>              */
109 /*                                                                         */
110 /*                                                                         */
111 /***************************************************************************/
112 //
113 // Description: Epl Userspace-Timermodule for Linux Kernel
114 //
115 //
116 /***************************************************************************/
117
118 //=========================================================================//
119 //                                                                         //
120 //          P U B L I C   F U N C T I O N S                                //
121 //                                                                         //
122 //=========================================================================//
123
124 //---------------------------------------------------------------------------
125 //
126 // Function:    EplTimeruInit
127 //
128 // Description: function inits first instance
129 //
130 // Parameters:  void
131 //
132 // Returns:     tEplKernel  = errorcode
133 //
134 // State:
135 //
136 //---------------------------------------------------------------------------
137
138 tEplKernel PUBLIC EplTimeruInit()
139 {
140 tEplKernel  Ret;
141
142     Ret = EplTimeruAddInstance();
143
144     return Ret;
145 }
146
147
148 //---------------------------------------------------------------------------
149 //
150 // Function:    EplTimeruAddInstance
151 //
152 // Description: function inits additional instance
153 //
154 // Parameters:  void
155 //
156 // Returns:     tEplKernel  = errorcode
157 //
158 // State:
159 //
160 //---------------------------------------------------------------------------
161
162 tEplKernel PUBLIC EplTimeruAddInstance()
163 {
164 tEplKernel Ret;
165
166     Ret = kEplSuccessful;
167
168     return Ret;
169 }
170
171
172 //---------------------------------------------------------------------------
173 //
174 // Function:    EplTimeruDelInstance
175 //
176 // Description: function deletes instance
177 //              -> under Linux nothing to do
178 //              -> no instance table needed
179 //
180 // Parameters:  void
181 //
182 // Returns:     tEplKernel  = errorcode
183 //
184 // State:
185 //
186 //---------------------------------------------------------------------------
187
188 tEplKernel PUBLIC EplTimeruDelInstance()
189 {
190 tEplKernel  Ret;
191
192     Ret = kEplSuccessful;
193
194     return Ret;
195 }
196
197
198 //---------------------------------------------------------------------------
199 //
200 // Function:    EplTimeruSetTimerMs
201 //
202 // Description: function creates a timer and returns the corresponding handle
203 //
204 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
205 //              ulTime_p    = time for timer in ms
206 //              Argument_p  = argument for timer
207 //
208 // Returns:     tEplKernel  = errorcode
209 //
210 // State:
211 //
212 //---------------------------------------------------------------------------
213
214 tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
215                                         unsigned long   ulTime_p,
216                                         tEplTimerArg    Argument_p)
217 {
218 tEplKernel          Ret = kEplSuccessful;
219 tEplTimeruData*     pData;
220
221     // check pointer to handle
222     if(pTimerHdl_p == NULL)
223     {
224         Ret = kEplTimerInvalidHandle;
225         goto Exit;
226     }
227
228     pData = (tEplTimeruData*) EPL_MALLOC(sizeof (tEplTimeruData));
229     if (pData == NULL)
230     {
231         Ret = kEplNoResource;
232         goto Exit;
233     }
234
235     init_timer(&pData->m_Timer);
236     pData->m_Timer.function = EplTimeruCbMs;
237     pData->m_Timer.data = (unsigned long) pData;
238     pData->m_Timer.expires = jiffies + ulTime_p * HZ / 1000;
239
240     EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
241
242     add_timer(&pData->m_Timer);
243
244     *pTimerHdl_p = (tEplTimerHdl) pData;
245
246 Exit:
247     return Ret;
248 }
249
250
251 //---------------------------------------------------------------------------
252 //
253 // Function:    EplTimeruModifyTimerMs
254 //
255 // Description: function changes a timer and returns the corresponding handle
256 //
257 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
258 //              ulTime_p    = time for timer in ms
259 //              Argument_p  = argument for timer
260 //
261 // Returns:     tEplKernel  = errorcode
262 //
263 // State:
264 //
265 //---------------------------------------------------------------------------
266
267 tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
268                                         unsigned long     ulTime_p,
269                                         tEplTimerArg      Argument_p)
270 {
271 tEplKernel          Ret = kEplSuccessful;
272 tEplTimeruData*     pData;
273
274     // check pointer to handle
275     if(pTimerHdl_p == NULL)
276     {
277         Ret = kEplTimerInvalidHandle;
278         goto Exit;
279     }
280
281     // check handle itself, i.e. was the handle initialized before
282     if (*pTimerHdl_p == 0)
283     {
284         Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p);
285         goto Exit;
286     }
287     pData = (tEplTimeruData*) *pTimerHdl_p;
288     if ((tEplTimeruData*)pData->m_Timer.data != pData)
289     {
290         Ret = kEplTimerInvalidHandle;
291         goto Exit;
292     }
293
294     mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));
295
296     // copy the TimerArg after the timer is restarted,
297     // so that a timer occured immediately before mod_timer
298     // won't use the new TimerArg and
299     // therefore the old timer cannot be distinguished from the new one.
300     // But if the new timer is too fast, it may get lost.
301     EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
302
303     // check if timer is really running
304     if (timer_pending(&pData->m_Timer) == 0)
305     {   // timer is not running
306         // retry starting it
307         add_timer(&pData->m_Timer);
308     }
309
310     // set handle to pointer of tEplTimeruData
311 //    *pTimerHdl_p = (tEplTimerHdl) pData;
312
313 Exit:
314     return Ret;
315 }
316
317
318 //---------------------------------------------------------------------------
319 //
320 // Function:    EplTimeruDeleteTimer
321 //
322 // Description: function deletes a timer
323 //
324 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
325 //
326 // Returns:     tEplKernel  = errorcode
327 //
328 // State:
329 //
330 //---------------------------------------------------------------------------
331
332 tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl*     pTimerHdl_p)
333 {
334 tEplKernel          Ret = kEplSuccessful;
335 tEplTimeruData*     pData;
336
337     // check pointer to handle
338     if(pTimerHdl_p == NULL)
339     {
340         Ret = kEplTimerInvalidHandle;
341         goto Exit;
342     }
343
344     // check handle itself, i.e. was the handle initialized before
345     if (*pTimerHdl_p == 0)
346     {
347         Ret = kEplSuccessful;
348         goto Exit;
349     }
350     pData = (tEplTimeruData*) *pTimerHdl_p;
351     if ((tEplTimeruData*)pData->m_Timer.data != pData)
352     {
353         Ret = kEplTimerInvalidHandle;
354         goto Exit;
355     }
356
357 /*    if (del_timer(&pData->m_Timer) == 1)
358     {
359         kfree(pData);
360     }
361 */
362     // try to delete the timer
363     del_timer(&pData->m_Timer);
364     // free memory in any case
365     kfree(pData);
366
367     // uninitialize handle
368     *pTimerHdl_p = 0;
369
370 Exit:
371     return Ret;
372
373 }
374
375
376 //---------------------------------------------------------------------------
377 //
378 // Function:    EplTimeruIsTimerActive
379 //
380 // Description: checks if the timer referenced by the handle is currently
381 //              active.
382 //
383 // Parameters:  TimerHdl_p  = handle of the timer to check
384 //
385 // Returns:     BOOL        = TRUE, if active;
386 //                            FALSE, otherwise
387 //
388 // State:
389 //
390 //---------------------------------------------------------------------------
391
392 BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
393 {
394 BOOL        fActive = FALSE;
395 tEplTimeruData*     pData;
396
397     // check handle itself, i.e. was the handle initialized before
398     if (TimerHdl_p == 0)
399     {   // timer was not created yet, so it is not active
400         goto Exit;
401     }
402     pData = (tEplTimeruData*) TimerHdl_p;
403     if ((tEplTimeruData*)pData->m_Timer.data != pData)
404     {   // invalid timer
405         goto Exit;
406     }
407
408     // check if timer is running
409     if (timer_pending(&pData->m_Timer) == 0)
410     {   // timer is not running
411         goto Exit;
412     }
413
414     fActive = TRUE;
415
416 Exit:
417     return fActive;
418 }
419
420
421 //=========================================================================//
422 //                                                                         //
423 //          P R I V A T E   F U N C T I O N S                              //
424 //                                                                         //
425 //=========================================================================//
426
427 //---------------------------------------------------------------------------
428 //
429 // Function:    EplTimeruCbMs
430 //
431 // Description: function to process timer
432 //
433 //
434 //
435 // Parameters:  lpParameter = pointer to structur of type tEplTimeruData
436 //
437 //
438 // Returns:     (none)
439 //
440 //
441 // State:
442 //
443 //---------------------------------------------------------------------------
444 static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
445 {
446 tEplKernel          Ret = kEplSuccessful;
447 tEplTimeruData*     pData;
448 tEplEvent           EplEvent;
449 tEplTimerEventArg   TimerEventArg;
450
451     pData = (tEplTimeruData*) ulParameter_p;
452
453     // call event function
454     TimerEventArg.m_TimerHdl = (tEplTimerHdl)pData;
455     TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg;
456
457     EplEvent.m_EventSink = pData->TimerArgument.m_EventSink;
458     EplEvent.m_EventType = kEplEventTypeTimer;
459     EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
460     EplEvent.m_pArg = &TimerEventArg;
461     EplEvent.m_uiSize = sizeof(TimerEventArg);
462
463     Ret = EplEventuPost(&EplEvent);
464
465     // d.k. do not free memory, user has to call EplTimeruDeleteTimer()
466     //kfree(pData);
467
468 }
469
470
471 // EOF
472