Merge branch 'linus' into tracing/hw-branch-tracing
[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 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 tEplKernel EplIdentuInit(void)
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 tEplKernel EplIdentuAddInstance(void)
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 tEplKernel EplIdentuDelInstance(void)
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 tEplKernel EplIdentuReset(void)
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 EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
304                                      tEplIdentResponse **ppIdentResponse_p)
305 {
306         tEplKernel Ret;
307
308         Ret = kEplSuccessful;
309
310         // decrement node ID, because array is zero based
311         uiNodeId_p--;
312         if (uiNodeId_p < tabentries(EplIdentuInstance_g.m_apIdentResponse)) {
313                 *ppIdentResponse_p =
314                     EplIdentuInstance_g.m_apIdentResponse[uiNodeId_p];
315         } else {                // invalid node ID specified
316                 *ppIdentResponse_p = NULL;
317                 Ret = kEplInvalidNodeId;
318         }
319
320         return Ret;
321
322 }
323
324 //---------------------------------------------------------------------------
325 //
326 // Function:    EplIdentuRequestIdentResponse
327 //
328 // Description: returns the IdentResponse for the specified node.
329 //
330 // Parameters:  uiNodeId_p                  = IN: node ID
331 //              pfnCbResponse_p             = IN: function pointer to callback function
332 //                                            which will be called if IdentResponse is received
333 //
334 // Return:      tEplKernel                  = error code
335 //
336 // State:       not tested
337 //
338 //---------------------------------------------------------------------------
339
340 tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
341                                          tEplIdentuCbResponse pfnCbResponse_p)
342 {
343         tEplKernel Ret;
344
345         Ret = kEplSuccessful;
346
347         // decrement node ID, because array is zero based
348         uiNodeId_p--;
349         if (uiNodeId_p < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) {
350 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
351                 if (EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL) { // request already issued (maybe by someone else)
352                         Ret = kEplInvalidOperation;
353                 } else {
354                         EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] =
355                             pfnCbResponse_p;
356                         Ret =
357                             EplDlluCalIssueRequest(kEplDllReqServiceIdent,
358                                                    (uiNodeId_p + 1), 0xFF);
359                 }
360 #else
361                 Ret = kEplInvalidOperation;
362 #endif
363         } else {                // invalid node ID specified
364                 Ret = kEplInvalidNodeId;
365         }
366
367         return Ret;
368
369 }
370
371 //---------------------------------------------------------------------------
372 //
373 // Function:    EplIdentuGetRunningRequests
374 //
375 // Description: returns a bit field with the running requests for node-ID 1-32
376 //              just for debugging purposes
377 //
378 //
379 // Parameters:
380 //
381 //
382 // Returns:     tEplKernel  = errorcode
383 //
384 //
385 // State:
386 //
387 //---------------------------------------------------------------------------
388
389 u32 EplIdentuGetRunningRequests(void)
390 {
391         u32 dwReqs = 0;
392         unsigned int uiIndex;
393
394         for (uiIndex = 0; uiIndex < 32; uiIndex++) {
395                 if (EplIdentuInstance_g.m_apfnCbResponse[uiIndex] != NULL) {
396                         dwReqs |= (1 << uiIndex);
397                 }
398         }
399
400         return dwReqs;
401 }
402
403 //=========================================================================//
404 //                                                                         //
405 //          P R I V A T E   F U N C T I O N S                              //
406 //                                                                         //
407 //=========================================================================//
408
409 //---------------------------------------------------------------------------
410 //
411 // Function:    EplIdentuCbIdentResponse
412 //
413 // Description: callback funktion for IdentResponse
414 //
415 //
416 //
417 // Parameters:  pFrameInfo_p            = Frame with the IdentResponse
418 //
419 //
420 // Returns:     tEplKernel              = error code
421 //
422 //
423 // State:
424 //
425 //---------------------------------------------------------------------------
426
427 static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p)
428 {
429         tEplKernel Ret = kEplSuccessful;
430         unsigned int uiNodeId;
431         unsigned int uiIndex;
432         tEplIdentuCbResponse pfnCbResponse;
433
434         uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);
435
436         uiIndex = uiNodeId - 1;
437
438         if (uiIndex < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) {
439                 // memorize pointer to callback function
440                 pfnCbResponse = EplIdentuInstance_g.m_apfnCbResponse[uiIndex];
441                 // reset callback function pointer so that caller may issue next request immediately
442                 EplIdentuInstance_g.m_apfnCbResponse[uiIndex] = NULL;
443
444                 if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_IDENTRES) { // IdentResponse not received or it has invalid size
445                         if (pfnCbResponse == NULL) {    // response was not requested
446                                 goto Exit;
447                         }
448                         Ret = pfnCbResponse(uiNodeId, NULL);
449                 } else {        // IdentResponse received
450                         if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) {   // memory for IdentResponse must be allocated
451                                 EplIdentuInstance_g.m_apIdentResponse[uiIndex] =
452                                     EPL_MALLOC(sizeof(tEplIdentResponse));
453                                 if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) {   // malloc failed
454                                         if (pfnCbResponse == NULL) {    // response was not requested
455                                                 goto Exit;
456                                         }
457                                         Ret =
458                                             pfnCbResponse(uiNodeId,
459                                                           &pFrameInfo_p->
460                                                           m_pFrame->m_Data.
461                                                           m_Asnd.m_Payload.
462                                                           m_IdentResponse);
463                                         goto Exit;
464                                 }
465                         }
466                         // copy IdentResponse to instance structure
467                         EPL_MEMCPY(EplIdentuInstance_g.
468                                    m_apIdentResponse[uiIndex],
469                                    &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.
470                                    m_Payload.m_IdentResponse,
471                                    sizeof(tEplIdentResponse));
472                         if (pfnCbResponse == NULL) {    // response was not requested
473                                 goto Exit;
474                         }
475                         Ret =
476                             pfnCbResponse(uiNodeId,
477                                           EplIdentuInstance_g.
478                                           m_apIdentResponse[uiIndex]);
479                 }
480         }
481
482       Exit:
483         return Ret;
484 }
485
486 // EOF