qlge: bugfix: Pad outbound frames smaller than 60 bytes.
[safe/jmp/linux-2.6] / 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