Staging: add epl stack
[platform/kernel/linux-starfive.git] / drivers / staging / epl / EplTimeruWin32.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 Userspace-Timermodule for Win32
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: EplTimeruWin32.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                     GCC V3.4
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/07/06 k.t.:   start of the implementation
68
69 ****************************************************************************/
70
71 #include "user/EplTimeru.h"
72
73 /***************************************************************************/
74 /*                                                                         */
75 /*                                                                         */
76 /*          G L O B A L   D E F I N I T I O N S                            */
77 /*                                                                         */
78 /*                                                                         */
79 /***************************************************************************/
80
81 //---------------------------------------------------------------------------
82 // const defines
83 //---------------------------------------------------------------------------
84
85 //---------------------------------------------------------------------------
86 // local types
87 //---------------------------------------------------------------------------
88 typedef struct
89 {
90     tEplTimerArg    TimerArgument;
91     HANDLE          DelteHandle;
92     unsigned long   ulTimeout;
93
94 }tEplTimeruThread;
95
96 typedef struct
97 {
98     LPCRITICAL_SECTION  m_pCriticalSection;
99     CRITICAL_SECTION    m_CriticalSection;
100 }tEplTimeruInstance;
101 //---------------------------------------------------------------------------
102 // modul globale vars
103 //---------------------------------------------------------------------------
104 static tEplTimeruInstance EplTimeruInstance_g;
105 static tEplTimeruThread   ThreadData_l;
106 //---------------------------------------------------------------------------
107 // local function prototypes
108 //---------------------------------------------------------------------------
109 DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
110
111 /***************************************************************************/
112 /*                                                                         */
113 /*                                                                         */
114 /*          C L A S S  <Epl Userspace-Timermodule for Win32>               */
115 /*                                                                         */
116 /*                                                                         */
117 /***************************************************************************/
118 //
119 // Description: Epl Userspace-Timermodule for Win32
120 //
121 //
122 /***************************************************************************/
123
124 //=========================================================================//
125 //                                                                         //
126 //          P U B L I C   F U N C T I O N S                                //
127 //                                                                         //
128 //=========================================================================//
129
130 //---------------------------------------------------------------------------
131 //
132 // Function:    EplTimeruInit
133 //
134 // Description: function init first instance
135 //
136 //
137 //
138 // Parameters:
139 //
140 //
141 // Returns:     tEplKernel  = errorcode
142 //
143 //
144 // State:
145 //
146 //---------------------------------------------------------------------------
147 tEplKernel PUBLIC EplTimeruInit()
148 {
149 tEplKernel  Ret;
150
151     Ret = EplTimeruAddInstance();
152
153 return Ret;
154 }
155
156 //---------------------------------------------------------------------------
157 //
158 // Function:    EplTimeruAddInstance
159 //
160 // Description: function init additional instance
161 //
162 //
163 //
164 // Parameters:
165 //
166 //
167 // Returns:     tEplKernel  = errorcode
168 //
169 //
170 // State:
171 //
172 //---------------------------------------------------------------------------
173 tEplKernel PUBLIC EplTimeruAddInstance()
174 {
175 tEplKernel Ret;
176
177     Ret = kEplSuccessful;
178
179
180     // create critical section
181     EplTimeruInstance_g.m_pCriticalSection = &EplTimeruInstance_g.m_CriticalSection;
182     InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
183
184
185
186 return Ret;
187 }
188
189 //---------------------------------------------------------------------------
190 //
191 // Function:    EplTimeruDelInstance
192 //
193 // Description: function delte instance
194 //              -> under Win32 nothing to do
195 //              -> no instnace table needed
196 //
197 //
198 //
199 // Parameters:
200 //
201 //
202 // Returns:     tEplKernel  = errorcode
203 //
204 //
205 // State:
206 //
207 //---------------------------------------------------------------------------
208 tEplKernel PUBLIC EplTimeruDelInstance()
209 {
210 tEplKernel  Ret;
211
212     Ret = kEplSuccessful;
213
214     return Ret;
215 }
216
217 //---------------------------------------------------------------------------
218 //
219 // Function:    EplTimeruSetTimerMs
220 //
221 // Description: function create a timer and return a handle to the pointer
222 //
223 //
224 //
225 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
226 //              ulTime_p    = time for timer in ms
227 //              Argument_p  = argument for timer
228 //
229 //
230 // Returns:     tEplKernel  = errorcode
231 //
232 //
233 // State:
234 //
235 //---------------------------------------------------------------------------
236 tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
237                                         unsigned long   ulTime_p,
238                                         tEplTimerArg    Argument_p)
239 {
240 tEplKernel          Ret;
241 HANDLE              DeleteHandle;
242 HANDLE              ThreadHandle;
243 DWORD               ThreadId;
244
245
246     Ret = kEplSuccessful;
247
248     // check handle
249     if(pTimerHdl_p == NULL)
250     {
251         Ret = kEplTimerInvalidHandle;
252         goto Exit;
253     }
254
255     // enter  critical section
256     EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
257
258     // first create event to delete timer
259     DeleteHandle = CreateEvent(NULL,FALSE,FALSE, NULL);
260     if(DeleteHandle == NULL)
261     {
262         Ret = kEplTimerNoTimerCreated;
263         goto Exit;
264     }
265
266     // set handle for caller
267     *pTimerHdl_p = (tEplTimerHdl)DeleteHandle;
268
269
270
271
272     // fill data for thread
273     ThreadData_l.DelteHandle = DeleteHandle;
274     EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, sizeof(tEplTimerArg));
275     ThreadData_l.ulTimeout = ulTime_p;
276
277     // create thread to create waitable timer and wait for timer
278     ThreadHandle = CreateThread(NULL,
279                                 0,
280                                 EplSdoTimeruThreadms,
281                                 &ThreadData_l,
282                                 0,
283                                 &ThreadId);
284     if(ThreadHandle == NULL)
285     {
286         // leave critical section
287         LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
288
289         // delte handle
290         CloseHandle(DeleteHandle);
291
292         Ret = kEplTimerNoTimerCreated;
293         goto Exit;
294     }
295
296 Exit:
297     return Ret;
298 }
299
300
301  //---------------------------------------------------------------------------
302 //
303 // Function:    EplTimeruModifyTimerMs
304 //
305 // Description: function change a timer and return a handle to the pointer
306 //
307 //
308 //
309 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
310 //              ulTime_p    = time for timer in ms
311 //              Argument_p  = argument for timer
312 //
313 //
314 // Returns:     tEplKernel  = errorcode
315 //
316 //
317 // State:
318 //
319 //---------------------------------------------------------------------------
320 tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
321                                         unsigned long     ulTime_p,
322                                         tEplTimerArg      Argument_p)
323 {
324 tEplKernel          Ret;
325 HANDLE              DeleteHandle;
326 HANDLE              ThreadHandle;
327 DWORD               ThreadId;
328
329     Ret = kEplSuccessful;
330
331     // check parameter
332     if(pTimerHdl_p == NULL)
333     {
334         Ret = kEplTimerInvalidHandle;
335         goto Exit;
336     }
337
338     DeleteHandle = (HANDLE)(*pTimerHdl_p);
339
340     // set event to end timer task for this timer
341     SetEvent(DeleteHandle);
342
343     // create new timer
344     // first create event to delete timer
345     DeleteHandle = CreateEvent(NULL,FALSE,FALSE, NULL);
346     if(DeleteHandle == NULL)
347     {
348         Ret = kEplTimerNoTimerCreated;
349         goto Exit;
350     }
351
352     // set handle for caller
353     *pTimerHdl_p = (tEplTimerHdl)DeleteHandle;
354
355     // enter  critical section
356     EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
357
358     // fill data for thread
359     ThreadData_l.DelteHandle = DeleteHandle;
360     EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, sizeof(tEplTimerArg));
361     ThreadData_l.ulTimeout = ulTime_p;
362
363     // create thread to create waitable timer and wait for timer
364     ThreadHandle = CreateThread(NULL,
365                                 0,
366                                 EplSdoTimeruThreadms,
367                                 &ThreadData_l,
368                                 0,
369                                 &ThreadId);
370     if(ThreadHandle == NULL)
371     {
372         // leave critical section
373         LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
374
375         // delte handle
376
377         Ret = kEplTimerNoTimerCreated;
378         goto Exit;
379     }
380
381 Exit:
382     return Ret;
383 }
384
385  //---------------------------------------------------------------------------
386 //
387 // Function:    EplTimeruDeleteTimer
388 //
389 // Description: function delte a timer
390 //
391 //
392 //
393 // Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
394 //
395 //
396 // Returns:     tEplKernel  = errorcode
397 //
398 //
399 // State:
400 //
401 //---------------------------------------------------------------------------
402 tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl*     pTimerHdl_p)
403 {
404 tEplKernel  Ret;
405 HANDLE      DeleteHandle;
406
407     Ret = kEplSuccessful;
408
409     // check parameter
410     if(pTimerHdl_p == NULL)
411     {
412         Ret = kEplTimerInvalidHandle;
413         goto Exit;
414     }
415
416     DeleteHandle = (HANDLE)(*pTimerHdl_p);
417
418     // set event to end timer task for this timer
419     SetEvent(DeleteHandle);
420
421     // set handle invalide
422     *pTimerHdl_p = 0;
423
424
425 Exit:
426     return Ret;
427
428 }
429
430 //=========================================================================//
431 //                                                                         //
432 //          P R I V A T E   F U N C T I O N S                              //
433 //                                                                         //
434 //=========================================================================//
435
436 //---------------------------------------------------------------------------
437 //
438 // Function:    EplSdoTimeruThreadms
439 //
440 // Description: function to process timer as thread
441 //
442 //
443 //
444 // Parameters:  lpParameter = pointer to structur of type tEplTimeruThread
445 //
446 //
447 // Returns:     DWORD = Errorcode
448 //
449 //
450 // State:
451 //
452 //---------------------------------------------------------------------------
453 DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
454 {
455 tEplKernel          Ret;
456 tEplTimeruThread*   pThreadData;
457 HANDLE              aHandles[2];
458 BOOL                fReturn;
459 LARGE_INTEGER       TimeoutTime;
460 unsigned long       ulEvent;
461 tEplEvent           EplEvent;
462 tEplTimeruThread    ThreadData;
463 tEplTimerEventArg   TimerEventArg;
464
465     Ret = kEplSuccessful;
466
467     // get pointer to data
468     pThreadData = (tEplTimeruThread*)lpParameter;
469     // copy thread data
470     EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
471     pThreadData = &ThreadData;
472
473     // leave critical section
474     LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
475
476     // create waitable timer
477     aHandles[1] = CreateWaitableTimer(NULL,FALSE,NULL);
478     if(aHandles[1] == NULL)
479     {
480         Ret = kEplTimerNoTimerCreated;
481         goto Exit;
482     }
483
484     // set timer
485     // set timeout interval -> needed to be negativ
486     // -> because relative timeout
487     // -> multiply by 10000 for 100 ns timebase of function
488     TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
489     fReturn = SetWaitableTimer(aHandles[1],
490                                &TimeoutTime,
491                                0,
492                                NULL,
493                                NULL,
494                                FALSE);
495     if(fReturn == 0)
496     {
497         Ret = kEplTimerNoTimerCreated;
498         goto Exit;
499     }
500
501     // save delte event handle in handle array
502     aHandles[0] = pThreadData->DelteHandle;
503
504     // wait for one of the events
505     ulEvent = WaitForMultipleObjects( 2,
506                             &aHandles[0],
507                             FALSE,
508                             INFINITE);
509     if(ulEvent == WAIT_OBJECT_0)
510     {   // delte event
511
512         // close handels
513         CloseHandle(aHandles[1]);
514         // terminate thread
515         goto Exit;
516     }
517     else if(ulEvent == (WAIT_OBJECT_0 + 1))
518     {   // timer event
519         // call event function
520         TimerEventArg.m_TimerHdl = (tEplTimerHdl)pThreadData->DelteHandle;
521         TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
522
523         EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
524         EplEvent.m_EventType = kEplEventTypeTimer;
525         EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
526         EplEvent.m_pArg = &TimerEventArg;
527         EplEvent.m_uiSize = sizeof(TimerEventArg);
528
529         Ret = EplEventuPost(&EplEvent);
530
531         // close handels
532         CloseHandle(aHandles[1]);
533         // terminate thread
534         goto Exit;
535
536     }
537     else
538     {   // error
539         ulEvent = GetLastError();
540         TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",ulEvent);
541          // terminate thread
542         goto Exit;
543     }
544
545 Exit:
546     return Ret;
547 }
548
549
550 // EOF
551