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