Staging: add epl stack
[firefly-linux-kernel-4.4.55.git] / drivers / staging / epl / EplIdentu.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 Identu-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: EplIdentu.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.8 $  $Date: 2008/11/21 09:00:38 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                     GCC V3.4
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/11/15 d.k.:   start of the implementation
68
69 ****************************************************************************/
70
71 #include "user/EplIdentu.h"
72 #include "user/EplDlluCal.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
90 //---------------------------------------------------------------------------
91 // modul globale vars
92 //---------------------------------------------------------------------------
93
94 //---------------------------------------------------------------------------
95 // local function prototypes
96 //---------------------------------------------------------------------------
97
98
99 /***************************************************************************/
100 /*                                                                         */
101 /*                                                                         */
102 /*          C L A S S  <xxxxx>                                             */
103 /*                                                                         */
104 /*                                                                         */
105 /***************************************************************************/
106 //
107 // Description:
108 //
109 //
110 /***************************************************************************/
111
112
113 //=========================================================================//
114 //                                                                         //
115 //          P R I V A T E   D E F I N I T I O N S                          //
116 //                                                                         //
117 //=========================================================================//
118
119 //---------------------------------------------------------------------------
120 // const defines
121 //---------------------------------------------------------------------------
122
123 //---------------------------------------------------------------------------
124 // local types
125 //---------------------------------------------------------------------------
126
127 typedef struct
128 {
129     tEplIdentResponse*   m_apIdentResponse[254];    // the IdentResponse are managed dynamically
130     tEplIdentuCbResponse m_apfnCbResponse[254];
131
132 } tEplIdentuInstance;
133
134 //---------------------------------------------------------------------------
135 // local vars
136 //---------------------------------------------------------------------------
137
138 static tEplIdentuInstance   EplIdentuInstance_g;
139
140 //---------------------------------------------------------------------------
141 // local function prototypes
142 //---------------------------------------------------------------------------
143
144 static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
145
146 //=========================================================================//
147 //                                                                         //
148 //          P U B L I C   F U N C T I O N S                                //
149 //                                                                         //
150 //=========================================================================//
151
152 //---------------------------------------------------------------------------
153 //
154 // Function:    EplIdentuInit
155 //
156 // Description: init first instance of the module
157 //
158 //
159 //
160 // Parameters:
161 //
162 //
163 // Returns:     tEplKernel  = errorcode
164 //
165 //
166 // State:
167 //
168 //---------------------------------------------------------------------------
169
170 EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
171 {
172 tEplKernel Ret;
173
174     Ret = EplIdentuAddInstance();
175
176     return Ret;
177 }
178
179
180 //---------------------------------------------------------------------------
181 //
182 // Function:    EplIdentuAddInstance
183 //
184 // Description: init other instances of the module
185 //
186 //
187 //
188 // Parameters:
189 //
190 //
191 // Returns:     tEplKernel  = errorcode
192 //
193 //
194 // State:
195 //
196 //---------------------------------------------------------------------------
197
198 EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
199 {
200 tEplKernel Ret;
201
202     Ret = kEplSuccessful;
203
204     // reset instance structure
205     EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof (EplIdentuInstance_g));
206
207     // register IdentResponse callback function
208     Ret = EplDlluCalRegAsndService(kEplDllAsndIdentResponse, EplIdentuCbIdentResponse, kEplDllAsndFilterAny);
209
210     return Ret;
211
212 }
213
214
215 //---------------------------------------------------------------------------
216 //
217 // Function:    EplIdentuDelInstance
218 //
219 // Description: delete instance
220 //
221 //
222 //
223 // Parameters:
224 //
225 //
226 // Returns:     tEplKernel  = errorcode
227 //
228 //
229 // State:
230 //
231 //---------------------------------------------------------------------------
232
233 EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
234 {
235 tEplKernel  Ret;
236
237     Ret = kEplSuccessful;
238
239     // deregister IdentResponse callback function
240     Ret = EplDlluCalRegAsndService(kEplDllAsndIdentResponse, NULL, kEplDllAsndFilterNone);
241
242     Ret = EplIdentuReset();
243
244     return Ret;
245
246 }
247
248
249 //---------------------------------------------------------------------------
250 //
251 // Function:    EplIdentuReset
252 //
253 // Description: resets this instance
254 //
255 //
256 //
257 // Parameters:
258 //
259 //
260 // Returns:     tEplKernel  = errorcode
261 //
262 //
263 // State:
264 //
265 //---------------------------------------------------------------------------
266
267 EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
268 {
269 tEplKernel  Ret;
270 int         iIndex;
271
272     Ret = kEplSuccessful;
273
274     for (iIndex = 0; iIndex < tabentries (EplIdentuInstance_g.m_apIdentResponse); iIndex++)
275     {
276         if (EplIdentuInstance_g.m_apIdentResponse[iIndex] != NULL)
277         {   // free memory
278             EPL_FREE(EplIdentuInstance_g.m_apIdentResponse[iIndex]);
279         }
280     }
281
282     EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof (EplIdentuInstance_g));
283
284     return Ret;
285
286 }
287
288
289 //---------------------------------------------------------------------------
290 //
291 // Function:    EplIdentuGetIdentResponse
292 //
293 // Description: returns the IdentResponse for the specified node.
294 //
295 // Parameters:  uiNodeId_p                  = IN: node ID
296 //              ppIdentResponse_p           = OUT: pointer to pointer of IdentResponse
297 //                                            equals NULL, if no IdentResponse available
298 //
299 // Return:      tEplKernel                  = error code
300 //
301 // State:       not tested
302 //
303 //---------------------------------------------------------------------------
304
305 tEplKernel PUBLIC EplIdentuGetIdentResponse(
306                                     unsigned int        uiNodeId_p,
307                                     tEplIdentResponse** ppIdentResponse_p)
308 {
309 tEplKernel  Ret;
310
311     Ret = kEplSuccessful;
312
313     // decrement node ID, because array is zero based
314     uiNodeId_p--;
315     if (uiNodeId_p < tabentries (EplIdentuInstance_g.m_apIdentResponse))
316     {
317         *ppIdentResponse_p = EplIdentuInstance_g.m_apIdentResponse[uiNodeId_p];
318     }
319     else
320     {   // invalid node ID specified
321         *ppIdentResponse_p = NULL;
322         Ret = kEplInvalidNodeId;
323     }
324
325     return Ret;
326
327 }
328
329
330 //---------------------------------------------------------------------------
331 //
332 // Function:    EplIdentuRequestIdentResponse
333 //
334 // Description: returns the IdentResponse for the specified node.
335 //
336 // Parameters:  uiNodeId_p                  = IN: node ID
337 //              pfnCbResponse_p             = IN: function pointer to callback function
338 //                                            which will be called if IdentResponse is received
339 //
340 // Return:      tEplKernel                  = error code
341 //
342 // State:       not tested
343 //
344 //---------------------------------------------------------------------------
345
346 tEplKernel PUBLIC EplIdentuRequestIdentResponse(
347                                     unsigned int        uiNodeId_p,
348                                     tEplIdentuCbResponse pfnCbResponse_p)
349 {
350 tEplKernel  Ret;
351
352     Ret = kEplSuccessful;
353
354     // decrement node ID, because array is zero based
355     uiNodeId_p--;
356     if (uiNodeId_p < tabentries (EplIdentuInstance_g.m_apfnCbResponse))
357     {
358 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
359         if (EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL)
360         {   // request already issued (maybe by someone else)
361             Ret = kEplInvalidOperation;
362         }
363         else
364         {
365             EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] = pfnCbResponse_p;
366             Ret = EplDlluCalIssueRequest(kEplDllReqServiceIdent, (uiNodeId_p + 1), 0xFF);
367         }
368 #else
369         Ret = kEplInvalidOperation;
370 #endif
371     }
372     else
373     {   // invalid node ID specified
374         Ret = kEplInvalidNodeId;
375     }
376
377     return Ret;
378
379 }
380
381
382 //---------------------------------------------------------------------------
383 //
384 // Function:    EplIdentuGetRunningRequests
385 //
386 // Description: returns a bit field with the running requests for node-ID 1-32
387 //              just for debugging purposes
388 //
389 //
390 // Parameters:
391 //
392 //
393 // Returns:     tEplKernel  = errorcode
394 //
395 //
396 // State:
397 //
398 //---------------------------------------------------------------------------
399
400 EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
401 {
402 DWORD       dwReqs = 0;
403 unsigned int    uiIndex;
404
405     for (uiIndex = 0; uiIndex < 32; uiIndex++)
406     {
407         if (EplIdentuInstance_g.m_apfnCbResponse[uiIndex] != NULL)
408         {
409             dwReqs |= (1 << uiIndex);
410         }
411     }
412
413     return dwReqs;
414 }
415
416
417 //=========================================================================//
418 //                                                                         //
419 //          P R I V A T E   F U N C T I O N S                              //
420 //                                                                         //
421 //=========================================================================//
422
423 //---------------------------------------------------------------------------
424 //
425 // Function:    EplIdentuCbIdentResponse
426 //
427 // Description: callback funktion for IdentResponse
428 //
429 //
430 //
431 // Parameters:  pFrameInfo_p            = Frame with the IdentResponse
432 //
433 //
434 // Returns:     tEplKernel              = error code
435 //
436 //
437 // State:
438 //
439 //---------------------------------------------------------------------------
440
441 static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p)
442 {
443 tEplKernel      Ret = kEplSuccessful;
444 unsigned int    uiNodeId;
445 unsigned int    uiIndex;
446 tEplIdentuCbResponse    pfnCbResponse;
447
448     uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);
449
450     uiIndex = uiNodeId - 1;
451
452     if (uiIndex < tabentries (EplIdentuInstance_g.m_apfnCbResponse))
453     {
454         // memorize pointer to callback function
455         pfnCbResponse = EplIdentuInstance_g.m_apfnCbResponse[uiIndex];
456         // reset callback function pointer so that caller may issue next request immediately
457         EplIdentuInstance_g.m_apfnCbResponse[uiIndex] = NULL;
458
459         if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_IDENTRES)
460         {   // IdentResponse not received or it has invalid size
461             if (pfnCbResponse == NULL)
462             {   // response was not requested
463                 goto Exit;
464             }
465             Ret = pfnCbResponse(uiNodeId, NULL);
466         }
467         else
468         {   // IdentResponse received
469             if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL)
470             {   // memory for IdentResponse must be allocated
471                 EplIdentuInstance_g.m_apIdentResponse[uiIndex] = EPL_MALLOC(sizeof (tEplIdentResponse));
472                 if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL)
473                 {   // malloc failed
474                     if (pfnCbResponse == NULL)
475                     {   // response was not requested
476                         goto Exit;
477                     }
478                     Ret = pfnCbResponse(uiNodeId, &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse);
479                     goto Exit;
480                 }
481             }
482             // copy IdentResponse to instance structure
483             EPL_MEMCPY(EplIdentuInstance_g.m_apIdentResponse[uiIndex], &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse, sizeof(tEplIdentResponse));
484             if (pfnCbResponse == NULL)
485             {   // response was not requested
486                 goto Exit;
487             }
488             Ret = pfnCbResponse(uiNodeId, EplIdentuInstance_g.m_apIdentResponse[uiIndex]);
489         }
490     }
491
492 Exit:
493     return Ret;
494 }
495
496 // EOF
497