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