]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
Staging: add epl stack
authorDaniel Krueger <daniel.krueger@systec-electronic.com>
Fri, 19 Dec 2008 19:41:57 +0000 (11:41 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 6 Jan 2009 21:52:36 +0000 (13:52 -0800)
This is the openPOWERLINK network stack from systec electronic.

It's a bit messed up as there is a driver mixed into the
middle of it, lots of work needs to be done to unwind the
different portions to make it sane.

Cc: Daniel Krueger <daniel.krueger@systec-electronic.com>
Cc: Ronald Sieber <Ronald.Sieber@systec-electronic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
112 files changed:
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/epl/Benchmark.h [new file with mode: 0644]
drivers/staging/epl/Debug.h [new file with mode: 0644]
drivers/staging/epl/Edrv8139.c [new file with mode: 0644]
drivers/staging/epl/EdrvFec.h [new file with mode: 0644]
drivers/staging/epl/EdrvFec5282.h [new file with mode: 0644]
drivers/staging/epl/EdrvSim.h [new file with mode: 0644]
drivers/staging/epl/Epl.h [new file with mode: 0644]
drivers/staging/epl/EplAmi.h [new file with mode: 0644]
drivers/staging/epl/EplApiGeneric.c [new file with mode: 0644]
drivers/staging/epl/EplApiLinux.h [new file with mode: 0644]
drivers/staging/epl/EplApiLinuxKernel.c [new file with mode: 0644]
drivers/staging/epl/EplApiProcessImage.c [new file with mode: 0644]
drivers/staging/epl/EplCfg.h [new file with mode: 0644]
drivers/staging/epl/EplDef.h [new file with mode: 0644]
drivers/staging/epl/EplDll.h [new file with mode: 0644]
drivers/staging/epl/EplDllCal.h [new file with mode: 0644]
drivers/staging/epl/EplDllk.c [new file with mode: 0644]
drivers/staging/epl/EplDllkCal.c [new file with mode: 0644]
drivers/staging/epl/EplDlluCal.c [new file with mode: 0644]
drivers/staging/epl/EplErrDef.h [new file with mode: 0644]
drivers/staging/epl/EplErrorHandlerk.c [new file with mode: 0644]
drivers/staging/epl/EplEvent.h [new file with mode: 0644]
drivers/staging/epl/EplEventk.c [new file with mode: 0644]
drivers/staging/epl/EplEventu.c [new file with mode: 0644]
drivers/staging/epl/EplFrame.h [new file with mode: 0644]
drivers/staging/epl/EplIdentu.c [new file with mode: 0644]
drivers/staging/epl/EplInc.h [new file with mode: 0644]
drivers/staging/epl/EplInstDef.h [new file with mode: 0644]
drivers/staging/epl/EplLed.h [new file with mode: 0644]
drivers/staging/epl/EplNmt.h [new file with mode: 0644]
drivers/staging/epl/EplNmtCnu.c [new file with mode: 0644]
drivers/staging/epl/EplNmtMnu.c [new file with mode: 0644]
drivers/staging/epl/EplNmtk.c [new file with mode: 0644]
drivers/staging/epl/EplNmtkCal.c [new file with mode: 0644]
drivers/staging/epl/EplNmtu.c [new file with mode: 0644]
drivers/staging/epl/EplNmtuCal.c [new file with mode: 0644]
drivers/staging/epl/EplObd.c [new file with mode: 0644]
drivers/staging/epl/EplObd.h [new file with mode: 0644]
drivers/staging/epl/EplObdMacro.h [new file with mode: 0644]
drivers/staging/epl/EplObdkCal.c [new file with mode: 0644]
drivers/staging/epl/EplObdu.c [new file with mode: 0644]
drivers/staging/epl/EplObduCal.c [new file with mode: 0644]
drivers/staging/epl/EplObjDef.h [new file with mode: 0644]
drivers/staging/epl/EplPdo.h [new file with mode: 0644]
drivers/staging/epl/EplPdok.c [new file with mode: 0644]
drivers/staging/epl/EplPdokCal.c [new file with mode: 0644]
drivers/staging/epl/EplPdou.c [new file with mode: 0644]
drivers/staging/epl/EplSdo.h [new file with mode: 0644]
drivers/staging/epl/EplSdoAc.h [new file with mode: 0644]
drivers/staging/epl/EplSdoAsndu.c [new file with mode: 0644]
drivers/staging/epl/EplSdoAsySequ.c [new file with mode: 0644]
drivers/staging/epl/EplSdoComu.c [new file with mode: 0644]
drivers/staging/epl/EplSdoUdpu.c [new file with mode: 0644]
drivers/staging/epl/EplStatusu.c [new file with mode: 0644]
drivers/staging/epl/EplTarget.h [new file with mode: 0644]
drivers/staging/epl/EplTimer.h [new file with mode: 0644]
drivers/staging/epl/EplTimeruLinuxKernel.c [new file with mode: 0644]
drivers/staging/epl/EplTimeruNull.c [new file with mode: 0644]
drivers/staging/epl/EplTimeruWin32.c [new file with mode: 0644]
drivers/staging/epl/EplVersion.h [new file with mode: 0644]
drivers/staging/epl/Kconfig [new file with mode: 0644]
drivers/staging/epl/Makefile [new file with mode: 0644]
drivers/staging/epl/SharedBuff.c [new file with mode: 0644]
drivers/staging/epl/SharedBuff.h [new file with mode: 0644]
drivers/staging/epl/ShbIpc-LinuxKernel.c [new file with mode: 0644]
drivers/staging/epl/ShbIpc-Win32.c [new file with mode: 0644]
drivers/staging/epl/ShbIpc.h [new file with mode: 0644]
drivers/staging/epl/ShbLinuxKernel.h [new file with mode: 0644]
drivers/staging/epl/SocketLinuxKernel.c [new file with mode: 0644]
drivers/staging/epl/SocketLinuxKernel.h [new file with mode: 0644]
drivers/staging/epl/TimerHighReskX86.c [new file with mode: 0644]
drivers/staging/epl/VirtualEthernetLinux.c [new file with mode: 0644]
drivers/staging/epl/amix86.c [new file with mode: 0644]
drivers/staging/epl/demo_main.c [new file with mode: 0644]
drivers/staging/epl/edrv.h [new file with mode: 0644]
drivers/staging/epl/global.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplDllk.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplDllkCal.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplErrorHandlerk.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplEventk.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplNmtk.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplNmtkCal.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplObdk.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplObdkCal.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplPdok.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplPdokCal.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplTimerHighResk.h [new file with mode: 0644]
drivers/staging/epl/kernel/EplTimerk.h [new file with mode: 0644]
drivers/staging/epl/kernel/VirtualEthernet.h [new file with mode: 0644]
drivers/staging/epl/proc_fs.c [new file with mode: 0644]
drivers/staging/epl/proc_fs.h [new file with mode: 0644]
drivers/staging/epl/user/EplCfgMau.h [new file with mode: 0644]
drivers/staging/epl/user/EplDllu.h [new file with mode: 0644]
drivers/staging/epl/user/EplDlluCal.h [new file with mode: 0644]
drivers/staging/epl/user/EplEventu.h [new file with mode: 0644]
drivers/staging/epl/user/EplIdentu.h [new file with mode: 0644]
drivers/staging/epl/user/EplLedu.h [new file with mode: 0644]
drivers/staging/epl/user/EplNmtCnu.h [new file with mode: 0644]
drivers/staging/epl/user/EplNmtMnu.h [new file with mode: 0644]
drivers/staging/epl/user/EplNmtu.h [new file with mode: 0644]
drivers/staging/epl/user/EplNmtuCal.h [new file with mode: 0644]
drivers/staging/epl/user/EplObdu.h [new file with mode: 0644]
drivers/staging/epl/user/EplObduCal.h [new file with mode: 0644]
drivers/staging/epl/user/EplPdou.h [new file with mode: 0644]
drivers/staging/epl/user/EplSdoAsndu.h [new file with mode: 0644]
drivers/staging/epl/user/EplSdoAsySequ.h [new file with mode: 0644]
drivers/staging/epl/user/EplSdoComu.h [new file with mode: 0644]
drivers/staging/epl/user/EplSdoUdpu.h [new file with mode: 0644]
drivers/staging/epl/user/EplStatusu.h [new file with mode: 0644]
drivers/staging/epl/user/EplTimeru.h [new file with mode: 0644]

index 15f2b1148df31929484cd24deada39b8c43c6fa0..c06397139ae1151c48713ae09e6cedfe3c42a0bc 100644 (file)
@@ -91,5 +91,7 @@ source "drivers/staging/mimio/Kconfig"
 
 source "drivers/staging/frontier/Kconfig"
 
+source "drivers/staging/epl/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
index d33803092b621f26f989568b64a8045ab071a43b..53478e84d1dd748634a826aef88b6aa0afbb411f 100644 (file)
@@ -28,3 +28,4 @@ obj-$(CONFIG_RTL8187SE)               += rtl8187se/
 obj-$(CONFIG_USB_RSPI)         += rspiusb/
 obj-$(CONFIG_INPUT_MIMIO)      += mimio/
 obj-$(CONFIG_TRANZPORT)                += frontier/
+obj-$(CONFIG_EPL)              += epl/
diff --git a/drivers/staging/epl/Benchmark.h b/drivers/staging/epl/Benchmark.h
new file mode 100644 (file)
index 0000000..681c1d9
--- /dev/null
@@ -0,0 +1,443 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  header file for benchmarking
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: Benchmark.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    ...
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/08/16 d.k.:  start of implementation
+
+****************************************************************************/
+
+#ifndef _BENCHMARK_H_
+#define _BENCHMARK_H_
+
+#include "global.h"
+
+
+#if (TARGET_SYSTEM == _NO_OS_) && (DEV_SYSTEM == _DEV_GNU_CF548X_)
+    #include "common.h"
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+
+//    #include <linux/config.h>
+    #include <linux/kernel.h>
+
+    #ifdef CONFIG_COLDFIRE
+        #include <asm/coldfire.h>
+        #include <asm/m5485gpio.h>
+
+        #define BENCHMARK_SET(x)    MCF_GPIO_PODR_PCIBG |= (1 << (x))   // (x+1)
+        #define BENCHMARK_RESET(x)  MCF_GPIO_PODR_PCIBG &= ~(1 << (x))  // (x+1)
+        #define BENCHMARK_TOGGLE(x) MCF_GPIO_PODR_PCIBR ^= (1 << (x - 5))
+    #else
+        #undef BENCHMARK_MODULES
+        #define BENCHMARK_MODULES           0x00000000
+    #endif
+
+#else
+    // disable Benchmarking
+    #undef BENCHMARK_MODULES
+    #define BENCHMARK_MODULES               0x00000000
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef BENCHMARK_MODULES
+#define BENCHMARK_MODULES                   0x00000000
+#endif
+
+#define BENCHMARK_MOD_01                    0x00000001
+#define BENCHMARK_MOD_02                    0x00000002
+#define BENCHMARK_MOD_03                    0x00000004
+#define BENCHMARK_MOD_04                    0x00000008
+#define BENCHMARK_MOD_05                    0x00000010
+#define BENCHMARK_MOD_06                    0x00000020
+#define BENCHMARK_MOD_07                    0x00000040
+#define BENCHMARK_MOD_08                    0x00000080
+#define BENCHMARK_MOD_09                    0x00000100
+#define BENCHMARK_MOD_10                    0x00000200
+#define BENCHMARK_MOD_11                    0x00000400
+#define BENCHMARK_MOD_12                    0x00000800
+#define BENCHMARK_MOD_13                    0x00001000
+#define BENCHMARK_MOD_14                    0x00002000
+#define BENCHMARK_MOD_15                    0x00004000
+#define BENCHMARK_MOD_16                    0x00008000
+#define BENCHMARK_MOD_17                    0x00010000
+#define BENCHMARK_MOD_18                    0x00020000
+#define BENCHMARK_MOD_19                    0x00040000
+#define BENCHMARK_MOD_20                    0x00080000
+#define BENCHMARK_MOD_21                    0x00100000
+#define BENCHMARK_MOD_22                    0x00200000
+#define BENCHMARK_MOD_23                    0x00400000
+#define BENCHMARK_MOD_24                    0x00800000
+#define BENCHMARK_MOD_25                    0x01000000
+#define BENCHMARK_MOD_26                    0x02000000
+#define BENCHMARK_MOD_27                    0x04000000
+#define BENCHMARK_MOD_28                    0x08000000
+#define BENCHMARK_MOD_29                    0x10000000
+#define BENCHMARK_MOD_30                    0x20000000
+#define BENCHMARK_MOD_31                    0x40000000
+#define BENCHMARK_MOD_32                    0x80000000
+
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_01)
+    #define BENCHMARK_MOD_01_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_01_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_01_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_01_SET(x)
+    #define BENCHMARK_MOD_01_RESET(x)
+    #define BENCHMARK_MOD_01_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_02)
+    #define BENCHMARK_MOD_02_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_02_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_02_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_02_SET(x)
+    #define BENCHMARK_MOD_02_RESET(x)
+    #define BENCHMARK_MOD_02_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_03)
+    #define BENCHMARK_MOD_03_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_03_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_03_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_03_SET(x)
+    #define BENCHMARK_MOD_03_RESET(x)
+    #define BENCHMARK_MOD_03_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_04)
+    #define BENCHMARK_MOD_04_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_04_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_04_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_04_SET(x)
+    #define BENCHMARK_MOD_04_RESET(x)
+    #define BENCHMARK_MOD_04_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_05)
+    #define BENCHMARK_MOD_05_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_05_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_05_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_05_SET(x)
+    #define BENCHMARK_MOD_05_RESET(x)
+    #define BENCHMARK_MOD_05_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_06)
+    #define BENCHMARK_MOD_06_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_06_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_06_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_06_SET(x)
+    #define BENCHMARK_MOD_06_RESET(x)
+    #define BENCHMARK_MOD_06_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_07)
+    #define BENCHMARK_MOD_07_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_07_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_07_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_07_SET(x)
+    #define BENCHMARK_MOD_07_RESET(x)
+    #define BENCHMARK_MOD_07_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_08)
+    #define BENCHMARK_MOD_08_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_08_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_08_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_08_SET(x)
+    #define BENCHMARK_MOD_08_RESET(x)
+    #define BENCHMARK_MOD_08_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_09)
+    #define BENCHMARK_MOD_09_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_09_RESET(x)       BENCHMARK_RESET(x)
+    #define BENCHMARK_MOD_09_TOGGLE(x)      BENCHMARK_TOGGLE(x)
+#else
+    #define BENCHMARK_MOD_09_SET(x)
+    #define BENCHMARK_MOD_09_RESET(x)
+    #define BENCHMARK_MOD_09_TOGGLE(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_10)
+    #define BENCHMARK_MOD_10_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_10_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_10_SET(x)
+    #define BENCHMARK_MOD_10_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_11)
+    #define BENCHMARK_MOD_11_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_11_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_11_SET(x)
+    #define BENCHMARK_MOD_11_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_12)
+    #define BENCHMARK_MOD_12_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_12_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_12_SET(x)
+    #define BENCHMARK_MOD_12_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_13)
+    #define BENCHMARK_MOD_13_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_13_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_13_SET(x)
+    #define BENCHMARK_MOD_13_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_14)
+    #define BENCHMARK_MOD_14_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_14_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_14_SET(x)
+    #define BENCHMARK_MOD_14_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_15)
+    #define BENCHMARK_MOD_15_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_15_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_15_SET(x)
+    #define BENCHMARK_MOD_15_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_16)
+    #define BENCHMARK_MOD_16_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_16_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_16_SET(x)
+    #define BENCHMARK_MOD_16_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_17)
+    #define BENCHMARK_MOD_17_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_17_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_17_SET(x)
+    #define BENCHMARK_MOD_17_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_18)
+    #define BENCHMARK_MOD_18_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_18_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_18_SET(x)
+    #define BENCHMARK_MOD_18_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_19)
+    #define BENCHMARK_MOD_19_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_19_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_19_SET(x)
+    #define BENCHMARK_MOD_19_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_20)
+    #define BENCHMARK_MOD_20_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_20_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_20_SET(x)
+    #define BENCHMARK_MOD_20_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_21)
+    #define BENCHMARK_MOD_21_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_21_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_21_SET(x)
+    #define BENCHMARK_MOD_21_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_22)
+    #define BENCHMARK_MOD_22_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_22_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_22_SET(x)
+    #define BENCHMARK_MOD_22_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_23)
+    #define BENCHMARK_MOD_23_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_23_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_23_SET(x)
+    #define BENCHMARK_MOD_23_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_24)
+    #define BENCHMARK_MOD_24_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_24_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_24_SET(x)
+    #define BENCHMARK_MOD_24_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_25)
+    #define BENCHMARK_MOD_25_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_25_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_25_SET(x)
+    #define BENCHMARK_MOD_25_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_26)
+    #define BENCHMARK_MOD_26_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_26_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_26_SET(x)
+    #define BENCHMARK_MOD_26_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_27)
+    #define BENCHMARK_MOD_27_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_27_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_27_SET(x)
+    #define BENCHMARK_MOD_27_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_28)
+    #define BENCHMARK_MOD_28_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_28_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_28_SET(x)
+    #define BENCHMARK_MOD_28_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_29)
+    #define BENCHMARK_MOD_29_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_29_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_29_SET(x)
+    #define BENCHMARK_MOD_29_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_30)
+    #define BENCHMARK_MOD_30_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_30_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_30_SET(x)
+    #define BENCHMARK_MOD_30_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_31)
+    #define BENCHMARK_MOD_31_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_31_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_31_SET(x)
+    #define BENCHMARK_MOD_31_RESET(x)
+#endif
+
+#if (BENCHMARK_MODULES & BENCHMARK_MOD_32)
+    #define BENCHMARK_MOD_32_SET(x)         BENCHMARK_SET(x)
+    #define BENCHMARK_MOD_32_RESET(x)       BENCHMARK_RESET(x)
+#else
+    #define BENCHMARK_MOD_32_SET(x)
+    #define BENCHMARK_MOD_32_RESET(x)
+#endif
+
+
+//---------------------------------------------------------------------------
+// modul global types
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif // _BENCHMARK_H_
diff --git a/drivers/staging/epl/Debug.h b/drivers/staging/epl/Debug.h
new file mode 100644 (file)
index 0000000..f804e2f
--- /dev/null
@@ -0,0 +1,750 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Debug interface
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: Debug.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    ...
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+****************************************************************************/
+
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#include "global.h"
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// global const defines
+//---------------------------------------------------------------------------
+
+// These definitions are important for level-debug traces.
+// A macro DEBUG_GLB_LVL() defines the current debug-level using following bis.
+// If the corresponding bit is set then trace message will be printed out
+// (only if NDEBUG is not defined). The upper debug-levels are reserved for
+// the debug-levels ALWAYS, ERROR and ASSERT.
+#define DEBUG_LVL_01                    0x00000001
+#define DEBUG_LVL_02                    0x00000002
+#define DEBUG_LVL_03                    0x00000004
+#define DEBUG_LVL_04                    0x00000008
+#define DEBUG_LVL_05                    0x00000010
+#define DEBUG_LVL_06                    0x00000020
+#define DEBUG_LVL_07                    0x00000040
+#define DEBUG_LVL_08                    0x00000080
+#define DEBUG_LVL_09                    0x00000100
+#define DEBUG_LVL_10                    0x00000200
+#define DEBUG_LVL_11                    0x00000400
+#define DEBUG_LVL_12                    0x00000800
+#define DEBUG_LVL_13                    0x00001000
+#define DEBUG_LVL_14                    0x00002000
+#define DEBUG_LVL_15                    0x00004000
+#define DEBUG_LVL_16                    0x00008000
+#define DEBUG_LVL_17                    0x00010000
+#define DEBUG_LVL_18                    0x00020000
+#define DEBUG_LVL_19                    0x00040000
+#define DEBUG_LVL_20                    0x00080000
+#define DEBUG_LVL_21                    0x00100000
+#define DEBUG_LVL_22                    0x00200000
+#define DEBUG_LVL_23                    0x00400000
+#define DEBUG_LVL_24                    0x00800000
+#define DEBUG_LVL_25                    0x01000000
+#define DEBUG_LVL_26                    0x02000000
+#define DEBUG_LVL_27                    0x04000000
+#define DEBUG_LVL_28                    0x08000000
+#define DEBUG_LVL_29                    0x10000000
+#define DEBUG_LVL_ASSERT                0x20000000
+#define DEBUG_LVL_ERROR                 0x40000000
+#define DEBUG_LVL_ALWAYS                0x80000000
+
+
+//---------------------------------------------------------------------------
+// global types
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// global vars
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// global function prototypes
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// global macros
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// this macro defines a version string
+#define MAKE_VERSION_STRING(product,appname,verstr,author) \
+    "§prd§:" product ",§app§:" appname ",§ver§:" verstr ",§dat§:" __DATE__ ",§aut§:" author
+
+
+//---------------------------------------------------------------------------
+// this macro defines a build info string (e.g. for using in printf())
+#define DEBUG_MAKE_BUILD_INFO(prefix,product,prodid,descr,verstr,author) "\n" \
+    prefix "***************************************************\n" \
+    prefix "Project:   " product ", " prodid                  "\n" \
+    prefix "Descript.: " descr                                "\n" \
+    prefix "Author:    " author                               "\n" \
+    prefix "Date:      " __DATE__                             "\n" \
+    prefix "Version:   " verstr                               "\n" \
+    prefix "***************************************************\n\n"
+
+
+//---------------------------------------------------------------------------
+// The default debug-level is: ERROR and ALWAYS.
+// You can define an other debug-level in project settings.
+#ifndef DEF_DEBUG_LVL
+    #define DEF_DEBUG_LVL                   (DEBUG_LVL_ALWAYS | DEBUG_LVL_ERROR)
+#endif
+#ifndef DEBUG_GLB_LVL
+    #define DEBUG_GLB_LVL()                 (DEF_DEBUG_LVL)
+#endif
+
+
+//---------------------------------------------------------------------------
+#if (DEV_SYSTEM == _DEV_WIN32_) && defined (TRACE_MSG)
+
+    // For WIN32 the macro DEBUG_TRACE0 can be defined as function call TraceLvl()
+    // or as macro TRACE().
+    //
+    // Here the parameter 'lvl' can be used with more than one
+    // debug-level (using OR).
+    //
+    // Example: DEBUG_TRACE1(DEBUG_LVL_30 | DEBUG_LVL_02, "Hello %d", bCount);
+
+    #define DEBUG_TRACE0(lvl,str)               TraceLvl((lvl),str)
+    #define DEBUG_TRACE1(lvl,str,p1)            TraceLvl((lvl),str,p1)
+    #define DEBUG_TRACE2(lvl,str,p1,p2)         TraceLvl((lvl),str,p1,p2)
+    #define DEBUG_TRACE3(lvl,str,p1,p2,p3)      TraceLvl((lvl),str,p1,p2,p3)
+    #define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4)   TraceLvl((lvl),str,p1,p2,p3,p4)
+    #define DEBUG_GLB_LVL()                     dwDebugLevel_g
+
+#else
+
+    // At microcontrollers we do reduce the memory usage by deleting DEBUG_TRACE-lines
+    // (compiler does delete the lines).
+    //
+    // Here the parameter 'lvl' can only be used with one debug-level.
+    //
+    // Example: DEBUG_TRACE1(DEBUG_LVL_ERROR, "error code %d", dwRet);
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_ALWAYS)
+        #define DEBUG_LVL_ALWAYS_TRACE0(str)                TRACE0(str)
+        #define DEBUG_LVL_ALWAYS_TRACE1(str,p1)             TRACE1(str,p1)
+        #define DEBUG_LVL_ALWAYS_TRACE2(str,p1,p2)          TRACE2(str,p1,p2)
+        #define DEBUG_LVL_ALWAYS_TRACE3(str,p1,p2,p3)       TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_ALWAYS_TRACE4(str,p1,p2,p3,p4)    TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_ALWAYS_TRACE0(str)
+        #define DEBUG_LVL_ALWAYS_TRACE1(str,p1)
+        #define DEBUG_LVL_ALWAYS_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_ALWAYS_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_ALWAYS_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_ERROR)
+        #define DEBUG_LVL_ERROR_TRACE0(str)                 TRACE0(str)
+        #define DEBUG_LVL_ERROR_TRACE1(str,p1)              TRACE1(str,p1)
+        #define DEBUG_LVL_ERROR_TRACE2(str,p1,p2)           TRACE2(str,p1,p2)
+        #define DEBUG_LVL_ERROR_TRACE3(str,p1,p2,p3)        TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_ERROR_TRACE4(str,p1,p2,p3,p4)     TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_ERROR_TRACE0(str)
+        #define DEBUG_LVL_ERROR_TRACE1(str,p1)
+        #define DEBUG_LVL_ERROR_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_ERROR_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_ERROR_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)
+        #define DEBUG_LVL_ASSERT_TRACE0(str)                TRACE0(str)
+        #define DEBUG_LVL_ASSERT_TRACE1(str,p1)             TRACE1(str,p1)
+        #define DEBUG_LVL_ASSERT_TRACE2(str,p1,p2)          TRACE2(str,p1,p2)
+        #define DEBUG_LVL_ASSERT_TRACE3(str,p1,p2,p3)       TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_ASSERT_TRACE4(str,p1,p2,p3,p4)    TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_ASSERT_TRACE0(str)
+        #define DEBUG_LVL_ASSERT_TRACE1(str,p1)
+        #define DEBUG_LVL_ASSERT_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_ASSERT_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_ASSERT_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_29)
+        #define DEBUG_LVL_29_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_29_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_29_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_29_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_29_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_29_TRACE0(str)
+        #define DEBUG_LVL_29_TRACE1(str,p1)
+        #define DEBUG_LVL_29_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_29_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_29_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_28)
+        #define DEBUG_LVL_28_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_28_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_28_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_28_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_28_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_28_TRACE0(str)
+        #define DEBUG_LVL_28_TRACE1(str,p1)
+        #define DEBUG_LVL_28_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_28_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_28_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_27)
+        #define DEBUG_LVL_27_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_27_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_27_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_27_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_27_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_27_TRACE0(str)
+        #define DEBUG_LVL_27_TRACE1(str,p1)
+        #define DEBUG_LVL_27_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_27_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_27_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_26)
+        #define DEBUG_LVL_26_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_26_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_26_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_26_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_26_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_26_TRACE0(str)
+        #define DEBUG_LVL_26_TRACE1(str,p1)
+        #define DEBUG_LVL_26_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_26_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_26_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_25)
+        #define DEBUG_LVL_25_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_25_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_25_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_25_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_25_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_25_TRACE0(str)
+        #define DEBUG_LVL_25_TRACE1(str,p1)
+        #define DEBUG_LVL_25_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_25_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_25_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_24)
+        #define DEBUG_LVL_24_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_24_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_24_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_24_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_24_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_24_TRACE0(str)
+        #define DEBUG_LVL_24_TRACE1(str,p1)
+        #define DEBUG_LVL_24_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_24_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_24_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_23)
+        #define DEBUG_LVL_23_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_23_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_23_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_23_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_23_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_23_TRACE0(str)
+        #define DEBUG_LVL_23_TRACE1(str,p1)
+        #define DEBUG_LVL_23_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_23_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_23_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_22)
+        #define DEBUG_LVL_22_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_22_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_22_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_22_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_22_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_22_TRACE0(str)
+        #define DEBUG_LVL_22_TRACE1(str,p1)
+        #define DEBUG_LVL_22_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_22_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_22_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_21)
+        #define DEBUG_LVL_21_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_21_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_21_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_21_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_21_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_21_TRACE0(str)
+        #define DEBUG_LVL_21_TRACE1(str,p1)
+        #define DEBUG_LVL_21_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_21_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_21_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_20)
+        #define DEBUG_LVL_20_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_20_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_20_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_20_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_20_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_20_TRACE0(str)
+        #define DEBUG_LVL_20_TRACE1(str,p1)
+        #define DEBUG_LVL_20_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_20_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_20_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_19)
+        #define DEBUG_LVL_19_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_19_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_19_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_19_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_19_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_19_TRACE0(str)
+        #define DEBUG_LVL_19_TRACE1(str,p1)
+        #define DEBUG_LVL_19_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_19_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_19_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_18)
+        #define DEBUG_LVL_18_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_18_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_18_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_18_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_18_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_18_TRACE0(str)
+        #define DEBUG_LVL_18_TRACE1(str,p1)
+        #define DEBUG_LVL_18_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_18_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_18_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_17)
+        #define DEBUG_LVL_17_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_17_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_17_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_17_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_17_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_17_TRACE0(str)
+        #define DEBUG_LVL_17_TRACE1(str,p1)
+        #define DEBUG_LVL_17_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_17_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_17_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_16)
+        #define DEBUG_LVL_16_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_16_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_16_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_16_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_16_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_16_TRACE0(str)
+        #define DEBUG_LVL_16_TRACE1(str,p1)
+        #define DEBUG_LVL_16_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_16_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_16_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_15)
+        #define DEBUG_LVL_15_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_15_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_15_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_15_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_15_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_15_TRACE0(str)
+        #define DEBUG_LVL_15_TRACE1(str,p1)
+        #define DEBUG_LVL_15_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_15_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_15_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_14)
+        #define DEBUG_LVL_14_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_14_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_14_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_14_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_14_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_14_TRACE0(str)
+        #define DEBUG_LVL_14_TRACE1(str,p1)
+        #define DEBUG_LVL_14_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_14_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_14_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_13)
+        #define DEBUG_LVL_13_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_13_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_13_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_13_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_13_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_13_TRACE0(str)
+        #define DEBUG_LVL_13_TRACE1(str,p1)
+        #define DEBUG_LVL_13_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_13_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_13_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_12)
+        #define DEBUG_LVL_12_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_12_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_12_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_12_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_12_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_12_TRACE0(str)
+        #define DEBUG_LVL_12_TRACE1(str,p1)
+        #define DEBUG_LVL_12_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_12_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_12_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_11)
+        #define DEBUG_LVL_11_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_11_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_11_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_11_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_11_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_11_TRACE0(str)
+        #define DEBUG_LVL_11_TRACE1(str,p1)
+        #define DEBUG_LVL_11_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_11_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_11_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_10)
+        #define DEBUG_LVL_10_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_10_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_10_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_10_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_10_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_10_TRACE0(str)
+        #define DEBUG_LVL_10_TRACE1(str,p1)
+        #define DEBUG_LVL_10_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_10_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_10_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_09)
+        #define DEBUG_LVL_09_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_09_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_09_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_09_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_09_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_09_TRACE0(str)
+        #define DEBUG_LVL_09_TRACE1(str,p1)
+        #define DEBUG_LVL_09_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_09_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_09_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_08)
+        #define DEBUG_LVL_08_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_08_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_08_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_08_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_08_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_08_TRACE0(str)
+        #define DEBUG_LVL_08_TRACE1(str,p1)
+        #define DEBUG_LVL_08_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_08_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_08_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_07)
+        #define DEBUG_LVL_07_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_07_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_07_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_07_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_07_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_07_TRACE0(str)
+        #define DEBUG_LVL_07_TRACE1(str,p1)
+        #define DEBUG_LVL_07_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_07_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_07_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_06)
+        #define DEBUG_LVL_06_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_06_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_06_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_06_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_06_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_06_TRACE0(str)
+        #define DEBUG_LVL_06_TRACE1(str,p1)
+        #define DEBUG_LVL_06_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_06_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_06_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_05)
+        #define DEBUG_LVL_05_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_05_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_05_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_05_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_05_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_05_TRACE0(str)
+        #define DEBUG_LVL_05_TRACE1(str,p1)
+        #define DEBUG_LVL_05_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_05_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_05_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_04)
+        #define DEBUG_LVL_04_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_04_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_04_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_04_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_04_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_04_TRACE0(str)
+        #define DEBUG_LVL_04_TRACE1(str,p1)
+        #define DEBUG_LVL_04_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_04_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_04_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_03)
+        #define DEBUG_LVL_03_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_03_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_03_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_03_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_03_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_03_TRACE0(str)
+        #define DEBUG_LVL_03_TRACE1(str,p1)
+        #define DEBUG_LVL_03_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_03_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_03_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_02)
+        #define DEBUG_LVL_02_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_02_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_02_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_02_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_02_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_02_TRACE0(str)
+        #define DEBUG_LVL_02_TRACE1(str,p1)
+        #define DEBUG_LVL_02_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_02_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_02_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #if (DEBUG_GLB_LVL() & DEBUG_LVL_01)
+        #define DEBUG_LVL_01_TRACE0(str)                    TRACE0(str)
+        #define DEBUG_LVL_01_TRACE1(str,p1)                 TRACE1(str,p1)
+        #define DEBUG_LVL_01_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
+        #define DEBUG_LVL_01_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_01_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
+    #else
+        #define DEBUG_LVL_01_TRACE0(str)
+        #define DEBUG_LVL_01_TRACE1(str,p1)
+        #define DEBUG_LVL_01_TRACE2(str,p1,p2)
+        #define DEBUG_LVL_01_TRACE3(str,p1,p2,p3)
+        #define DEBUG_LVL_01_TRACE4(str,p1,p2,p3,p4)
+    #endif
+
+    #define DEBUG_TRACE0(lvl,str)                           lvl##_TRACE0(str)
+    #define DEBUG_TRACE1(lvl,str,p1)                        lvl##_TRACE1(str,p1)
+    #define DEBUG_TRACE2(lvl,str,p1,p2)                     lvl##_TRACE2(str,p1,p2)
+    #define DEBUG_TRACE3(lvl,str,p1,p2,p3)                  lvl##_TRACE3(str,p1,p2,p3)
+    #define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4)               lvl##_TRACE4(str,p1,p2,p3,p4)
+
+#endif
+
+
+//---------------------------------------------------------------------------
+// The macro DEBUG_DUMP_DATA() can be used with the same debug-levels to dump
+// out data bytes. Function DumpData() has to be included.
+// NOTE: DUMP_DATA has to be defined in project settings.
+#if (!defined (NDEBUG) && defined (DUMP_DATA)) || (DEV_SYSTEM == _DEV_WIN32_)
+
+    #ifdef __cplusplus
+    extern "C"
+    {
+    #endif
+
+        void DumpData (char* szStr_p, BYTE MEM* pbData_p, WORD wSize_p);
+
+    #ifdef __cplusplus
+    } // von extern "C"
+    #endif
+
+    #define DEBUG_DUMP_DATA(lvl,str,ptr,siz)    if ((DEBUG_GLB_LVL() & (lvl))==(lvl)) \
+                                                    DumpData (str, (BYTE MEM*) (ptr), (WORD) (siz));
+
+#else
+
+    #define DEBUG_DUMP_DATA(lvl,str,ptr,siz)
+
+#endif
+
+
+//---------------------------------------------------------------------------
+// The macro DEBUG_ASSERT() can be used to print out an error string if the
+// parametered expresion does not result TRUE.
+// NOTE: If DEBUG_KEEP_ASSERT is defined, then DEBUG_ASSERT-line will not be
+//       deleted from compiler (in release version too).
+#if !defined (NDEBUG) || defined (DEBUG_KEEP_ASSERT)
+
+    #if (DEV_SYSTEM == _DEV_WIN32_)
+
+        // For WIN32 process will be killed after closing message box.
+
+        #define DEBUG_ASSERT0(expr,str)         if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
+                                                    MessageBox (NULL, \
+                                                        "Assertion failed: line " __LINE__ " file " __FILE__ \
+                                                        "\n    -> " str "\n"); \
+                                                    ExitProcess (-1); }
+
+        #define DEBUG_ASSERT1(expr,str,p1)      if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
+                                                    MessageBox (NULL, \
+                                                        "Assertion failed: line " __LINE__ " file " __FILE__ \
+                                                        "\n    -> " str "\n"); \
+                                                    ExitProcess (-1); }
+
+    #else
+
+        // For microcontrollers process will be stopped using endless loop.
+
+        #define DEBUG_ASSERT0(expr,str)         if (!(expr )) { \
+                                                    DEBUG_LVL_ASSERT_TRACE3 ( \
+                                                        "Assertion failed: line %d file '%s'\n" \
+                                                        "    -> '%s'\n", __LINE__, __FILE__, str); \
+                                                    while (1); }
+
+        #define DEBUG_ASSERT1(expr,str,p1)      if (!(expr )) { \
+                                                    DEBUG_LVL_ASSERT_TRACE4 ( \
+                                                        "Assertion failed: line %d file '%s'\n" \
+                                                        "    -> '%s'\n" \
+                                                        "    -> 0x%08lX\n", __LINE__, __FILE__, str, (DWORD) p1); \
+                                                    while (1); }
+
+    #endif
+
+#else
+
+    #define DEBUG_ASSERT0(expr,str)
+    #define DEBUG_ASSERT1(expr,str,p1)
+
+#endif
+
+
+//---------------------------------------------------------------------------
+// The macro DEBUG_ONLY() implements code, if NDEBUG is not defined.
+#if !defined (DEBUG_ONLY)
+    #if !defined (NDEBUG)
+
+        #define DEBUG_ONLY(expr)    expr
+
+    #else
+
+        #define DEBUG_ONLY(expr)
+
+    #endif
+#endif
+
+
+#endif // _DEBUG_H_
diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c
new file mode 100644 (file)
index 0000000..3fa0564
--- /dev/null
@@ -0,0 +1,1317 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Ethernet driver for Realtek RTL8139 chips
+                except the RTL8139C+, because it has a different
+                Tx descriptor handling.
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: Edrv8139.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.10 $  $Date: 2008/11/21 09:00:38 $
+
+                $State: Exp $
+
+                Build Environment:
+                Dev C++ and GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2008/02/05 d.k.:   start of implementation
+
+****************************************************************************/
+
+#include "global.h"
+#include "EplInc.h"
+#include "edrv.h"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+// Buffer handling:
+// All buffers are created statically (i.e. at compile time resp. at
+// initialisation via kmalloc() ) and not dynamically on request (i.e. via
+// EdrvAllocTxMsgBuffer().
+// EdrvAllocTxMsgBuffer() searches for an unused buffer which is large enough.
+// EdrvInit() may allocate some buffers with sizes less than maximum frame
+// size (i.e. 1514 bytes), e.g. for SoC, SoA, StatusResponse, IdentResponse,
+// NMT requests / commands. The less the size of the buffer the less the
+// number of the buffer.
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef EDRV_MAX_TX_BUFFERS
+#define EDRV_MAX_TX_BUFFERS     20
+#endif
+
+#define EDRV_MAX_FRAME_SIZE     0x600
+
+#define EDRV_RX_BUFFER_SIZE     0x8610  // 32 kB + 16 Byte + 1,5 kB (WRAP is enabled)
+#define EDRV_RX_BUFFER_LENGTH   (EDRV_RX_BUFFER_SIZE & 0xF800)  // buffer size cut down to 2 kB alignment
+
+#define EDRV_TX_BUFFER_SIZE     (EDRV_MAX_TX_BUFFERS * EDRV_MAX_FRAME_SIZE) // n * (MTU + 14 + 4)
+
+#define DRV_NAME                "epl"
+
+
+#define EDRV_REGW_INT_MASK      0x3C    // interrupt mask register
+#define EDRV_REGW_INT_STATUS    0x3E    // interrupt status register
+#define EDRV_REGW_INT_ROK       0x0001  // Receive OK interrupt
+#define EDRV_REGW_INT_RER       0x0002  // Receive error interrupt
+#define EDRV_REGW_INT_TOK       0x0004  // Transmit OK interrupt
+#define EDRV_REGW_INT_TER       0x0008  // Transmit error interrupt
+#define EDRV_REGW_INT_RXOVW     0x0010  // Rx buffer overflow interrupt
+#define EDRV_REGW_INT_PUN       0x0020  // Packet underrun/ link change interrupt
+#define EDRV_REGW_INT_FOVW      0x0040  // Rx FIFO overflow interrupt
+#define EDRV_REGW_INT_LENCHG    0x2000  // Cable length change interrupt
+#define EDRV_REGW_INT_TIMEOUT   0x4000  // Time out interrupt
+#define EDRV_REGW_INT_SERR      0x8000  // System error interrupt
+#define EDRV_REGW_INT_MASK_DEF  (EDRV_REGW_INT_ROK \
+                                 | EDRV_REGW_INT_RER \
+                                 | EDRV_REGW_INT_TOK \
+                                 | EDRV_REGW_INT_TER \
+                                 | EDRV_REGW_INT_RXOVW \
+                                 | EDRV_REGW_INT_FOVW \
+                                 | EDRV_REGW_INT_PUN \
+                                 | EDRV_REGW_INT_TIMEOUT \
+                                 | EDRV_REGW_INT_SERR)   // default interrupt mask
+
+#define EDRV_REGB_COMMAND       0x37    // command register
+#define EDRV_REGB_COMMAND_RST   0x10
+#define EDRV_REGB_COMMAND_RE    0x08
+#define EDRV_REGB_COMMAND_TE    0x04
+#define EDRV_REGB_COMMAND_BUFE  0x01
+
+#define EDRV_REGB_CMD9346       0x50    // 93C46 command register
+#define EDRV_REGB_CMD9346_LOCK  0x00    // lock configuration registers
+#define EDRV_REGB_CMD9346_UNLOCK 0xC0   // unlock configuration registers
+
+#define EDRV_REGDW_RCR          0x44    // Rx configuration register
+#define EDRV_REGDW_RCR_NO_FTH   0x0000E000  // no receive FIFO threshold
+#define EDRV_REGDW_RCR_RBLEN32K 0x00001000  // 32 kB receive buffer
+#define EDRV_REGDW_RCR_MXDMAUNL 0x00000700  // unlimited maximum DMA burst size
+#define EDRV_REGDW_RCR_NOWRAP   0x00000080  // do not wrap frame at end of buffer
+#define EDRV_REGDW_RCR_AER      0x00000020  // accept error frames (CRC, alignment, collided)
+#define EDRV_REGDW_RCR_AR       0x00000010  // accept runt
+#define EDRV_REGDW_RCR_AB       0x00000008  // accept broadcast frames
+#define EDRV_REGDW_RCR_AM       0x00000004  // accept multicast frames
+#define EDRV_REGDW_RCR_APM      0x00000002  // accept physical match frames
+#define EDRV_REGDW_RCR_AAP      0x00000001  // accept all frames
+#define EDRV_REGDW_RCR_DEF      (EDRV_REGDW_RCR_NO_FTH \
+                                 | EDRV_REGDW_RCR_RBLEN32K \
+                                 | EDRV_REGDW_RCR_MXDMAUNL \
+                                 | EDRV_REGDW_RCR_NOWRAP \
+                                 | EDRV_REGDW_RCR_AB \
+                                 | EDRV_REGDW_RCR_AM \
+                                 | EDRV_REGDW_RCR_APM)  // default value
+
+#define EDRV_REGDW_TCR          0x40    // Tx configuration register
+#define EDRV_REGDW_TCR_VER_MASK 0x7CC00000  // mask for hardware version
+#define EDRV_REGDW_TCR_VER_C    0x74000000  // RTL8139C
+#define EDRV_REGDW_TCR_VER_D    0x74400000  // RTL8139D
+#define EDRV_REGDW_TCR_IFG96    0x03000000  // default interframe gap (960 ns)
+#define EDRV_REGDW_TCR_CRC      0x00010000  // disable appending of CRC by the controller
+#define EDRV_REGDW_TCR_MXDMAUNL 0x00000700  // maximum DMA burst size of 2048 b
+#define EDRV_REGDW_TCR_TXRETRY  0x00000000  // 16 retries
+#define EDRV_REGDW_TCR_DEF      (EDRV_REGDW_TCR_IFG96 \
+                                 | EDRV_REGDW_TCR_MXDMAUNL \
+                                 | EDRV_REGDW_TCR_TXRETRY)
+
+#define EDRV_REGW_MULINT        0x5C    // multiple interrupt select register
+
+#define EDRV_REGDW_MPC          0x4C    // missed packet counter register
+
+#define EDRV_REGDW_TSAD0        0x20    // Transmit start address of descriptor 0
+#define EDRV_REGDW_TSAD1        0x24    // Transmit start address of descriptor 1
+#define EDRV_REGDW_TSAD2        0x28    // Transmit start address of descriptor 2
+#define EDRV_REGDW_TSAD3        0x2C    // Transmit start address of descriptor 3
+#define EDRV_REGDW_TSD0         0x10    // Transmit status of descriptor 0
+#define EDRV_REGDW_TSD_CRS      0x80000000  // Carrier sense lost
+#define EDRV_REGDW_TSD_TABT     0x40000000  // Transmit Abort
+#define EDRV_REGDW_TSD_OWC      0x20000000  // Out of window collision
+#define EDRV_REGDW_TSD_TXTH_DEF 0x00020000  // Transmit FIFO threshold of 64 bytes
+#define EDRV_REGDW_TSD_TOK      0x00008000  // Transmit OK
+#define EDRV_REGDW_TSD_TUN      0x00004000  // Transmit FIFO underrun
+#define EDRV_REGDW_TSD_OWN      0x00002000  // Owner
+
+#define EDRV_REGDW_RBSTART      0x30    // Receive buffer start address
+
+#define EDRV_REGW_CAPR          0x38    // Current address of packet read
+
+#define EDRV_REGDW_IDR0         0x00    // ID register 0
+#define EDRV_REGDW_IDR4         0x04    // ID register 4
+
+#define EDRV_REGDW_MAR0         0x08    // Multicast address register 0
+#define EDRV_REGDW_MAR4         0x0C    // Multicast address register 4
+
+
+// defines for the status word in the receive buffer
+#define EDRV_RXSTAT_MAR         0x8000  // Multicast address received
+#define EDRV_RXSTAT_PAM         0x4000  // Physical address matched
+#define EDRV_RXSTAT_BAR         0x2000  // Broadcast address received
+#define EDRV_RXSTAT_ISE         0x0020  // Invalid symbol error
+#define EDRV_RXSTAT_RUNT        0x0010  // Runt packet received
+#define EDRV_RXSTAT_LONG        0x0008  // Long packet
+#define EDRV_RXSTAT_CRC         0x0004  // CRC error
+#define EDRV_RXSTAT_FAE         0x0002  // Frame alignment error
+#define EDRV_RXSTAT_ROK         0x0001  // Receive OK
+
+
+#define EDRV_REGDW_WRITE(dwReg, dwVal)  writel(dwVal, EdrvInstance_l.m_pIoAddr + dwReg)
+#define EDRV_REGW_WRITE(dwReg, wVal)    writew(wVal, EdrvInstance_l.m_pIoAddr + dwReg)
+#define EDRV_REGB_WRITE(dwReg, bVal)    writeb(bVal, EdrvInstance_l.m_pIoAddr + dwReg)
+#define EDRV_REGDW_READ(dwReg)          readl(EdrvInstance_l.m_pIoAddr + dwReg)
+#define EDRV_REGW_READ(dwReg)           readw(EdrvInstance_l.m_pIoAddr + dwReg)
+#define EDRV_REGB_READ(dwReg)           readb(EdrvInstance_l.m_pIoAddr + dwReg)
+
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+
+#define EDRV_COUNT_SEND                 TGT_DBG_SIGNAL_TRACE_POINT(2)
+#define EDRV_COUNT_TIMEOUT              TGT_DBG_SIGNAL_TRACE_POINT(3)
+#define EDRV_COUNT_PCI_ERR              TGT_DBG_SIGNAL_TRACE_POINT(4)
+#define EDRV_COUNT_TX                   TGT_DBG_SIGNAL_TRACE_POINT(5)
+#define EDRV_COUNT_RX                   TGT_DBG_SIGNAL_TRACE_POINT(6)
+#define EDRV_COUNT_LATECOLLISION        TGT_DBG_SIGNAL_TRACE_POINT(10)
+#define EDRV_COUNT_TX_COL_RL            TGT_DBG_SIGNAL_TRACE_POINT(11)
+#define EDRV_COUNT_TX_FUN               TGT_DBG_SIGNAL_TRACE_POINT(12)
+#define EDRV_COUNT_TX_ERR               TGT_DBG_SIGNAL_TRACE_POINT(13)
+#define EDRV_COUNT_RX_CRC               TGT_DBG_SIGNAL_TRACE_POINT(14)
+#define EDRV_COUNT_RX_ERR               TGT_DBG_SIGNAL_TRACE_POINT(15)
+#define EDRV_COUNT_RX_FOVW              TGT_DBG_SIGNAL_TRACE_POINT(16)
+#define EDRV_COUNT_RX_PUN               TGT_DBG_SIGNAL_TRACE_POINT(17)
+#define EDRV_COUNT_RX_FAE               TGT_DBG_SIGNAL_TRACE_POINT(18)
+#define EDRV_COUNT_RX_OVW               TGT_DBG_SIGNAL_TRACE_POINT(19)
+
+#define EDRV_TRACE_CAPR(x)              TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x06000000)
+#define EDRV_TRACE_RX_CRC(x)            TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0E000000)
+#define EDRV_TRACE_RX_ERR(x)            TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0F000000)
+#define EDRV_TRACE_RX_PUN(x)            TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x11000000)
+#define EDRV_TRACE(x)                   TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF0000) | 0x0000FEC0)
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+/*
+typedef struct
+{
+    BOOL            m_fUsed;
+    unsigned int    m_uiSize;
+    MCD_bufDescFec *m_pBufDescr;
+
+} tEdrvTxBufferIntern;
+*/
+
+// Private structure
+typedef struct
+{
+    struct pci_dev*     m_pPciDev;      // pointer to PCI device structure
+    void*               m_pIoAddr;      // pointer to register space of Ethernet controller
+    BYTE*               m_pbRxBuf;      // pointer to Rx buffer
+    dma_addr_t          m_pRxBufDma;
+    BYTE*               m_pbTxBuf;      // pointer to Tx buffer
+    dma_addr_t          m_pTxBufDma;
+    BOOL                m_afTxBufUsed[EDRV_MAX_TX_BUFFERS];
+    unsigned int        m_uiCurTxDesc;
+
+    tEdrvInitParam      m_InitParam;
+    tEdrvTxBuffer*      m_pLastTransmittedTxBuffer;
+
+} tEdrvInstance;
+
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static int EdrvInitOne(struct pci_dev *pPciDev,
+                       const struct pci_device_id *pId);
+
+static void EdrvRemoveOne(struct pci_dev *pPciDev);
+
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+// buffers and buffer descriptors and pointers
+
+static struct pci_device_id aEdrvPciTbl[] = {
+    {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+    {0,}
+};
+MODULE_DEVICE_TABLE (pci, aEdrvPciTbl);
+
+
+static tEdrvInstance EdrvInstance_l;
+
+
+static struct pci_driver EdrvDriver = {
+    .name         = DRV_NAME,
+    .id_table     = aEdrvPciTbl,
+    .probe        = EdrvInitOne,
+    .remove       = EdrvRemoveOne,
+};
+
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <edrv>                                              */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static BYTE EdrvCalcHash (BYTE * pbMAC_p);
+
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvInit
+//
+// Description: function for init of the Ethernet controller
+//
+// Parameters:  pEdrvInitParam_p    = pointer to struct including the init-parameters
+//
+// Returns:     Errorcode           = kEplSuccessful
+//                                  = kEplNoResource
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p)
+{
+tEplKernel  Ret;
+int         iResult;
+
+    Ret = kEplSuccessful;
+
+    // clear instance structure
+    EPL_MEMSET(&EdrvInstance_l, 0, sizeof (EdrvInstance_l));
+
+    // save the init data
+    EdrvInstance_l.m_InitParam = *pEdrvInitParam_p;
+
+
+    // register PCI driver
+    iResult = pci_register_driver (&EdrvDriver);
+    if (iResult != 0)
+    {
+        printk("%s pci_register_driver failed with %d\n", __FUNCTION__, iResult);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    if (EdrvInstance_l.m_pPciDev == NULL)
+    {
+        printk("%s m_pPciDev=NULL\n", __FUNCTION__);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    // read MAC address from controller
+    printk("%s local MAC = ", __FUNCTION__);
+    for (iResult = 0; iResult < 6; iResult++)
+    {
+        pEdrvInitParam_p->m_abMyMacAddr[iResult] = EDRV_REGB_READ((EDRV_REGDW_IDR0 + iResult));
+        printk("%02X ", (unsigned int)pEdrvInitParam_p->m_abMyMacAddr[iResult]);
+    }
+    printk("\n");
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvShutdown
+//
+// Description: Shutdown the Ethernet controller
+//
+// Parameters:  void
+//
+// Returns:     Errorcode   = kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvShutdown(void)
+{
+
+    // unregister PCI driver
+    printk("%s calling pci_unregister_driver()\n", __FUNCTION__);
+    pci_unregister_driver (&EdrvDriver);
+
+    return kEplSuccessful;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvDefineRxMacAddrEntry
+//
+// Description: Set a multicast entry into the Ethernet controller
+//
+// Parameters:  pbMacAddr_p     = pointer to multicast entry to set
+//
+// Returns:     Errorcode       = kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvDefineRxMacAddrEntry (BYTE * pbMacAddr_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+DWORD       dwData;
+BYTE        bHash;
+
+    bHash = EdrvCalcHash (pbMacAddr_p);
+/*
+    dwData = ether_crc(6, pbMacAddr_p);
+
+    printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u  ether_crc = 0x%08lX\n",
+        (WORD) pbMacAddr_p[0], (WORD) pbMacAddr_p[1], (WORD) pbMacAddr_p[2],
+        (WORD) pbMacAddr_p[3], (WORD) pbMacAddr_p[4], (WORD) pbMacAddr_p[5],
+        (WORD) bHash, (WORD) (dwData >> 26), dwData);
+*/
+    if (bHash > 31)
+    {
+        dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
+        dwData |= 1 << (bHash - 32);
+        EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData);
+    }
+    else
+    {
+        dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
+        dwData |= 1 << bHash;
+        EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData);
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvUndefineRxMacAddrEntry
+//
+// Description: Reset a multicast entry in the Ethernet controller
+//
+// Parameters:  pbMacAddr_p     = pointer to multicast entry to reset
+//
+// Returns:     Errorcode       = kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvUndefineRxMacAddrEntry (BYTE * pbMacAddr_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+DWORD       dwData;
+BYTE        bHash;
+
+    bHash = EdrvCalcHash (pbMacAddr_p);
+
+    if (bHash > 31)
+    {
+        dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
+        dwData &= ~(1 << (bHash - 32));
+        EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData);
+    }
+    else
+    {
+        dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
+        dwData &= ~(1 << bHash);
+        EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData);
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvAllocTxMsgBuffer
+//
+// Description: Register a Tx-Buffer
+//
+// Parameters:  pBuffer_p   = pointer to Buffer structure
+//
+// Returns:     Errorcode   = kEplSuccessful
+//                          = kEplEdrvNoFreeBufEntry
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvAllocTxMsgBuffer       (tEdrvTxBuffer * pBuffer_p)
+{
+tEplKernel Ret = kEplSuccessful;
+DWORD i;
+
+    if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE)
+    {
+        Ret = kEplEdrvNoFreeBufEntry;
+        goto Exit;
+    }
+
+    // search a free Tx buffer with appropriate size
+    for (i = 0; i < EDRV_MAX_TX_BUFFERS; i++)
+    {
+        if (EdrvInstance_l.m_afTxBufUsed[i] == FALSE)
+        {
+            // free channel found
+            EdrvInstance_l.m_afTxBufUsed[i] = TRUE;
+            pBuffer_p->m_uiBufferNumber = i;
+            pBuffer_p->m_pbBuffer = EdrvInstance_l.m_pbTxBuf + (i * EDRV_MAX_FRAME_SIZE);
+            pBuffer_p->m_uiMaxBufferLen = EDRV_MAX_FRAME_SIZE;
+            break;
+        }
+    }
+    if (i >= EDRV_MAX_TX_BUFFERS)
+    {
+        Ret = kEplEdrvNoFreeBufEntry;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvReleaseTxMsgBuffer
+//
+// Description: Register a Tx-Buffer
+//
+// Parameters:  pBuffer_p   = pointer to Buffer structure
+//
+// Returns:     Errorcode   = kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvReleaseTxMsgBuffer     (tEdrvTxBuffer * pBuffer_p)
+{
+unsigned int uiBufferNumber;
+
+    uiBufferNumber = pBuffer_p->m_uiBufferNumber;
+
+    if (uiBufferNumber < EDRV_MAX_TX_BUFFERS)
+    {
+        EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] = FALSE;
+    }
+
+    return kEplSuccessful;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvSendTxMsg
+//
+// Description: immediately starts the transmission of the buffer
+//
+// Parameters:  pBuffer_p   = buffer descriptor to transmit
+//
+// Returns:     Errorcode   = kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvSendTxMsg              (tEdrvTxBuffer * pBuffer_p)
+{
+tEplKernel Ret = kEplSuccessful;
+unsigned int uiBufferNumber;
+DWORD       dwTemp;
+
+    uiBufferNumber = pBuffer_p->m_uiBufferNumber;
+
+    if ((uiBufferNumber >= EDRV_MAX_TX_BUFFERS)
+        || (EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] == FALSE))
+    {
+        Ret = kEplEdrvBufNotExisting;
+        goto Exit;
+    }
+
+    if (EdrvInstance_l.m_pLastTransmittedTxBuffer != NULL)
+    {   // transmission is already active
+        Ret = kEplInvalidOperation;
+        dwTemp = EDRV_REGDW_READ((EDRV_REGDW_TSD0 + (EdrvInstance_l.m_uiCurTxDesc * sizeof (DWORD))));
+        printk("%s InvOp TSD%u = 0x%08lX", __FUNCTION__, EdrvInstance_l.m_uiCurTxDesc, dwTemp);
+        printk("  Cmd = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+        goto Exit;
+    }
+
+    // save pointer to buffer structure for TxHandler
+    EdrvInstance_l.m_pLastTransmittedTxBuffer = pBuffer_p;
+
+    EDRV_COUNT_SEND;
+
+    // pad with zeros if necessary, because controller does not do it
+    if (pBuffer_p->m_uiTxMsgLen < MIN_ETH_SIZE)
+    {
+        EPL_MEMSET(pBuffer_p->m_pbBuffer + pBuffer_p->m_uiTxMsgLen, 0, MIN_ETH_SIZE - pBuffer_p->m_uiTxMsgLen);
+        pBuffer_p->m_uiTxMsgLen = MIN_ETH_SIZE;
+    }
+
+    // set DMA address of buffer
+    EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 + (EdrvInstance_l.m_uiCurTxDesc * sizeof (DWORD))), (EdrvInstance_l.m_pTxBufDma + (uiBufferNumber * EDRV_MAX_FRAME_SIZE)));
+    dwTemp = EDRV_REGDW_READ((EDRV_REGDW_TSAD0 + (EdrvInstance_l.m_uiCurTxDesc * sizeof (DWORD))));
+//    printk("%s TSAD%u = 0x%08lX", __FUNCTION__, EdrvInstance_l.m_uiCurTxDesc, dwTemp);
+
+    // start transmission
+    EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 + (EdrvInstance_l.m_uiCurTxDesc * sizeof (DWORD))), (EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
+    dwTemp = EDRV_REGDW_READ((EDRV_REGDW_TSD0 + (EdrvInstance_l.m_uiCurTxDesc * sizeof (DWORD))));
+//    printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (DWORD)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
+
+Exit:
+    return Ret;
+}
+
+#if 0
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvTxMsgReady
+//
+// Description: starts copying the buffer to the ethernet controller's FIFO
+//
+// Parameters:  pbBuffer_p - bufferdescriptor to transmit
+//
+// Returns:     Errorcode - kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvTxMsgReady              (tEdrvTxBuffer * pBuffer_p)
+{
+tEplKernel Ret = kEplSuccessful;
+unsigned int uiBufferNumber;
+
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvTxMsgStart
+//
+// Description: starts transmission of the ethernet controller's FIFO
+//
+// Parameters:  pbBuffer_p - bufferdescriptor to transmit
+//
+// Returns:     Errorcode - kEplSuccessful
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel EdrvTxMsgStart              (tEdrvTxBuffer * pBuffer_p)
+{
+tEplKernel Ret = kEplSuccessful;
+
+
+
+    return Ret;
+}
+#endif
+
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvReinitRx
+//
+// Description: reinitialize the Rx process, because of error
+//
+// Parameters:  void
+//
+// Returns:     void
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static void EdrvReinitRx(void)
+{
+BYTE    bCmd;
+
+    // simply switch off and on the receiver
+    // this will reset the CAPR register
+    bCmd = EDRV_REGB_READ(EDRV_REGB_COMMAND);
+    EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (bCmd & ~EDRV_REGB_COMMAND_RE));
+    EDRV_REGB_WRITE(EDRV_REGB_COMMAND, bCmd);
+
+    // set receive configuration register
+    EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF);
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:     EdrvInterruptHandler
+//
+// Description:  interrupt handler
+//
+// Parameters:   void
+//
+// Returns:      void
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if 0
+void EdrvInterruptHandler (void)
+{
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
+static int TgtEthIsr (int nIrqNum_p, void* ppDevInstData_p)
+#else
+static int TgtEthIsr (int nIrqNum_p, void* ppDevInstData_p, struct pt_regs* ptRegs_p)
+#endif
+{
+//    EdrvInterruptHandler();
+tEdrvRxBuffer   RxBuffer;
+tEdrvTxBuffer*  pTxBuffer;
+WORD            wStatus;
+DWORD           dwTxStatus;
+DWORD           dwRxStatus;
+WORD            wCurRx;
+BYTE*           pbRxBuf;
+unsigned int    uiLength;
+int             iHandled = IRQ_HANDLED;
+
+//    printk("¤");
+
+    // read the interrupt status
+    wStatus = EDRV_REGW_READ(EDRV_REGW_INT_STATUS);
+
+    // acknowledge the interrupts
+    EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, wStatus);
+
+    if (wStatus == 0)
+    {
+        iHandled = IRQ_NONE;
+        goto Exit;
+    }
+
+    // process tasks
+    if ((wStatus & (EDRV_REGW_INT_TER | EDRV_REGW_INT_TOK)) != 0)
+    {   // transmit interrupt
+
+        if (EdrvInstance_l.m_pbTxBuf == NULL)
+        {
+            printk("%s Tx buffers currently not allocated\n", __FUNCTION__);
+            goto Exit;
+        }
+
+        // read transmit status
+        dwTxStatus = EDRV_REGDW_READ((EDRV_REGDW_TSD0 + (EdrvInstance_l.m_uiCurTxDesc * sizeof (DWORD))));
+        if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0)
+        {   // transmit finished
+            EdrvInstance_l.m_uiCurTxDesc = (EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03;
+            pTxBuffer = EdrvInstance_l.m_pLastTransmittedTxBuffer;
+            EdrvInstance_l.m_pLastTransmittedTxBuffer = NULL;
+
+            if ((dwTxStatus & EDRV_REGDW_TSD_TOK) != 0)
+            {
+                EDRV_COUNT_TX;
+            }
+            else if ((dwTxStatus & EDRV_REGDW_TSD_TUN) != 0)
+            {
+                EDRV_COUNT_TX_FUN;
+            }
+            else
+            {   // assume EDRV_REGDW_TSD_TABT
+                EDRV_COUNT_TX_COL_RL;
+            }
+
+//            printk("T");
+            if (pTxBuffer != NULL)
+            {
+                // call Tx handler of Data link layer
+                EdrvInstance_l.m_InitParam.m_pfnTxHandler(pTxBuffer);
+            }
+        }
+        else
+        {
+            EDRV_COUNT_TX_ERR;
+        }
+    }
+
+    if ((wStatus & (EDRV_REGW_INT_RER | EDRV_REGW_INT_FOVW | EDRV_REGW_INT_RXOVW | EDRV_REGW_INT_PUN)) != 0)
+    {   // receive error interrupt
+
+        if ((wStatus & EDRV_REGW_INT_FOVW) != 0)
+        {
+            EDRV_COUNT_RX_FOVW;
+        }
+        else if ((wStatus & EDRV_REGW_INT_RXOVW) != 0)
+        {
+            EDRV_COUNT_RX_OVW;
+        }
+        else if ((wStatus & EDRV_REGW_INT_PUN) != 0)
+        {   // Packet underrun
+            EDRV_TRACE_RX_PUN(wStatus);
+            EDRV_COUNT_RX_PUN;
+        }
+        else /*if ((wStatus & EDRV_REGW_INT_RER) != 0)*/
+        {
+            EDRV_TRACE_RX_ERR(wStatus);
+            EDRV_COUNT_RX_ERR;
+        }
+
+        // reinitialize Rx process
+        EdrvReinitRx();
+    }
+
+    if ((wStatus & EDRV_REGW_INT_ROK) != 0)
+    {   // receive interrupt
+
+        if (EdrvInstance_l.m_pbRxBuf == NULL)
+        {
+            printk("%s Rx buffers currently not allocated\n", __FUNCTION__);
+            goto Exit;
+        }
+
+        // read current offset in receive buffer
+        wCurRx = (EDRV_REGW_READ(EDRV_REGW_CAPR) + 0x10) % EDRV_RX_BUFFER_LENGTH;
+
+        while ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_BUFE) == 0)
+        {   // frame available
+
+            // calculate pointer to current frame in receive buffer
+            pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx;
+
+            // read receive status DWORD
+            dwRxStatus = le32_to_cpu(*((DWORD*)pbRxBuf));
+
+            // calculate length of received frame
+            uiLength = dwRxStatus >> 16;
+
+            if (uiLength == 0xFFF0)
+            {   // frame is unfinished (maybe early Rx interrupt is active)
+                break;
+            }
+
+            if ((dwRxStatus & EDRV_RXSTAT_ROK) == 0)
+            {   // error occured while receiving this frame
+                // ignore it
+                if ((dwRxStatus & EDRV_RXSTAT_FAE) != 0)
+                {
+                    EDRV_COUNT_RX_FAE;
+                }
+                else if ((dwRxStatus & EDRV_RXSTAT_CRC) != 0)
+                {
+                    EDRV_TRACE_RX_CRC(dwRxStatus);
+                    EDRV_COUNT_RX_CRC;
+                }
+                else
+                {
+                    EDRV_TRACE_RX_ERR(dwRxStatus);
+                    EDRV_COUNT_RX_ERR;
+                }
+
+                // reinitialize Rx process
+                EdrvReinitRx();
+
+                break;
+            }
+            else
+            {   // frame is OK
+                RxBuffer.m_BufferInFrame = kEdrvBufferLastInFrame;
+                RxBuffer.m_uiRxMsgLen = uiLength - ETH_CRC_SIZE;
+                RxBuffer.m_pbBuffer = pbRxBuf + sizeof (dwRxStatus);
+
+//                printk("R");
+                EDRV_COUNT_RX;
+
+                // call Rx handler of Data link layer
+                EdrvInstance_l.m_InitParam.m_pfnRxHandler(&RxBuffer);
+            }
+
+            // calulate new offset (DWORD aligned)
+            wCurRx = (WORD) ((wCurRx + uiLength + sizeof (dwRxStatus) + 3) & ~0x3);
+            EDRV_TRACE_CAPR(wCurRx - 0x10);
+            EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10);
+
+            // reread current offset in receive buffer
+            wCurRx = (EDRV_REGW_READ(EDRV_REGW_CAPR) + 0x10) % EDRV_RX_BUFFER_LENGTH;
+
+        }
+    }
+
+    if ((wStatus & EDRV_REGW_INT_SERR) != 0)
+    {   // PCI error
+        EDRV_COUNT_PCI_ERR;
+    }
+
+    if ((wStatus & EDRV_REGW_INT_TIMEOUT) != 0)
+    {   // Timeout
+        EDRV_COUNT_TIMEOUT;
+    }
+
+Exit:
+    return iHandled;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvInitOne
+//
+// Description: initializes one PCI device
+//
+// Parameters:  pPciDev             = pointer to corresponding PCI device structure
+//              pId                 = PCI device ID
+//
+// Returns:     (int)               = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static int EdrvInitOne(struct pci_dev *pPciDev,
+                       const struct pci_device_id *pId)
+{
+int     iResult = 0;
+DWORD   dwTemp;
+
+    if (EdrvInstance_l.m_pPciDev != NULL)
+    {   // Edrv is already connected to a PCI device
+        printk("%s device %s discarded\n", __FUNCTION__, pci_name(pPciDev));
+        iResult = -ENODEV;
+        goto Exit;
+    }
+
+    if (pPciDev->revision >= 0x20)
+    {
+        printk("%s device %s is an enhanced 8139C+ version, which is not supported\n", __FUNCTION__, pci_name(pPciDev));
+        iResult = -ENODEV;
+        goto Exit;
+    }
+
+    EdrvInstance_l.m_pPciDev = pPciDev;
+
+    // enable device
+    printk("%s enable device\n", __FUNCTION__);
+    iResult = pci_enable_device(pPciDev);
+    if (iResult != 0)
+    {
+        goto Exit;
+    }
+
+    if ((pci_resource_flags(pPciDev, 1) & IORESOURCE_MEM) == 0)
+    {
+        iResult = -ENODEV;
+        goto Exit;
+    }
+
+    printk("%s request regions\n", __FUNCTION__);
+    iResult = pci_request_regions(pPciDev, DRV_NAME);
+    if (iResult != 0)
+    {
+        goto Exit;
+    }
+
+    printk("%s ioremap\n", __FUNCTION__);
+    EdrvInstance_l.m_pIoAddr = ioremap (pci_resource_start(pPciDev, 1), pci_resource_len(pPciDev, 1));
+    if (EdrvInstance_l.m_pIoAddr == NULL)
+    {   // remap of controller's register space failed
+        iResult = -EIO;
+        goto Exit;
+    }
+
+    // enable PCI busmaster
+    printk("%s enable busmaster\n", __FUNCTION__);
+    pci_set_master (pPciDev);
+
+    // reset controller
+    printk("%s reset controller\n", __FUNCTION__);
+    EDRV_REGB_WRITE(EDRV_REGB_COMMAND, EDRV_REGB_COMMAND_RST);
+
+    // wait until reset has finished
+    for (iResult = 500; iResult > 0; iResult--)
+    {
+        if ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_RST) == 0)
+        {
+            break;
+        }
+
+        schedule_timeout(10);
+    }
+
+    // check hardware version, i.e. chip ID
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR);
+    if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C)
+        && ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D))
+    {   // unsupported chip
+        printk("%s Unsupported chip! TCR = 0x%08lX\n", __FUNCTION__, dwTemp);
+        iResult = -ENODEV;
+        goto Exit;
+    }
+
+    // disable interrupts
+    printk("%s disable interrupts\n", __FUNCTION__);
+    EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0);
+    // acknowledge all pending interrupts
+    EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, EDRV_REGW_READ(EDRV_REGW_INT_STATUS));
+
+    // install interrupt handler
+    printk("%s install interrupt handler\n", __FUNCTION__);
+    iResult = request_irq(pPciDev->irq, TgtEthIsr, IRQF_SHARED, DRV_NAME /*pPciDev->dev.name*/, pPciDev);
+    if (iResult != 0)
+    {
+        goto Exit;
+    }
+
+/*
+    // unlock configuration registers
+    printk("%s unlock configuration registers\n", __FUNCTION__);
+    EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_UNLOCK);
+
+    // check if user specified a MAC address
+    printk("%s check specified MAC address\n", __FUNCTION__);
+    for (iResult = 0; iResult < 6; iResult++)
+    {
+        if (EdrvInstance_l.m_InitParam.m_abMyMacAddr[iResult] != 0)
+        {
+            printk("%s set local MAC address\n", __FUNCTION__);
+            // write this MAC address to controller
+            EDRV_REGDW_WRITE(EDRV_REGDW_IDR0,
+                le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
+            dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0);
+
+            EDRV_REGDW_WRITE(EDRV_REGDW_IDR4,
+                le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
+            dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4);
+            break;
+        }
+    }
+    iResult = 0;
+
+    // lock configuration registers
+    EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_LOCK);
+*/
+
+    // allocate buffers
+    printk("%s allocate buffers\n", __FUNCTION__);
+    EdrvInstance_l.m_pbTxBuf = pci_alloc_consistent(pPciDev, EDRV_TX_BUFFER_SIZE,
+                     &EdrvInstance_l.m_pTxBufDma);
+    if (EdrvInstance_l.m_pbTxBuf == NULL)
+    {
+        iResult = -ENOMEM;
+        goto Exit;
+    }
+
+    EdrvInstance_l.m_pbRxBuf = pci_alloc_consistent(pPciDev, EDRV_RX_BUFFER_SIZE,
+                     &EdrvInstance_l.m_pRxBufDma);
+    if (EdrvInstance_l.m_pbRxBuf == NULL)
+    {
+        iResult = -ENOMEM;
+        goto Exit;
+    }
+
+    // reset pointers for Tx buffers
+    printk("%s reset pointers fo Tx buffers\n", __FUNCTION__);
+    EDRV_REGDW_WRITE(EDRV_REGDW_TSAD0, 0);
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD0);
+    EDRV_REGDW_WRITE(EDRV_REGDW_TSAD1, 0);
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD1);
+    EDRV_REGDW_WRITE(EDRV_REGDW_TSAD2, 0);
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD2);
+    EDRV_REGDW_WRITE(EDRV_REGDW_TSAD3, 0);
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3);
+
+    printk("    Command = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+
+    // set pointer for receive buffer in controller
+    printk("%s set pointer to Rx buffer\n", __FUNCTION__);
+    EDRV_REGDW_WRITE(EDRV_REGDW_RBSTART, EdrvInstance_l.m_pRxBufDma);
+
+    // enable transmitter and receiver
+    printk("%s enable Tx and Rx", __FUNCTION__);
+    EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
+    printk("  Command = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+
+    // clear missed packet counter to enable Rx/Tx process
+    EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0);
+
+    // set transmit configuration register
+    printk("%s set Tx conf register", __FUNCTION__);
+    EDRV_REGDW_WRITE(EDRV_REGDW_TCR, EDRV_REGDW_TCR_DEF);
+    printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_TCR));
+
+    // set receive configuration register
+    printk("%s set Rx conf register", __FUNCTION__);
+    EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF);
+    printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_RCR));
+
+    // reset multicast MAC address filter
+    EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, 0);
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
+    EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, 0);
+    dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
+
+/*
+    // enable transmitter and receiver
+    printk("%s enable Tx and Rx", __FUNCTION__);
+    EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
+    printk("  Command = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+*/
+    // disable early interrupts
+    EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0);
+
+    // enable interrupts
+    printk("%s enable interrupts\n", __FUNCTION__);
+    EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, EDRV_REGW_INT_MASK_DEF);
+
+
+Exit:
+    printk("%s finished with %d\n", __FUNCTION__, iResult);
+    return iResult;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvRemoveOne
+//
+// Description: shuts down one PCI device
+//
+// Parameters:  pPciDev             = pointer to corresponding PCI device structure
+//
+// Returns:     (void)
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static void EdrvRemoveOne(struct pci_dev *pPciDev)
+{
+
+    if (EdrvInstance_l.m_pPciDev != pPciDev)
+    {   // trying to remove unknown device
+        BUG_ON(EdrvInstance_l.m_pPciDev != pPciDev);
+        goto Exit;
+    }
+
+    // disable transmitter and receiver
+    EDRV_REGB_WRITE(EDRV_REGB_COMMAND, 0);
+
+    // disable interrupts
+    EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0);
+
+    // remove interrupt handler
+    free_irq(pPciDev->irq, pPciDev);
+
+
+    // free buffers
+    if (EdrvInstance_l.m_pbTxBuf != NULL)
+    {
+        pci_free_consistent(pPciDev, EDRV_TX_BUFFER_SIZE,
+                     EdrvInstance_l.m_pbTxBuf, EdrvInstance_l.m_pTxBufDma);
+        EdrvInstance_l.m_pbTxBuf = NULL;
+    }
+
+    if (EdrvInstance_l.m_pbRxBuf != NULL)
+    {
+        pci_free_consistent(pPciDev, EDRV_RX_BUFFER_SIZE,
+                     EdrvInstance_l.m_pbRxBuf, EdrvInstance_l.m_pRxBufDma);
+        EdrvInstance_l.m_pbRxBuf = NULL;
+    }
+
+    // unmap controller's register space
+    if (EdrvInstance_l.m_pIoAddr != NULL)
+    {
+        iounmap(EdrvInstance_l.m_pIoAddr);
+    }
+
+    // disable the PCI device
+    pci_disable_device(pPciDev);
+
+    // release memory regions
+    pci_release_regions(pPciDev);
+
+    EdrvInstance_l.m_pPciDev = NULL;
+
+Exit:;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EdrvCalcHash
+//
+// Description: function calculates the entry for the hash-table from MAC
+//              address
+//
+// Parameters:  pbMAC_p - pointer to MAC address
+//
+// Returns:     hash value
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#define HASH_BITS              6  // used bits in hash
+#define CRC32_POLY    0x04C11DB6  //
+//#define CRC32_POLY    0xEDB88320  //
+// G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
+
+static BYTE EdrvCalcHash (BYTE * pbMAC_p)
+{
+DWORD dwByteCounter;
+DWORD dwBitCounter;
+DWORD dwData;
+DWORD dwCrc;
+DWORD dwCarry;
+BYTE * pbData;
+BYTE bHash;
+
+    pbData = pbMAC_p;
+
+    // calculate crc32 value of mac address
+    dwCrc = 0xFFFFFFFF;
+
+    for (dwByteCounter = 0; dwByteCounter < 6; dwByteCounter++)
+    {
+        dwData = *pbData;
+        pbData++;
+        for (dwBitCounter = 0; dwBitCounter < 8; dwBitCounter++, dwData >>= 1)
+        {
+            dwCarry = (((dwCrc >> 31) ^ dwData) & 1);
+            dwCrc = dwCrc << 1;
+            if (dwCarry != 0)
+            {
+                dwCrc = (dwCrc ^ CRC32_POLY) | dwCarry;
+            }
+        }
+    }
+
+//    printk("MyCRC = 0x%08lX\n", dwCrc);
+    // only upper 6 bits (HASH_BITS) are used
+    // which point to specific bit in the hash registers
+    bHash = (BYTE)((dwCrc >> (32 - HASH_BITS)) & 0x3f);
+
+    return bHash;
+}
+
diff --git a/drivers/staging/epl/EdrvFec.h b/drivers/staging/epl/EdrvFec.h
new file mode 100644 (file)
index 0000000..2dd737e
--- /dev/null
@@ -0,0 +1,126 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  interface for ethernetdriver
+                "fast ethernet controller" (FEC)
+                freescale coldfire MCF528x and compatible FEC
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EdrvFec.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Dev C++ and GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2005/08/01 m.b.:   start of implementation
+
+****************************************************************************/
+
+#ifndef _EDRVFEC_H_
+#define _EDRVFEC_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+// do this in config header
+#define TARGET_HARDWARE TGTHW_SPLC_CF54
+
+
+// base addresses
+#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282)
+
+
+#elif ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5485)
+
+
+#else
+
+    #error 'ERROR: Target was never implemented!'
+
+#endif
+
+
+
+//---------------------------------------------------------------------------
+// types
+//---------------------------------------------------------------------------
+
+
+// Rx and Tx buffer descriptor format
+typedef struct
+{
+       WORD   m_wStatus;       // control / status  ---  used by edrv, do not change in application
+       WORD   m_wLength;       // transfer length
+       BYTE * m_pbData;        // buffer address
+} tBufferDescr;
+
+#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282)
+
+#elif ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5485)
+
+#endif
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+
+#endif  // #ifndef _EDRV_FEC_H_
+
+
diff --git a/drivers/staging/epl/EdrvFec5282.h b/drivers/staging/epl/EdrvFec5282.h
new file mode 100644 (file)
index 0000000..8213d0a
--- /dev/null
@@ -0,0 +1,347 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  interface for ethernetdriver
+                "fast ethernet controller" (FEC)
+                freescale coldfire MCF528x and compatible FEC
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EdrvFec5282.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Dev C++ and GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2005/08/01 m.b.:   start of implementation
+
+****************************************************************************/
+
+#ifndef _EDRVFEC_H_
+#define _EDRVFEC_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+// base addresses
+#define FEC0_ADDR 0x0000
+#define FEC1_ADDR 0x0000 //tbd
+
+// control / status registers
+#define FEC_EIR                 0x1004  // interrupt event register
+#define FEC_EIMR                0x1008  // interrupt mask register
+#define FEC_RDAR                0x1010  // receive descriptor active register
+#define FEC_TDAR                0x1014  // transmit descriptor active register
+#define FEC_ECR                 0x1024  // ethernet control register
+#define FEC_MMFR                0x1040  // MII data register
+#define FEC_MSCR                0x1044  // MII speed register
+#define FEC_MIBC                0x1064  // MIB control/status register
+#define FEC_RCR                 0x1084  // receive control register
+#define FEC_TCR                 0x10C4  // transmit control register
+#define FEC_PALR                0x10E4  // physical address low register
+#define FEC_PAUR                0x10E8  // physical address high + type register
+#define FEC_OPD                 0x10EC  // opcode + pause register
+#define FEC_IAUR                0x1118  // upper 32 bit of individual hash table
+#define FEC_IALR                0x111C  // lower 32 bit of individual hash table
+#define FEC_GAUR                0x1120  // upper 32 bit of group hash table
+#define FEC_GALR                0x1124  // lower 32 bit of group hash table
+#define FEC_TFWR                0x1144  // transmit FIFO watermark
+#define FEC_FRBR                0x114C  // FIFO receive bound register
+#define FEC_FRSR                0x1150  // FIFO receive FIFO start register
+#define FEC_ERDSR               0x1180  // pointer to receive descriptor ring
+#define FEC_ETDSR               0x1184  // pointer to transmit descriptor ring
+#define FEC_EMRBR               0x1188  // maximum receive buffer size
+
+// mib block counters memory map
+#define FEC_RMON_T_DROP         0x1200  // count of frames not counted correctly
+#define FEC_RMON_T_PACKETS      0x1204  // RMON tx packet count
+#define FEC_RMON_T_BC_PKT       0x1208  // RMON tx broadcast packets
+#define FEC_RMON_T_MC_PKT       0x120C  // RMON tx multicast packets
+#define FEC_RMON_T_CRC_ALIGN    0x1210  // RMON tx packets w CRC/align error
+#define FEC_RMON_T_UNDERSIZE    0x1214  // RMON tx packets < 64 bytes, good CRC
+#define FEC_RMON_T_OVERSIZE     0x1218  // RMON tx packets > MAX_FL bytes, good CRC
+#define FEC_RMON_T_FRAG         0x121C  // RMON tx packets < 64 bytes, bad CRC
+#define FEC_RMON_T_JAB          0x1220  // RMON tx packets > MAX_FL bytes, bad CRC
+#define FEC_RMON_T_COL          0x1224  // RMON tx collision count
+#define FEC_RMON_T_P64          0x1228  // RMON tx           64 byte packets
+#define FEC_RMON_T_P65TO127     0x122C  // RMON tx   65 to  127 byte packets
+#define FEC_RMON_T_P128TO255    0x1230  // RMON tx  128 to  255 byte packets
+#define FEC_RMON_T_P256TO511    0x1234  // RMON tx  256 to  511 byte packets
+#define FEC_RMON_T_P512TO1023   0x1238  // RMON tx  512 to 1023 byte packets
+#define FEC_RMON_T_P1024TO2047  0x123C  // RMON tx 1024 to 2047 byte packets
+#define FEC_RMON_T_P_GTE2048    0x1240  // RMON tx w > 2048 bytes
+#define FEC_RMON_T_OCTETS       0x1244  // RMON tx octets
+#define FEC_IEEE_T_DROP         0x1248  // count of frames not counted correctly
+#define FEC_IEEE_T_FRAME_OK     0x124C  // frames transmitted OK
+#define FEC_IEEE_T_1COL         0x1250  // frames transmitted with single collision
+#define FEC_IEEE_T_MCOL         0x1254  // frames transmitted with multiple collisions
+#define FEC_IEEE_T_DEF          0x1258  // frames transmitted after deferral delay
+#define FEC_IEEE_T_LCOL         0x125C  // frames transmitted with late collisions
+#define FEC_IEEE_T_EXCOL        0x1260  // frames transmitted with excessive collisions
+#define FEC_IEEE_T_MACERR       0x1264  // frames transmitted with tx-FIFO underrun
+#define FEC_IEEE_T_CSERR        0x1268  // frames transmitted with carrier sense error
+#define FEC_IEEE_T_SQE          0x126C  // frames transmitted with SQE error
+#define FEC_IEEE_T_FDXFC        0x1270  // flow control pause frames transmitted
+#define FEC_IEEE_T_OCTETS_OK    0x1274  // octet count for frames transmitted w/o error
+#define FEC_RMON_R_PACKETS      0x1284  // RMON rx packet count
+#define FEC_RMON_R_BC_PKT       0x1288  // RMON rx broadcast packets
+#define FEC_RMON_R_MC_PKT       0x128C  // RMON rx multicast packets
+#define FEC_RMON_R_CRC_ALIGN    0x1290  // RMON rx packets w CRC/align error
+#define FEC_RMON_R_UNDERSIZE    0x1294  // RMON rx packets < 64 bytes, good CRC
+#define FEC_RMON_R_OVERSIZE     0x1298  // RMON rx packets > MAX_FL bytes, good CRC
+#define FEC_RMON_R_FRAG         0x129C  // RMON rx packets < 64 bytes, bad CRC
+#define FEC_RMON_R_JAB          0x12A0  // RMON rx packets > MAX_FL bytes, bad CRC
+#define FEC_RMON_R_RESVD_0      0x12A4  //
+#define FEC_RMON_R_P64          0x12A8  // RMON rx           64 byte packets
+#define FEC_RMON_R_P65T0127     0x12AC  // RMON rx   65 to  127 byte packets
+#define FEC_RMON_R_P128TO255    0x12B0  // RMON rx  128 to  255 byte packets
+#define FEC_RMON_R_P256TO511    0x12B4  // RMON rx  256 to  511 byte packets
+#define FEC_RMON_R_P512TO1023   0x12B8  // RMON rx  512 to 1023 byte packets
+#define FEC_RMON_R_P1024TO2047  0x12BC  // RMON rx 1024 to 2047 byte packets
+#define FEC_RMON_R_GTE2048      0x12C0  // RMON rx w > 2048 bytes
+#define FEC_RMON_R_OCTETS       0x12C4  // RMON rx octets
+#define FEC_IEEE_R_DROP         0x12C8  // count of frames not counted correctly
+#define FEC_IEEE_R_FRAME_OK     0x12CC  // frames received OK
+#define FEC_IEEE_R_CRC          0x12D0  // frames received with CRC error
+#define FEC_IEEE_R_ALIGN        0x12D4  // frames received with alignment error
+#define FEC_IEEE_R_MACERR       0x12D8  // receive FIFO overflow count
+#define FEC_IEEE_R_FDXFC        0x12DC  // flow control pause frames received
+#define FEC_IEEE_R_OCTETS_OK    0x12E0  // octet count for frames rcvd w/o error
+
+// register bit definitions and macros
+#define FEC_EIR_UN              (0x00080000)
+#define FEC_EIR_RL              (0x00100000)
+#define FEC_EIR_LC              (0x00200000)
+#define FEC_EIR_EBERR           (0x00400000)
+#define FEC_EIR_MII             (0x00800000)
+#define FEC_EIR_RXB             (0x01000000)
+#define FEC_EIR_RXF             (0x02000000)
+#define FEC_EIR_TXB             (0x04000000)
+#define FEC_EIR_TXF             (0x08000000)
+#define FEC_EIR_GRA             (0x10000000)
+#define FEC_EIR_BABT            (0x20000000)
+#define FEC_EIR_BABR            (0x40000000)
+#define FEC_EIR_HBERR           (0x80000000)
+
+#define FEC_EIMR_UN             (0x00080000)
+#define FEC_EIMR_RL             (0x00100000)
+#define FEC_EIMR_LC             (0x00200000)
+#define FEC_EIMR_EBERR          (0x00400000)
+#define FEC_EIMR_MII            (0x00800000)
+#define FEC_EIMR_RXB            (0x01000000)
+#define FEC_EIMR_RXF            (0x02000000)
+#define FEC_EIMR_TXB            (0x04000000)
+#define FEC_EIMR_TXF            (0x08000000)
+#define FEC_EIMR_GRA            (0x10000000)
+#define FEC_EIMR_BABT           (0x20000000)
+#define FEC_EIMR_BABR           (0x40000000)
+#define FEC_EIMR_HBERR          (0x80000000)
+
+#define FEC_RDAR_R_DES_ACTIVE   (0x01000000)
+
+#define FEC_TDAR_X_DES_ACTIVE   (0x01000000)
+
+#define FEC_ECR_RESET           (0x00000001)
+#define FEC_ECR_ETHER_EN        (0x00000002)
+
+#define FEC_MMFR_DATA(x)        (((x) & 0xFFFF))
+#define FEC_MMFR_TA             (0x00020000)
+#define FEC_MMFR_RA(x)          (((x) & 0x1F) << 18)
+#define FEC_MMFR_PA(x)          (((x) & 0x1F) << 23)
+#define FEC_MMFR_OP_WR          (0x10000000)
+#define FEC_MMFR_OP_RD          (0x20000000)
+#define FEC_MMFR_ST             (0x40000000)
+
+#define FEC_MSCR_MII_SPEED(x)   (((x) & 0x1F) << 1)
+#define FEC_MSCR_DIS_PREAMBLE   (0x00000008)
+
+#define FEC_MIBC_MIB_IDLE       (0x40000000)
+#define FEC_MIBC_MIB_DISABLE    (0x80000000)
+
+#define FEC_RCR_LOOP            (0x00000001)
+#define FEC_RCR_DRT             (0x00000002)
+#define FEC_RCR_MII_MODE        (0x00000004)
+#define FEC_RCR_PROM            (0x00000008)
+#define FEC_RCR_BC_REJ          (0x00000010)
+#define FEC_RCR_FCE             (0x00000020)
+#define FEC_RCR_MAX_FL(x)       (((x) & 0x07FF) << 16)
+
+#define FEC_TCR_GTS             (0x00000001)
+#define FEC_TCR_HBC             (0x00000002)
+#define FEC_TCR_FDEN            (0x00000004)
+#define FEC_TCR_TFC_PAUSE       (0x00000008)
+#define FEC_TCR_RFC_PAUSE       (0x00000010)
+
+#define FEC_PALR_BYTE3(x)       (((x) & 0xFF) <<  0)
+#define FEC_PALR_BYTE2(x)       (((x) & 0xFF) <<  8)
+#define FEC_PALR_BYTE1(x)       (((x) & 0xFF) << 16)
+#define FEC_PALR_BYTE0(x)       (((x) & 0xFF) << 24)
+
+//#define FEC_PAUR_TYPE(x)        (((x) & 0xFFFF) <<  0)
+#define FEC_PAUR_BYTE5(x)       (((x) &   0xFF) << 16)
+#define FEC_PAUR_BYTE4(x)       (((x) &   0xFF) << 24)
+
+#define FEC_OPD_PAUSE_DUR(x)    (((x) & 0xFFFF))
+//#define FEC_OPD_OPCODE(x)       (((x) & 0xFFFF) << 16)
+
+//m.b.
+#define FEC_IAUR_BYTE7(x)       (((x) & 0xFF) <<  0)
+#define FEC_IAUR_BYTE6(x)       (((x) & 0xFF) <<  8)
+#define FEC_IAUR_BYTE5(x)       (((x) & 0xFF) << 16)
+#define FEC_IAUR_BYTE4(x)       (((x) & 0xFF) << 24)
+
+#define FEC_IALR_BYTE3(x)       (((x) & 0xFF) <<  0)
+#define FEC_IALR_BYTE2(x)       (((x) & 0xFF) <<  8)
+#define FEC_IALR_BYTE1(x)       (((x) & 0xFF) << 16)
+#define FEC_IALR_BYTE0(x)       (((x) & 0xFF) << 24)
+
+#define FEC_GAUR_BYTE7(x)       (((x) & 0xFF) <<  0)
+#define FEC_GAUR_BYTE6(x)       (((x) & 0xFF) <<  8)
+#define FEC_GAUR_BYTE5(x)       (((x) & 0xFF) << 16)
+#define FEC_GAUR_BYTE4(x)       (((x) & 0xFF) << 24)
+
+#define FEC_GALR_BYTE3(x)       (((x) & 0xFF) <<  0)
+#define FEC_GALR_BYTE2(x)       (((x) & 0xFF) <<  8)
+#define FEC_GALR_BYTE1(x)       (((x) & 0xFF) << 16)
+#define FEC_GALR_BYTE0(x)       (((x) & 0xFF) << 24)
+// ^^^^
+
+#define FEC_TFWR_X_WMRK_64      (0x00000001)
+#define FEC_TFWR_X_WMRK_128     (0x00000002)
+#define FEC_TFWR_X_WMRK_192     (0x00000003)
+
+//m.b.
+#define FEC_FRBR_R_BOUND(x)     (((x) & 0xFF) << 2)
+
+//m.b.
+#define FEC_FRSR_R_FSTART(x)    (((x) & 0xFF) << 2)
+
+//m.b.
+#define FEC_ERDSR_R_DES_START(x)  (((x) & 0x3FFFFFFF) << 2)
+
+//m.b.
+#define FEC_ETSDR_X_DES_START(x)  (((x) & 0x3FFFFFFF) << 2)
+
+#define FEC_EMRBR_R_BUF_SIZE(x) (((x) & 0x7F) <<  4)
+
+#define FEC_RxBD_TR             0x0001
+#define FEC_RxBD_OV             0x0002
+#define FEC_RxBD_CR             0x0004
+#define FEC_RxBD_NO             0x0010
+#define FEC_RxBD_LG             0x0020
+#define FEC_RxBD_MC             0x0040
+#define FEC_RxBD_BC             0x0080
+#define FEC_RxBD_M              0x0100
+#define FEC_RxBD_L              0x0800
+#define FEC_RxBD_R02            0x1000
+#define FEC_RxBD_W              0x2000
+#define FEC_RxBD_R01            0x4000
+#define FEC_RxBD_INUSE          0x4000
+#define FEC_RxBD_E              0x8000
+
+//m.b.
+//#define FEC_TxBD_CSL            0x0001
+//#define FEC_TxBD_UN             0x0002
+//#define FEC_TxBD_RL             0x0040
+//#define FEC_TxBD_LC             0x0080
+//#define FEC_TxBD_HB             0x0100
+//#define FEC_TxBD_DEF            0x0200
+#define FEC_TxBD_ABC            0x0200
+// ^^^^
+#define FEC_TxBD_TC             0x0400
+#define FEC_TxBD_L              0x0800
+#define FEC_TxBD_TO2            0x1000
+#define FEC_TxBD_W              0x2000
+#define FEC_TxBD_TO1            0x4000
+#define FEC_TxBD_INUSE          0x4000
+#define FEC_TxBD_R              0x8000
+
+//---------------------------------------------------------------------------
+// types
+//---------------------------------------------------------------------------
+
+// Rx and Tx buffer descriptor format
+typedef struct
+{
+       WORD   m_wStatus;       // control / status  ---  used by edrv, do not change in application
+       WORD   m_wLength;       // transfer length
+       BYTE * m_pbData;        // buffer address
+} tBufferDescr;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if (NO_OF_INSTANCES > 1)
+    #define ECI_WRITE_DW_REG(off,val)       (*(DWORD *)(void *)(&__IPSBAR[off]) = val)
+    #define ECI_READ_DW_REG(off)            (*(DWORD *)(void *)(&__IPSBAR[off]))
+#else
+    #if (EDRV_USED_ETH_CTRL == 0)
+        #define ECI_WRITE_DW_REG(off,val)       (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]) = val)
+        #define ECI_READ_DW_REG(off)            (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]))
+    #else
+        #define ECI_WRITE_DW_REG(off,val)       (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]) = val)
+        #define ECI_READ_DW_REG(off)            (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]))
+    #endif
+#endif
+
+
+
+
+#endif  // #ifndef _EDRV_FEC_H_
+
+
diff --git a/drivers/staging/epl/EdrvSim.h b/drivers/staging/epl/EdrvSim.h
new file mode 100644 (file)
index 0000000..eb3ef83
--- /dev/null
@@ -0,0 +1,94 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  interface for ethernet driver simulation
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EdrvSim.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Dev C++ and GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/15 d.k.:   start of implementation
+
+****************************************************************************/
+
+#ifndef _EDRVSIM_H_
+#define _EDRVSIM_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// types
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+void EdrvRxInterruptHandler (BYTE bBufferInFrame_p, BYTE * pbEthernetData_p, WORD wDataLen_p);
+
+
+
+#endif  // #ifndef _EDRVSIM_H_
+
+
diff --git a/drivers/staging/epl/Epl.h b/drivers/staging/epl/Epl.h
new file mode 100644 (file)
index 0000000..986995e
--- /dev/null
@@ -0,0 +1,304 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for EPL API layer
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: Epl.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_API_H_
+#define _EPL_API_H_
+
+#include "EplInc.h"
+#include "EplSdo.h"
+#include "EplObd.h"
+#include "EplLed.h"
+#include "EplEvent.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+typedef struct
+{
+    unsigned int        m_uiNodeId;
+    tEplNmtState        m_NmtState;
+    tEplNmtNodeEvent    m_NodeEvent;
+    WORD                m_wErrorCode;   // EPL error code if m_NodeEvent == kEplNmtNodeEventError
+    BOOL                m_fMandatory;
+
+} tEplApiEventNode;
+
+
+typedef struct
+{
+    tEplNmtState        m_NmtState;     // local NMT state
+    tEplNmtBootEvent    m_BootEvent;
+    WORD                m_wErrorCode;   // EPL error code if m_BootEvent == kEplNmtBootEventError
+
+} tEplApiEventBoot;
+
+
+typedef struct
+{
+    tEplLedType         m_LedType;      // type of the LED (e.g. Status or Error)
+    BOOL                m_fOn;          // state of the LED (e.g. on or off)
+
+} tEplApiEventLed;
+
+
+typedef enum
+{
+    kEplApiEventNmtStateChange = 0x10,    // m_NmtStateChange
+//    kEplApiEventRequestNmt     = 0x11,    // m_bNmtCmd
+    kEplApiEventCriticalError  = 0x12,    // m_InternalError, Stack halted
+    kEplApiEventWarning        = 0x13,    // m_InternalError, Stack running
+    kEplApiEventNode           = 0x20,    // m_Node
+    kEplApiEventBoot           = 0x21,    // m_Boot
+    kEplApiEventSdo            = 0x62,    // m_Sdo
+    kEplApiEventObdAccess      = 0x69,    // m_ObdCbParam
+    kEplApiEventLed            = 0x70,    // m_Led
+
+} tEplApiEventType;
+
+
+typedef union
+{
+    tEplEventNmtStateChange m_NmtStateChange;
+    tEplEventError          m_InternalError;
+    tEplSdoComFinished      m_Sdo;
+    tEplObdCbParam          m_ObdCbParam;
+    tEplApiEventNode        m_Node;
+    tEplApiEventBoot        m_Boot;
+    tEplApiEventLed         m_Led;
+
+} tEplApiEventArg;
+
+
+typedef tEplKernel (PUBLIC ROM* tEplApiCbEvent) (
+    tEplApiEventType        EventType_p,   // IN: event type (enum)
+    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
+    void GENERIC*           pUserArg_p);
+
+
+typedef struct
+{
+    unsigned int        m_uiSizeOfStruct;
+    BOOL                m_fAsyncOnly;   // do not need to register PRes
+    unsigned int        m_uiNodeId;     // local node ID
+    BYTE                m_abMacAddress[6];  // local MAC address
+
+    // 0x1F82: NMT_FeatureFlags_U32
+    DWORD               m_dwFeatureFlags;
+    // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
+    DWORD               m_dwCycleLen;     // required for error detection
+    // 0x1F98: NMT_CycleTiming_REC
+    // 0x1F98.1: IsochrTxMaxPayload_U16
+    unsigned int        m_uiIsochrTxMaxPayload; // const
+    // 0x1F98.2: IsochrRxMaxPayload_U16
+    unsigned int        m_uiIsochrRxMaxPayload; // const
+    // 0x1F98.3: PResMaxLatency_U32
+    DWORD               m_dwPresMaxLatency;  // const in [ns], only required for IdentRes
+    // 0x1F98.4: PReqActPayloadLimit_U16
+    unsigned int        m_uiPreqActPayloadLimit; // required for initialisation (+28 bytes)
+    // 0x1F98.5: PResActPayloadLimit_U16
+    unsigned int        m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+28 bytes)
+    // 0x1F98.6: ASndMaxLatency_U32
+    DWORD               m_dwAsndMaxLatency;   // const in [ns], only required for IdentRes
+    // 0x1F98.7: MultiplCycleCnt_U8
+    unsigned int        m_uiMultiplCycleCnt;  // required for error detection
+    // 0x1F98.8: AsyncMTU_U16
+    unsigned int        m_uiAsyncMtu;         // required to set up max frame size
+    // 0x1F98.9: Prescaler_U16
+    unsigned int        m_uiPrescaler;         // required for sync
+    // $$$ Multiplexed Slot
+
+    // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
+    DWORD               m_dwLossOfFrameTolerance;
+
+    // 0x1F8A: NMT_MNCycleTiming_REC
+    // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
+    DWORD               m_dwWaitSocPreq;
+
+    // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
+    DWORD               m_dwAsyncSlotTimeout;
+
+    DWORD               m_dwDeviceType;              // NMT_DeviceType_U32
+    DWORD               m_dwVendorId;                // NMT_IdentityObject_REC.VendorId_U32
+    DWORD               m_dwProductCode;             // NMT_IdentityObject_REC.ProductCode_U32
+    DWORD               m_dwRevisionNumber;          // NMT_IdentityObject_REC.RevisionNo_U32
+    DWORD               m_dwSerialNumber;            // NMT_IdentityObject_REC.SerialNo_U32
+    QWORD               m_qwVendorSpecificExt1;
+    DWORD               m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+    DWORD               m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+    DWORD               m_dwApplicationSwDate;       // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+    DWORD               m_dwApplicationSwTime;       // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+    DWORD               m_dwIpAddress;
+    DWORD               m_dwSubnetMask;
+    DWORD               m_dwDefaultGateway;
+    BYTE                m_sHostname[32];
+    BYTE                m_abVendorSpecificExt2[48];
+
+    char*               m_pszDevName;       // NMT_ManufactDevName_VS (0x1008/0 local OD)
+    char*               m_pszHwVersion;     // NMT_ManufactHwVers_VS  (0x1009/0 local OD)
+    char*               m_pszSwVersion;     // NMT_ManufactSwVers_VS  (0x100A/0 local OD)
+
+    tEplApiCbEvent      m_pfnCbEvent;
+    void*               m_pEventUserArg;
+    tEplSyncCb          m_pfnCbSync;
+
+} tEplApiInitParam;
+
+
+typedef struct
+{
+    void*          m_pImage;
+    unsigned int   m_uiSize;
+
+} tEplApiProcessImage;
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam* pInitParam_p);
+
+tEplKernel PUBLIC EplApiShutdown(void);
+
+tEplKernel PUBLIC EplApiReadObject(
+            tEplSdoComConHdl* pSdoComConHdl_p,
+            unsigned int      uiNodeId_p,
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pDstData_le_p,
+            unsigned int*     puiSize_p,
+            tEplSdoType       SdoType_p,
+            void*             pUserArg_p);
+
+tEplKernel PUBLIC EplApiWriteObject(
+            tEplSdoComConHdl* pSdoComConHdl_p,
+            unsigned int      uiNodeId_p,
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pSrcData_le_p,
+            unsigned int      uiSize_p,
+            tEplSdoType       SdoType_p,
+            void*             pUserArg_p);
+
+tEplKernel PUBLIC EplApiFreeSdoChannel(
+            tEplSdoComConHdl SdoComConHdl_p);
+
+tEplKernel PUBLIC EplApiReadLocalObject(
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pDstData_p,
+            unsigned int*     puiSize_p);
+
+tEplKernel PUBLIC EplApiWriteLocalObject(
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pSrcData_p,
+            unsigned int      uiSize_p);
+
+tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM* pParam_p);
+
+tEplKernel PUBLIC EplApiLinkObject( unsigned int    uiObjIndex_p,
+                                    void*           pVar_p,
+                                    unsigned int*   puiVarEntries_p,
+                                    tEplObdSize*    pEntrySize_p,
+                                    unsigned int    uiFirstSubindex_p);
+
+tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
+
+tEplKernel PUBLIC EplApiProcess(void);
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+                                             tEplNmtNodeCommand  NodeCommand_p);
+#endif
+
+tEplKernel PUBLIC EplApiGetIdentResponse(
+                                    unsigned int        uiNodeId_p,
+                                    tEplIdentResponse** ppIdentResponse_p);
+
+
+// functions for process image will be implemented in separate file
+tEplKernel PUBLIC EplApiProcessImageSetup(void);
+tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage* pPI_p);
+tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage* pPI_p);
+
+
+#endif  // #ifndef _EPL_API_H_
+
+
diff --git a/drivers/staging/epl/EplAmi.h b/drivers/staging/epl/EplAmi.h
new file mode 100644 (file)
index 0000000..17cb62a
--- /dev/null
@@ -0,0 +1,380 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Definitions for Abstract Memory Interface
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplAmi.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.2 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                GCC
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+   06.03.2000  -rs
+               Implementation
+
+   16.09.2002  -as
+               To save code space the functions AmiSetByte and AmiGetByte
+               are replaced by macros. For targets which assign BYTE by
+               an 16Bit type, the definition of macros must changed to
+               functions.
+
+   23.02.2005  r.d.:
+               Functions included for extended data types such as UNSIGNED24,
+               UNSIGNED40, ...
+
+   13.06.2006  d.k.:
+               Extended the interface for EPL with the different functions
+               for little endian and big endian
+
+****************************************************************************/
+
+#ifndef _EPLAMI_H_
+#define _EPLAMI_H_
+
+
+#if ((DEV_SYSTEM & _DEV_64BIT_SUPPORT_) == 0)
+//    #ifdef USE_VAR64
+        #error 'ERROR: development system does not support 64 bit operations!'
+//    #endif
+#endif
+
+
+//---------------------------------------------------------------------------
+//  types
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+//  Prototypen
+//---------------------------------------------------------------------------
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+#if (TARGET_SYSTEM == _WIN32_)
+    #if defined(INLINE_FUNCTION_DEF)
+        #undef  INLINE_FUNCTION
+        #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+        #define INLINE_ENABLED      TRUE
+        #define EPL_AMI_INLINED
+        #include "../EplStack/amix86.c"
+    #endif
+
+#elif (TARGET_SYSTEM == _LINUX_)
+    #if defined(__m68k__)   // it is an big endian machine
+        #if defined(INLINE_FUNCTION_DEF)
+            #undef  INLINE_FUNCTION
+            #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+            #define INLINE_ENABLED      TRUE
+            #define EPL_AMI_INLINED
+            #include "../EplStack/amibe.c"
+        #endif
+    #endif
+#endif
+
+//---------------------------------------------------------------------------
+//
+// write functions
+//
+// To save code space the function AmiSetByte is replaced by
+// an macro.
+// void   PUBLIC  AmiSetByte  (void FAR* pAddr_p, BYTE bByteVal_p);
+
+#define AmiSetByteToBe(pAddr_p, bByteVal_p)  {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToLe(pAddr_p, bByteVal_p)  {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
+
+#if !defined(INLINE_ENABLED)
+void   PUBLIC  AmiSetWordToBe  (void FAR* pAddr_p, WORD wWordVal_p);
+void   PUBLIC  AmiSetDwordToBe (void FAR* pAddr_p, DWORD dwDwordVal_p);
+void   PUBLIC  AmiSetWordToLe  (void FAR* pAddr_p, WORD wWordVal_p);
+void   PUBLIC  AmiSetDwordToLe (void FAR* pAddr_p, DWORD dwDwordVal_p);
+#endif
+
+
+//---------------------------------------------------------------------------
+//
+// read functions
+//
+// To save code space the function AmiGetByte is replaced by
+// an macro.
+// BYTE   PUBLIC  AmiGetByte  (void FAR* pAddr_p);
+
+#define AmiGetByteFromBe(pAddr_p)  (*(BYTE FAR*)(pAddr_p))
+#define AmiGetByteFromLe(pAddr_p)  (*(BYTE FAR*)(pAddr_p))
+
+#if !defined(INLINE_ENABLED)
+
+WORD   PUBLIC  AmiGetWordFromBe  (void FAR* pAddr_p);
+DWORD  PUBLIC  AmiGetDwordFromBe (void FAR* pAddr_p);
+WORD   PUBLIC  AmiGetWordFromLe  (void FAR* pAddr_p);
+DWORD  PUBLIC  AmiGetDwordFromLe (void FAR* pAddr_p);
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetDword24()
+//
+// Description: sets a 24 bit value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              dwDwordVal_p    = value to set
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiSetDword24ToBe (void FAR* pAddr_p, DWORD dwDwordVal_p);
+void PUBLIC AmiSetDword24ToLe (void FAR* pAddr_p, DWORD dwDwordVal_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetDword24()
+//
+// Description: reads a 24 bit value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      DWORD           = read value
+//
+//---------------------------------------------------------------------------
+
+DWORD PUBLIC AmiGetDword24FromBe (void FAR* pAddr_p);
+DWORD PUBLIC AmiGetDword24FromLe (void FAR* pAddr_p);
+
+
+//#ifdef USE_VAR64
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword40()
+//
+// Description: sets a 40 bit value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiSetQword40ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+void PUBLIC AmiSetQword40ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword40()
+//
+// Description: reads a 40 bit value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+//---------------------------------------------------------------------------
+
+QWORD PUBLIC AmiGetQword40FromBe (void FAR* pAddr_p);
+QWORD PUBLIC AmiGetQword40FromLe (void FAR* pAddr_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword48()
+//
+// Description: sets a 48 bit value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiSetQword48ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+void PUBLIC AmiSetQword48ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword48()
+//
+// Description: reads a 48 bit value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+//---------------------------------------------------------------------------
+
+QWORD PUBLIC AmiGetQword48FromBe (void FAR* pAddr_p);
+QWORD PUBLIC AmiGetQword48FromLe (void FAR* pAddr_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword56()
+//
+// Description: sets a 56 bit value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiSetQword56ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+void PUBLIC AmiSetQword56ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword56()
+//
+// Description: reads a 56 bit value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+//---------------------------------------------------------------------------
+
+QWORD PUBLIC AmiGetQword56FromBe (void FAR* pAddr_p);
+QWORD PUBLIC AmiGetQword56FromLe (void FAR* pAddr_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword64()
+//
+// Description: sets a 64 bit value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiSetQword64ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+void PUBLIC AmiSetQword64ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword64()
+//
+// Description: reads a 64 bit value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+QWORD PUBLIC AmiGetQword64FromBe (void FAR* pAddr_p);
+QWORD PUBLIC AmiGetQword64FromLe (void FAR* pAddr_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetTimeOfDay()
+//
+// Description: sets a TIME_OF_DAY (CANopen) value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiSetTimeOfDay (void FAR* pAddr_p, tTimeOfDay FAR* pTimeOfDay_p);
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetTimeOfDay()
+//
+// Description: reads a TIME_OF_DAY (CANopen) value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
+//
+// Return:      void
+//
+//---------------------------------------------------------------------------
+
+void PUBLIC AmiGetTimeOfDay (void FAR* pAddr_p, tTimeOfDay FAR* pTimeOfDay_p);
+
+#endif
+
+
+#undef  INLINE_ENABLED              // disable actual inlining of functions
+#define EPL_AMI_INCLUDED
+
+#ifdef __cplusplus
+    }
+#endif
+
+
+#endif  // ifndef _EPLAMI_H_
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
diff --git a/drivers/staging/epl/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c
new file mode 100644 (file)
index 0000000..61ed18e
--- /dev/null
@@ -0,0 +1,2093 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for generic EPL API module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplApiGeneric.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.21 $  $Date: 2008/11/21 09:00:38 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/09/05 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "Epl.h"
+#include "kernel/EplDllk.h"
+#include "kernel/EplErrorHandlerk.h"
+#include "kernel/EplEventk.h"
+#include "kernel/EplNmtk.h"
+#include "kernel/EplObdk.h"
+#include "kernel/EplTimerk.h"
+#include "kernel/EplDllkCal.h"
+#include "kernel/EplPdokCal.h"
+#include "user/EplDlluCal.h"
+#include "user/EplLedu.h"
+#include "user/EplNmtCnu.h"
+#include "user/EplNmtMnu.h"
+#include "user/EplSdoComu.h"
+#include "user/EplIdentu.h"
+#include "user/EplStatusu.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+#include "kernel/EplPdok.h"
+#endif
+
+#include "SharedBuff.h"
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
+#error "EPL API layer needs EPL module OBDK!"
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplApi                                              */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplApiInitParam    m_InitParam;
+
+} tEplApiInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplApiInstance  EplApiInstance_g;
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+// NMT state change event callback function
+static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
+
+// update DLL configuration from OD
+static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
+
+// update OD from init param
+static tEplKernel PUBLIC EplApiUpdateObd(void);
+
+// process events from user event queue
+static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent* pEplEvent_p);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+// callback function of SDO module
+static tEplKernel PUBLIC  EplApiCbSdoCon(tEplSdoComFinished* pSdoComFinished_p);
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+// callback functions of NmtMnu module
+static tEplKernel PUBLIC  EplApiCbNodeEvent(unsigned int uiNodeId_p,
+                                            tEplNmtNodeEvent NodeEvent_p,
+                                            tEplNmtState NmtState_p,
+                                            WORD wErrorCode_p,
+                                            BOOL fMandatory_p);
+
+static tEplKernel PUBLIC  EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+                                            tEplNmtState NmtState_p,
+                                            WORD wErrorCode_p);
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+// callback function of Ledu module
+static tEplKernel PUBLIC  EplApiCbLedStateChange(tEplLedType LedType_p,
+                                                 BOOL fOn_p);
+#endif
+
+// OD initialization function (implemented in Objdict.c)
+tEplKernel PUBLIC  EplObdInitRam (tEplObdInitParam MEM* pInitParam_p);
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiInitialize()
+//
+// Description: add and initialize new instance of EPL stack.
+//              After return from this function the application must start
+//              the NMT state machine via
+//              EplApiExecNmtCommand(kEplNmtEventSwReset)
+//              and thereby the whole EPL stack :-)
+//
+// Parameters:  pInitParam_p            = initialisation parameters
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplObdInitParam    ObdInitParam;
+tEplDllkInitParam   DllkInitParam;
+#ifndef EPL_NO_FIFO
+    tShbError           ShbError;
+#endif
+
+    // reset instance structure
+    EPL_MEMSET(&EplApiInstance_g, 0, sizeof (EplApiInstance_g));
+
+    EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p, min(sizeof (tEplApiInitParam), pInitParam_p->m_uiSizeOfStruct));
+
+    // check event callback function pointer
+    if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL)
+    {   // application must always have an event callback function
+        Ret = kEplApiInvalidParam;
+        goto Exit;
+    }
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    // init OD
+// FIXME
+//    Ret = EplObdInitRam(&ObdInitParam);
+//    if (Ret != kEplSuccessful)
+//    {
+//        goto Exit;
+//    }
+
+    // initialize EplObd module
+    Ret = EplObdInit(&ObdInitParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+#ifndef EPL_NO_FIFO
+    ShbError = ShbInit();
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+#endif
+
+    // initialize EplEventk module
+    Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize EplEventu module
+    Ret = EplEventuInit(EplApiProcessEvent);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // init EplTimerk module
+    Ret = EplTimerkInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize EplNmtk module before DLL
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+    Ret = EplNmtkInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // initialize EplDllk module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+    EPL_MEMCPY(DllkInitParam.m_be_abSrcMac, EplApiInstance_g.m_InitParam.m_abMacAddress, 6);
+    Ret = EplDllkAddInstance(&DllkInitParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize EplErrorHandlerk module
+    Ret = EplErrorHandlerkInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize EplDllkCal module
+    Ret = EplDllkCalAddInstance();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // initialize EplDlluCal module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalAddInstance();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#endif
+
+    // initialize EplPdok module
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+    Ret = EplPdokAddInstance();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplPdokCalAddInstance();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#endif
+
+    // initialize EplNmtCnu module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
+    Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // initialize EplNmtu module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+    Ret = EplNmtuInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // register NMT event callback function
+    Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // initialize EplNmtMnu module
+    Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize EplIdentu module
+    Ret = EplIdentuInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize EplStatusu module
+    Ret = EplStatusuInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // initialize EplLedu module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+    Ret = EplLeduInit(EplApiCbLedStateChange);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // init SDO module
+#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
+     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
+    // init sdo command layer
+    Ret = EplSdoComInit();
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // the application must start NMT state machine
+    // via EplApiExecNmtCommand(kEplNmtEventSwReset)
+    // and thereby the whole EPL stack
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiShutdown()
+//
+// Description: deletes an instance of EPL stack
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiShutdown(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    // $$$ d.k.: check if NMT state is NMT_GS_OFF
+
+    // $$$ d.k.: maybe delete event queues at first, but this implies that
+    //           no other module must not use the event queues for communication
+    //           during shutdown.
+
+    // delete instance for all modules
+
+    // deinitialize EplSdoCom module
+#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
+     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
+    Ret = EplSdoComDelInstance();
+//    PRINTF1("EplSdoComDelInstance():  0x%X\n", Ret);
+#endif
+
+    // deinitialize EplLedu module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+    Ret = EplLeduDelInstance();
+//    PRINTF1("EplLeduDelInstance():    0x%X\n", Ret);
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // deinitialize EplNmtMnu module
+    Ret = EplNmtMnuDelInstance();
+//    PRINTF1("EplNmtMnuDelInstance():  0x%X\n", Ret);
+
+    // deinitialize EplIdentu module
+    Ret = EplIdentuDelInstance();
+//    PRINTF1("EplIdentuDelInstance():  0x%X\n", Ret);
+
+    // deinitialize EplStatusu module
+    Ret = EplStatusuDelInstance();
+//    PRINTF1("EplStatusuDelInstance():  0x%X\n", Ret);
+#endif
+
+    // deinitialize EplNmtCnu module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
+    Ret = EplNmtCnuDelInstance();
+//    PRINTF1("EplNmtCnuDelInstance():  0x%X\n", Ret);
+#endif
+
+    // deinitialize EplNmtu module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+    Ret = EplNmtuDelInstance();
+//    PRINTF1("EplNmtuDelInstance():    0x%X\n", Ret);
+#endif
+
+    // deinitialize EplDlluCal module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalDelInstance();
+//    PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
+
+#endif
+
+    // deinitialize EplEventu module
+    Ret = EplEventuDelInstance();
+//    PRINTF1("EplEventuDelInstance():  0x%X\n", Ret);
+
+    // deinitialize EplNmtk module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+    Ret = EplNmtkDelInstance();
+//    PRINTF1("EplNmtkDelInstance():    0x%X\n", Ret);
+#endif
+
+    // deinitialize EplDllk module
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+    Ret = EplDllkDelInstance();
+//    PRINTF1("EplDllkDelInstance():    0x%X\n", Ret);
+
+    // deinitialize EplDllkCal module
+    Ret = EplDllkCalDelInstance();
+//    PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret);
+#endif
+
+    // deinitialize EplEventk module
+    Ret = EplEventkDelInstance();
+//    PRINTF1("EplEventkDelInstance():  0x%X\n", Ret);
+
+    // deinitialize EplTimerk module
+    Ret = EplTimerkDelInstance();
+//    PRINTF1("EplTimerkDelInstance():  0x%X\n", Ret);
+
+#ifndef EPL_NO_FIFO
+    ShbExit();
+#endif
+
+    return Ret;
+}
+
+
+//----------------------------------------------------------------------------
+// Function:    EplApiExecNmtCommand()
+//
+// Description: executes a NMT command, i.e. post the NMT command/event to the
+//              NMTk module. NMT commands which are not appropriate in the current
+//              NMT state are silently ignored. Please keep in mind that the
+//              NMT state may change until the NMT command is actually executed.
+//
+// Parameters:  NmtEvent_p              = NMT command/event
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+    Ret = EplNmtuNmtEvent(NmtEvent_p);
+#endif
+
+    return Ret;
+}
+
+
+//----------------------------------------------------------------------------
+// Function:    EplApiLinkObject()
+//
+// Description: Function maps array of application variables onto specified object in OD
+//
+// Parameters:  uiObjIndex_p            = Function maps variables for this object index
+//              pVar_p                  = Pointer to data memory area for the specified object
+//              puiVarEntries_p         = IN: pointer to number of entries to map
+//                                        OUT: pointer to number of actually used entries
+//              pEntrySize_p            = IN: pointer to size of one entry;
+//                                            if size is zero, the actual size will be read from OD
+//                                        OUT: pointer to entire size of all entries mapped
+//              uiFirstSubindex_p       = This is the first subindex to be mapped.
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiLinkObject( unsigned int    uiObjIndex_p,
+                                    void*           pVar_p,
+                                    unsigned int*   puiVarEntries_p,
+                                    tEplObdSize*    pEntrySize_p,
+                                    unsigned int    uiFirstSubindex_p)
+{
+BYTE            bVarEntries;
+BYTE            bIndexEntries;
+BYTE MEM*       pbData;
+unsigned int    uiSubindex;
+tEplVarParam    VarParam;
+tEplObdSize     EntrySize;
+tEplObdSize     UsedSize;
+
+tEplKernel      RetCode = kEplSuccessful;
+
+    if ((pVar_p == NULL)
+        || (puiVarEntries_p == NULL)
+        || (*puiVarEntries_p == 0)
+        || (pEntrySize_p == NULL))
+    {
+        RetCode = kEplApiInvalidParam;
+        goto Exit;
+    }
+
+    pbData      = (BYTE MEM*) pVar_p;
+    bVarEntries = (BYTE) *puiVarEntries_p;
+    UsedSize    = 0;
+
+    // init VarParam structure with default values
+    VarParam.m_uiIndex    = uiObjIndex_p;
+    VarParam.m_ValidFlag  = kVarValidAll;
+
+    if (uiFirstSubindex_p != 0)
+    {   // check if object exists by reading subindex 0x00,
+        // because user wants to link a variable to a subindex unequal 0x00
+        // read number of entries
+        EntrySize = (tEplObdSize)  sizeof(bIndexEntries);
+        RetCode = EplObdReadEntry (
+                                uiObjIndex_p,
+                                0x00,
+                                (void GENERIC*) &bIndexEntries,
+                                &EntrySize );
+
+        if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00) )
+        {
+            // Object doesn't exist or invalid entry number
+            RetCode = kEplObdIndexNotExist;
+            goto Exit;
+        }
+    }
+    else
+    {   // user wants to link a variable to subindex 0x00
+        // that's OK
+        bIndexEntries = 0;
+    }
+
+    // Correct number of entries if number read from OD is greater
+    // than the specified number.
+    // This is done, so that we do not set more entries than subindexes the
+    // object actually has.
+    if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
+        (bVarEntries   != 0x00) )
+    {
+        bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
+    }
+
+    // map entries
+    for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries; uiSubindex++)
+    {
+        // if passed entry size is 0, then get size from OD
+        if (*pEntrySize_p == 0x00)
+        {
+            // read entry size
+            EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex);
+
+            if (EntrySize == 0x00)
+            {
+                // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty)
+                RetCode = kEplObdSubindexNotExist;
+                break;
+            }
+        }
+        else
+        {   // use passed entry size
+            EntrySize = *pEntrySize_p;
+        }
+
+        VarParam.m_uiSubindex = uiSubindex;
+
+        // set pointer to user var
+        VarParam.m_Size  = EntrySize;
+        VarParam.m_pData = pbData;
+
+        UsedSize += EntrySize;
+        pbData   += EntrySize;
+
+        RetCode = EplObdDefineVar(&VarParam);
+        if (RetCode != kEplSuccessful)
+        {
+            break;
+        }
+    }
+
+    // set number of mapped entries and entry size
+    *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
+    *pEntrySize_p = UsedSize;
+
+
+Exit:
+
+    return (RetCode);
+
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// Function:    EplApiReadObject()
+//
+// Description: reads the specified entry from the OD of the specified node.
+//              If this node is a remote node, it performs a SDO transfer, which
+//              means this function returns kEplApiTaskDeferred and the application
+//              is informed via the event callback function when the task is completed.
+//
+// Parameters:  pSdoComConHdl_p         = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
+//              uiNodeId_p              = IN: node ID (0 = itself)
+//              uiIndex_p               = IN: index of object in OD
+//              uiSubindex_p            = IN: sub-index of object in OD
+//              pDstData_le_p           = OUT: pointer to data in little endian
+//              puiSize_p               = INOUT: pointer to size of data
+//              SdoType_p               = IN: type of SDO transfer
+//              pUserArg_p              = IN: user-definable argument pointer,
+//                                            which will be passed to the event callback function
+//
+// Return:      tEplKernel              = error code
+//
+// ----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiReadObject(
+            tEplSdoComConHdl* pSdoComConHdl_p,
+            unsigned int      uiNodeId_p,
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pDstData_le_p,
+            unsigned int*     puiSize_p,
+            tEplSdoType       SdoType_p,
+            void*             pUserArg_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL) || (*puiSize_p == 0))
+    {
+        Ret = kEplApiInvalidParam;
+        goto Exit;
+    }
+
+    if (uiNodeId_p == 0
+        || uiNodeId_p == EplObdGetNodeId())
+    {   // local OD access can be performed
+    tEplObdSize     ObdSize;
+
+        ObdSize = (tEplObdSize) *puiSize_p;
+        Ret = EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p, &ObdSize);
+        *puiSize_p = (unsigned int) ObdSize;
+    }
+    else
+    {   // perform SDO transfer
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+    tEplSdoComTransParamByIndex TransParamByIndex;
+//    tEplSdoComConHdl            SdoComConHdl;
+
+        // check if application provides space for handle
+        if (pSdoComConHdl_p == NULL)
+        {
+            Ret = kEplApiInvalidParam;
+            goto Exit;
+//            pSdoComConHdl_p = &SdoComConHdl;
+        }
+
+        // init command layer connection
+        Ret = EplSdoComDefineCon(pSdoComConHdl_p,
+                                    uiNodeId_p,  // target node id
+                                    SdoType_p);    // SDO type
+        if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists))
+        {
+            goto Exit;
+        }
+        TransParamByIndex.m_pData = pDstData_le_p;
+        TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead;
+        TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
+        TransParamByIndex.m_uiDataSize = *puiSize_p;
+        TransParamByIndex.m_uiIndex = uiIndex_p;
+        TransParamByIndex.m_uiSubindex = uiSubindex_p;
+        TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
+        TransParamByIndex.m_pUserArg = pUserArg_p;
+
+        Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        Ret = kEplApiTaskDeferred;
+
+#else
+        Ret = kEplApiInvalidParam;
+#endif
+    }
+
+Exit:
+    return Ret;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// Function:    EplApiWriteObject()
+//
+// Description: writes the specified entry to the OD of the specified node.
+//              If this node is a remote node, it performs a SDO transfer, which
+//              means this function returns kEplApiTaskDeferred and the application
+//              is informed via the event callback function when the task is completed.
+//
+// Parameters:  pSdoComConHdl_p         = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
+//              uiNodeId_p              = IN: node ID (0 = itself)
+//              uiIndex_p               = IN: index of object in OD
+//              uiSubindex_p            = IN: sub-index of object in OD
+//              pSrcData_le_p           = IN: pointer to data in little endian
+//              uiSize_p                = IN: size of data in bytes
+//              SdoType_p               = IN: type of SDO transfer
+//              pUserArg_p              = IN: user-definable argument pointer,
+//                                            which will be passed to the event callback function
+//
+// Return:      tEplKernel              = error code
+//
+// ----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiWriteObject(
+            tEplSdoComConHdl* pSdoComConHdl_p,
+            unsigned int      uiNodeId_p,
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pSrcData_le_p,
+            unsigned int      uiSize_p,
+            tEplSdoType       SdoType_p,
+            void*             pUserArg_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0))
+    {
+        Ret = kEplApiInvalidParam;
+        goto Exit;
+    }
+
+    if (uiNodeId_p == 0
+        || uiNodeId_p == EplObdGetNodeId())
+    {   // local OD access can be performed
+
+        Ret = EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p, pSrcData_le_p, uiSize_p);
+    }
+    else
+    {   // perform SDO transfer
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+    tEplSdoComTransParamByIndex TransParamByIndex;
+//    tEplSdoComConHdl            SdoComConHdl;
+
+        // check if application provides space for handle
+        if (pSdoComConHdl_p == NULL)
+        {
+            Ret = kEplApiInvalidParam;
+            goto Exit;
+//            pSdoComConHdl_p = &SdoComConHdl;
+        }
+
+        // d.k.: How to recycle command layer connection?
+        //       Try to redefine it, which will return kEplSdoComHandleExists
+        //       and the existing command layer handle.
+        //       If the returned handle is busy, EplSdoComInitTransferByIndex()
+        //       will return with error.
+        // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and
+        //           Configuration Manager, are trying to communicate with the very same node.
+        //     possible solution: disallow communication by application if Configuration Manager is busy
+
+        // init command layer connection
+        Ret = EplSdoComDefineCon(pSdoComConHdl_p,
+                                    uiNodeId_p,  // target node id
+                                    SdoType_p);    // SDO type
+        if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists))
+        {
+            goto Exit;
+        }
+        TransParamByIndex.m_pData = pSrcData_le_p;
+        TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite;
+        TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
+        TransParamByIndex.m_uiDataSize = uiSize_p;
+        TransParamByIndex.m_uiIndex = uiIndex_p;
+        TransParamByIndex.m_uiSubindex = uiSubindex_p;
+        TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
+        TransParamByIndex.m_pUserArg = pUserArg_p;
+
+        Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        Ret = kEplApiTaskDeferred;
+
+#else
+        Ret = kEplApiInvalidParam;
+#endif
+    }
+
+Exit:
+    return Ret;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// Function:    EplApiFreeSdoChannel()
+//
+// Description: frees the specified SDO channel.
+//              This function must be called after each call to EplApiReadObject()/EplApiWriteObject()
+//              which returns kEplApiTaskDeferred and the application
+//              is informed via the event callback function when the task is completed.
+//
+// Parameters:  SdoComConHdl_p          = IN: SDO connection handle
+//
+// Return:      tEplKernel              = error code
+//
+// ----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiFreeSdoChannel(
+            tEplSdoComConHdl SdoComConHdl_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+
+    // init command layer connection
+    Ret = EplSdoComUndefineCon(SdoComConHdl_p);
+
+#else
+    Ret = kEplApiInvalidParam;
+#endif
+
+    return Ret;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// Function:    EplApiReadLocalObject()
+//
+// Description: reads the specified entry from the local OD.
+//
+// Parameters:  uiIndex_p               = IN: index of object in OD
+//              uiSubindex_p            = IN: sub-index of object in OD
+//              pDstData_p              = OUT: pointer to data in platform byte order
+//              puiSize_p               = INOUT: pointer to size of data
+//
+// Return:      tEplKernel              = error code
+//
+// ----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiReadLocalObject(
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pDstData_p,
+            unsigned int*     puiSize_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplObdSize     ObdSize;
+
+    ObdSize = (tEplObdSize) *puiSize_p;
+    Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
+    *puiSize_p = (unsigned int) ObdSize;
+
+    return Ret;
+}
+
+
+// ----------------------------------------------------------------------------
+//
+// Function:    EplApiWriteLocalObject()
+//
+// Description: writes the specified entry to the local OD.
+//
+// Parameters:  uiIndex_p               = IN: index of object in OD
+//              uiSubindex_p            = IN: sub-index of object in OD
+//              pSrcData_p              = IN: pointer to data in platform byte order
+//              uiSize_p                = IN: size of data in bytes
+//
+// Return:      tEplKernel              = error code
+//
+// ----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiWriteLocalObject(
+            unsigned int      uiIndex_p,
+            unsigned int      uiSubindex_p,
+            void*             pSrcData_p,
+            unsigned int      uiSize_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    Ret = EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p, (tEplObdSize) uiSize_p);
+
+    return Ret;
+}
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+// ----------------------------------------------------------------------------
+//
+// Function:    EplApiMnTriggerStateChange()
+//
+// Description: triggers the specified node command for the specified node.
+//
+// Parameters:  uiNodeId_p              = node ID for which the node command will be executed
+//              NodeCommand_p           = node command
+//
+// Return:      tEplKernel              = error code
+//
+// ----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+                                             tEplNmtNodeCommand  NodeCommand_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p);
+
+    return Ret;
+}
+
+#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiCbObdAccess
+//
+// Description: callback function for OD accesses
+//
+// Parameters:  pParam_p                = OBD parameter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM* pParam_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+
+#if (EPL_API_OBD_FORWARD_EVENT != FALSE)
+tEplApiEventArg     EventArg;
+
+    // call user callback
+    // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem
+    // for local OD access. This is not so bad as user callback function in
+    // application does not use OD callbacks at the moment.
+    EventArg.m_ObdCbParam = *pParam_p;
+    Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess,
+                                                    &EventArg,
+                                                    EplApiInstance_g.m_InitParam.m_pEventUserArg);
+#endif
+
+    switch (pParam_p->m_uiIndex)
+    {
+        //case 0x1006:    // NMT_CycleLen_U32 (valid on reset)
+        case 0x1C14:    // DLL_LossOfFrameTolerance_U32
+        //case 0x1F98:    // NMT_CycleTiming_REC (valid on reset)
+        {
+            if (pParam_p->m_ObdEvent == kEplObdEvPostWrite)
+            {
+                // update DLL configuration
+                Ret = EplApiUpdateDllConfig(FALSE);
+            }
+            break;
+        }
+
+        case 0x1020:    // CFM_VerifyConfiguration_REC.ConfId_U32 != 0
+        {
+            if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
+                && (pParam_p->m_uiSubIndex == 3)
+                && (*((DWORD*)pParam_p->m_pArg) != 0))
+            {
+            DWORD   dwVerifyConfInvalid = 0;
+                // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
+                Ret = EplObdWriteEntry(0x1020, 4, &dwVerifyConfInvalid, 4);
+                // ignore any error because this objekt is optional
+                Ret = kEplSuccessful;
+            }
+            break;
+        }
+
+        case 0x1F9E:    // NMT_ResetCmd_U8
+        {
+            if (pParam_p->m_ObdEvent == kEplObdEvPreWrite)
+            {
+            BYTE    bNmtCommand;
+
+                bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+                // check value range
+                switch ((tEplNmtCommand)bNmtCommand)
+                {
+                    case kEplNmtCmdResetNode:
+                    case kEplNmtCmdResetCommunication:
+                    case kEplNmtCmdResetConfiguration:
+                    case kEplNmtCmdSwReset:
+                    case kEplNmtCmdInvalidService:
+                        // valid command identifier specified
+                        break;
+
+                    default:
+                        pParam_p->m_dwAbortCode = EPL_SDOAC_VALUE_RANGE_EXCEEDED;
+                        Ret = kEplObdAccessViolation;
+                        break;
+                }
+            }
+            else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite)
+            {
+            BYTE    bNmtCommand;
+
+                bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+                // check value range
+                switch ((tEplNmtCommand)bNmtCommand)
+                {
+                    case kEplNmtCmdResetNode:
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+                        Ret = EplNmtuNmtEvent(kEplNmtEventResetNode);
+#endif
+                        break;
+
+                    case kEplNmtCmdResetCommunication:
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+                        Ret = EplNmtuNmtEvent(kEplNmtEventResetCom);
+#endif
+                        break;
+
+                    case kEplNmtCmdResetConfiguration:
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+                        Ret = EplNmtuNmtEvent(kEplNmtEventResetConfig);
+#endif
+                        break;
+
+                    case kEplNmtCmdSwReset:
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+                        Ret = EplNmtuNmtEvent(kEplNmtEventSwReset);
+#endif
+                        break;
+
+                    case kEplNmtCmdInvalidService:
+                        break;
+
+                    default:
+                        pParam_p->m_dwAbortCode = EPL_SDOAC_VALUE_RANGE_EXCEEDED;
+                        Ret = kEplObdAccessViolation;
+                        break;
+                }
+            }
+            break;
+        }
+
+        default:
+            break;
+    }
+
+//Exit:
+    return Ret;
+}
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiProcessEvent
+//
+// Description: processes events from event queue and forwards these to
+//              the application's event callback function
+//
+// Parameters:  pEplEvent_p =   pointer to event
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplApiProcessEvent(
+            tEplEvent* pEplEvent_p)
+{
+tEplKernel          Ret;
+tEplEventError*     pEventError;
+tEplApiEventType    EventType;
+
+    Ret = kEplSuccessful;
+
+    // process event
+    switch(pEplEvent_p->m_EventType)
+    {
+        // error event
+        case kEplEventTypeError:
+        {
+            pEventError = (tEplEventError*) pEplEvent_p->m_pArg;
+            switch (pEventError->m_EventSource)
+            {
+                // treat the errors from the following sources as critical
+                case kEplEventSourceEventk:
+                case kEplEventSourceEventu:
+                case kEplEventSourceDllk:
+                {
+                    EventType = kEplApiEventCriticalError;
+                    // halt the stack by entering NMT state Off
+                    Ret = EplNmtuNmtEvent(kEplNmtEventCriticalError);
+                    break;
+                }
+
+                // the other errors are just warnings
+                default:
+                {
+                    EventType = kEplApiEventWarning;
+                    break;
+                }
+            }
+
+            // call user callback
+            Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType, (tEplApiEventArg*) pEventError, EplApiInstance_g.m_InitParam.m_pEventUserArg);
+            // discard error from callback function, because this could generate an endless loop
+            Ret = kEplSuccessful;
+            break;
+        }
+
+        // at present, there are no other events for this module
+        default:
+            break;
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiCbNmtStateChange
+//
+// Description: callback function for NMT state changes
+//
+// Parameters:  NmtStateChange_p        = NMT state change event
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+BYTE                bNmtState;
+tEplApiEventArg     EventArg;
+
+    // save NMT state in OD
+    bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
+    Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // do work which must be done in that state
+    switch (NmtStateChange_p.m_NewNmtState)
+    {
+        // EPL stack is not running
+        case kEplNmtGsOff:
+            break;
+
+        // first init of the hardware
+        case kEplNmtGsInitialising:
+#if 0
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+            // configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
+            Ret = EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress, EPL_C_SDO_EPL_PORT);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+#endif
+#endif
+
+            break;
+
+        // init of the manufacturer-specific profile area and the
+        // standardised device profile area
+        case kEplNmtGsResetApplication:
+        {
+            // reset application part of OD
+            Ret = EplObdAccessOdPart(
+                kEplObdPartApp,
+                kEplObdDirLoad);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            break;
+        }
+
+        // init of the communication profile area
+        case kEplNmtGsResetCommunication:
+        {
+            // reset communication part of OD
+            Ret = EplObdAccessOdPart(
+                kEplObdPartGen,
+                kEplObdDirLoad);
+
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
+            Ret = EplApiUpdateObd();
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            break;
+        }
+
+        // build the configuration with infos from OD
+        case kEplNmtGsResetConfiguration:
+        {
+
+            Ret = EplApiUpdateDllConfig(TRUE);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            break;
+        }
+
+        //-----------------------------------------------------------
+        // CN part of the state machine
+
+        // node liste for EPL-Frames and check timeout
+        case kEplNmtCsNotActive:
+        {
+            // indicate completion of reset in NMT_ResetCmd_U8
+            bNmtState = (BYTE) kEplNmtCmdInvalidService;
+            Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            break;
+        }
+
+        // node process only async frames
+        case kEplNmtCsPreOperational1:
+        {
+            break;
+        }
+
+        // node process isochronus and asynchronus frames
+        case kEplNmtCsPreOperational2:
+        {
+            break;
+        }
+
+        // node should be configured und application is ready
+        case kEplNmtCsReadyToOperate:
+        {
+            break;
+        }
+
+        // normal work state
+        case kEplNmtCsOperational:
+        {
+            break;
+        }
+
+        // node stopped by MN
+        // -> only process asynchronus frames
+        case kEplNmtCsStopped:
+        {
+            break;
+        }
+
+        // no EPL cycle
+        // -> normal ethernet communication
+        case kEplNmtCsBasicEthernet:
+        {
+            break;
+        }
+
+        //-----------------------------------------------------------
+        // MN part of the state machine
+
+        // node listens for EPL-Frames and check timeout
+        case kEplNmtMsNotActive:
+        {
+            break;
+        }
+
+        // node processes only async frames
+        case kEplNmtMsPreOperational1:
+        {
+            break;
+        }
+
+        // node processes isochronous and asynchronous frames
+        case kEplNmtMsPreOperational2:
+        {
+            break;
+        }
+
+        // node should be configured und application is ready
+        case kEplNmtMsReadyToOperate:
+        {
+            break;
+        }
+
+        // normal work state
+        case kEplNmtMsOperational:
+        {
+            break;
+        }
+
+        // no EPL cycle
+        // -> normal ethernet communication
+        case kEplNmtMsBasicEthernet:
+        {
+            break;
+        }
+
+        default:
+        {
+            TRACE0("EplApiCbNmtStateChange(): unhandled NMT state\n");
+        }
+    }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+    // forward event to Led module
+    Ret = EplLeduCbNmtStateChange(NmtStateChange_p);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // forward event to NmtMn module
+    Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // call user callback
+    EventArg.m_NmtStateChange = NmtStateChange_p;
+    Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNmtStateChange,
+                                                    &EventArg,
+                                                    EplApiInstance_g.m_InitParam.m_pEventUserArg);
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiUpdateDllConfig
+//
+// Description: update configuration of DLL
+//
+// Parameters:  fUpdateIdentity_p       = TRUE, if identity must be updated
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplDllConfigParam  DllConfigParam;
+tEplDllIdentParam   DllIdentParam;
+tEplObdSize         ObdSize;
+WORD                wTemp;
+BYTE                bTemp;
+
+    // configure Dll
+    EPL_MEMSET(&DllConfigParam, 0, sizeof (DllConfigParam));
+    DllConfigParam.m_uiNodeId = EplObdGetNodeId();
+
+    // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // 0x1F82: NMT_FeatureFlags_U32
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // d.k. There is no dependance between FeatureFlags and async-only CN
+    DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly;
+
+    // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // 0x1F98: NMT_CycleTiming_REC
+    // 0x1F98.1: IsochrTxMaxPayload_U16
+    ObdSize = 2;
+    Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
+
+    // 0x1F98.2: IsochrRxMaxPayload_U16
+    ObdSize = 2;
+    Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
+
+    // 0x1F98.3: PResMaxLatency_U32
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // 0x1F98.4: PReqActPayloadLimit_U16
+    ObdSize = 2;
+    Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
+
+    // 0x1F98.5: PResActPayloadLimit_U16
+    ObdSize = 2;
+    Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    DllConfigParam.m_uiPresActPayloadLimit = wTemp;
+
+    // 0x1F98.6: ASndMaxLatency_U32
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // 0x1F98.7: MultiplCycleCnt_U8
+    ObdSize = 1;
+    Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    DllConfigParam.m_uiMultiplCycleCnt = bTemp;
+
+    // 0x1F98.8: AsyncMTU_U16
+    ObdSize = 2;
+    Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    DllConfigParam.m_uiAsyncMtu = wTemp;
+
+    // $$$ Prescaler
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq, &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
+    ObdSize = 4;
+    Ret = EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout, &ObdSize);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+#endif
+
+    DllConfigParam.m_uiSizeOfStruct = sizeof (DllConfigParam);
+    Ret = EplDllkConfig(&DllConfigParam);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    if (fUpdateIdentity_p != FALSE)
+    {
+        // configure Identity
+        EPL_MEMSET(&DllIdentParam, 0, sizeof (DllIdentParam));
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType, &ObdSize);
+        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId, &ObdSize);
+        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode, &ObdSize);
+        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1018, 3, &DllIdentParam.m_dwRevisionNumber, &ObdSize);
+        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber, &ObdSize);
+        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        DllIdentParam.m_dwIpAddress = EplApiInstance_g.m_InitParam.m_dwIpAddress;
+        DllIdentParam.m_dwSubnetMask = EplApiInstance_g.m_InitParam.m_dwSubnetMask;
+        EPL_MEMCPY(DllIdentParam.m_sHostname, EplApiInstance_g.m_InitParam.m_sHostname, sizeof (DllIdentParam.m_sHostname));
+
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1020, 1, &DllIdentParam.m_dwVerifyConfigurationDate, &ObdSize);
+        // ignore any error, because this object is optional
+
+        ObdSize = 4;
+        Ret = EplObdReadEntry(0x1020, 2, &DllIdentParam.m_dwVerifyConfigurationTime, &ObdSize);
+        // ignore any error, because this object is optional
+
+        // $$$ d.k.: fill rest of ident structure
+
+        DllIdentParam.m_uiSizeOfStruct = sizeof (DllIdentParam);
+        Ret = EplDllkSetIdentity(&DllIdentParam);
+        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiUpdateObd
+//
+// Description: update OD from init param
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplApiUpdateObd(void)
+{
+tEplKernel          Ret = kEplSuccessful;
+WORD                wTemp;
+BYTE                bTemp;
+
+    // set node id in OD
+    Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId,    // node id
+                            kEplObdNodeIdHardware); // set by hardware
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1)
+    {
+        Ret = EplObdWriteEntry(0x1006, 0, &EplApiInstance_g.m_InitParam.m_dwCycleLen, 4);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1)
+    {
+        Ret = EplObdWriteEntry(0x1C14, 0, &EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance, 4);
+    /*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    // d.k. There is no dependance between FeatureFlags and async-only CN.
+    if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1)
+    {
+        Ret = EplObdWriteEntry(0x1F82, 0, &EplApiInstance_g.m_InitParam.m_dwFeatureFlags, 4);
+    /*    if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
+    Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+
+    wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
+    Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+
+    Ret = EplObdWriteEntry(0x1F98, 3, &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency, 4);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+
+    if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <= EPL_C_DLL_ISOCHR_MAX_PAYL)
+    {
+        wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
+        Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <= EPL_C_DLL_ISOCHR_MAX_PAYL)
+    {
+        wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
+        Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+    }
+
+    Ret = EplObdWriteEntry(0x1F98, 6, &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency, 4);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+
+    if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF)
+    {
+        bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
+        Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <= EPL_C_DLL_MAX_ASYNC_MTU)
+    {
+        wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
+        Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
+/*    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000)
+    {
+        wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler;
+        Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
+        // ignore return code
+        Ret = kEplSuccessful;
+    }
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1)
+    {
+        Ret = EplObdWriteEntry(0x1F8A, 1, &EplApiInstance_g.m_InitParam.m_dwWaitSocPreq, 4);
+    /*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0) && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1))
+    {
+        Ret = EplObdWriteEntry(0x1F8A, 2, &EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout, 4);
+    /*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+#endif
+
+    // configure Identity
+    if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1)
+    {
+        Ret = EplObdWriteEntry(0x1000, 0, &EplApiInstance_g.m_InitParam.m_dwDeviceType, 4);
+/*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1)
+    {
+        Ret = EplObdWriteEntry(0x1018, 1, &EplApiInstance_g.m_InitParam.m_dwVendorId, 4);
+/*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1)
+    {
+        Ret = EplObdWriteEntry(0x1018, 2, &EplApiInstance_g.m_InitParam.m_dwProductCode, 4);
+/*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1)
+    {
+        Ret = EplObdWriteEntry(0x1018, 3, &EplApiInstance_g.m_InitParam.m_dwRevisionNumber, 4);
+/*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1)
+    {
+        Ret = EplObdWriteEntry(0x1018, 4, &EplApiInstance_g.m_InitParam.m_dwSerialNumber, 4);
+/*        if(Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL)
+    {
+        // write Device Name (0x1008)
+        Ret = EplObdWriteEntry (
+            0x1008, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszDevName, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszDevName));
+/*        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL)
+    {
+        // write Hardware version (0x1009)
+        Ret = EplObdWriteEntry (
+            0x1009, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszHwVersion, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszHwVersion));
+/*        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+    if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL)
+    {
+        // write Software version (0x100A)
+        Ret = EplObdWriteEntry (
+            0x100A, 0, (void GENERIC*) EplApiInstance_g.m_InitParam.m_pszSwVersion, (tEplObdSize) strlen(EplApiInstance_g.m_InitParam.m_pszSwVersion));
+/*        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiCbSdoCon
+//
+// Description: callback function for SDO transfers
+//
+// Parameters:  pSdoComFinished_p       = SDO parameter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+static tEplKernel PUBLIC  EplApiCbSdoCon(tEplSdoComFinished* pSdoComFinished_p)
+{
+tEplKernel Ret;
+tEplApiEventArg EventArg;
+
+    Ret = kEplSuccessful;
+
+    // call user callback
+    EventArg.m_Sdo = *pSdoComFinished_p;
+    Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo,
+                                                    &EventArg,
+                                                    EplApiInstance_g.m_InitParam.m_pEventUserArg);
+
+    return Ret;
+
+}
+#endif
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiCbNodeEvent
+//
+// Description: callback function for node events
+//
+// Parameters:  uiNodeId_p              = node ID of the CN
+//              NodeEvent_p             = event from the specified CN
+//              NmtState_p              = current NMT state of the CN
+//              wErrorCode_p            = EPL error code if NodeEvent_p==kEplNmtNodeEventError
+//              fMandatory_p            = flag if CN is mandatory
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC  EplApiCbNodeEvent(unsigned int uiNodeId_p,
+                                            tEplNmtNodeEvent NodeEvent_p,
+                                            tEplNmtState NmtState_p,
+                                            WORD wErrorCode_p,
+                                            BOOL fMandatory_p)
+{
+tEplKernel Ret;
+tEplApiEventArg EventArg;
+
+    Ret = kEplSuccessful;
+
+    // call user callback
+    EventArg.m_Node.m_uiNodeId = uiNodeId_p;
+    EventArg.m_Node.m_NodeEvent = NodeEvent_p;
+    EventArg.m_Node.m_NmtState = NmtState_p;
+    EventArg.m_Node.m_wErrorCode = wErrorCode_p;
+    EventArg.m_Node.m_fMandatory = fMandatory_p;
+
+    Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode,
+                                                    &EventArg,
+                                                    EplApiInstance_g.m_InitParam.m_pEventUserArg);
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiCbBootEvent
+//
+// Description: callback function for boot events
+//
+// Parameters:  BootEvent_p             = event from the boot-up process
+//              NmtState_p              = current local NMT state
+//              wErrorCode_p            = EPL error code if BootEvent_p==kEplNmtBootEventError
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC  EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+                                            tEplNmtState NmtState_p,
+                                            WORD wErrorCode_p)
+{
+tEplKernel Ret;
+tEplApiEventArg EventArg;
+
+    Ret = kEplSuccessful;
+
+    // call user callback
+    EventArg.m_Boot.m_BootEvent = BootEvent_p;
+    EventArg.m_Boot.m_NmtState = NmtState_p;
+    EventArg.m_Boot.m_wErrorCode = wErrorCode_p;
+
+    Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot,
+                                                    &EventArg,
+                                                    EplApiInstance_g.m_InitParam.m_pEventUserArg);
+
+    return Ret;
+
+}
+
+#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiCbLedStateChange
+//
+// Description: callback function for LED change events.
+//
+// Parameters:  LedType_p       = type of LED
+//              fOn_p           = state of LED
+//
+// Returns:     tEplKernel      = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC  EplApiCbLedStateChange(tEplLedType LedType_p,
+                                                 BOOL fOn_p)
+{
+tEplKernel Ret;
+tEplApiEventArg EventArg;
+
+    Ret = kEplSuccessful;
+
+    // call user callback
+    EventArg.m_Led.m_LedType = LedType_p;
+    EventArg.m_Led.m_fOn = fOn_p;
+
+    Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed,
+                                                    &EventArg,
+                                                    EplApiInstance_g.m_InitParam.m_pEventUserArg);
+
+    return Ret;
+
+}
+
+#endif
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplApiLinux.h b/drivers/staging/epl/EplApiLinux.h
new file mode 100644 (file)
index 0000000..02714e7
--- /dev/null
@@ -0,0 +1,153 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for EPL API layer for Linux (kernel and user space)
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplApiLinux.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/08/25 12:17:41 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/10/11 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_API_LINUX_H_
+#define _EPL_API_LINUX_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPLLIN_DEV_NAME     "epl"              // used for "/dev" and "/proc" entry
+
+
+//---------------------------------------------------------------------------
+//  Commands for <ioctl>
+//---------------------------------------------------------------------------
+
+#define EPLLIN_CMD_INITIALIZE               0   // ulArg_p ~ tEplApiInitParam*
+#define EPLLIN_CMD_PI_IN                    1   // ulArg_p ~ tEplApiProcessImage*
+#define EPLLIN_CMD_PI_OUT                   2   // ulArg_p ~ tEplApiProcessImage*
+#define EPLLIN_CMD_WRITE_OBJECT             3   // ulArg_p ~ tEplLinSdoObject*
+#define EPLLIN_CMD_READ_OBJECT              4   // ulArg_p ~ tEplLinSdoObject*
+#define EPLLIN_CMD_WRITE_LOCAL_OBJECT       5   // ulArg_p ~ tEplLinLocalObject*
+#define EPLLIN_CMD_READ_LOCAL_OBJECT        6   // ulArg_p ~ tEplLinLocalObject*
+#define EPLLIN_CMD_FREE_SDO_CHANNEL         7   // ulArg_p ~ tEplSdoComConHdl
+#define EPLLIN_CMD_NMT_COMMAND              8   // ulArg_p ~ tEplNmtEvent
+#define EPLLIN_CMD_GET_EVENT                9   // ulArg_p ~ tEplLinEvent*
+#define EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE 10   // ulArg_p ~ tEplLinNodeCmdObject*
+#define EPLLIN_CMD_PI_SETUP                11   // ulArg_p ~ 0
+#define EPLLIN_CMD_SHUTDOWN                12   // ulArg_p ~ 0
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    unsigned int        m_uiEventArgSize;
+    tEplApiEventArg*    m_pEventArg;
+    tEplApiEventType*   m_pEventType;
+    tEplKernel          m_RetCbEvent;
+
+} tEplLinEvent;
+
+typedef struct
+{
+    tEplSdoComConHdl  m_SdoComConHdl;
+    BOOL              m_fValidSdoComConHdl;
+    unsigned int      m_uiNodeId;
+    unsigned int      m_uiIndex;
+    unsigned int      m_uiSubindex;
+    void*             m_le_pData;
+    unsigned int      m_uiSize;
+    tEplSdoType       m_SdoType;
+    void*             m_pUserArg;
+
+} tEplLinSdoObject;
+
+typedef struct
+{
+    unsigned int      m_uiIndex;
+    unsigned int      m_uiSubindex;
+    void*             m_pData;
+    unsigned int      m_uiSize;
+
+} tEplLinLocalObject;
+
+typedef struct
+{
+    unsigned int        m_uiNodeId;
+    tEplNmtNodeCommand  m_NodeCommand;
+
+} tEplLinNodeCmdObject;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+
+#endif  // #ifndef _EPL_API_LINUX_H_
+
+
diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c
new file mode 100644 (file)
index 0000000..4941760
--- /dev/null
@@ -0,0 +1,1317 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Linux kernel module as wrapper of EPL API layer,
+                i.e. counterpart to a Linux application
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplApiLinuxKernel.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.9 $  $Date: 2008/11/21 09:00:38 $
+
+                $State: Exp $
+
+                Build Environment:
+                GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/10/11 d.k.:  Initial Version
+  2008/04/10 m.u.:  Changed to new char driver init
+
+****************************************************************************/
+
+
+// kernel modul and driver
+
+//#include <linux/version.h>
+//#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/types.h>
+
+//#include <linux/module.h>
+//#include <linux/kernel.h>
+//#include <linux/init.h>
+//#include <linux/errno.h>
+
+// scheduling
+#include <linux/sched.h>
+
+// memory access
+#include <asm/uaccess.h>
+#include <linux/vmalloc.h>
+
+#ifdef CONFIG_DEVFS_FS
+#include <linux/major.h>
+#include <linux/devfs_fs_kernel.h>
+#endif
+
+#include "Epl.h"
+#include "EplApiLinux.h"
+//#include "kernel/EplPdokCal.h"
+#include "proc_fs.h"
+
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    // remove ("make invisible") obsolete symbols for kernel versions 2.6
+    // and higher
+    #define MOD_INC_USE_COUNT
+    #define MOD_DEC_USE_COUNT
+    #define EXPORT_NO_SYMBOLS
+#else
+    #error "This driver needs a 2.6.x kernel or higher"
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+// Metainformation
+MODULE_LICENSE("Dual BSD/GPL");
+#ifdef MODULE_AUTHOR
+    MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
+    MODULE_DESCRIPTION("EPL API driver");
+#endif
+
+
+//---------------------------------------------------------------------------
+//  Configuration
+//---------------------------------------------------------------------------
+
+
+#define EPLLIN_DRV_NAME     "systec_epl"       // used for <register_chrdev>
+
+
+
+//---------------------------------------------------------------------------
+//  Constant definitions
+//---------------------------------------------------------------------------
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+#endif
+
+#define EVENT_STATE_INIT        0
+#define EVENT_STATE_IOCTL       1   // ioctl entered and ready to receive EPL event
+#define EVENT_STATE_READY       2   // EPL event can be forwarded to user application
+#define EVENT_STATE_TERM        3   // terminate processing
+
+#define EPL_STATE_NOTOPEN       0
+#define EPL_STATE_NOTINIT       1
+#define EPL_STATE_RUNNING       2
+#define EPL_STATE_SHUTDOWN      3
+
+
+//---------------------------------------------------------------------------
+//  Global variables
+//---------------------------------------------------------------------------
+
+#ifdef CONFIG_DEVFS_FS
+
+    // driver major number
+    static int  nDrvMajorNumber_g;
+
+#else
+
+    // device number (major and minor)
+    static dev_t        nDevNum_g;
+    static struct cdev *pEpl_cdev_g;
+
+#endif
+
+
+static volatile unsigned int uiEplState_g = EPL_STATE_NOTOPEN;
+
+static struct semaphore     SemaphoreCbEvent_g; // semaphore for EplLinCbEvent
+static wait_queue_head_t    WaitQueueCbEvent_g; // wait queue EplLinCbEvent
+static wait_queue_head_t    WaitQueueProcess_g; // wait queue for EplApiProcess (user process)
+static wait_queue_head_t    WaitQueueRelease_g; // wait queue for EplLinRelease
+static atomic_t             AtomicEventState_g = ATOMIC_INIT(EVENT_STATE_INIT);
+static tEplApiEventType     EventType_g;        // event type (enum)
+static tEplApiEventArg*     pEventArg_g;        // event argument (union)
+static tEplKernel           RetCbEvent_g;       // return code from event callback function
+static wait_queue_head_t    WaitQueueCbSync_g;  // wait queue EplLinCbSync
+static wait_queue_head_t    WaitQueuePI_In_g;   // wait queue for EplApiProcessImageExchangeIn (user process)
+static atomic_t             AtomicSyncState_g = ATOMIC_INIT(EVENT_STATE_INIT);
+
+
+//---------------------------------------------------------------------------
+//  Local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    void*       m_pUserArg;
+    void*       m_pData;
+
+} tEplLinSdoBufHeader;
+
+
+//---------------------------------------------------------------------------
+//  Local variables
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Prototypes of internal functions
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplLinCbEvent(
+    tEplApiEventType        EventType_p,   // IN: event type (enum)
+    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
+    void GENERIC*           pUserArg_p);
+
+tEplKernel PUBLIC EplLinCbSync(void);
+
+static int  __init  EplLinInit (void);
+static void __exit  EplLinExit (void);
+
+
+static  int      EplLinOpen    (struct inode* pDeviceFile_p, struct file* pInstance_p);
+static  int      EplLinRelease (struct inode* pDeviceFile_p, struct file* pInstance_p);
+static  ssize_t  EplLinRead    (struct file* pInstance_p, char* pDstBuff_p, size_t BuffSize_p, loff_t* pFileOffs_p);
+static  ssize_t  EplLinWrite   (struct file* pInstance_p, const char* pSrcBuff_p, size_t BuffSize_p, loff_t* pFileOffs_p);
+static  int      EplLinIoctl   (struct inode* pDeviceFile_p, struct file* pInstance_p, unsigned int uiIoctlCmd_p, unsigned long ulArg_p);
+
+
+
+
+//---------------------------------------------------------------------------
+//  Kernel Module specific Data Structures
+//---------------------------------------------------------------------------
+
+EXPORT_NO_SYMBOLS;
+
+
+
+module_init(EplLinInit);
+module_exit(EplLinExit);
+
+
+
+
+static struct file_operations  EplLinFileOps_g =
+{
+    .owner =     THIS_MODULE,
+    .open =      EplLinOpen,
+    .release =   EplLinRelease,
+    .read =      EplLinRead,
+    .write =     EplLinWrite,
+    .ioctl =     EplLinIoctl,
+
+};
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//  Initailize Driver
+//---------------------------------------------------------------------------
+//  -> insmod driver
+//---------------------------------------------------------------------------
+
+static  int  __init  EplLinInit (void)
+{
+
+tEplKernel          EplRet;
+int  iErr;
+int  iRet;
+#ifdef CONFIG_DEVFS_FS
+int  nMinorNumber;
+#endif
+
+    TRACE0("EPL: + EplLinInit...\n");
+    TRACE2("EPL:   Driver build: %s / %s\n", __DATE__, __TIME__);
+
+    iRet = 0;
+
+    // initialize global variables
+    atomic_set(&AtomicEventState_g, EVENT_STATE_INIT);
+    sema_init(&SemaphoreCbEvent_g, 1);
+    init_waitqueue_head(&WaitQueueCbEvent_g);
+    init_waitqueue_head(&WaitQueueProcess_g);
+    init_waitqueue_head(&WaitQueueRelease_g);
+
+
+
+#ifdef CONFIG_DEVFS_FS
+
+    // register character device handler
+    TRACE2("EPL:   Installing Driver '%s', Version %s...\n", EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION);
+    TRACE0("EPL:   (using dynamic major number assignment)\n");
+    nDrvMajorNumber_g = register_chrdev (0, EPLLIN_DRV_NAME, &EplLinFileOps_g);
+    if (nDrvMajorNumber_g != 0)
+    {
+        TRACE2("EPL:   Driver '%s' installed successful, assigned MajorNumber=%d\n", EPLLIN_DRV_NAME, nDrvMajorNumber_g);
+    }
+    else
+    {
+        TRACE1("EPL:   ERROR: Driver '%s' is unable to get a free MajorNumber!\n", EPLLIN_DRV_NAME);
+        iRet = -EIO;
+        goto Exit;
+    }
+
+
+    // create device node in DEVFS
+    nMinorNumber = 0;
+    TRACE1("EPL:   Creating device node '/dev/%s'...\n", EPLLIN_DEV_NAME);
+    iErr = devfs_mk_cdev (MKDEV(nDrvMajorNumber_g, nMinorNumber), S_IFCHR | S_IRUGO | S_IWUGO, EPLLIN_DEV_NAME);
+    if (iErr == 0)
+    {
+        TRACE1("EPL:   Device node '/dev/%s' created successful.\n", EPLLIN_DEV_NAME);
+    }
+    else
+    {
+        TRACE1("EPL:   ERROR: unable to create device node '/dev/%s'\n", EPLLIN_DEV_NAME);
+        iRet = -EIO;
+        goto Exit;
+    }
+
+#else
+
+    // register character device handler
+    // only one Minor required
+    TRACE2("EPL:   Installing Driver '%s', Version %s...\n", EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION);
+    iRet = alloc_chrdev_region (&nDevNum_g, 0, 1, EPLLIN_DRV_NAME);
+    if (iRet == 0)
+    {
+        TRACE2("EPL:   Driver '%s' installed successful, assigned MajorNumber=%d\n", EPLLIN_DRV_NAME, MAJOR(nDevNum_g));
+    }
+    else
+    {
+        TRACE1("EPL:   ERROR: Driver '%s' is unable to get a free MajorNumber!\n", EPLLIN_DRV_NAME);
+        iRet = -EIO;
+        goto Exit;
+    }
+
+    // register cdev structure
+    pEpl_cdev_g = cdev_alloc();
+    pEpl_cdev_g->ops = &EplLinFileOps_g;
+    pEpl_cdev_g->owner = THIS_MODULE;
+    iErr = cdev_add (pEpl_cdev_g, nDevNum_g, 1);
+    if (iErr)
+    {
+        TRACE2("EPL:   ERROR %d: Driver '%s' could not be added!\n", iErr, EPLLIN_DRV_NAME);
+        iRet = -EIO;
+        goto Exit;
+    }
+
+#endif
+
+    // create device node in PROCFS
+    EplRet = EplLinProcInit();
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+
+Exit:
+
+    TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet);
+    return (iRet);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Remove Driver
+//---------------------------------------------------------------------------
+//  -> rmmod driver
+//---------------------------------------------------------------------------
+
+static void  __exit  EplLinExit (void)
+{
+
+tEplKernel          EplRet;
+
+    // delete instance for all modules
+//    EplRet = EplApiShutdown();
+//    printk("EplApiShutdown():  0x%X\n", EplRet);
+
+    // deinitialize proc fs
+    EplRet = EplLinProcFree();
+    printk("EplLinProcFree():        0x%X\n", EplRet);
+
+
+    TRACE0("EPL: + EplLinExit...\n");
+
+
+#ifdef CONFIG_DEVFS_FS
+
+    // remove device node from DEVFS
+    devfs_remove (EPLLIN_DEV_NAME);
+    TRACE1("EPL:   Device node '/dev/%s' removed.\n", EPLLIN_DEV_NAME);
+
+    // unregister character device handler
+    unregister_chrdev (nDrvMajorNumber_g, EPLLIN_DRV_NAME);
+
+#else
+
+    // remove cdev structure
+    cdev_del(pEpl_cdev_g);
+
+    // unregister character device handler
+    unregister_chrdev_region (nDevNum_g, 1);
+
+#endif
+
+    TRACE1("EPL:   Driver '%s' removed.\n", EPLLIN_DRV_NAME);
+
+
+    TRACE0("EPL: - EplLinExit\n");
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Open Driver
+//---------------------------------------------------------------------------
+//  -> open("/dev/driver", O_RDWR)...
+//---------------------------------------------------------------------------
+
+static int  EplLinOpen (
+    struct inode* pDeviceFile_p,    // information about the device to open
+    struct file* pInstance_p)       // information about driver instance
+{
+
+int  iRet;
+
+
+    TRACE0("EPL: + EplLinOpen...\n");
+
+    MOD_INC_USE_COUNT;
+
+    if (uiEplState_g != EPL_STATE_NOTOPEN)
+    {   // stack already initialized
+        iRet = -EALREADY;
+    }
+    else
+    {
+        atomic_set(&AtomicEventState_g, EVENT_STATE_INIT);
+        sema_init(&SemaphoreCbEvent_g, 1);
+        init_waitqueue_head(&WaitQueueCbEvent_g);
+        init_waitqueue_head(&WaitQueueProcess_g);
+        init_waitqueue_head(&WaitQueueRelease_g);
+        atomic_set(&AtomicSyncState_g, EVENT_STATE_INIT);
+        init_waitqueue_head(&WaitQueueCbSync_g);
+        init_waitqueue_head(&WaitQueuePI_In_g);
+
+        uiEplState_g = EPL_STATE_NOTINIT;
+        iRet = 0;
+    }
+
+    TRACE1("EPL: - EplLinOpen (iRet=%d)\n", iRet);
+    return (iRet);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Close Driver
+//---------------------------------------------------------------------------
+//  -> close(device)...
+//---------------------------------------------------------------------------
+
+static int  EplLinRelease (
+    struct inode* pDeviceFile_p,    // information about the device to open
+    struct file* pInstance_p)       // information about driver instance
+{
+
+tEplKernel          EplRet = kEplSuccessful;
+int  iRet;
+
+
+    TRACE0("EPL: + EplLinRelease...\n");
+
+    if (uiEplState_g != EPL_STATE_NOTINIT)
+    {
+        // pass control to sync kernel thread, but signal termination
+        atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
+        wake_up_interruptible(&WaitQueueCbSync_g);
+        wake_up_interruptible(&WaitQueuePI_In_g);
+
+        // pass control to event queue kernel thread
+        atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
+        wake_up_interruptible(&WaitQueueCbEvent_g);
+
+        if (uiEplState_g == EPL_STATE_RUNNING)
+        {   // post NmtEventSwitchOff
+            EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
+
+        }
+
+        if (EplRet == kEplSuccessful)
+        {
+            TRACE0("EPL:   waiting for NMT_GS_OFF\n");
+            wait_event_interruptible(WaitQueueRelease_g,
+                                        (uiEplState_g == EPL_STATE_SHUTDOWN));
+        }
+        else
+        {   // post NmtEventSwitchOff failed
+            TRACE0("EPL:   event post failed\n");
+        }
+
+        // $$$ d.k.: What if waiting was interrupted by signal?
+
+        TRACE0("EPL:   call EplApiShutdown()\n");
+        // EPL stack can be safely shut down
+        // delete instance for all EPL modules
+        EplRet = EplApiShutdown();
+        printk("EplApiShutdown():  0x%X\n", EplRet);
+    }
+
+    uiEplState_g = EPL_STATE_NOTOPEN;
+    iRet = 0;
+
+
+    MOD_DEC_USE_COUNT;
+
+
+    TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet);
+    return (iRet);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Read Data from Driver
+//---------------------------------------------------------------------------
+//  -> read(...)
+//---------------------------------------------------------------------------
+
+static ssize_t  EplLinRead (
+    struct file* pInstance_p,       // information about driver instance
+    char* pDstBuff_p,               // address of buffer to fill with data
+    size_t BuffSize_p,              // length of the buffer
+    loff_t* pFileOffs_p)            // offset in the file
+{
+
+int  iRet;
+
+
+    TRACE0("EPL: + EplLinRead...\n");
+
+
+    TRACE0("EPL:   Sorry, this operation isn't supported.\n");
+    iRet = -EINVAL;
+
+
+    TRACE1("EPL: - EplLinRead (iRet=%d)\n", iRet);
+    return (iRet);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Write Data to Driver
+//---------------------------------------------------------------------------
+//  -> write(...)
+//---------------------------------------------------------------------------
+
+static ssize_t  EplLinWrite (
+    struct file* pInstance_p,       // information about driver instance
+    const char* pSrcBuff_p,         // address of buffer to get data from
+    size_t BuffSize_p,              // length of the buffer
+    loff_t* pFileOffs_p)            // offset in the file
+{
+
+int  iRet;
+
+
+    TRACE0("EPL: + EplLinWrite...\n");
+
+
+    TRACE0("EPL:   Sorry, this operation isn't supported.\n");
+    iRet = -EINVAL;
+
+
+    TRACE1("EPL: - EplLinWrite (iRet=%d)\n", iRet);
+    return (iRet);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Generic Access to Driver
+//---------------------------------------------------------------------------
+//  -> ioctl(...)
+//---------------------------------------------------------------------------
+
+static int  EplLinIoctl (
+    struct inode* pDeviceFile_p,    // information about the device to open
+    struct file* pInstance_p,       // information about driver instance
+    unsigned int uiIoctlCmd_p,      // Ioctl command to execute
+    unsigned long ulArg_p)          // Ioctl command specific argument/parameter
+{
+
+tEplKernel          EplRet;
+int  iErr;
+int  iRet;
+
+
+//    TRACE1("EPL: + EplLinIoctl (uiIoctlCmd_p=%d)...\n", uiIoctlCmd_p);
+
+
+    iRet = -EINVAL;
+
+    switch (uiIoctlCmd_p)
+    {
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_INITIALIZE:
+        {
+        tEplApiInitParam EplApiInitParam;
+
+            iErr = copy_from_user(&EplApiInitParam, (const void*)ulArg_p, sizeof (EplApiInitParam));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            EplApiInitParam.m_pfnCbEvent = EplLinCbEvent;
+            EplApiInitParam.m_pfnCbSync = EplLinCbSync;
+
+            EplRet = EplApiInitialize(&EplApiInitParam);
+
+            uiEplState_g = EPL_STATE_RUNNING;
+
+            iRet = (int) EplRet;
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_SHUTDOWN:
+        {   // shutdown the threads
+
+            // pass control to sync kernel thread, but signal termination
+            atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
+            wake_up_interruptible(&WaitQueueCbSync_g);
+            wake_up_interruptible(&WaitQueuePI_In_g);
+
+            // pass control to event queue kernel thread
+            atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
+            wake_up_interruptible(&WaitQueueCbEvent_g);
+
+            if (uiEplState_g == EPL_STATE_RUNNING)
+            {   // post NmtEventSwitchOff
+                EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
+
+            }
+
+            iRet = 0;
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_READ_LOCAL_OBJECT:
+        {
+        tEplLinLocalObject  LocalObject;
+        void*               pData;
+
+            iErr = copy_from_user(&LocalObject, (const void*)ulArg_p, sizeof (LocalObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if ((LocalObject.m_pData == NULL) || (LocalObject.m_uiSize == 0))
+            {
+                iRet = (int) kEplApiInvalidParam;
+                goto Exit;
+            }
+
+            pData = vmalloc(LocalObject.m_uiSize);
+            if (pData == NULL)
+            {   // no memory available
+                iRet = -ENOMEM;
+                goto Exit;
+            }
+
+            EplRet = EplApiReadLocalObject(LocalObject.m_uiIndex, LocalObject.m_uiSubindex, pData, &LocalObject.m_uiSize);
+
+            if (EplRet == kEplSuccessful)
+            {
+                iErr = copy_to_user(LocalObject.m_pData, pData, LocalObject.m_uiSize);
+
+                vfree(pData);
+
+                if (iErr != 0)
+                {
+                    iRet = -EIO;
+                    goto Exit;
+                }
+
+                // return actual size (LocalObject.m_uiSize)
+                iErr = put_user(LocalObject.m_uiSize,
+                                (unsigned int*)(ulArg_p + (unsigned long)&LocalObject.m_uiSize - (unsigned long)&LocalObject));
+                if (iErr != 0)
+                {
+                    iRet = -EIO;
+                    goto Exit;
+                }
+
+            }
+            else
+            {
+                vfree(pData);
+            }
+
+            iRet = (int) EplRet;
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_WRITE_LOCAL_OBJECT:
+        {
+        tEplLinLocalObject  LocalObject;
+        void*               pData;
+
+            iErr = copy_from_user(&LocalObject, (const void*)ulArg_p, sizeof (LocalObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if ((LocalObject.m_pData == NULL) || (LocalObject.m_uiSize == 0))
+            {
+                iRet = (int) kEplApiInvalidParam;
+                goto Exit;
+            }
+
+            pData = vmalloc(LocalObject.m_uiSize);
+            if (pData == NULL)
+            {   // no memory available
+                iRet = -ENOMEM;
+                goto Exit;
+            }
+            iErr = copy_from_user(pData, LocalObject.m_pData, LocalObject.m_uiSize);
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            EplRet = EplApiWriteLocalObject(LocalObject.m_uiIndex, LocalObject.m_uiSubindex, pData, LocalObject.m_uiSize);
+
+            vfree(pData);
+
+            iRet = (int) EplRet;
+            break;
+        }
+
+
+        case EPLLIN_CMD_READ_OBJECT:
+        {
+        tEplLinSdoObject        SdoObject;
+        void*                   pData;
+        tEplLinSdoBufHeader*    pBufHeader;
+        tEplSdoComConHdl*       pSdoComConHdl;
+
+            iErr = copy_from_user(&SdoObject, (const void*)ulArg_p, sizeof (SdoObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if ((SdoObject.m_le_pData == NULL) || (SdoObject.m_uiSize == 0))
+            {
+                iRet = (int) kEplApiInvalidParam;
+                goto Exit;
+            }
+
+            pBufHeader = (tEplLinSdoBufHeader*) vmalloc(sizeof (tEplLinSdoBufHeader) + SdoObject.m_uiSize);
+            if (pBufHeader == NULL)
+            {   // no memory available
+                iRet = -ENOMEM;
+                goto Exit;
+            }
+
+            // initiate temporary buffer
+            pBufHeader->m_pUserArg = SdoObject.m_pUserArg;  // original user argument pointer
+            pBufHeader->m_pData = SdoObject.m_le_pData;     // original data pointer from app
+            pData = pBufHeader + sizeof (tEplLinSdoBufHeader);
+
+            if (SdoObject.m_fValidSdoComConHdl != FALSE)
+            {
+                pSdoComConHdl = &SdoObject.m_SdoComConHdl;
+            }
+            else
+            {
+                pSdoComConHdl = NULL;
+            }
+
+            EplRet = EplApiReadObject(pSdoComConHdl, SdoObject.m_uiNodeId, SdoObject.m_uiIndex,
+                                      SdoObject.m_uiSubindex, pData, &SdoObject.m_uiSize,
+                                      SdoObject.m_SdoType, pBufHeader);
+
+            // return actual SDO handle (SdoObject.m_SdoComConHdl)
+            iErr = put_user(SdoObject.m_SdoComConHdl,
+                            (unsigned int*)(ulArg_p + (unsigned long)&SdoObject.m_SdoComConHdl - (unsigned long)&SdoObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if (EplRet == kEplSuccessful)
+            {
+                iErr = copy_to_user(SdoObject.m_le_pData, pData, SdoObject.m_uiSize);
+
+                vfree(pBufHeader);
+
+                if (iErr != 0)
+                {
+                    iRet = -EIO;
+                    goto Exit;
+                }
+
+                // return actual size (SdoObject.m_uiSize)
+                iErr = put_user(SdoObject.m_uiSize,
+                                (unsigned int*)(ulArg_p + (unsigned long)&SdoObject.m_uiSize - (unsigned long)&SdoObject));
+                if (iErr != 0)
+                {
+                    iRet = -EIO;
+                    goto Exit;
+                }
+            }
+            else if (EplRet != kEplApiTaskDeferred)
+            {   // error ocurred
+                vfree(pBufHeader);
+                if (iErr != 0)
+                {
+                    iRet = -EIO;
+                    goto Exit;
+                }
+            }
+
+            iRet = (int) EplRet;
+            break;
+        }
+
+
+        case EPLLIN_CMD_WRITE_OBJECT:
+        {
+        tEplLinSdoObject        SdoObject;
+        void*                   pData;
+        tEplLinSdoBufHeader*    pBufHeader;
+        tEplSdoComConHdl*       pSdoComConHdl;
+
+            iErr = copy_from_user(&SdoObject, (const void*)ulArg_p, sizeof (SdoObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if ((SdoObject.m_le_pData == NULL) || (SdoObject.m_uiSize == 0))
+            {
+                iRet = (int) kEplApiInvalidParam;
+                goto Exit;
+            }
+
+            pBufHeader = (tEplLinSdoBufHeader*) vmalloc(sizeof (tEplLinSdoBufHeader) + SdoObject.m_uiSize);
+            if (pBufHeader == NULL)
+            {   // no memory available
+                iRet = -ENOMEM;
+                goto Exit;
+            }
+
+            // initiate temporary buffer
+            pBufHeader->m_pUserArg = SdoObject.m_pUserArg;  // original user argument pointer
+            pBufHeader->m_pData = SdoObject.m_le_pData;     // original data pointer from app
+            pData = pBufHeader + sizeof (tEplLinSdoBufHeader);
+
+            iErr = copy_from_user(pData, SdoObject.m_le_pData, SdoObject.m_uiSize);
+
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if (SdoObject.m_fValidSdoComConHdl != FALSE)
+            {
+                pSdoComConHdl = &SdoObject.m_SdoComConHdl;
+            }
+            else
+            {
+                pSdoComConHdl = NULL;
+            }
+
+            EplRet = EplApiWriteObject(pSdoComConHdl, SdoObject.m_uiNodeId, SdoObject.m_uiIndex,
+                                      SdoObject.m_uiSubindex, pData, SdoObject.m_uiSize,
+                                      SdoObject.m_SdoType, pBufHeader);
+
+            // return actual SDO handle (SdoObject.m_SdoComConHdl)
+            iErr = put_user(SdoObject.m_SdoComConHdl,
+                            (unsigned int*)(ulArg_p + (unsigned long)&SdoObject.m_SdoComConHdl - (unsigned long)&SdoObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if (EplRet != kEplApiTaskDeferred)
+            {   // succeeded or error ocurred, but task not deferred
+                vfree(pBufHeader);
+            }
+
+            iRet = (int) EplRet;
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_FREE_SDO_CHANNEL:
+        {
+            // forward SDO handle to EPL stack
+            EplRet = EplApiFreeSdoChannel((tEplSdoComConHdl)ulArg_p);
+
+            iRet = (int) EplRet;
+            break;
+        }
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE:
+        {
+        tEplLinNodeCmdObject        NodeCmdObject;
+
+            iErr = copy_from_user(&NodeCmdObject, (const void*)ulArg_p, sizeof (NodeCmdObject));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            EplRet = EplApiMnTriggerStateChange(NodeCmdObject.m_uiNodeId,
+                                                NodeCmdObject.m_NodeCommand);
+            iRet = (int) EplRet;
+            break;
+        }
+#endif
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_GET_EVENT:
+        {
+        tEplLinEvent         Event;
+
+            // save event structure
+            iErr = copy_from_user(&Event, (const void*)ulArg_p, sizeof (Event));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            // save return code from application's event callback function
+            RetCbEvent_g = Event.m_RetCbEvent;
+
+            if (RetCbEvent_g == kEplShutdown)
+            {
+                // pass control to event queue kernel thread, but signal termination
+                atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
+                wake_up_interruptible(&WaitQueueCbEvent_g);
+                // exit with error -> EplApiProcess() will leave the infinite loop
+                iRet = 1;
+                goto Exit;
+            }
+
+            // pass control to event queue kernel thread
+            atomic_set(&AtomicEventState_g, EVENT_STATE_IOCTL);
+            wake_up_interruptible(&WaitQueueCbEvent_g);
+
+            // fall asleep itself in own wait queue
+            iErr = wait_event_interruptible(WaitQueueProcess_g,
+                                            (atomic_read(&AtomicEventState_g) == EVENT_STATE_READY)
+                                            || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM));
+            if (iErr != 0)
+            {   // waiting was interrupted by signal
+                // pass control to event queue kernel thread, but signal termination
+                atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
+                wake_up_interruptible(&WaitQueueCbEvent_g);
+                // exit with this error -> EplApiProcess() will leave the infinite loop
+                iRet = iErr;
+                goto Exit;
+            }
+            else if (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM)
+            {   // termination in progress
+                // pass control to event queue kernel thread, but signal termination
+                wake_up_interruptible(&WaitQueueCbEvent_g);
+                // exit with this error -> EplApiProcess() will leave the infinite loop
+                iRet = 1;
+                goto Exit;
+            }
+
+            // copy event to user space
+            iErr = copy_to_user(Event.m_pEventType, &EventType_g, sizeof (EventType_g));
+            if (iErr != 0)
+            {   // not all data could be copied
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            // $$$ d.k. perform SDO event processing
+            if (EventType_g == kEplApiEventSdo)
+            {
+            void*               pData;
+            tEplLinSdoBufHeader*    pBufHeader;
+
+                pBufHeader = (tEplLinSdoBufHeader*) pEventArg_g->m_Sdo.m_pUserArg;
+                pData = pBufHeader + sizeof (tEplLinSdoBufHeader);
+
+                if (pEventArg_g->m_Sdo.m_SdoAccessType == kEplSdoAccessTypeRead)
+                {
+                    // copy read data to user space
+                    iErr = copy_to_user(pBufHeader->m_pData, pData, pEventArg_g->m_Sdo.m_uiTransferredByte);
+                    if (iErr != 0)
+                    {   // not all data could be copied
+                        iRet = -EIO;
+                        goto Exit;
+                    }
+                }
+                pEventArg_g->m_Sdo.m_pUserArg = pBufHeader->m_pUserArg;
+                vfree(pBufHeader);
+            }
+
+            iErr = copy_to_user(Event.m_pEventArg, pEventArg_g, min(sizeof (tEplApiEventArg), Event.m_uiEventArgSize));
+            if (iErr != 0)
+            {   // not all data could be copied
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            // return to EplApiProcess(), which will call the application's event callback function
+            iRet = 0;
+
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_PI_SETUP:
+        {
+            EplRet = EplApiProcessImageSetup();
+            iRet = (int) EplRet;
+
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_PI_IN:
+        {
+        tEplApiProcessImage ProcessImageIn;
+
+            // save process image structure
+            iErr = copy_from_user(&ProcessImageIn, (const void*)ulArg_p, sizeof (ProcessImageIn));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            // pass control to event queue kernel thread
+            atomic_set(&AtomicSyncState_g, EVENT_STATE_IOCTL);
+
+            // fall asleep itself in own wait queue
+            iErr = wait_event_interruptible(WaitQueuePI_In_g,
+                                            (atomic_read(&AtomicSyncState_g) == EVENT_STATE_READY)
+                                            || (atomic_read(&AtomicSyncState_g) == EVENT_STATE_TERM));
+            if (iErr != 0)
+            {   // waiting was interrupted by signal
+                // pass control to sync kernel thread, but signal termination
+                atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
+                wake_up_interruptible(&WaitQueueCbSync_g);
+                // exit with this error -> application will leave the infinite loop
+                iRet = iErr;
+                goto Exit;
+            }
+            else if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_TERM)
+            {   // termination in progress
+                // pass control to sync kernel thread, but signal termination
+                wake_up_interruptible(&WaitQueueCbSync_g);
+                // exit with this error -> application will leave the infinite loop
+                iRet = 1;
+                goto Exit;
+            }
+
+            // exchange process image
+            EplRet = EplApiProcessImageExchangeIn(&ProcessImageIn);
+
+            // return to EplApiProcessImageExchangeIn()
+            iRet = (int) EplRet;
+
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_PI_OUT:
+        {
+        tEplApiProcessImage ProcessImageOut;
+
+            // save process image structure
+            iErr = copy_from_user(&ProcessImageOut, (const void*)ulArg_p, sizeof (ProcessImageOut));
+            if (iErr != 0)
+            {
+                iRet = -EIO;
+                goto Exit;
+            }
+
+            if (atomic_read(&AtomicSyncState_g) != EVENT_STATE_READY)
+            {
+                iRet = (int) kEplInvalidOperation;
+                goto Exit;
+            }
+
+            // exchange process image
+            EplRet = EplApiProcessImageExchangeOut(&ProcessImageOut);
+
+            // pass control to sync kernel thread
+            atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
+            wake_up_interruptible(&WaitQueueCbSync_g);
+
+            // return to EplApiProcessImageExchangeout()
+            iRet = (int) EplRet;
+
+            break;
+        }
+
+
+        // ----------------------------------------------------------
+        case EPLLIN_CMD_NMT_COMMAND:
+        {
+            // forward NMT command to EPL stack
+            EplRet = EplApiExecNmtCommand((tEplNmtEvent)ulArg_p);
+
+            iRet = (int) EplRet;
+
+            break;
+        }
+
+
+
+        // ----------------------------------------------------------
+        default:
+        {
+            break;
+        }
+    }
+
+
+Exit:
+
+//    TRACE1("EPL: - EplLinIoctl (iRet=%d)\n", iRet);
+    return (iRet);
+
+}
+
+
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+
+tEplKernel PUBLIC EplLinCbEvent(
+    tEplApiEventType        EventType_p,   // IN: event type (enum)
+    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
+    void GENERIC*           pUserArg_p)
+{
+tEplKernel          EplRet = kEplSuccessful;
+int  iErr;
+
+    // block any further call to this function, i.e. enter critical section
+    iErr = down_interruptible(&SemaphoreCbEvent_g);
+    if (iErr != 0)
+    {   // waiting was interrupted by signal
+        EplRet = kEplShutdown;
+        goto Exit;
+    }
+
+    // wait for EplApiProcess() to call ioctl
+    // normally it should be waiting already for us to pass a new event
+    iErr = wait_event_interruptible(WaitQueueCbEvent_g,
+                                    (atomic_read(&AtomicEventState_g) == EVENT_STATE_IOCTL)
+                                    || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM));
+    if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM))
+    {   // waiting was interrupted by signal
+        EplRet = kEplShutdown;
+        goto LeaveCriticalSection;
+    }
+
+    // save event information for ioctl
+    EventType_g = EventType_p;
+    pEventArg_g = pEventArg_p;
+
+    // pass control to application's event callback function, i.e. EplApiProcess()
+    atomic_set(&AtomicEventState_g, EVENT_STATE_READY);
+    wake_up_interruptible(&WaitQueueProcess_g);
+
+    // now, the application's event callback function processes the event
+
+    // wait for completion of application's event callback function, i.e. EplApiProcess() calls ioctl again
+    iErr = wait_event_interruptible(WaitQueueCbEvent_g,
+                                    (atomic_read(&AtomicEventState_g) == EVENT_STATE_IOCTL)
+                                    || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM));
+    if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM))
+    {   // waiting was interrupted by signal
+        EplRet = kEplShutdown;
+        goto LeaveCriticalSection;
+    }
+
+    // read return code from application's event callback function
+    EplRet = RetCbEvent_g;
+
+
+LeaveCriticalSection:
+    up(&SemaphoreCbEvent_g);
+
+Exit:
+    // check if NMT_GS_OFF is reached
+    if (EventType_p == kEplApiEventNmtStateChange)
+    {
+        if (pEventArg_p->m_NmtStateChange.m_NewNmtState == kEplNmtGsOff)
+        {   // NMT state machine was shut down
+            TRACE0("EPL:   EplLinCbEvent(NMT_GS_OFF)\n");
+            uiEplState_g = EPL_STATE_SHUTDOWN;
+            atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
+            wake_up(&WaitQueueRelease_g);
+        }
+        else
+        {   // NMT state machine is running
+            uiEplState_g = EPL_STATE_RUNNING;
+        }
+    }
+
+
+    return EplRet;
+}
+
+
+tEplKernel PUBLIC EplLinCbSync(void)
+{
+tEplKernel          EplRet = kEplSuccessful;
+int  iErr;
+
+    // check if user process waits for sync
+    if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_IOCTL)
+    {
+        // pass control to application, i.e. EplApiProcessImageExchangeIn()
+        atomic_set(&AtomicSyncState_g, EVENT_STATE_READY);
+        wake_up_interruptible(&WaitQueuePI_In_g);
+
+        // now, the application processes the sync event
+
+        // wait for call of EplApiProcessImageExchangeOut()
+        iErr = wait_event_interruptible(WaitQueueCbSync_g,
+                                        (atomic_read(&AtomicSyncState_g) == EVENT_STATE_IOCTL)
+                                        || (atomic_read(&AtomicSyncState_g) == EVENT_STATE_TERM));
+        if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_IOCTL))
+        {   // waiting was interrupted by signal or application called wrong function
+            EplRet = kEplShutdown;
+        }
+    }
+    else
+    {   // application is currently not waiting for sync
+        // continue without interruption
+        // TPDO are set valid by caller (i.e. EplEventkProcess())
+    }
+
+    TGT_DBG_SIGNAL_TRACE_POINT(1);
+
+    return EplRet;
+}
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplApiProcessImage.c b/drivers/staging/epl/EplApiProcessImage.c
new file mode 100644 (file)
index 0000000..b433369
--- /dev/null
@@ -0,0 +1,374 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for EPL API module (process image)
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplApiProcessImage.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.7 $  $Date: 2008/11/13 17:13:09 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/10/10 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "Epl.h"
+//#include "kernel/EplPdokCal.h"
+
+#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+#include <asm/uaccess.h>
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplApi                                              */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
+    typedef struct
+    {
+        #if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
+            BYTE        m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
+        #endif
+        #if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
+            BYTE        m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
+        #endif
+
+    } tEplApiProcessImageInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplApiProcessImageInstance  EplApiProcessImageInstance_g;
+#endif
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplApiProcessImageSetup()
+//
+// Description: sets up static process image
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiProcessImageSetup(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
+unsigned int    uiVarEntries;
+tEplObdSize     ObdSize;
+#endif
+
+#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN;
+    ObdSize = 1;
+    Ret = EplApiLinkObject(
+                            0x2000,
+                            EplApiProcessImageInstance_g.m_abProcessImageInput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN;
+    ObdSize = 1;
+    Ret = EplApiLinkObject(
+                            0x2001,
+                            EplApiProcessImageInstance_g.m_abProcessImageInput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 2;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2010,
+                            EplApiProcessImageInstance_g.m_abProcessImageInput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 2;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2011,
+                            EplApiProcessImageInstance_g.m_abProcessImageInput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 4;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2020,
+                            EplApiProcessImageInstance_g.m_abProcessImageInput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 4;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2021,
+                            EplApiProcessImageInstance_g.m_abProcessImageInput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+#endif
+
+#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT;
+    ObdSize = 1;
+    Ret = EplApiLinkObject(
+                            0x2030,
+                            EplApiProcessImageInstance_g.m_abProcessImageOutput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT;
+    ObdSize = 1;
+    Ret = EplApiLinkObject(
+                            0x2031,
+                            EplApiProcessImageInstance_g.m_abProcessImageOutput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 2;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2040,
+                            EplApiProcessImageInstance_g.m_abProcessImageOutput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 2;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2041,
+                            EplApiProcessImageInstance_g.m_abProcessImageOutput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 4;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2050,
+                            EplApiProcessImageInstance_g.m_abProcessImageOutput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+
+    ObdSize = 4;
+    uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
+    Ret = EplApiLinkObject(
+                            0x2051,
+                            EplApiProcessImageInstance_g.m_abProcessImageOutput,
+                            &uiVarEntries,
+                            &ObdSize,
+                            1);
+#endif
+
+    return Ret;
+}
+
+//----------------------------------------------------------------------------
+// Function:    EplApiProcessImageExchangeIn()
+//
+// Description: replaces passed input process image with the one of EPL stack
+//
+// Parameters:  pPI_p                   = input process image
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage* pPI_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
+    #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+        copy_to_user(pPI_p->m_pImage,
+            EplApiProcessImageInstance_g.m_abProcessImageInput,
+            min(pPI_p->m_uiSize, sizeof (EplApiProcessImageInstance_g.m_abProcessImageInput)));
+    #else
+        EPL_MEMCPY(pPI_p->m_pImage,
+            EplApiProcessImageInstance_g.m_abProcessImageInput,
+            min(pPI_p->m_uiSize, sizeof (EplApiProcessImageInstance_g.m_abProcessImageInput)));
+    #endif
+#endif
+
+    return Ret;
+}
+
+
+//----------------------------------------------------------------------------
+// Function:    EplApiProcessImageExchangeOut()
+//
+// Description: copies passed output process image to EPL stack.
+//
+// Parameters:  pPI_p                   = output process image
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//----------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage* pPI_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
+    #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+        copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput,
+            pPI_p->m_pImage,
+            min(pPI_p->m_uiSize, sizeof (EplApiProcessImageInstance_g.m_abProcessImageOutput)));
+    #else
+        EPL_MEMCPY(EplApiProcessImageInstance_g.m_abProcessImageOutput,
+            pPI_p->m_pImage,
+            min(pPI_p->m_uiSize, sizeof (EplApiProcessImageInstance_g.m_abProcessImageOutput)));
+    #endif
+#endif
+
+    return Ret;
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplCfg.h b/drivers/staging/epl/EplCfg.h
new file mode 100644 (file)
index 0000000..0684583
--- /dev/null
@@ -0,0 +1,207 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  configuration file
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplCfg.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    ...
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/06    k.t.: Start of Implementation
+
+****************************************************************************/
+
+#ifndef _EPLCFG_H_
+#define _EPLCFG_H_
+
+
+
+
+// =========================================================================
+// generic defines which for whole EPL Stack
+// =========================================================================
+#define EPL_USE_DELETEINST_FUNC TRUE
+
+// needed to support datatypes over 32 bit by global.h
+#define USE_VAR64
+
+// EPL_MAX_INSTANCES specifies count of instances of all EPL modules.
+// If it is greater than 1 the first parameter of all
+// functions is the instance number.
+#define EPL_MAX_INSTANCES               1
+
+// This defines the target hardware. Here is encoded wich CPU and wich external
+// peripherals are connected. For possible values refere to target.h. If
+// necessary value is not available EPL stack has to
+// be adapted and tested.
+#define TARGET_HARDWARE                 TGTHW_PC_WRAPP
+
+// use no FIFOs, make direct calls
+//#define EPL_NO_FIFO
+
+// use no IPC between user- and kernelspace modules, make direct calls
+#define EPL_NO_USER_KERNEL
+
+#ifndef BENCHMARK_MODULES
+#define BENCHMARK_MODULES       0 //0xEE800042L
+#endif
+
+// Default defug level:
+// Only debug traces of these modules will be compiled which flags are set in define DEF_DEBUG_LVL.
+#ifndef DEF_DEBUG_LVL
+#define DEF_DEBUG_LVL           0xEC000000L
+#endif
+//   EPL_DBGLVL_OBD         =   0x00000004L
+// * EPL_DBGLVL_ASSERT      =   0x20000000L
+// * EPL_DBGLVL_ERROR       =   0x40000000L
+// * EPL_DBGLVL_ALWAYS      =   0x80000000L
+
+
+// EPL_MODULE_INTEGRATION defines all modules which are included in
+// EPL application. Please add or delete modules for your application.
+#define EPL_MODULE_INTEGRATION EPL_MODULE_OBDK \
+                               | EPL_MODULE_PDOK \
+                               | EPL_MODULE_NMT_MN \
+                               | EPL_MODULE_SDOS \
+                               | EPL_MODULE_SDOC \
+                               | EPL_MODULE_SDO_ASND \
+                               | EPL_MODULE_SDO_UDP \
+                               | EPL_MODULE_NMT_CN \
+                               | EPL_MODULE_NMTU \
+                               | EPL_MODULE_NMTK \
+                               | EPL_MODULE_DLLK \
+                               | EPL_MODULE_DLLU \
+                               | EPL_MODULE_VETH
+//                               | EPL_MODULE_OBDU
+
+// =========================================================================
+// EPL ethernet driver (Edrv) specific defines
+// =========================================================================
+
+// switch this define to TRUE if Edrv supports fast tx frames
+#define EDRV_FAST_TXFRAMES              FALSE
+//#define EDRV_FAST_TXFRAMES              TRUE
+
+// switch this define to TRUE if Edrv supports early receive interrupts
+#define EDRV_EARLY_RX_INT               FALSE
+//#define EDRV_EARLY_RX_INT               TRUE
+
+// enables setting of several port pins for benchmarking purposes
+#define EDRV_BENCHMARK                  FALSE
+//#define EDRV_BENCHMARK                  TRUE // MCF_GPIO_PODR_PCIBR
+
+// Call Tx handler (i.e. EplDllCbFrameTransmitted()) already if DMA has finished,
+// otherwise call the Tx handler if frame was actually transmitted over ethernet.
+#define EDRV_DMA_TX_HANDLER             FALSE
+//#define EDRV_DMA_TX_HANDLER             TRUE
+
+// number of used ethernet controller
+//#define EDRV_USED_ETH_CTRL              1
+
+
+// =========================================================================
+// Data Link Layer (DLL) specific defines
+// =========================================================================
+
+// switch this define to TRUE if Edrv supports fast tx frames
+// and DLL shall pass PRes as ready to Edrv after SoC
+#define EPL_DLL_PRES_READY_AFTER_SOC    FALSE
+//#define EPL_DLL_PRES_READY_AFTER_SOC    TRUE
+
+// switch this define to TRUE if Edrv supports fast tx frames
+// and DLL shall pass PRes as ready to Edrv after SoA
+#define EPL_DLL_PRES_READY_AFTER_SOA    FALSE
+//#define EPL_DLL_PRES_READY_AFTER_SOA    TRUE
+
+
+// =========================================================================
+// OBD specific defines
+// =========================================================================
+
+// switch this define to TRUE if Epl should compare object range
+// automaticly
+#define EPL_OBD_CHECK_OBJECT_RANGE          FALSE
+//#define EPL_OBD_CHECK_OBJECT_RANGE          TRUE
+
+// set this define to TRUE if there are strings or domains in OD, which
+// may be changed in object size and/or object data pointer by its object
+// callback function (called event kObdEvWrStringDomain)
+//#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM    FALSE
+#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM    TRUE
+
+#define EPL_OBD_USE_VARIABLE_SUBINDEX_TAB TRUE
+
+
+// =========================================================================
+// Timer module specific defines
+// =========================================================================
+
+// if TRUE it uses the Timer module implementation of EPL user also in EPL kernel
+#define EPL_TIMER_USE_USER              TRUE
+
+// if TRUE the high resolution timer module will be used
+#define EPL_TIMER_USE_HIGHRES              TRUE
+//#define EPL_TIMER_USE_HIGHRES              FALSE
+
+
+#endif //_EPLCFG_H_
+
+
+
diff --git a/drivers/staging/epl/EplDef.h b/drivers/staging/epl/EplDef.h
new file mode 100644 (file)
index 0000000..ff704d6
--- /dev/null
@@ -0,0 +1,362 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for EPL default constants
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDef.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.15 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DEF_H_
+#define _EPL_DEF_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPL_C_ADR_BROADCAST         0xFF // EPL broadcast address
+#define EPL_C_ADR_DIAG_DEF_NODE_ID  0xFD // EPL default address of dignostic device
+#define EPL_C_ADR_DUMMY_NODE_ID     0xFC // EPL dummy node address
+#define EPL_C_ADR_INVALID           0x00 // invalid EPL address
+#define EPL_C_ADR_MN_DEF_NODE_ID    0xF0 // EPL default address of MN
+#define EPL_C_ADR_RT1_DEF_NODE_ID   0xFE // EPL default address of router type 1
+#define EPL_C_DLL_ASND_PRIO_NMTRQST 7    // increased ASnd request priority to be used by NMT Requests
+#define EPL_C_DLL_ASND_PRIO_STD     0    // standard ASnd request priority
+#define EPL_C_DLL_ETHERTYPE_EPL     0x88AB
+#define EPL_C_DLL_ISOCHR_MAX_PAYL   1490 // Byte: maximum size of PReq and PRes payload data, requires C_IP_MAX_MTU
+#define EPL_C_DLL_MAX_ASYNC_MTU     1500 // Byte: maximum asynchronous payload in bytes
+#define EPL_C_DLL_MAX_PAYL_OFFSET   1499 // Byte: maximum offset of Ethernet frame payload, requires C_IP_MAX_MTU
+#define EPL_C_DLL_MAX_RS            7
+#define EPL_C_DLL_MIN_ASYNC_MTU     282  // Byte: minimum asynchronous payload in bytes.
+#define EPL_C_DLL_MIN_PAYL_OFFSET   45   // Byte: minimum offset of Ethernet frame payload
+#define EPL_C_DLL_MULTICAST_ASND    0x01111E000004LL // EPL ASnd multicast MAC address, canonical form
+#define EPL_C_DLL_MULTICAST_PRES    0x01111E000002LL // EPL PRes multicast MAC address, canonical form
+#define EPL_C_DLL_MULTICAST_SOA     0x01111E000003LL // EPL SoA multicast MAC address, canonical form
+#define EPL_C_DLL_MULTICAST_SOC     0x01111E000001LL // EPL Soc multicast MAC address, canonical form
+#define EPL_C_DLL_PREOP1_START_CYCLES 10 // number of unassigning SoA frames at start of NMT_MS_PRE_OPERATIONAL_1
+#define EPL_C_DLL_T_BITTIME         10   // ns: Transmission time per bit on 100 Mbit/s network
+#define EPL_C_DLL_T_EPL_PDO_HEADER  10   // Byte: size of PReq and PRes EPL PDO message header
+#define EPL_C_DLL_T_ETH2_WRAPPER    18   // Byte: size of Ethernet type II wrapper consisting of header and checksum
+#define EPL_C_DLL_T_IFG             640  // ns: Ethernet Interframe Gap
+#define EPL_C_DLL_T_MIN_FRAME       5120 // ns: Size of minimum Ethernet frame (without preamble)
+#define EPL_C_DLL_T_PREAMBLE        960  // ns: Size of Ethernet frame preamble
+
+#define EPL_C_DLL_MINSIZE_SOC       36   // minimum size of SoC without padding and CRC
+#define EPL_C_DLL_MINSIZE_PREQ      60   // minimum size of PRec without CRC
+#define EPL_C_DLL_MINSIZE_PRES      60   // minimum size of PRes without CRC
+#define EPL_C_DLL_MINSIZE_SOA       24   // minimum size of SoA without padding and CRC
+#define EPL_C_DLL_MINSIZE_IDENTRES  176  // minimum size of IdentResponse without CRC
+#define EPL_C_DLL_MINSIZE_STATUSRES 72   // minimum size of StatusResponse without CRC
+#define EPL_C_DLL_MINSIZE_NMTCMD    20   // minimum size of NmtCommand without CommandData, padding and CRC
+#define EPL_C_DLL_MINSIZE_NMTCMDEXT 52   // minimum size of NmtCommand without padding and CRC
+#define EPL_C_DLL_MINSIZE_NMTREQ    20   // minimum size of NmtRequest without CommandData, padding and CRC
+#define EPL_C_DLL_MINSIZE_NMTREQEXT 52   // minimum size of NmtRequest without padding and CRC
+
+#define EPL_C_ERR_MONITOR_DELAY     10   // Error monitoring start delay (not used in DS 1.0.0)
+#define EPL_C_IP_ADR_INVALID        0x00000000L // invalid IP address (0.0.0.0) used to indicate no change
+#define EPL_C_IP_INVALID_MTU        0    // Byte: invalid MTU size used to indicate no change
+#define EPL_C_IP_MAX_MTU            1518 // Byte: maximum size in bytes of the IP stack which must be processed.
+#define EPL_C_IP_MIN_MTU            300  // Byte: minimum size in bytes of the IP stack which must be processed.
+#define EPL_C_NMT_STATE_TOLERANCE   5    // Cycles: maximum reaction time to NMT state commands
+#define EPL_C_NMT_STATREQ_CYCLE     5    // sec: StatusRequest cycle time to be applied to AsyncOnly CNs
+#define EPL_C_SDO_EPL_PORT          3819
+
+#define EPL_C_DLL_MAX_ASND_SERVICE_IDS  5   // see tEplDllAsndServiceId in EplDll.h
+
+
+
+// Default configuration
+// ======================
+
+#ifndef EPL_D_PDO_Granularity_U8
+#define EPL_D_PDO_Granularity_U8    8    // minimum size of objects to be mapped in bits UNSIGNED8 O O 1 1
+#endif
+
+#ifndef EPL_NMT_MAX_NODE_ID
+#define EPL_NMT_MAX_NODE_ID         254  // maximum node-ID
+#endif
+
+#ifndef EPL_D_NMT_MaxCNNumber_U8
+#define EPL_D_NMT_MaxCNNumber_U8    239  // maximum number of supported regular CNs in the Node ID range 1 .. 239 UNSIGNED8 O O 239 239
+#endif
+
+// defines for EPL API layer static process image
+#ifndef EPL_API_PROCESS_IMAGE_SIZE_IN
+#define EPL_API_PROCESS_IMAGE_SIZE_IN   0
+#endif
+
+#ifndef EPL_API_PROCESS_IMAGE_SIZE_OUT
+#define EPL_API_PROCESS_IMAGE_SIZE_OUT  0
+#endif
+
+// configure whether OD access events shall be forwarded
+// to user callback function.
+// Because of reentrancy for local OD accesses, this has to be disabled
+// when application resides in other address space as the stack (e.g. if
+// EplApiLinuxUser.c and EplApiLinuxKernel.c are used)
+#ifndef EPL_API_OBD_FORWARD_EVENT
+#define EPL_API_OBD_FORWARD_EVENT       TRUE
+#endif
+
+#ifndef EPL_OBD_MAX_STRING_SIZE
+#define EPL_OBD_MAX_STRING_SIZE        32          // is used for objects 0x1008/0x1009/0x100A
+#endif
+
+#ifndef EPL_OBD_USE_STORE_RESTORE
+#define EPL_OBD_USE_STORE_RESTORE       FALSE
+#endif
+
+#ifndef EPL_OBD_CHECK_OBJECT_RANGE
+#define EPL_OBD_CHECK_OBJECT_RANGE      TRUE
+#endif
+
+#ifndef EPL_OBD_USE_STRING_DOMAIN_IN_RAM
+#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM    TRUE
+#endif
+
+#ifndef EPL_OBD_USE_VARIABLE_SUBINDEX_TAB
+#define EPL_OBD_USE_VARIABLE_SUBINDEX_TAB   TRUE
+#endif
+
+#ifndef EPL_OBD_USE_KERNEL
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0)
+#define EPL_OBD_USE_KERNEL                  TRUE
+#else
+#define EPL_OBD_USE_KERNEL                  FALSE
+#endif
+#endif
+
+#ifndef EPL_OBD_INCLUDE_A000_TO_DEVICE_PART
+#define EPL_OBD_INCLUDE_A000_TO_DEVICE_PART FALSE
+#endif
+
+#ifndef EPL_VETH_NAME
+#define EPL_VETH_NAME       "epl"   // name of net device in Linux
+#endif
+
+/*
+#define EPL_D_CFG_ConfigManager_BOOL // Ability of a MN node to perform Configuration Manager functions BOOLEAN O - N -
+#define EPL_D_CFM_VerifyConf_BOOL   // Support of objects CFM_VerifyConfiguration_REC, CFM_ExpConfDateList_AU32, CFM_ExpConfTimeList_AU32 BOOLEAN O O N N
+#define EPL_D_CFM_VerifyConfId_BOOL // Support of objects CFM_VerifyConfiguration_REC.ConfId_U32 and CFM_ExpConfIdList_AU32 BOOLEAN O O N N
+#define EPL_D_DLL_CNFeatureIsochr_BOOL // CN\92s ability to perform isochronous functions BOOLEAN - O - Y
+#define EPL_D_DLL_CNFeatureMultiplex_BOOL // node\92s ability to perform control of multiplexed isochronous communication BOOLEAN - O - N
+#define EPL_D_DLL_FeatureCN_BOOL // node\92s ability to perform CN functions BOOLEAN O O Y Y
+#define EPL_D_DLL_FeatureMN_BOOL // node\92s ability to perform MN functions BOOLEAN M O - N
+#define EPL_D_DLL_MNFeatureMultiplex_BOOL // MN\92s ability to perform control of multiplexed isochronous communication BOOLEAN O - Y -
+#define EPL_D_DLL_MNFeaturePResTx_BOOL // MN\92s ability to transmit PRes BOOLEAN O - Y -
+#define EPL_D_NMT_ASndRxMaxPayload_U16 // size of ASnd frame receive buffer UNSIGNED16 M M - -
+#define EPL_D_NMT_ASndTxMaxPayload_U16 // size of ASnd frame transmit buffer UNSIGNED16 M M - -
+#define EPL_D_NMT_CNASnd2SoC_U32 // minimum delay between end of reception of ASnd and start of reception of SoC UNSIGNED32 - M - -
+#define EPL_D_NMT_CNASndMaxLatency_U32 // delay between end of SoA reception and start of ASnd transmission UNSIGNED32 - M - -
+#define EPL_D_NMT_CNPResMaxLatency_U32 // delay between end of PReq reception and start of PRes transmission UNSIGNED32 - M - -
+#define EPL_D_NMT_CNSoC2PReq_U32 // CN SoC handling maximum time, a subsequent PReq won\92t be handled before SoC handling was finished UNSIGNED32 - M - -
+#define EPL_D_NMT_DeviceType_U32 // Device Type ID UNSIGNED32 M M - -
+#define EPL_D_NMT_EPLVers_U8 EPL // Version implemented by the device UNSIGNED8 M M - -
+#define EPL_D_NMT_ExtStateCmd_BOOL // abitilty to support Extended NMT State Commands BOOLEAN O O Y Y
+#define EPL_D_NMT_InfoSvc_BOOL // ability to support NMT Info Services BOOLEAN O - Y -
+#define EPL_D_NMT_InterfaceAddr_Xh_OSTR // Physical Address of Interface No. Xh OCTET_STRING M M - -
+#define EPL_D_NMT_InterfaceDescr_Xh_VSTR // Description text of Interface No. Xh VISIBLE_STRINGM M - -
+#define EPL_D_NMT_InterfaceMtu_Xh_U32 // MTU of Interface No. Xh UNSIGNED32 M M - -
+#define EPL_D_NMT_InterfaceType_Xh_U8 // Type of Interface No. Xh UNSIGNED8 M M - -
+#define EPL_D_NMT_IsochrRxMaxPayload_U16 // size of isochronous frame receive buffer UNSIGNED16 M M - -
+#define EPL_D_NMT_IsochrTxMaxPayload_U16 // size of isochronous frame transmit buffer UNSIGNED16 M M - -
+#define EPL_D_NMT_ManufactDevName_VS // Manufacturer Device Name VISIBLE_STRING O O - -
+#define EPL_D_NMT_ManufactHwVers_VS // Manufacturer HW version VISIBLE_STRING O O - -
+#define EPL_D_NMT_ManufactSwVers_VS // Manufacturer SW version VISIBLE_STRING O O - -
+#define EPL_D_NMT_MaxCNNodeID_U8 // maximum Node ID available for regular CNs the entry provides an upper limit to the NodeID available for cross traffic PDO reception from a regular CN UNSIGNED8 O O 239 239
+#define EPL_D_NMT_MaxCNNumber_U8 // maximum number of supported regular CNs in the Node ID range 1 .. 239 UNSIGNED8 O O 239 239
+#define EPL_D_NMT_MaxHeartbeats_U8 // number of guard channels UNSIGNED8 O O 254 254
+#define EPL_D_NMT_MNASnd2SoC_U32 // minimum delay between end of reception of ASnd and start of transmission of SoC UNSIGNED32 M - - -
+#define EPL_D_NMT_MNMultiplCycMax_U8 // maximum number of EPL cycles per multiplexed cycle UNSIGNED8 O - 0 -
+#define EPL_D_NMT_MNPRes2PReq_U32 // delay between end of PRes reception and start of PReq transmission UNSIGNED32 M - - -
+#define EPL_D_NMT_MNPRes2PRes_U32 // delay between end of reception of PRes from CNn and start of transmission of PRes by MN UNSIGNED32 M - - -
+#define EPL_D_NMT_MNPResRx2SoA_U32 // delay between end of reception of PRes from CNn and start of transmission of SoA by MN UNSIGNED32 M - - -
+#define EPL_D_NMT_MNPResTx2SoA_U32 // delay between end of PRes transmission by MN and start of transmission of SoA by MN UNSIGNED32 M - - -
+#define EPL_D_NMT_MNSoA2ASndTx_U32 // delay between end of transmission of SoA and start of transmission of ASnd by MN UNSIGNED32 M - - -
+#define EPL_D_NMT_MNSoC2PReq_U32 // MN minimum delay between end of SoC transmission and start of PReq transmission UNSIGNED32 M - - -
+#define EPL_D_NMT_NMTSvcViaUDPIP_BOOL // Ability of a node to perform NMT services via UDP/IP BOOLEAN O - Y -
+#define EPL_D_NMT_NodeIDByHW_BOOL // Ability of a node to support NodeID setup by HW BOOLEAN O O Y Y
+#define EPL_D_NMT_NodeIDBySW_BOOL // Ability of a node to support NodeID setup by SW BOOLEAN O O N N
+#define EPL_D_NMT_ProductCode_U32 // Identity Object Product Code UNSIGNED32 M M - -
+#define EPL_D_NMT_RevisionNo_U32 // Identity Object Revision Number UNSIGNED32 M M - -
+#define EPL_D_NMT_SerialNo_U32 // Identity Object Serial Number UNSIGNED32 M M - -
+#define EPL_D_NMT_SimpleBoot_BOOL // Ability of a MN node to perform Simple Boot Process, if not set Indivual Boot Process shall be proviced BOOLEAN M - - -
+#define EPL_D_NMT_VendorID_U32 // Identity Object Vendor ID UNSIGNED32 M M - -
+#define EPL_D_NWL_Forward_BOOL // Ability of node to forward datagrams BOOLEAN O O N N
+#define EPL_D_NWL_IPSupport_BOOL // Ability of the node cummunicate via IP BOOLEAN - - Y Y
+#define EPL_D_PDO_DynamicMapping_BOOL // Ability of a node to perform dynamic PDO mapping BOOLEAN O O Y Y
+#define EPL_D_PDO_MaxDescrMem_U32 // maximum cumulative memory consumption of TPDO and RPDO describing objects in byte UNSIGNED32 O O MAX_U32 MAX_U32
+#define EPL_D_PDO_RPDOChannels_U8 // number of supported RPDO channels UNSIGNED8 O O 256 256
+#define EPL_D_PDO_RPDOMaxMem_U32 // Maximum memory available for RPDO data per EPL cycle in byte UNSIGNED32 O O MAX_U32 MAX_U32
+#define EPL_D_PDO_RPDOObjects_U8 // Number of supported mapped objects per RPDO channel UNSIGNED8 O O 254 254
+#define EPL_D_PDO_TPDOChannels_U8 // number of supported TPDO channels UNSIGNED8 O - 256 -
+#define EPL_D_PDO_TPDOMaxMem_U32 // Maximum memory available for TPDO data per EPL cycle in byte UNSIGNED32 O O MAX_U32 MAX_U32
+#define EPL_D_PDO_TPDOObjects_U8 // Number of supported mapped objects per TPDO channel UNSIGNED8 O O 254 254
+#define EPL_D_SDO_ViaASnd_BOOL // Ability of a CN to perform SDO transfer by EPL ASnd BOOLEAN - M - -
+#define EPL_D_SDO_ViaPDO_BOOL // Ability of a node to perform SDO transfer by PDO BOOLEAN O O N N
+#define EPL_D_SDO_ViaUDPIP_BOOL // Ability of a CN to perform SDO transfer by UDP/IP BOOLEAN - M - -
+#define EPL_D_SYN_OptimizedSync_BOOL // Ability of node to perform optimized synchronisation BOOLEAN O O N N
+*/
+
+// Emergency error codes
+// ======================
+#define EPL_E_NO_ERROR                  0x0000
+// 0xFxxx manufacturer specific error codes
+#define EPL_E_NMT_NO_IDENT_RES          0xF001
+#define EPL_E_NMT_NO_STATUS_RES         0xF002
+
+// 0x816x HW errors
+#define EPL_E_DLL_BAD_PHYS_MODE         0x8161
+#define EPL_E_DLL_COLLISION             0x8162
+#define EPL_E_DLL_COLLISION_TH          0x8163
+#define EPL_E_DLL_CRC_TH                0x8164
+#define EPL_E_DLL_LOSS_OF_LINK          0x8165
+#define EPL_E_DLL_MAC_BUFFER            0x8166
+// 0x82xx Protocol errors
+#define EPL_E_DLL_ADDRESS_CONFLICT      0x8201
+#define EPL_E_DLL_MULTIPLE_MN           0x8202
+// 0x821x Frame size errors
+#define EPL_E_PDO_SHORT_RX              0x8210
+#define EPL_E_PDO_MAP_VERS              0x8211
+#define EPL_E_NMT_ASND_MTU_DIF          0x8212
+#define EPL_E_NMT_ASND_MTU_LIM          0x8213
+#define EPL_E_NMT_ASND_TX_LIM           0x8214
+// 0x823x Timing errors
+#define EPL_E_NMT_CYCLE_LEN             0x8231
+#define EPL_E_DLL_CYCLE_EXCEED          0x8232
+#define EPL_E_DLL_CYCLE_EXCEED_TH       0x8233
+#define EPL_E_NMT_IDLE_LIM              0x8234
+#define EPL_E_DLL_JITTER_TH             0x8235
+#define EPL_E_DLL_LATE_PRES_TH          0x8236
+#define EPL_E_NMT_PREQ_CN               0x8237
+#define EPL_E_NMT_PREQ_LIM              0x8238
+#define EPL_E_NMT_PRES_CN               0x8239
+#define EPL_E_NMT_PRES_RX_LIM           0x823A
+#define EPL_E_NMT_PRES_TX_LIM           0x823B
+// 0x824x Frame errors
+#define EPL_E_DLL_INVALID_FORMAT        0x8241
+#define EPL_E_DLL_LOSS_PREQ_TH          0x8242
+#define EPL_E_DLL_LOSS_PRES_TH          0x8243
+#define EPL_E_DLL_LOSS_SOA_TH           0x8244
+#define EPL_E_DLL_LOSS_SOC_TH           0x8245
+// 0x84xx BootUp Errors
+#define EPL_E_NMT_BA1                   0x8410  // other MN in MsNotActive active
+#define EPL_E_NMT_BA1_NO_MN_SUPPORT     0x8411  // MN is not supported
+#define EPL_E_NMT_BPO1                  0x8420  // mandatory CN was not found or failed in BootStep1
+#define EPL_E_NMT_BPO1_GET_IDENT        0x8421  // IdentRes was not received
+#define EPL_E_NMT_BPO1_DEVICE_TYPE      0x8422  // wrong device type
+#define EPL_E_NMT_BPO1_VENDOR_ID        0x8423  // wrong vendor ID
+#define EPL_E_NMT_BPO1_PRODUCT_CODE     0x8424  // wrong product code
+#define EPL_E_NMT_BPO1_REVISION_NO      0x8425  // wrong revision number
+#define EPL_E_NMT_BPO1_SERIAL_NO        0x8426  // wrong serial number
+#define EPL_E_NMT_BPO1_CF_VERIFY        0x8428  // verification of configuration failed
+#define EPL_E_NMT_BPO2                  0x8430  // mandatory CN failed in BootStep2
+#define EPL_E_NMT_BRO                   0x8440  // CheckCommunication failed for mandatory CN
+#define EPL_E_NMT_WRONG_STATE           0x8480  // mandatory CN has wrong NMT state
+
+// Defines for object 0x1F80 NMT_StartUp_U32
+// ==========================================
+#define EPL_NMTST_STARTALLNODES         0x00000002L // Bit 1
+#define EPL_NMTST_NO_AUTOSTART          0x00000004L // Bit 2
+#define EPL_NMTST_NO_STARTNODE          0x00000008L // Bit 3
+#define EPL_NMTST_RESETALL_MAND_CN      0x00000010L // Bit 4
+#define EPL_NMTST_STOPALL_MAND_CN       0x00000040L // Bit 6
+#define EPL_NMTST_NO_AUTOPREOP2         0x00000080L // Bit 7
+#define EPL_NMTST_NO_AUTOREADYTOOP      0x00000100L // Bit 8
+#define EPL_NMTST_EXT_CNIDENTCHECK      0x00000200L // Bit 9
+#define EPL_NMTST_SWVERSIONCHECK        0x00000400L // Bit 10
+#define EPL_NMTST_CONFCHECK             0x00000800L // Bit 11
+#define EPL_NMTST_NO_RETURN_PREOP1      0x00001000L // Bit 12
+#define EPL_NMTST_BASICETHERNET         0x00002000L // Bit 13
+
+// Defines for object 0x1F81 NMT_NodeAssignment_AU32
+// ==================================================
+#define EPL_NODEASSIGN_NODE_EXISTS      0x00000001L // Bit 0
+#define EPL_NODEASSIGN_NODE_IS_CN       0x00000002L // Bit 1
+#define EPL_NODEASSIGN_START_CN         0x00000004L // Bit 2
+#define EPL_NODEASSIGN_MANDATORY_CN     0x00000008L // Bit 3
+#define EPL_NODEASSIGN_KEEPALIVE        0x00000010L //currently not used in EPL V2 standard
+#define EPL_NODEASSIGN_SWVERSIONCHECK   0x00000020L // Bit 5
+#define EPL_NODEASSIGN_SWUPDATE         0x00000040L // Bit 6
+#define EPL_NODEASSIGN_ASYNCONLY_NODE   0x00000100L // Bit 8
+#define EPL_NODEASSIGN_MULTIPLEXED_CN   0x00000200L // Bit 9
+#define EPL_NODEASSIGN_RT1              0x00000400L // Bit 10
+#define EPL_NODEASSIGN_RT2              0x00000800L // Bit 11
+#define EPL_NODEASSIGN_MN_PRES          0x00001000L // Bit 12
+#define EPL_NODEASSIGN_VALID            0x80000000L // Bit 31
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPL_DEF_H_
diff --git a/drivers/staging/epl/EplDll.h b/drivers/staging/epl/EplDll.h
new file mode 100644 (file)
index 0000000..941ccef
--- /dev/null
@@ -0,0 +1,220 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for DLL module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDll.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/08 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DLL_H_
+#define _EPL_DLL_H_
+
+#include "EplInc.h"
+#include "EplFrame.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+#ifndef EPL_DLL_MAX_ASND_SERVICE_ID
+#define EPL_DLL_MAX_ASND_SERVICE_ID (EPL_C_DLL_MAX_ASND_SERVICE_IDS + 1)    // last is kEplDllAsndSdo == 5
+#endif
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef enum
+{
+    kEplDllAsndNotDefined       = 0x00,
+    kEplDllAsndIdentResponse    = 0x01,
+    kEplDllAsndStatusResponse   = 0x02,
+    kEplDllAsndNmtRequest       = 0x03,
+    kEplDllAsndNmtCommand       = 0x04,
+    kEplDllAsndSdo              = 0x05
+
+} tEplDllAsndServiceId;
+
+typedef enum
+{
+    kEplDllAsndFilterNone     = 0x00,
+    kEplDllAsndFilterLocal    = 0x01,  // receive only ASnd frames with local or broadcast node ID
+    kEplDllAsndFilterAny      = 0x02,  // receive any ASnd frame
+} tEplDllAsndFilter;
+
+typedef enum
+{
+    kEplDllReqServiceNo         = 0x00,
+    kEplDllReqServiceIdent      = 0x01,
+    kEplDllReqServiceStatus     = 0x02,
+    kEplDllReqServiceNmtRequest = 0x03,
+    kEplDllReqServiceUnspecified= 0xFF,
+
+} tEplDllReqServiceId;
+
+typedef enum
+{
+    kEplDllAsyncReqPrioNmt      = 0x07, // PRIO_NMT_REQUEST
+    kEplDllAsyncReqPrio6        = 0x06,
+    kEplDllAsyncReqPrio5        = 0x05,
+    kEplDllAsyncReqPrio4        = 0x04,
+    kEplDllAsyncReqPrioGeneric  = 0x03, // PRIO_GENERIC_REQUEST
+    kEplDllAsyncReqPrio2        = 0x02, // till WSP 0.1.3: PRIO_ABOVE_GENERIC
+    kEplDllAsyncReqPrio1        = 0x01, // till WSP 0.1.3: PRIO_BELOW_GENERIC
+    kEplDllAsyncReqPrio0        = 0x00, // till WSP 0.1.3: PRIO_GENERIC_REQUEST
+
+} tEplDllAsyncReqPriority;
+
+typedef struct
+{
+    unsigned int      m_uiFrameSize;
+    tEplFrame       * m_pFrame;
+    tEplNetTime       m_NetTime;
+
+} tEplFrameInfo;
+
+typedef struct
+{
+    unsigned int        m_uiSizeOfStruct;
+    BOOL                m_fAsyncOnly;   // do not need to register PRes-Frame
+    unsigned int        m_uiNodeId;     // local node ID
+
+    // 0x1F82: NMT_FeatureFlags_U32
+    DWORD               m_dwFeatureFlags;
+    // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
+    DWORD               m_dwCycleLen;         // required for error detection
+    // 0x1F98: NMT_CycleTiming_REC
+    // 0x1F98.1: IsochrTxMaxPayload_U16
+    unsigned int        m_uiIsochrTxMaxPayload; // const
+    // 0x1F98.2: IsochrRxMaxPayload_U16
+    unsigned int        m_uiIsochrRxMaxPayload; // const
+    // 0x1F98.3: PResMaxLatency_U32
+    DWORD               m_dwPresMaxLatency;   // const in [ns], only required for IdentRes
+    // 0x1F98.4: PReqActPayloadLimit_U16
+    unsigned int        m_uiPreqActPayloadLimit; // required for initialisation (+24 bytes)
+    // 0x1F98.5: PResActPayloadLimit_U16
+    unsigned int        m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+24 bytes)
+    // 0x1F98.6: ASndMaxLatency_U32
+    DWORD               m_dwAsndMaxLatency;   // const in [ns], only required for IdentRes
+    // 0x1F98.7: MultiplCycleCnt_U8
+    unsigned int        m_uiMultiplCycleCnt;  // required for error detection
+    // 0x1F98.8: AsyncMTU_U16
+    unsigned int        m_uiAsyncMtu;         // required to set up max frame size
+    // $$$ 0x1F98.9: Prescaler_U16
+    // $$$ Multiplexed Slot
+
+    // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
+    DWORD               m_dwLossOfFrameTolerance;
+
+    // 0x1F8A: NMT_MNCycleTiming_REC
+    // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
+    DWORD               m_dwWaitSocPreq;
+
+    // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
+    DWORD               m_dwAsyncSlotTimeout;
+
+} tEplDllConfigParam;
+
+typedef struct
+{
+    unsigned int      m_uiSizeOfStruct;
+    DWORD             m_dwDeviceType;              // NMT_DeviceType_U32
+    DWORD             m_dwVendorId;                // NMT_IdentityObject_REC.VendorId_U32
+    DWORD             m_dwProductCode;             // NMT_IdentityObject_REC.ProductCode_U32
+    DWORD             m_dwRevisionNumber;          // NMT_IdentityObject_REC.RevisionNo_U32
+    DWORD             m_dwSerialNumber;            // NMT_IdentityObject_REC.SerialNo_U32
+    QWORD             m_qwVendorSpecificExt1;
+    DWORD             m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+    DWORD             m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+    DWORD             m_dwApplicationSwDate;       // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+    DWORD             m_dwApplicationSwTime;       // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+    DWORD             m_dwIpAddress;
+    DWORD             m_dwSubnetMask;
+    DWORD             m_dwDefaultGateway;
+    BYTE              m_sHostname[32];
+    BYTE              m_abVendorSpecificExt2[48];
+
+} tEplDllIdentParam;
+
+typedef struct
+{
+    unsigned int                m_uiNodeId;
+    WORD                        m_wPreqPayloadLimit;    // object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
+    WORD                        m_wPresPayloadLimit;    // object 0x1F8D: NMT_PResPayloadLimitList_AU16
+    DWORD                       m_dwPresTimeout;        // object 0x1F92: NMT_MNCNPResTimeout_AU32
+
+} tEplDllNodeInfo;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+
+#endif  // #ifndef _EPL_DLL_H_
+
+
diff --git a/drivers/staging/epl/EplDllCal.h b/drivers/staging/epl/EplDllCal.h
new file mode 100644 (file)
index 0000000..d8bf731
--- /dev/null
@@ -0,0 +1,131 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for DLL Communication Abstraction Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDllCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/20 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DLLCAL_H_
+#define _EPL_DLLCAL_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+/*#ifndef EPL_DLLCAL_BUFFER_ID_RX
+#define EPL_DLLCAL_BUFFER_ID_RX    "EplSblDllCalRx"
+#endif
+
+#ifndef EPL_DLLCAL_BUFFER_SIZE_RX
+#define EPL_DLLCAL_BUFFER_SIZE_RX  32767
+#endif
+*/
+#ifndef EPL_DLLCAL_BUFFER_ID_TX_NMT
+#define EPL_DLLCAL_BUFFER_ID_TX_NMT     "EplSblDllCalTxNmt"
+#endif
+
+#ifndef EPL_DLLCAL_BUFFER_SIZE_TX_NMT
+#define EPL_DLLCAL_BUFFER_SIZE_TX_NMT   32767
+#endif
+
+#ifndef EPL_DLLCAL_BUFFER_ID_TX_GEN
+#define EPL_DLLCAL_BUFFER_ID_TX_GEN     "EplSblDllCalTxGen"
+#endif
+
+#ifndef EPL_DLLCAL_BUFFER_SIZE_TX_GEN
+#define EPL_DLLCAL_BUFFER_SIZE_TX_GEN   32767
+#endif
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplDllAsndServiceId    m_ServiceId;
+    tEplDllAsndFilter       m_Filter;
+
+} tEplDllCalAsndServiceIdFilter;
+
+typedef struct
+{
+    tEplDllReqServiceId     m_Service;
+    unsigned int            m_uiNodeId;
+    BYTE                    m_bSoaFlag1;
+
+} tEplDllCalIssueRequest;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+
+#endif  // #ifndef _EPL_DLLKCAL_H_
+
+
diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c
new file mode 100644 (file)
index 0000000..dee0d3d
--- /dev/null
@@ -0,0 +1,3783 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for kernel DLL module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDllk.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.21 $  $Date: 2008/11/13 17:13:09 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/12 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "kernel/EplDllk.h"
+#include "kernel/EplDllkCal.h"
+#include "kernel/EplEventk.h"
+#include "kernel/EplNmtk.h"
+#include "edrv.h"
+#include "Benchmark.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+#include "kernel/EplPdok.h"
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
+#include "kernel/VirtualEthernet.h"
+#endif
+
+//#if EPL_TIMER_USE_HIGHRES != FALSE
+#include "kernel/EplTimerHighResk.h"
+//#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) == 0)
+#error "EPL module DLLK needs EPL module NMTK!"
+#endif
+
+#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) && (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
+#error "EPL module DLLK: select only one of EPL_DLL_PRES_READY_AFTER_SOA and EPL_DLL_PRES_READY_AFTER_SOC."
+#endif
+
+#if ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) \
+    && (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
+#error "EPL module DLLK: currently, EPL_DLL_PRES_READY_AFTER_* is not supported if EPL_MODULE_NMT_MN is enabled."
+#endif
+
+#if (EDRV_FAST_TXFRAMES == FALSE) && \
+    ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE))
+#error "EPL module DLLK: EPL_DLL_PRES_READY_AFTER_* is enabled, but not EDRV_FAST_TXFRAMES."
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+#define EPL_DLLK_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
+    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkDllk << 28) | (Event_p << 24) \
+                             | (uiNodeId_p << 16) | wErrorCode_p)
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplDllk                                             */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// defines for indexes of tEplDllInstance.m_pTxFrameInfo
+#define EPL_DLLK_TXFRAME_IDENTRES   0   // IdentResponse on CN / MN
+#define EPL_DLLK_TXFRAME_STATUSRES  1   // StatusResponse on CN / MN
+#define EPL_DLLK_TXFRAME_NMTREQ     2   // NMT Request from FIFO on CN / MN
+#define EPL_DLLK_TXFRAME_NONEPL     3   // non-EPL frame from FIFO on CN / MN
+#define EPL_DLLK_TXFRAME_PRES       4   // PRes on CN / MN
+#define EPL_DLLK_TXFRAME_SOC        5   // SoC on MN
+#define EPL_DLLK_TXFRAME_SOA        6   // SoA on MN
+#define EPL_DLLK_TXFRAME_PREQ       7   // PReq on MN
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+#define EPL_DLLK_TXFRAME_COUNT      (7 + EPL_D_NMT_MaxCNNumber_U8 + 2)   // on MN: 7 + MaxPReq of regular CNs + 1 Diag + 1 Router
+#else
+#define EPL_DLLK_TXFRAME_COUNT      5   // on CN: 5
+#endif
+
+#define EPL_DLLK_BUFLEN_EMPTY       0   // buffer is empty
+#define EPL_DLLK_BUFLEN_FILLING     1   // just the buffer is being filled
+#define EPL_DLLK_BUFLEN_MIN         60  // minimum ethernet frame length
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef enum
+{
+    kEplDllGsInit           = 0x00, // MN/CN: initialisation (< PreOp2)
+    kEplDllCsWaitPreq       = 0x01, // CN: wait for PReq frame
+    kEplDllCsWaitSoc        = 0x02, // CN: wait for SoC frame
+    kEplDllCsWaitSoa        = 0x03, // CN: wait for SoA frame
+    kEplDllMsNonCyclic      = 0x04, // MN: reduced EPL cycle (PreOp1)
+    kEplDllMsWaitSocTrig    = 0x05, // MN: wait for SoC trigger (cycle timer)
+    kEplDllMsWaitPreqTrig   = 0x06, // MN: wait for (first) PReq trigger (WaitSoCPReq_U32)
+    kEplDllMsWaitPres       = 0x07, // MN: wait for PRes frame from CN
+    kEplDllMsWaitSoaTrig    = 0x08, // MN: wait for SoA trigger (PRes transmitted)
+    kEplDllMsWaitAsndTrig   = 0x09, // MN: wait for ASnd trigger (SoA transmitted)
+    kEplDllMsWaitAsnd       = 0x0A, // MN: wait for ASnd frame if SoA contained invitation
+
+} tEplDllState;
+
+typedef struct
+{
+    BYTE                m_be_abSrcMac[6];
+    tEdrvTxBuffer*      m_pTxBuffer;        // Buffers for Tx-Frames
+    unsigned int        m_uiMaxTxFrames;
+    BYTE                m_bFlag1;           // Flag 1 with EN, EC for PRes, StatusRes
+    BYTE                m_bMnFlag1;         // Flag 1 with EA, ER from PReq, SoA of MN
+    BYTE                m_bFlag2;           // Flag 2 with PR and RS for PRes, StatusRes, IdentRes
+    tEplDllConfigParam  m_DllConfigParam;
+    tEplDllIdentParam   m_DllIdentParam;
+    tEplDllState        m_DllState;
+    tEplDllkCbAsync     m_pfnCbAsync;
+    tEplDllAsndFilter   m_aAsndFilter[EPL_DLL_MAX_ASND_SERVICE_ID];
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    tEplDllkNodeInfo*   m_pFirstNodeInfo;
+    tEplDllkNodeInfo*   m_pCurNodeInfo;
+    tEplDllkNodeInfo    m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
+    tEplDllReqServiceId m_LastReqServiceId;
+    unsigned int        m_uiLastTargetNodeId;
+#endif
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    tEplTimerHdl        m_TimerHdlCycle;    // used for EPL cycle monitoring on CN and generation on MN
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    tEplTimerHdl        m_TimerHdlResponse; // used for CN response monitoring
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+#endif
+
+    unsigned int        m_uiCycleCount;     // cycle counter (needed for multiplexed cycle support)
+    unsigned long long  m_ullFrameTimeout;  // frame timeout (cycle length + loss of frame tolerance)
+
+} tEplDllkInstance;
+
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+// if no dynamic memory allocation shall be used
+// define structures statically
+static tEplDllkInstance     EplDllkInstance_g;
+
+static tEdrvTxBuffer        aEplDllkTxBuffer_l[EPL_DLLK_TXFRAME_COUNT];
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+// change DLL state on event
+static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p, tEplNmtState NmtState_p);
+
+// called from EdrvInterruptHandler()
+static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p);
+
+// called from EdrvInterruptHandler()
+static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p);
+
+// check frame and set missing information
+static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p, unsigned int uiFrameSize_p);
+
+// called by high resolution timer module to monitor EPL cycle as CN
+#if EPL_TIMER_USE_HIGHRES != FALSE
+static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg* pEventArg_p);
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+// MN: returns internal node info structure
+static tEplDllkNodeInfo* EplDllkGetNodeInfo(unsigned int uiNodeId_p);
+
+// transmit SoA
+static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
+                                   tEplDllState* pDllStateProposed_p,
+                                   BOOL fEnableInvitation_p);
+
+static tEplKernel EplDllkMnSendSoc(void);
+
+static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
+                                    tEplDllState* pDllStateProposed_p);
+
+static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId ReqServiceId_p, unsigned int uiNodeId_p);
+
+static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg* pEventArg_p);
+
+static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg* pEventArg_p);
+
+#endif
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkAddInstance()
+//
+// Description: add and initialize new instance of EPL stack
+//
+// Parameters:  pInitParam_p            = initialisation parameters like MAC address
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiIndex;
+tEdrvInitParam  EdrvInitParam;
+
+    // reset instance structure
+    EPL_MEMSET(&EplDllkInstance_g, 0, sizeof (EplDllkInstance_g));
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    Ret = EplTimerHighReskInit();
+    if (Ret != kEplSuccessful)
+    {   // error occured while initializing high resolution timer module
+        goto Exit;
+    }
+#endif
+
+    // if dynamic memory allocation available
+    // allocate instance structure
+    // allocate TPDO and RPDO table with default size
+
+    // initialize and link pointers in instance structure to frame tables
+    EplDllkInstance_g.m_pTxBuffer = aEplDllkTxBuffer_l;
+    EplDllkInstance_g.m_uiMaxTxFrames = sizeof (aEplDllkTxBuffer_l) / sizeof (tEdrvTxBuffer);
+
+    // initialize state
+    EplDllkInstance_g.m_DllState = kEplDllGsInit;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // set up node info structure
+    for (uiIndex = 0; uiIndex < tabentries (EplDllkInstance_g.m_aNodeInfo); uiIndex++)
+    {
+        EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
+        EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit = 0xFFFF;
+    }
+#endif
+
+    // initialize Edrv
+    EPL_MEMCPY(EdrvInitParam.m_abMyMacAddr, pInitParam_p->m_be_abSrcMac, 6);
+    EdrvInitParam.m_pfnRxHandler = EplDllkCbFrameReceived;
+    EdrvInitParam.m_pfnTxHandler = EplDllkCbFrameTransmitted;
+    Ret = EdrvInit(&EdrvInitParam);
+    if (Ret != kEplSuccessful)
+    {   // error occured while initializing ethernet driver
+        goto Exit;
+    }
+
+    // copy local MAC address from Ethernet driver back to local instance structure
+    // because Ethernet driver may have read it from controller EEPROM
+    EPL_MEMCPY(EplDllkInstance_g.m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, 6);
+    EPL_MEMCPY(pInitParam_p->m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, 6);
+
+    // initialize TxBuffer array
+    for (uiIndex = 0; uiIndex < EplDllkInstance_g.m_uiMaxTxFrames; uiIndex++)
+    {
+        EplDllkInstance_g.m_pTxBuffer[uiIndex].m_pbBuffer = NULL;
+    }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
+    Ret = VEthAddInstance(pInitParam_p);
+#endif
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkDelInstance()
+//
+// Description: deletes an instance of EPL stack
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkDelInstance(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    // reset state
+    EplDllkInstance_g.m_DllState = kEplDllGsInit;
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    Ret = EplTimerHighReskDelInstance();
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
+    Ret = VEthDelInstance();
+#endif
+
+    Ret = EdrvShutdown();
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCreateTxFrame
+//
+// Description: creates the buffer for a Tx frame and registers it to the
+//              ethernet driver
+//
+// Parameters:  puiHandle_p             = OUT: handle to frame buffer
+//              ppFrame_p               = OUT: pointer to pointer of EPL frame
+//              puiFrameSize_p          = IN/OUT: pointer to size of frame
+//                                        returned size is always equal or larger than
+//                                        requested size, if that is not possible
+//                                        an error will be returned
+//              MsgType_p               = EPL message type
+//              ServiceId_p             = Service ID in case of ASnd frame, otherwise
+//                                        kEplDllAsndNotDefined
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCreateTxFrame (unsigned int * puiHandle_p,
+                                 tEplFrame ** ppFrame_p,
+                                 unsigned int * puiFrameSize_p,
+                                 tEplMsgType MsgType_p,
+                                 tEplDllAsndServiceId ServiceId_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplFrame      *pTxFrame;
+unsigned int    uiHandle = EplDllkInstance_g.m_uiMaxTxFrames;
+tEdrvTxBuffer  *pTxBuffer = NULL;
+
+    if (MsgType_p == kEplMsgTypeAsnd)
+    {
+        // search for fixed Tx buffers
+        if (ServiceId_p == kEplDllAsndIdentResponse)
+        {
+            uiHandle = EPL_DLLK_TXFRAME_IDENTRES;
+        }
+        else if (ServiceId_p == kEplDllAsndStatusResponse)
+        {
+            uiHandle = EPL_DLLK_TXFRAME_STATUSRES;
+        }
+        else if ((ServiceId_p == kEplDllAsndNmtRequest) || (ServiceId_p == kEplDllAsndNmtCommand))
+        {
+            uiHandle = EPL_DLLK_TXFRAME_NMTREQ;
+        }
+
+        if (uiHandle >= EplDllkInstance_g.m_uiMaxTxFrames)
+        {   // look for free entry
+            uiHandle = EPL_DLLK_TXFRAME_PREQ;
+            pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
+            for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames; uiHandle++, pTxBuffer++)
+            {
+                if (pTxBuffer->m_pbBuffer == NULL)
+                {   // free entry found
+                    break;
+                }
+            }
+        }
+    }
+    else if (MsgType_p == kEplMsgTypeNonEpl)
+    {
+        uiHandle = EPL_DLLK_TXFRAME_NONEPL;
+    }
+    else if (MsgType_p == kEplMsgTypePres)
+    {
+        uiHandle = EPL_DLLK_TXFRAME_PRES;
+    }
+    else if (MsgType_p == kEplMsgTypeSoc)
+    {
+        uiHandle = EPL_DLLK_TXFRAME_SOC;
+    }
+    else if (MsgType_p == kEplMsgTypeSoa)
+    {
+        uiHandle = EPL_DLLK_TXFRAME_SOA;
+    }
+    else
+    {   // look for free entry
+        uiHandle = EPL_DLLK_TXFRAME_PREQ;
+        pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
+        for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames; uiHandle++, pTxBuffer++)
+        {
+            if (pTxBuffer->m_pbBuffer == NULL)
+            {   // free entry found
+                break;
+            }
+        }
+        if (pTxBuffer->m_pbBuffer != NULL)
+        {
+            Ret = kEplEdrvNoFreeBufEntry;
+            goto Exit;
+        }
+    }
+
+    // test if requested entry is free
+    pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
+    if (pTxBuffer->m_pbBuffer != NULL)
+    {   // entry is not free
+        Ret = kEplEdrvNoFreeBufEntry;
+        goto Exit;
+    }
+
+    // setup Tx buffer
+    pTxBuffer->m_EplMsgType = MsgType_p;
+    pTxBuffer->m_uiMaxBufferLen = *puiFrameSize_p;
+
+    Ret = EdrvAllocTxMsgBuffer(pTxBuffer);
+    if (Ret != kEplSuccessful)
+    {   // error occured while registering Tx frame
+        goto Exit;
+    }
+
+    // because buffer size may be larger than requested
+    // memorize real length of frame
+    pTxBuffer->m_uiTxMsgLen = *puiFrameSize_p;
+
+    // fill whole frame with 0
+    EPL_MEMSET(pTxBuffer->m_pbBuffer, 0, pTxBuffer->m_uiMaxBufferLen);
+
+    pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+
+    if (MsgType_p != kEplMsgTypeNonEpl)
+    {   // fill out Frame only if it is an EPL frame
+        // ethertype
+        AmiSetWordToBe(&pTxFrame->m_be_wEtherType, EPL_C_DLL_ETHERTYPE_EPL);
+        // source node ID
+        AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId, (BYTE) EplDllkInstance_g.m_DllConfigParam.m_uiNodeId);
+        // source MAC address
+        EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0], &EplDllkInstance_g.m_be_abSrcMac[0], 6);
+        switch (MsgType_p)
+        {
+            case kEplMsgTypeAsnd:
+                // destination MAC address
+                AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], EPL_C_DLL_MULTICAST_ASND);
+                // destination node ID
+                switch (ServiceId_p)
+                {
+                    case kEplDllAsndIdentResponse:
+                    case kEplDllAsndStatusResponse:
+                    {   // IdentResponses and StatusResponses are Broadcast
+                        AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, (BYTE) EPL_C_ADR_BROADCAST);
+                        break;
+                    }
+
+                    default:
+                        break;
+                }
+                // ASnd Service ID
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_le_bServiceId, ServiceId_p);
+                break;
+
+            case kEplMsgTypeSoc:
+                // destination MAC address
+                AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], EPL_C_DLL_MULTICAST_SOC);
+                // destination node ID
+                AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, (BYTE) EPL_C_ADR_BROADCAST);
+                // reset Flags
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (BYTE) 0);
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (BYTE) 0);
+                break;
+
+            case kEplMsgTypeSoa:
+                // destination MAC address
+                AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], EPL_C_DLL_MULTICAST_SOA);
+                // destination node ID
+                AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, (BYTE) EPL_C_ADR_BROADCAST);
+                // reset Flags
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (BYTE) 0);
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (BYTE) 0);
+                // EPL profile version
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion, (BYTE) EPL_SPEC_VERSION);
+                break;
+
+            case kEplMsgTypePres:
+                // destination MAC address
+                AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0], EPL_C_DLL_MULTICAST_PRES);
+                // destination node ID
+                AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId, (BYTE) EPL_C_ADR_BROADCAST);
+                // reset Flags
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (BYTE) 0);
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (BYTE) 0);
+                // PDO size
+                //AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0);
+                break;
+
+            case kEplMsgTypePreq:
+                // reset Flags
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (BYTE) 0);
+                //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (BYTE) 0);
+                // PDO size
+                //AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0);
+                break;
+
+            default:
+                break;
+        }
+        // EPL message type
+        AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (BYTE) MsgType_p);
+    }
+
+    *ppFrame_p = pTxFrame;
+    *puiFrameSize_p = pTxBuffer->m_uiMaxBufferLen;
+    *puiHandle_p = uiHandle;
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkDeleteTxFrame
+//
+// Description: deletes the buffer for a Tx frame and frees it in the
+//              ethernet driver
+//
+// Parameters:  uiHandle_p              = IN: handle to frame buffer
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkDeleteTxFrame (unsigned int uiHandle_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEdrvTxBuffer    *pTxBuffer = NULL;
+
+    if (uiHandle_p >= EplDllkInstance_g.m_uiMaxTxFrames)
+    {   // handle is not valid
+        Ret = kEplDllIllegalHdl;
+        goto Exit;
+    }
+
+    pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle_p];
+
+    // mark buffer as free so that frame will not be send in future anymore
+    // $$$ d.k. What's up with running transmissions?
+    pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+    pTxBuffer->m_pbBuffer = NULL;
+
+    // delete Tx buffer
+    Ret = EdrvReleaseTxMsgBuffer(pTxBuffer);
+    if (Ret != kEplSuccessful)
+    {   // error occured while releasing Tx frame
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkProcess
+//
+// Description: process the passed event
+//
+// Parameters:  pEvent_p                = event to be processed
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplFrame      *pTxFrame;
+tEdrvTxBuffer  *pTxBuffer;
+unsigned int    uiHandle;
+unsigned int    uiFrameSize;
+BYTE            abMulticastMac[6];
+tEplDllAsyncReqPriority AsyncReqPriority;
+unsigned int    uiFrameCount;
+tEplNmtState    NmtState;
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+tEplFrameInfo   FrameInfo;
+#endif
+
+
+    switch (pEvent_p->m_EventType)
+    {
+        case kEplEventTypeDllkCreate:
+        {
+            // $$$ reset ethernet driver
+
+            NmtState = *((tEplNmtState*)pEvent_p->m_pArg);
+
+            // initialize flags for PRes and StatusRes
+            EplDllkInstance_g.m_bFlag1 = EPL_FRAME_FLAG1_EC;
+            EplDllkInstance_g.m_bMnFlag1 = 0;
+            EplDllkInstance_g.m_bFlag2 = 0;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            // initialize linked node list
+            EplDllkInstance_g.m_pFirstNodeInfo = NULL;
+#endif
+
+            // register TxFrames in Edrv
+
+            // IdentResponse
+            uiFrameSize = EPL_C_DLL_MINSIZE_IDENTRES;
+            Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypeAsnd, kEplDllAsndIdentResponse);
+            if (Ret != kEplSuccessful)
+            {   // error occured while registering Tx frame
+                goto Exit;
+            }
+
+            // EPL profile version
+            AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_bEplProfileVersion,
+                (BYTE) EPL_SPEC_VERSION);
+            // FeatureFlags
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwFeatureFlags,
+                EplDllkInstance_g.m_DllConfigParam.m_dwFeatureFlags);
+            // MTU
+            AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_wMtu,
+                (WORD) EplDllkInstance_g.m_DllConfigParam.m_uiAsyncMtu);
+            // PollInSize
+            AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_wPollInSize,
+                (WORD)EplDllkInstance_g.m_DllConfigParam.m_uiPreqActPayloadLimit);
+            // PollOutSize
+            AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_wPollOutSize,
+                (WORD)EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit);
+            // ResponseTime / PresMaxLatency
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwResponseTime,
+                EplDllkInstance_g.m_DllConfigParam.m_dwPresMaxLatency);
+            // DeviceType
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwDeviceType,
+                EplDllkInstance_g.m_DllIdentParam.m_dwDeviceType);
+            // VendorId
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwVendorId,
+                EplDllkInstance_g.m_DllIdentParam.m_dwVendorId);
+            // ProductCode
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwProductCode,
+                EplDllkInstance_g.m_DllIdentParam.m_dwProductCode);
+            // RevisionNumber
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwRevisionNumber,
+                EplDllkInstance_g.m_DllIdentParam.m_dwRevisionNumber);
+            // SerialNumber
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwSerialNumber,
+                EplDllkInstance_g.m_DllIdentParam.m_dwSerialNumber);
+            // VendorSpecificExt1
+            AmiSetQword64ToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_qwVendorSpecificExt1,
+                EplDllkInstance_g.m_DllIdentParam.m_qwVendorSpecificExt1);
+            // VerifyConfigurationDate
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwVerifyConfigurationDate,
+                EplDllkInstance_g.m_DllIdentParam.m_dwVerifyConfigurationDate);
+            // VerifyConfigurationTime
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwVerifyConfigurationTime,
+                EplDllkInstance_g.m_DllIdentParam.m_dwVerifyConfigurationTime);
+            // ApplicationSwDate
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwApplicationSwDate,
+                EplDllkInstance_g.m_DllIdentParam.m_dwApplicationSwDate);
+            // ApplicationSwTime
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwApplicationSwTime,
+                EplDllkInstance_g.m_DllIdentParam.m_dwApplicationSwTime);
+            // IPAddress
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwIpAddress,
+                EplDllkInstance_g.m_DllIdentParam.m_dwIpAddress);
+            // SubnetMask
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwSubnetMask,
+                EplDllkInstance_g.m_DllIdentParam.m_dwSubnetMask);
+            // DefaultGateway
+            AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_dwDefaultGateway,
+                EplDllkInstance_g.m_DllIdentParam.m_dwDefaultGateway);
+            // HostName
+            EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_sHostname[0],
+                &EplDllkInstance_g.m_DllIdentParam.m_sHostname[0],
+                sizeof (EplDllkInstance_g.m_DllIdentParam.m_sHostname));
+            // VendorSpecificExt2
+            EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_abVendorSpecificExt2[0],
+                &EplDllkInstance_g.m_DllIdentParam.m_abVendorSpecificExt2[0],
+                sizeof (EplDllkInstance_g.m_DllIdentParam.m_abVendorSpecificExt2));
+
+            // StatusResponse
+            uiFrameSize = EPL_C_DLL_MINSIZE_STATUSRES;
+            Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypeAsnd, kEplDllAsndStatusResponse);
+            if (Ret != kEplSuccessful)
+            {   // error occured while registering Tx frame
+                goto Exit;
+            }
+
+            // PRes $$$ maybe move this to PDO module
+            if ((EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly == FALSE)
+                && (EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit >= 36))
+            {   // it is not configured as async-only CN,
+                // so take part in isochronous phase and register PRes frame
+                uiFrameSize = EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit + 24;
+                Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypePres, kEplDllAsndNotDefined);
+                if (Ret != kEplSuccessful)
+                {   // error occured while registering Tx frame
+                    goto Exit;
+                }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+                // initially encode TPDO -> inform PDO module
+                FrameInfo.m_pFrame = pTxFrame;
+                FrameInfo.m_uiFrameSize = uiFrameSize;
+                Ret = EplPdokCbPdoTransmitted(&FrameInfo);
+#endif
+                // reset cycle counter
+                EplDllkInstance_g.m_uiCycleCount = 0;
+            }
+            else
+            {   // it is an async-only CN
+                // fool EplDllkChangeState() to think that PRes was not expected
+                EplDllkInstance_g.m_uiCycleCount = 1;
+            }
+
+            // NMT request
+            uiFrameSize = EPL_C_IP_MAX_MTU;
+            Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypeAsnd, kEplDllAsndNmtRequest);
+            if (Ret != kEplSuccessful)
+            {   // error occured while registering Tx frame
+                goto Exit;
+            }
+            // mark Tx buffer as empty
+            EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+
+            // non-EPL frame
+            uiFrameSize = EPL_C_IP_MAX_MTU;
+            Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypeNonEpl, kEplDllAsndNotDefined);
+            if (Ret != kEplSuccessful)
+            {   // error occured while registering Tx frame
+                goto Exit;
+            }
+            // mark Tx buffer as empty
+            EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+
+            // register multicast MACs in ethernet driver
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_SOC);
+            Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_SOA);
+            Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_PRES);
+            Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_ASND);
+            Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            if (NmtState >= kEplNmtMsNotActive)
+            {   // local node is MN
+            unsigned int    uiIndex;
+
+                // SoC
+                uiFrameSize = EPL_C_DLL_MINSIZE_SOC;
+                Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypeSoc, kEplDllAsndNotDefined);
+                if (Ret != kEplSuccessful)
+                {   // error occured while registering Tx frame
+                    goto Exit;
+                }
+
+                // SoA
+                uiFrameSize = EPL_C_DLL_MINSIZE_SOA;
+                Ret = EplDllkCreateTxFrame(&uiHandle, &pTxFrame, &uiFrameSize, kEplMsgTypeSoa, kEplDllAsndNotDefined);
+                if (Ret != kEplSuccessful)
+                {   // error occured while registering Tx frame
+                    goto Exit;
+                }
+
+                for (uiIndex = 0; uiIndex < tabentries (EplDllkInstance_g.m_aNodeInfo); uiIndex++)
+                {
+//                    EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
+                    EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit = (WORD) EplDllkInstance_g.m_DllConfigParam.m_uiIsochrRxMaxPayload;
+                }
+
+                // calculate cycle length
+                EplDllkInstance_g.m_ullFrameTimeout = 1000LL
+                    * ((unsigned long long) EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen);
+            }
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+            Ret = EplDllkCalAsyncClearBuffer();
+
+            break;
+        }
+
+        case kEplEventTypeDllkDestroy:
+        {
+            // destroy all data structures
+
+            NmtState = *((tEplNmtState*)pEvent_p->m_pArg);
+
+            // delete Tx frames
+            Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_IDENTRES);
+            if (Ret != kEplSuccessful)
+            {   // error occured while deregistering Tx frame
+                goto Exit;
+            }
+
+            Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_STATUSRES);
+            if (Ret != kEplSuccessful)
+            {   // error occured while deregistering Tx frame
+                goto Exit;
+            }
+
+            Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_PRES);
+            if (Ret != kEplSuccessful)
+            {   // error occured while deregistering Tx frame
+                goto Exit;
+            }
+
+            Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NMTREQ);
+            if (Ret != kEplSuccessful)
+            {   // error occured while deregistering Tx frame
+                goto Exit;
+            }
+
+            Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NONEPL);
+            if (Ret != kEplSuccessful)
+            {   // error occured while deregistering Tx frame
+                goto Exit;
+            }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            if (NmtState >= kEplNmtMsNotActive)
+            {   // local node was MN
+            unsigned int    uiIndex;
+
+                Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOC);
+                if (Ret != kEplSuccessful)
+                {   // error occured while deregistering Tx frame
+                    goto Exit;
+                }
+
+                Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOA);
+                if (Ret != kEplSuccessful)
+                {   // error occured while deregistering Tx frame
+                    goto Exit;
+                }
+
+                for (uiIndex = 0; uiIndex < tabentries (EplDllkInstance_g.m_aNodeInfo); uiIndex++)
+                {
+                    if (EplDllkInstance_g.m_aNodeInfo[uiIndex].m_pPreqTxBuffer != NULL)
+                    {
+                        uiHandle = EplDllkInstance_g.m_aNodeInfo[uiIndex].m_pPreqTxBuffer - EplDllkInstance_g.m_pTxBuffer;
+                        EplDllkInstance_g.m_aNodeInfo[uiIndex].m_pPreqTxBuffer = NULL;
+                        Ret = EplDllkDeleteTxFrame(uiHandle);
+                        if (Ret != kEplSuccessful)
+                        {   // error occured while deregistering Tx frame
+                            goto Exit;
+                        }
+
+                    }
+                    EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit = 0xFFFF;
+                }
+            }
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+            // deregister multicast MACs in ethernet driver
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_SOC);
+            Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_SOA);
+            Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_PRES);
+            Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
+            AmiSetQword48ToBe(&abMulticastMac[0], EPL_C_DLL_MULTICAST_ASND);
+            Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
+
+            // delete timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+            Ret = EplTimerHighReskDeleteTimer(&EplDllkInstance_g.m_TimerHdlCycle);
+#endif
+
+            break;
+        }
+
+        case kEplEventTypeDllkFillTx:
+        {
+            // fill TxBuffer of specified priority with new frame if empty
+
+            pTxFrame = NULL;
+            AsyncReqPriority = *((tEplDllAsyncReqPriority *) pEvent_p->m_pArg);
+            switch (AsyncReqPriority)
+            {
+                case kEplDllAsyncReqPrioNmt:    // NMT request priority
+                {
+                    pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ];
+                    if (pTxBuffer->m_pbBuffer != NULL)
+                    {   // NmtRequest does exist
+                        // check if frame is empty and not being filled
+                        if (pTxBuffer->m_uiTxMsgLen == EPL_DLLK_BUFLEN_EMPTY)
+                        {
+                            // mark Tx buffer as filling is in process
+                            pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_FILLING;
+                            // set max buffer size as input parameter
+                            uiFrameSize = pTxBuffer->m_uiMaxBufferLen;
+                            // copy frame from shared loop buffer to Tx buffer
+                            Ret = EplDllkCalAsyncGetTxFrame(
+                                pTxBuffer->m_pbBuffer, &uiFrameSize, AsyncReqPriority);
+                            if (Ret == kEplSuccessful)
+                            {
+                                pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+                                Ret = EplDllkCheckFrame(pTxFrame, uiFrameSize);
+
+                                // set buffer valid
+                                pTxBuffer->m_uiTxMsgLen = uiFrameSize;
+                            }
+                            else if (Ret == kEplDllAsyncTxBufferEmpty)
+                            {   // empty Tx buffer is not a real problem
+                                // so just ignore it
+                                Ret = kEplSuccessful;
+                                // mark Tx buffer as empty
+                                pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+                            }
+                        }
+                    }
+                    break;
+                }
+
+                default:    // generic priority
+                {
+                    pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL];
+                    if (pTxBuffer->m_pbBuffer != NULL)
+                    {   // non-EPL frame does exist
+                        // check if frame is empty and not being filled
+                        if (pTxBuffer->m_uiTxMsgLen == EPL_DLLK_BUFLEN_EMPTY)
+                        {
+                            // mark Tx buffer as filling is in process
+                            pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_FILLING;
+                            // set max buffer size as input parameter
+                            uiFrameSize = pTxBuffer->m_uiMaxBufferLen;
+                            // copy frame from shared loop buffer to Tx buffer
+                            Ret = EplDllkCalAsyncGetTxFrame(
+                                pTxBuffer->m_pbBuffer, &uiFrameSize, AsyncReqPriority);
+                            if (Ret == kEplSuccessful)
+                            {
+                                pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+                                Ret = EplDllkCheckFrame(pTxFrame, uiFrameSize);
+
+                                // set buffer valid
+                                pTxBuffer->m_uiTxMsgLen = uiFrameSize;
+                            }
+                            else if (Ret == kEplDllAsyncTxBufferEmpty)
+                            {   // empty Tx buffer is not a real problem
+                                // so just ignore it
+                                Ret = kEplSuccessful;
+                                // mark Tx buffer as empty
+                                pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+
+            NmtState = EplNmtkGetNmtState();
+
+            if ((NmtState == kEplNmtCsBasicEthernet) || (NmtState == kEplNmtMsBasicEthernet))
+            {   // send frame immediately
+                if (pTxFrame != NULL)
+                {   // frame is present
+                    // padding is done by Edrv or ethernet controller
+                    Ret = EdrvSendTxMsg(pTxBuffer);
+                }
+                else
+                {   // no frame moved to TxBuffer
+                    // check if TxBuffers contain unsent frames
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY)
+                    {   // NMT request Tx buffer contains a frame
+                        Ret = EdrvSendTxMsg(
+                                &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ]);
+                    }
+                    else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY)
+                    {   // non-EPL Tx buffer contains a frame
+                        Ret = EdrvSendTxMsg(
+                                &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL]);
+                    }
+                    if (Ret == kEplInvalidOperation)
+                    {   // ignore error if caused by already active transmission
+                        Ret = kEplSuccessful;
+                    }
+                }
+                // reset PRes flag 2
+                EplDllkInstance_g.m_bFlag2 = 0;
+            }
+            else
+            {
+                // update Flag 2 (PR, RS)
+                Ret = EplDllkCalAsyncGetTxCount(&AsyncReqPriority, &uiFrameCount);
+                if (AsyncReqPriority == kEplDllAsyncReqPrioNmt)
+                {   // non-empty FIFO with hightest priority is for NMT requests
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY)
+                    {   // NMT request Tx buffer contains a frame
+                        // add one more frame
+                        uiFrameCount++;
+                    }
+                }
+                else
+                {   // non-empty FIFO with highest priority is for generic frames
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY)
+                    {   // NMT request Tx buffer contains a frame
+                        // use NMT request FIFO, because of higher priority
+                        uiFrameCount = 1;
+                        AsyncReqPriority = kEplDllAsyncReqPrioNmt;
+                    }
+                    else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY)
+                    {   // non-EPL Tx buffer contains a frame
+                        // use NMT request FIFO, because of higher priority
+                        // add one more frame
+                        uiFrameCount++;
+                    }
+                }
+
+                if (uiFrameCount > 7)
+                {   // limit frame request to send counter to 7
+                    uiFrameCount = 7;
+                }
+                if (uiFrameCount > 0)
+                {
+                    EplDllkInstance_g.m_bFlag2 =
+                        (BYTE) (((AsyncReqPriority << EPL_FRAME_FLAG2_PR_SHIFT) & EPL_FRAME_FLAG2_PR)
+                        | (uiFrameCount & EPL_FRAME_FLAG2_RS));
+                }
+                else
+                {
+                    EplDllkInstance_g.m_bFlag2 = 0;
+                }
+            }
+
+            break;
+        }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        case kEplEventTypeDllkStartReducedCycle:
+        {
+            // start the reduced cycle by programming the cycle timer
+            // it is issued by NMT MN module, when PreOp1 is entered
+
+            // clear the asynchronous queues
+            Ret = EplDllkCalAsyncClearQueues();
+
+            // reset cycle counter (everytime a SoA is triggerd in PreOp1 the counter is incremented
+            // and when it reaches EPL_C_DLL_PREOP1_START_CYCLES the SoA may contain invitations)
+            EplDllkInstance_g.m_uiCycleCount = 0;
+
+            // remove any CN from isochronous phase
+            while (EplDllkInstance_g.m_pFirstNodeInfo != NULL)
+            {
+                EplDllkDeleteNode(EplDllkInstance_g.m_pFirstNodeInfo->m_uiNodeId);
+            }
+
+            // change state to NonCyclic,
+            // hence EplDllkChangeState() will not ignore the next call
+            EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic;
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+            if (EplDllkInstance_g.m_DllConfigParam.m_dwAsyncSlotTimeout != 0)
+            {
+                Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle,
+                    EplDllkInstance_g.m_DllConfigParam.m_dwAsyncSlotTimeout,
+                    EplDllkCbMnTimerCycle,
+                    0L,
+                    FALSE);
+            }
+#endif
+
+            break;
+        }
+#endif
+
+#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
+        case kEplEventTypeDllkPresReady:
+        {
+            // post PRes to transmit FIFO
+
+            NmtState = EplNmtkGetNmtState();
+
+            if (NmtState != kEplNmtCsBasicEthernet)
+            {
+                // Does PRes exist?
+                if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].m_pbBuffer != NULL)
+                {   // PRes does exist
+                    pTxFrame = (tEplFrame *) EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].m_pbBuffer;
+                    // update frame (NMT state, RD, RS, PR, MS, EN flags)
+                    if (NmtState < kEplNmtCsPreOperational2)
+                    {   // NMT state is not PreOp2, ReadyToOp or Op
+                        // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater
+                        NmtState = kEplNmtCsPreOperational2;
+                    }
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, (BYTE) NmtState);
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                    if (NmtState != kEplNmtCsOperational)
+                    {   // mark PDO as invalid in NMT state Op
+                        // $$$ reset only RD flag; set other flags appropriately
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, 0);
+                    }
+                    // $$$ make function that updates Pres, StatusRes
+                    // mark PRes frame as ready for transmission
+                    Ret = EdrvTxMsgReady(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]);
+                }
+            }
+
+            break;
+        }
+#endif
+        default:
+        {
+            ASSERTMSG(FALSE, "EplDllkProcess(): unhandled event type!\n");
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkConfig
+//
+// Description: configure parameters of DLL
+//
+// Parameters:  pDllConfigParam_p       = configuration parameters
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+// d.k. check of NMT state disabled, because CycleLen is programmed at run time by MN without reset of CN
+/*tEplNmtState    NmtState;
+
+    NmtState = EplNmtkGetNmtState();
+
+    if (NmtState > kEplNmtGsResetConfiguration)
+    {   // only allowed in state DLL_GS_INIT
+        Ret = kEplInvalidOperation;
+        goto Exit;
+    }
+*/
+    EPL_MEMCPY (&EplDllkInstance_g.m_DllConfigParam, pDllConfigParam_p,
+        (pDllConfigParam_p->m_uiSizeOfStruct < sizeof (tEplDllConfigParam) ?
+        pDllConfigParam_p->m_uiSizeOfStruct : sizeof (tEplDllConfigParam)));
+
+    if ((EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen != 0)
+        && (EplDllkInstance_g.m_DllConfigParam.m_dwLossOfFrameTolerance != 0))
+    {   // monitor EPL cycle, calculate frame timeout
+        EplDllkInstance_g.m_ullFrameTimeout = (1000LL
+            * ((unsigned long long) EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen))
+            + ((unsigned long long) EplDllkInstance_g.m_DllConfigParam.m_dwLossOfFrameTolerance);
+    }
+    else
+    {
+        EplDllkInstance_g.m_ullFrameTimeout = 0LL;
+    }
+
+    if (EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly != FALSE)
+    {   // it is configured as async-only CN
+        // disable multiplexed cycle, that m_uiCycleCount will not be incremented spuriously on SoC
+        EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt = 0;
+    }
+
+//Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkSetIdentity
+//
+// Description: configure identity of local node for IdentResponse
+//
+// Parameters:  pDllIdentParam_p        = identity
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    EPL_MEMCPY (&EplDllkInstance_g.m_DllIdentParam, pDllIdentParam_p,
+        (pDllIdentParam_p->m_uiSizeOfStruct < sizeof (tEplDllIdentParam) ?
+        pDllIdentParam_p->m_uiSizeOfStruct : sizeof (tEplDllIdentParam)));
+
+    // $$$ if IdentResponse frame exists update it
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkRegAsyncHandler
+//
+// Description: registers handler for non-EPL frames
+//
+// Parameters:  pfnDllkCbAsync_p        = pointer to callback function
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    if (EplDllkInstance_g.m_pfnCbAsync == NULL)
+    {   // no handler registered yet
+        EplDllkInstance_g.m_pfnCbAsync = pfnDllkCbAsync_p;
+    }
+    else
+    {   // handler already registered
+        Ret = kEplDllCbAsyncRegistered;
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkDeregAsyncHandler
+//
+// Description: deregisters handler for non-EPL frames
+//
+// Parameters:  pfnDllkCbAsync_p        = pointer to callback function
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    if (EplDllkInstance_g.m_pfnCbAsync == pfnDllkCbAsync_p)
+    {   // same handler is registered
+        // deregister it
+        EplDllkInstance_g.m_pfnCbAsync = NULL;
+    }
+    else
+    {   // wrong handler or no handler registered
+        Ret = kEplDllCbAsyncRegistered;
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkSetAsndServiceIdFilter()
+//
+// Description: sets the specified node ID filter for the specified
+//              AsndServiceId. It registers C_DLL_MULTICAST_ASND in ethernet
+//              driver if any AsndServiceId is open.
+//
+// Parameters:  ServiceId_p             = ASnd Service ID
+//              Filter_p                = node ID filter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, tEplDllAsndFilter Filter_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    if (ServiceId_p < tabentries (EplDllkInstance_g.m_aAsndFilter))
+    {
+        EplDllkInstance_g.m_aAsndFilter[ServiceId_p] = Filter_p;
+    }
+
+    return Ret;
+}
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkSetFlag1OfNode()
+//
+// Description: sets Flag1 (for PReq and SoA) of the specified node ID.
+//
+// Parameters:  uiNodeId_p              = node ID
+//              bSoaFlag1_p             = flag1
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplDllkNodeInfo*   pNodeInfo;
+
+    pNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
+    if (pNodeInfo == NULL)
+    {   // no node info structure available
+        Ret = kEplDllNoNodeInfo;
+        goto Exit;
+    }
+
+    // store flag1 in internal node info structure
+    pNodeInfo->m_bSoaFlag1 = bSoaFlag1_p;
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkGetFirstNodeInfo()
+//
+// Description: returns first info structure of first node in isochronous phase.
+//              It is only useful for ErrorHandlerk module.
+//
+// Parameters:  ppNodeInfo_p            = pointer to pointer of internal node info structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo** ppNodeInfo_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+
+    *ppNodeInfo_p = EplDllkInstance_g.m_pFirstNodeInfo;
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkAddNode()
+//
+// Description: adds the specified node to the isochronous phase.
+//
+// Parameters:  pNodeInfo_p             = pointer of node info structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplDllkNodeInfo*   pIntNodeInfo;
+tEplDllkNodeInfo**  ppIntNodeInfo;
+unsigned int        uiHandle;
+tEplFrame*          pFrame;
+unsigned int        uiFrameSize;
+
+    pIntNodeInfo = EplDllkGetNodeInfo(pNodeInfo_p->m_uiNodeId);
+    if (pIntNodeInfo == NULL)
+    {   // no node info structure available
+        Ret = kEplDllNoNodeInfo;
+        goto Exit;
+    }
+
+    EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkAddNode,
+                                  pNodeInfo_p->m_uiNodeId,
+                                  0);
+
+    // copy node configuration
+    pIntNodeInfo->m_dwPresTimeout = pNodeInfo_p->m_dwPresTimeout;
+    pIntNodeInfo->m_wPresPayloadLimit = pNodeInfo_p->m_wPresPayloadLimit;
+
+    // $$$ d.k.: actually add node only if MN. On CN it is sufficient to update the node configuration
+    if (pNodeInfo_p->m_uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)
+    {   // we shall send PRes ourself
+        // insert our node at the end of the list
+        ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
+        while ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_pNextNodeInfo != NULL))
+        {
+            ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
+        }
+        if (*ppIntNodeInfo != NULL)
+        {
+            if ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId)
+            {   // node was already added to list
+                // $$$ d.k. maybe this should be an error
+                goto Exit;
+            }
+            else
+            {   // add our node at the end of the list
+                ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
+            }
+        }
+        // set "PReq"-TxBuffer to PRes-TxBuffer
+        pIntNodeInfo->m_pPreqTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
+    }
+    else
+    {   // normal CN shall be added to isochronous phase
+        // insert node into list in ascending order
+        ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
+        while ((*ppIntNodeInfo != NULL)
+               && ((*ppIntNodeInfo)->m_uiNodeId < pNodeInfo_p->m_uiNodeId)
+               && ((*ppIntNodeInfo)->m_uiNodeId != EplDllkInstance_g.m_DllConfigParam.m_uiNodeId))
+        {
+            ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
+        }
+        if ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId))
+        {   // node was already added to list
+            // $$$ d.k. maybe this should be an error
+            goto Exit;
+        }
+    }
+
+    // initialize elements of internal node info structure
+    pIntNodeInfo->m_bSoaFlag1 = 0;
+    pIntNodeInfo->m_fSoftDelete = FALSE;
+    pIntNodeInfo->m_NmtState = kEplNmtCsNotActive;
+    if (pIntNodeInfo->m_pPreqTxBuffer == NULL)
+    {   // create TxBuffer entry
+        uiFrameSize = pNodeInfo_p->m_wPreqPayloadLimit + 24;
+        Ret = EplDllkCreateTxFrame(&uiHandle, &pFrame, &uiFrameSize, kEplMsgTypePreq, kEplDllAsndNotDefined);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        pIntNodeInfo->m_pPreqTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
+        AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) pNodeInfo_p->m_uiNodeId);
+
+        // set up destination MAC address
+        EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr, 6);
+
+        #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+        {
+        tEplFrameInfo       FrameInfo;
+
+            // initially encode TPDO -> inform PDO module
+            FrameInfo.m_pFrame = pFrame;
+            FrameInfo.m_uiFrameSize = uiFrameSize;
+            Ret = EplPdokCbPdoTransmitted(&FrameInfo);
+        }
+        #endif
+    }
+    pIntNodeInfo->m_ulDllErrorEvents = 0L;
+    // add node to list
+    pIntNodeInfo->m_pNextNodeInfo = *ppIntNodeInfo;
+    *ppIntNodeInfo = pIntNodeInfo;
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkDeleteNode()
+//
+// Description: removes the specified node from the isochronous phase.
+//
+// Parameters:  uiNodeId_p              = node ID
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplDllkNodeInfo*   pIntNodeInfo;
+tEplDllkNodeInfo**  ppIntNodeInfo;
+unsigned int        uiHandle;
+
+    pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
+    if (pIntNodeInfo == NULL)
+    {   // no node info structure available
+        Ret = kEplDllNoNodeInfo;
+        goto Exit;
+    }
+
+    EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkDelNode,
+                                  uiNodeId_p,
+                                  0);
+
+    // search node in whole list
+    ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
+    while ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p))
+    {
+        ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
+    }
+    if ((*ppIntNodeInfo == NULL) || ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p))
+    {   // node was not found in list
+        // $$$ d.k. maybe this should be an error
+        goto Exit;
+    }
+
+    // remove node from list
+    *ppIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo;
+
+    if ((pIntNodeInfo->m_pPreqTxBuffer != NULL)
+        && (pIntNodeInfo->m_pPreqTxBuffer != &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]))
+    {   // delete TxBuffer entry
+        uiHandle = pIntNodeInfo->m_pPreqTxBuffer - EplDllkInstance_g.m_pTxBuffer;
+        pIntNodeInfo->m_pPreqTxBuffer = NULL;
+        Ret = EplDllkDeleteTxFrame(uiHandle);
+/*        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }*/
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkSoftDeleteNode()
+//
+// Description: removes the specified node not immediately from the isochronous phase.
+//              Instead the will be removed after error (late/loss PRes) without
+//              charging the error.
+//
+// Parameters:  uiNodeId_p              = node ID
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplDllkNodeInfo*   pIntNodeInfo;
+
+    pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
+    if (pIntNodeInfo == NULL)
+    {   // no node info structure available
+        Ret = kEplDllNoNodeInfo;
+        goto Exit;
+    }
+
+    EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkSoftDelNode,
+                                  uiNodeId_p,
+                                  0);
+
+    pIntNodeInfo->m_fSoftDelete = TRUE;
+
+Exit:
+    return Ret;
+}
+
+
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkChangeState
+//
+// Description: change DLL state on event and diagnose some communication errors
+//
+// Parameters:  NmtEvent_p              = DLL event (wrapped in NMT event)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p, tEplNmtState NmtState_p)
+{
+tEplKernel              Ret = kEplSuccessful;
+tEplEvent               Event;
+tEplErrorHandlerkEvent  DllEvent;
+
+    DllEvent.m_ulDllErrorEvents = 0;
+    DllEvent.m_uiNodeId = 0;
+    DllEvent.m_NmtState = NmtState_p;
+
+    switch (NmtState_p)
+    {
+        case kEplNmtGsOff:
+        case kEplNmtGsInitialising:
+        case kEplNmtGsResetApplication:
+        case kEplNmtGsResetCommunication:
+        case kEplNmtGsResetConfiguration:
+        case kEplNmtCsBasicEthernet:
+            // enter DLL_GS_INIT
+            EplDllkInstance_g.m_DllState = kEplDllGsInit;
+            break;
+
+        case kEplNmtCsNotActive:
+        case kEplNmtCsPreOperational1:
+            // reduced EPL cycle is active
+            if (NmtEvent_p == kEplNmtEventDllCeSoc)
+            {   // SoC received
+                // enter DLL_CS_WAIT_PREQ
+                EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
+            }
+            else
+            {
+                // enter DLL_GS_INIT
+                EplDllkInstance_g.m_DllState = kEplDllGsInit;
+            }
+            break;
+
+        case kEplNmtCsPreOperational2:
+        case kEplNmtCsReadyToOperate:
+        case kEplNmtCsOperational:
+            // full EPL cycle is active
+
+            switch (EplDllkInstance_g.m_DllState)
+            {
+                case kEplDllCsWaitPreq:
+                    switch (NmtEvent_p)
+                    {
+                            // DLL_CT2
+                        case kEplNmtEventDllCePreq:
+                            // enter DLL_CS_WAIT_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_RECVD_PREQ;
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
+                            break;
+
+                            // DLL_CT8
+                        case kEplNmtEventDllCeFrameTimeout:
+                            if (NmtState_p == kEplNmtCsPreOperational2)
+                            {   // ignore frame timeout in PreOp2,
+                                // because the previously configured cycle len
+                                // may be wrong.
+                                // 2008/10/15 d.k. If it would not be ignored,
+                                // we would go cyclically to PreOp1 and on next
+                                // SoC back to PreOp2.
+                                break;
+                            }
+
+                            // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA | EPL_DLL_ERR_CN_LOSS_SOC;
+
+                            // enter DLL_CS_WAIT_SOC
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
+                            break;
+
+                        case kEplNmtEventDllCeSoa:
+                            // check if multiplexed and PReq should have been received in this cycle
+                            // and if >= NMT_CS_READY_TO_OPERATE
+                            if ((EplDllkInstance_g.m_uiCycleCount == 0)
+                                && (NmtState_p >= kEplNmtCsReadyToOperate))
+                            {   // report DLL_CEV_LOSS_OF_PREQ
+                                DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_PREQ;
+                            }
+
+                            // enter DLL_CS_WAIT_SOC
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
+                            break;
+
+                            // DLL_CT7
+                        case kEplNmtEventDllCeSoc:
+                        case kEplNmtEventDllCeAsnd:
+                            // report DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA;
+
+                        case kEplNmtEventDllCePres:
+                        default:
+                            // remain in this state
+                            break;
+                    }
+                    break;
+
+                case kEplDllCsWaitSoc:
+                    switch (NmtEvent_p)
+                    {
+                            // DLL_CT1
+                        case kEplNmtEventDllCeSoc:
+                            // start of cycle and isochronous phase
+                            // enter DLL_CS_WAIT_PREQ
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
+                            break;
+
+                            // DLL_CT4
+//                        case kEplNmtEventDllCePres:
+                        case kEplNmtEventDllCeFrameTimeout:
+                            if (NmtState_p == kEplNmtCsPreOperational2)
+                            {   // ignore frame timeout in PreOp2,
+                                // because the previously configured cycle len
+                                // may be wrong.
+                                // 2008/10/15 d.k. If it would not be ignored,
+                                // we would go cyclically to PreOp1 and on next
+                                // SoC back to PreOp2.
+                                break;
+                            }
+
+                            // fall through
+
+                        case kEplNmtEventDllCePreq:
+                        case kEplNmtEventDllCeSoa:
+                            // report DLL_CEV_LOSS_SOC
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOC;
+
+                        case kEplNmtEventDllCeAsnd:
+                        default:
+                            // remain in this state
+                            break;
+                    }
+                    break;
+
+                case kEplDllCsWaitSoa:
+                    switch (NmtEvent_p)
+                    {
+                        case kEplNmtEventDllCeFrameTimeout:
+                            // DLL_CT3
+                            if (NmtState_p == kEplNmtCsPreOperational2)
+                            {   // ignore frame timeout in PreOp2,
+                                // because the previously configured cycle len
+                                // may be wrong.
+                                // 2008/10/15 d.k. If it would not be ignored,
+                                // we would go cyclically to PreOp1 and on next
+                                // SoC back to PreOp2.
+                                break;
+                            }
+
+                            // fall through
+
+                        case kEplNmtEventDllCePreq:
+                            // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA | EPL_DLL_ERR_CN_LOSS_SOC;
+
+                        case kEplNmtEventDllCeSoa:
+                            // enter DLL_CS_WAIT_SOC
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
+                            break;
+
+                            // DLL_CT9
+                        case kEplNmtEventDllCeSoc:
+                            // report DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA;
+
+                            // enter DLL_CS_WAIT_PREQ
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
+                            break;
+
+                            // DLL_CT10
+                        case kEplNmtEventDllCeAsnd:
+                            // report DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA;
+
+                        case kEplNmtEventDllCePres:
+                        default:
+                            // remain in this state
+                            break;
+                    }
+                    break;
+
+                case kEplDllGsInit:
+                    // enter DLL_CS_WAIT_PREQ
+                    EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
+                    break;
+
+                default:
+                    break;
+            }
+            break;
+
+        case kEplNmtCsStopped:
+            // full EPL cycle is active, but without PReq/PRes
+
+            switch (EplDllkInstance_g.m_DllState)
+            {
+                case kEplDllCsWaitPreq:
+                    switch (NmtEvent_p)
+                    {
+                            // DLL_CT2
+                        case kEplNmtEventDllCePreq:
+                            // enter DLL_CS_WAIT_SOA
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
+                            break;
+
+                            // DLL_CT8
+                        case kEplNmtEventDllCeFrameTimeout:
+                            // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA | EPL_DLL_ERR_CN_LOSS_SOC;
+
+                        case kEplNmtEventDllCeSoa:
+                            // NMT_CS_STOPPED active
+                            // it is Ok if no PReq was received
+
+                            // enter DLL_CS_WAIT_SOC
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
+                            break;
+
+                            // DLL_CT7
+                        case kEplNmtEventDllCeSoc:
+                        case kEplNmtEventDllCeAsnd:
+                            // report DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA;
+
+                        case kEplNmtEventDllCePres:
+                        default:
+                            // remain in this state
+                            break;
+                    }
+                    break;
+
+                case kEplDllCsWaitSoc:
+                    switch (NmtEvent_p)
+                    {
+                            // DLL_CT1
+                        case kEplNmtEventDllCeSoc:
+                            // start of cycle and isochronous phase
+                            // enter DLL_CS_WAIT_SOA
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
+                            break;
+
+                            // DLL_CT4
+//                        case kEplNmtEventDllCePres:
+                        case kEplNmtEventDllCePreq:
+                        case kEplNmtEventDllCeSoa:
+                        case kEplNmtEventDllCeFrameTimeout:
+                            // report DLL_CEV_LOSS_SOC
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOC;
+
+                        case kEplNmtEventDllCeAsnd:
+                        default:
+                            // remain in this state
+                            break;
+                    }
+                    break;
+
+                case kEplDllCsWaitSoa:
+                    switch (NmtEvent_p)
+                    {
+                            // DLL_CT3
+                        case kEplNmtEventDllCeFrameTimeout:
+                            // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA | EPL_DLL_ERR_CN_LOSS_SOC;
+
+                        case kEplNmtEventDllCeSoa:
+                            // enter DLL_CS_WAIT_SOC
+                            EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
+                            break;
+
+                            // DLL_CT9
+                        case kEplNmtEventDllCeSoc:
+                            // report DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA;
+                            // remain in DLL_CS_WAIT_SOA
+                            break;
+
+                            // DLL_CT10
+                        case kEplNmtEventDllCeAsnd:
+                            // report DLL_CEV_LOSS_SOA
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_CN_LOSS_SOA;
+
+                        case kEplNmtEventDllCePreq:
+                            // NMT_CS_STOPPED active and we do not expect any PReq
+                            // so just ignore it
+                        case kEplNmtEventDllCePres:
+                        default:
+                            // remain in this state
+                            break;
+                    }
+                    break;
+
+                case kEplDllGsInit:
+                default:
+                    // enter DLL_CS_WAIT_PREQ
+                    EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
+                    break;
+            }
+            break;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        case kEplNmtMsNotActive:
+        case kEplNmtMsBasicEthernet:
+            break;
+
+        case kEplNmtMsPreOperational1:
+            // reduced EPL cycle is active
+            if (EplDllkInstance_g.m_DllState != kEplDllMsNonCyclic)
+            {   // stop cycle timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+                Ret = EplTimerHighReskDeleteTimer(&EplDllkInstance_g.m_TimerHdlCycle);
+#endif
+                EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic;
+
+                // stop further processing,
+                // because it will be restarted by NMT MN module
+                break;
+            }
+
+            switch (NmtEvent_p)
+            {
+                case kEplNmtEventDllMeSocTrig:
+                case kEplNmtEventDllCeAsnd:
+                {   // because of reduced EPL cycle SoA shall be triggered, not SoC
+                tEplDllState    DummyDllState;
+
+                    Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId,
+                                                       EplDllkInstance_g.m_uiLastTargetNodeId);
+
+                    // go ahead and send SoA
+                    Ret = EplDllkMnSendSoa(NmtState_p,
+                                           &DummyDllState,
+                                           (EplDllkInstance_g.m_uiCycleCount >= EPL_C_DLL_PREOP1_START_CYCLES));
+                    // increment cycle counter to detect if EPL_C_DLL_PREOP1_START_CYCLES empty cycles are elapsed
+                    EplDllkInstance_g.m_uiCycleCount++;
+
+                    // reprogram timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+                    if (EplDllkInstance_g.m_DllConfigParam.m_dwAsyncSlotTimeout != 0)
+                    {
+                        Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle,
+                            EplDllkInstance_g.m_DllConfigParam.m_dwAsyncSlotTimeout,
+                            EplDllkCbMnTimerCycle,
+                            0L,
+                            FALSE);
+                    }
+#endif
+                    break;
+                }
+
+                default:
+                    break;
+            }
+            break;
+
+        case kEplNmtMsPreOperational2:
+        case kEplNmtMsReadyToOperate:
+        case kEplNmtMsOperational:
+            // full EPL cycle is active
+            switch (NmtEvent_p)
+            {
+                case kEplNmtEventDllMeSocTrig:
+                {
+                    // update cycle counter
+                    if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0)
+                    {   // multiplexed cycle active
+                        EplDllkInstance_g.m_uiCycleCount = (EplDllkInstance_g.m_uiCycleCount + 1) % EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt;
+                        // $$$ check multiplexed cycle restart
+                        //     -> toggle MC flag
+                        //     -> change node linked list
+                    }
+                    else
+                    {   // non-multiplexed cycle active
+                        // start with first node in isochronous phase
+                        EplDllkInstance_g.m_pCurNodeInfo = NULL;
+                    }
+
+                    switch (EplDllkInstance_g.m_DllState)
+                    {
+                        case kEplDllMsNonCyclic:
+                        {   // start continuous cycle timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+                            Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle,
+                                EplDllkInstance_g.m_ullFrameTimeout,
+                                EplDllkCbMnTimerCycle,
+                                0L,
+                                TRUE);
+#endif
+                            // continue with sending SoC
+                        }
+
+                        case kEplDllMsWaitAsnd:
+                        case kEplDllMsWaitSocTrig:
+                        {   // if m_LastReqServiceId is still valid,
+                            // SoA was not correctly answered
+                            // and user part has to be informed
+                            Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId,
+                                                               EplDllkInstance_g.m_uiLastTargetNodeId);
+
+                            // send SoC
+                            Ret = EplDllkMnSendSoc();
+
+                            // new DLL state
+                            EplDllkInstance_g.m_DllState = kEplDllMsWaitPreqTrig;
+
+                            // start WaitSoCPReq Timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+                            Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlResponse,
+                                EplDllkInstance_g.m_DllConfigParam.m_dwWaitSocPreq,
+                                EplDllkCbMnTimerResponse,
+                                0L,
+                                FALSE);
+#endif
+                            break;
+                        }
+
+                        default:
+                        {   // wrong DLL state / cycle time exceeded
+                            DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CYCTIMEEXCEED;
+                            EplDllkInstance_g.m_DllState = kEplDllMsWaitSocTrig;
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+
+                case kEplNmtEventDllMePresTimeout:
+                {
+
+                    switch (EplDllkInstance_g.m_DllState)
+                    {
+                        case kEplDllMsWaitPres:
+                        {   // PRes not received
+
+                            if (EplDllkInstance_g.m_pCurNodeInfo->m_fSoftDelete == FALSE)
+                            {   // normal isochronous CN
+                                DllEvent.m_ulDllErrorEvents |= EPL_DLL_ERR_MN_CN_LOSS_PRES;
+                                DllEvent.m_uiNodeId = EplDllkInstance_g.m_pCurNodeInfo->m_uiNodeId;
+                            }
+                            else
+                            {   // CN shall be deleted softly
+                                Event.m_EventSink = kEplEventSinkDllkCal;
+                                Event.m_EventType = kEplEventTypeDllkSoftDelNode;
+                                // $$$ d.k. set Event.m_NetTime to current time
+                                Event.m_uiSize = sizeof (unsigned int);
+                                Event.m_pArg = &EplDllkInstance_g.m_pCurNodeInfo->m_uiNodeId;
+                                Ret = EplEventkPost(&Event);
+                            }
+
+                            // continue with sending next PReq
+                        }
+
+                        case kEplDllMsWaitPreqTrig:
+                        {
+                            // send next PReq
+                            Ret = EplDllkMnSendPreq(NmtState_p, &EplDllkInstance_g.m_DllState);
+
+                            break;
+                        }
+
+                        default:
+                        {   // wrong DLL state
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+
+                case kEplNmtEventDllCePres:
+                {
+
+                    switch (EplDllkInstance_g.m_DllState)
+                    {
+                        case kEplDllMsWaitPres:
+                        {   // PRes received
+                            // send next PReq
+                            Ret = EplDllkMnSendPreq(NmtState_p, &EplDllkInstance_g.m_DllState);
+
+                            break;
+                        }
+
+                        default:
+                        {   // wrong DLL state
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+
+                case kEplNmtEventDllMeSoaTrig:
+                {
+
+                    switch (EplDllkInstance_g.m_DllState)
+                    {
+                        case kEplDllMsWaitSoaTrig:
+                        {   // MN PRes sent
+                            // send SoA
+                            Ret = EplDllkMnSendSoa(NmtState_p, &EplDllkInstance_g.m_DllState, TRUE);
+
+                            break;
+                        }
+
+                        default:
+                        {   // wrong DLL state
+                            break;
+                        }
+                    }
+
+                    break;
+                }
+
+                case kEplNmtEventDllCeAsnd:
+                {   // ASnd has been received, but it may be not the requested one
+/*
+                    // report if SoA was correctly answered
+                    Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId,
+                                                       EplDllkInstance_g.m_uiLastTargetNodeId);
+*/
+                    if (EplDllkInstance_g.m_DllState == kEplDllMsWaitAsnd)
+                    {
+                        EplDllkInstance_g.m_DllState = kEplDllMsWaitSocTrig;
+                    }
+                    break;
+                }
+
+                default:
+                    break;
+            }
+            break;
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+        default:
+            break;
+    }
+
+    if (DllEvent.m_ulDllErrorEvents != 0)
+    {   // error event set -> post it to error handler
+        Event.m_EventSink = kEplEventSinkErrk;
+        Event.m_EventType = kEplEventTypeDllError;
+        // $$$ d.k. set Event.m_NetTime to current time
+        Event.m_uiSize = sizeof (DllEvent);
+        Event.m_pArg = &DllEvent;
+        Ret = EplEventkPost(&Event);
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCbFrameReceived()
+//
+// Description: called from EdrvInterruptHandler()
+//
+// Parameters:  pRxBuffer_p             = receive buffer structure
+//
+// Returns:     (none)
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplNmtState    NmtState;
+tEplNmtEvent    NmtEvent = kEplNmtEventNoEvent;
+tEplEvent       Event;
+tEplFrame      *pFrame;
+tEplFrame      *pTxFrame;
+tEdrvTxBuffer  *pTxBuffer = NULL;
+tEplFrameInfo   FrameInfo;
+tEplMsgType     MsgType;
+tEplDllReqServiceId     ReqServiceId;
+unsigned int    uiAsndServiceId;
+unsigned int    uiNodeId;
+BYTE            bFlag1;
+
+    BENCHMARK_MOD_02_SET(3);
+    NmtState = EplNmtkGetNmtState();
+
+    if (NmtState <= kEplNmtGsResetConfiguration)
+    {
+        goto Exit;
+    }
+
+    pFrame = (tEplFrame *) pRxBuffer_p->m_pbBuffer;
+
+#if EDRV_EARLY_RX_INT != FALSE
+    switch (pRxBuffer_p->m_BufferInFrame)
+    {
+        case kEdrvBufferFirstInFrame:
+        {
+            MsgType = (tEplMsgType)AmiGetByteFromLe(&pFrame->m_le_bMessageType);
+            if (MsgType == kEplMsgTypePreq)
+            {
+            if (EplDllkInstance_g.m_DllState == kEplDllCsWaitPreq)
+            {   // PReq expected and actually received
+                // d.k.: The condition above is sufficent, because EPL cycle is active
+                //       and no non-EPL frame shall be received in isochronous phase.
+                // start transmission PRes
+                // $$$ What if Tx buffer is invalid?
+                pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
+#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
+                Ret = EdrvTxMsgStart(pTxBuffer);
+#else
+                pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+                // update frame (NMT state, RD, RS, PR, MS, EN flags)
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, (BYTE) NmtState);
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                if (NmtState != kEplNmtCsOperational)
+                {   // mark PDO as invalid in NMT state Op
+                    // $$$ reset only RD flag; set other flags appropriately
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, 0);
+                }
+                // $$$ make function that updates Pres, StatusRes
+                // send PRes frame
+                Ret = EdrvSendTxMsg(pTxBuffer);
+#endif
+            }
+            }
+            goto Exit;
+        }
+
+        case kEdrvBufferMiddleInFrame:
+        {
+            goto Exit;
+        }
+
+        case kEdrvBufferLastInFrame:
+        {
+            break;
+        }
+    }
+#endif
+
+    FrameInfo.m_pFrame = pFrame;
+    FrameInfo.m_uiFrameSize = pRxBuffer_p->m_uiRxMsgLen;
+    FrameInfo.m_NetTime.m_dwNanoSec = pRxBuffer_p->m_NetTime.m_dwNanoSec;
+    FrameInfo.m_NetTime.m_dwSec = pRxBuffer_p->m_NetTime.m_dwSec;
+
+    if (AmiGetWordFromBe(&pFrame->m_be_wEtherType) != EPL_C_DLL_ETHERTYPE_EPL)
+    {   // non-EPL frame
+        //TRACE2("EplDllkCbFrameReceived: pfnCbAsync=0x%p SrcMAC=0x%llx\n", EplDllkInstance_g.m_pfnCbAsync, AmiGetQword48FromBe(pFrame->m_be_abSrcMac));
+        if (EplDllkInstance_g.m_pfnCbAsync != NULL)
+        {   // handler for async frames is registered
+            EplDllkInstance_g.m_pfnCbAsync(&FrameInfo);
+        }
+
+        goto Exit;
+    }
+
+    MsgType = (tEplMsgType)AmiGetByteFromLe(&pFrame->m_le_bMessageType);
+    switch (MsgType)
+    {
+        case kEplMsgTypePreq:
+        {
+            // PReq frame
+            // d.k.: (we assume that this PReq frame is intended for us and don't check DstNodeId)
+            if (AmiGetByteFromLe(&pFrame->m_le_bDstNodeId) != EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)
+            {   // this PReq is not intended for us
+                goto Exit;
+            }
+            NmtEvent = kEplNmtEventDllCePreq;
+
+            if (NmtState >= kEplNmtMsNotActive)
+            {   // MN is active -> wrong msg type
+                break;
+            }
+
+#if EDRV_EARLY_RX_INT == FALSE
+            if (NmtState >= kEplNmtCsPreOperational2)
+            {   // respond to and process PReq frames only in PreOp2, ReadyToOp and Op
+                // Does PRes exist?
+                pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
+                if (pTxBuffer->m_pbBuffer != NULL)
+                {   // PRes does exist
+#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
+                    EdrvTxMsgStart(pTxBuffer);
+#else
+                    pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+                    // update frame (NMT state, RD, RS, PR, MS, EN flags)
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, (BYTE) NmtState);
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                    bFlag1 = AmiGetByteFromLe(&pFrame->m_Data.m_Preq.m_le_bFlag1);
+                    // save EA flag
+                    EplDllkInstance_g.m_bMnFlag1 =
+                        (EplDllkInstance_g.m_bMnFlag1 & ~EPL_FRAME_FLAG1_EA)
+                        | (bFlag1 & EPL_FRAME_FLAG1_EA);
+                    // preserve MS flag
+                    bFlag1 &= EPL_FRAME_FLAG1_MS;
+                    // add EN flag from Error signaling module
+                    bFlag1 |= EplDllkInstance_g.m_bFlag1 & EPL_FRAME_FLAG1_EN;
+                    if (NmtState != kEplNmtCsOperational)
+                    {   // mark PDO as invalid in NMT state Op
+                        // reset only RD flag
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, bFlag1);
+                    }
+                    else
+                    {   // leave RD flag untouched
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1,
+                            (AmiGetByteFromLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1) & EPL_FRAME_FLAG1_RD)
+                            | bFlag1);
+                    }
+                    // $$$ update EPL_DLL_PRES_READY_AFTER_* code
+                    // send PRes frame
+                    Ret = EdrvSendTxMsg(pTxBuffer);
+                    if (Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+#endif
+                }
+#endif
+                // inform PDO module
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+                if (NmtState >= kEplNmtCsReadyToOperate)
+                {   // inform PDO module only in ReadyToOp and Op
+                    if (NmtState != kEplNmtCsOperational)
+                    {
+                        // reset RD flag and all other flags, but that does not matter, because they were processed above
+                        AmiSetByteToLe(&pFrame->m_Data.m_Preq.m_le_bFlag1, 0);
+                    }
+
+                    // compares real frame size and PDO size
+                    if ((unsigned int) (AmiGetWordFromLe(&pFrame->m_Data.m_Preq.m_le_wSize) + 24)
+                        > FrameInfo.m_uiFrameSize)
+                    {   // format error
+                    tEplErrorHandlerkEvent  DllEvent;
+
+                        DllEvent.m_ulDllErrorEvents = EPL_DLL_ERR_INVALID_FORMAT;
+                        DllEvent.m_uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
+                        DllEvent.m_NmtState = NmtState;
+                        Event.m_EventSink = kEplEventSinkErrk;
+                        Event.m_EventType = kEplEventTypeDllError;
+                        Event.m_NetTime = FrameInfo.m_NetTime;
+                        Event.m_uiSize = sizeof (DllEvent);
+                        Event.m_pArg = &DllEvent;
+                        Ret = EplEventkPost(&Event);
+                        break;
+                    }
+
+                    // forward PReq frame as RPDO to PDO module
+                    Ret = EplPdokCbPdoReceived(&FrameInfo);
+
+                }
+#if (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
+                if (pTxBuffer->m_pbBuffer != NULL)
+                {   // PRes does exist
+                    // inform PDO module about PRes after PReq
+                    FrameInfo.m_pFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+                    FrameInfo.m_uiFrameSize = pTxBuffer->m_uiMaxBufferLen;
+                    Ret = EplPdokCbPdoTransmitted(&FrameInfo);
+                }
+#endif
+#endif
+
+#if EDRV_EARLY_RX_INT == FALSE
+                // $$$ inform emergency protocol handling (error signaling module) about flags
+            }
+#endif
+
+            // reset cycle counter
+            EplDllkInstance_g.m_uiCycleCount = 0;
+
+            break;
+        }
+
+        case kEplMsgTypePres:
+        {
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        tEplDllkNodeInfo*   pIntNodeInfo;
+        tEplHeartbeatEvent  HeartbeatEvent;
+#endif
+
+            // PRes frame
+            NmtEvent = kEplNmtEventDllCePres;
+
+            uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
+
+            if ((NmtState >= kEplNmtCsPreOperational2)
+                && (NmtState <= kEplNmtCsOperational))
+            {   // process PRes frames only in PreOp2, ReadyToOp and Op of CN
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+                pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId);
+                if (pIntNodeInfo == NULL)
+                {   // no node info structure available
+                    Ret = kEplDllNoNodeInfo;
+                    goto Exit;
+                }
+            }
+            else if (EplDllkInstance_g.m_DllState == kEplDllMsWaitPres)
+            {   // or process PRes frames in MsWaitPres
+
+                pIntNodeInfo = EplDllkInstance_g.m_pCurNodeInfo;
+                if ((pIntNodeInfo == NULL) || (pIntNodeInfo->m_uiNodeId != uiNodeId))
+                {   // ignore PRes, because it is from wrong CN
+                    // $$$ maybe post event to NmtMn module
+                    goto Exit;
+                }
+
+                // forward Flag2 to asynchronous scheduler
+                bFlag1 = AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bFlag2);
+                Ret = EplDllkCalAsyncSetPendingRequests(uiNodeId,
+                    ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)),
+                    (bFlag1 & EPL_FRAME_FLAG2_RS));
+
+#endif
+            }
+            else
+            {   // ignore PRes, because it was received in wrong NMT state
+                // but execute EplDllkChangeState() and post event to NMT module
+                break;
+            }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            {   // check NMT state of CN
+                HeartbeatEvent.m_wErrorCode = EPL_E_NO_ERROR;
+                HeartbeatEvent.m_NmtState =
+                    (tEplNmtState) (AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bNmtStatus) | EPL_NMT_TYPE_CS);
+                if (pIntNodeInfo->m_NmtState != HeartbeatEvent.m_NmtState)
+                {   // NMT state of CN has changed -> post event to NmtMnu module
+                    if (pIntNodeInfo->m_fSoftDelete == FALSE)
+                    {   // normal isochronous CN
+                        HeartbeatEvent.m_uiNodeId = uiNodeId;
+                        Event.m_EventSink = kEplEventSinkNmtMnu;
+                        Event.m_EventType = kEplEventTypeHeartbeat;
+                        Event.m_uiSize = sizeof (HeartbeatEvent);
+                        Event.m_pArg = &HeartbeatEvent;
+                    }
+                    else
+                    {   // CN shall be deleted softly
+                        Event.m_EventSink = kEplEventSinkDllkCal;
+                        Event.m_EventType = kEplEventTypeDllkSoftDelNode;
+                        Event.m_uiSize = sizeof (unsigned int);
+                        Event.m_pArg = &pIntNodeInfo->m_uiNodeId;
+                    }
+                    Event.m_NetTime = FrameInfo.m_NetTime;
+                    Ret = EplEventkPost(&Event);
+
+                    // save current NMT state of CN in internal node structure
+                    pIntNodeInfo->m_NmtState = HeartbeatEvent.m_NmtState;
+                }
+            }
+#endif
+
+            // inform PDO module
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+            if ((NmtState != kEplNmtCsPreOperational2)
+                && (NmtState != kEplNmtMsPreOperational2))
+            {   // inform PDO module only in ReadyToOp and Op
+                // compare real frame size and PDO size?
+                if (((unsigned int) (AmiGetWordFromLe(&pFrame->m_Data.m_Pres.m_le_wSize) + 24)
+                    > FrameInfo.m_uiFrameSize)
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+                    || (AmiGetWordFromLe(&pFrame->m_Data.m_Pres.m_le_wSize) > pIntNodeInfo->m_wPresPayloadLimit)
+#endif
+                    )
+                {   // format error
+                tEplErrorHandlerkEvent  DllEvent;
+
+                    DllEvent.m_ulDllErrorEvents = EPL_DLL_ERR_INVALID_FORMAT;
+                    DllEvent.m_uiNodeId = uiNodeId;
+                    DllEvent.m_NmtState = NmtState;
+                    Event.m_EventSink = kEplEventSinkErrk;
+                    Event.m_EventType = kEplEventTypeDllError;
+                    Event.m_NetTime = FrameInfo.m_NetTime;
+                    Event.m_uiSize = sizeof (DllEvent);
+                    Event.m_pArg = &DllEvent;
+                    Ret = EplEventkPost(&Event);
+                    break;
+                }
+                if ((NmtState != kEplNmtCsOperational)
+                    && (NmtState != kEplNmtMsOperational))
+                {
+                    // reset RD flag and all other flags, but that does not matter, because they were processed above
+                    AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bFlag1, 0);
+                }
+                Ret = EplPdokCbPdoReceived(&FrameInfo);
+            }
+#endif
+
+            break;
+        }
+
+        case kEplMsgTypeSoc:
+        {
+            // SoC frame
+            NmtEvent = kEplNmtEventDllCeSoc;
+
+            if (NmtState >= kEplNmtMsNotActive)
+            {   // MN is active -> wrong msg type
+                break;
+            }
+
+#if EPL_DLL_PRES_READY_AFTER_SOC != FALSE
+            // post PRes to transmit FIFO of the ethernet controller, but don't start
+            // transmission over bus
+            pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
+            // Does PRes exist?
+            if (pTxBuffer->m_pbBuffer != NULL)
+            {   // PRes does exist
+                pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+                // update frame (NMT state, RD, RS, PR, MS, EN flags)
+                if (NmtState < kEplNmtCsPreOperational2)
+                {   // NMT state is not PreOp2, ReadyToOp or Op
+                    // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater
+                    NmtState = kEplNmtCsPreOperational2;
+                }
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, (BYTE) NmtState);
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                if (NmtState != kEplNmtCsOperational)
+                {   // mark PDO as invalid in NMT state Op
+                    // $$$ reset only RD flag; set other flags appropriately
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, 0);
+                }
+                // $$$ make function that updates Pres, StatusRes
+                // mark PRes frame as ready for transmission
+                Ret = EdrvTxMsgReady(pTxBuffer);
+            }
+#endif
+
+            if (NmtState >= kEplNmtCsPreOperational2)
+            {   // SoC frames only in PreOp2, ReadyToOp and Op
+                // trigger synchronous task
+                Event.m_EventSink = kEplEventSinkSync;
+                Event.m_EventType = kEplEventTypeSync;
+                Event.m_uiSize = 0;
+                Ret = EplEventkPost(&Event);
+
+                // update cycle counter
+                if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0)
+                {   // multiplexed cycle active
+                    EplDllkInstance_g.m_uiCycleCount = (EplDllkInstance_g.m_uiCycleCount + 1) % EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt;
+                }
+            }
+
+            // reprogram timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+            if (EplDllkInstance_g.m_ullFrameTimeout != 0)
+            {
+                Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle, EplDllkInstance_g.m_ullFrameTimeout, EplDllkCbCnTimer, 0L, FALSE);
+            }
+#endif
+
+            break;
+        }
+
+        case kEplMsgTypeSoa:
+        {
+            // SoA frame
+            NmtEvent = kEplNmtEventDllCeSoa;
+
+            if (NmtState >= kEplNmtMsNotActive)
+            {   // MN is active -> wrong msg type
+                break;
+            }
+
+            pTxFrame = NULL;
+
+            if ((NmtState & EPL_NMT_SUPERSTATE_MASK) != EPL_NMT_CS_EPLMODE)
+            {   // do not respond, if NMT state is < PreOp1 (i.e. not EPL_MODE)
+                break;
+            }
+
+            // check TargetNodeId
+            uiNodeId = AmiGetByteFromLe(&pFrame->m_Data.m_Soa.m_le_bReqServiceTarget);
+            if (uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)
+            {   // local node is the target of the current request
+
+                // check ServiceId
+                ReqServiceId = (tEplDllReqServiceId) AmiGetByteFromLe(&pFrame->m_Data.m_Soa.m_le_bReqServiceId);
+                if (ReqServiceId == kEplDllReqServiceStatus)
+                {   // StatusRequest
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL)
+                    {   // StatusRes does exist
+
+                        pTxFrame = (tEplFrame *) EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer;
+                        // update StatusRes frame (NMT state, EN, EC, RS, PR flags)
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bNmtStatus, (BYTE) NmtState);
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bFlag1, EplDllkInstance_g.m_bFlag1);
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                        // send StatusRes
+                        Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES]);
+                        if (Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        TGT_DBG_SIGNAL_TRACE_POINT(8);
+
+                        // update error signaling
+                        bFlag1 = AmiGetByteFromLe(&pFrame->m_Data.m_Soa.m_le_bFlag1);
+                        if (((bFlag1 ^ EplDllkInstance_g.m_bMnFlag1) & EPL_FRAME_FLAG1_ER) != 0)
+                        {   // exception reset flag was changed by MN
+                            // assume same state for EC in next cycle (clear all other bits)
+                            if ((bFlag1 & EPL_FRAME_FLAG1_ER) != 0)
+                            {
+                                // set EC and reset rest
+                                EplDllkInstance_g.m_bFlag1 = EPL_FRAME_FLAG1_EC;
+                            }
+                            else
+                            {
+                                // reset complete flag 1 (including EC and EN)
+                                EplDllkInstance_g.m_bFlag1 = 0;
+                            }
+                        }
+                        // save flag 1 from MN for Status request response cycle
+                        EplDllkInstance_g.m_bMnFlag1 = bFlag1;
+                    }
+                }
+                else if (ReqServiceId == kEplDllReqServiceIdent)
+                {   // IdentRequest
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL)
+                    {   // IdentRes does exist
+                        pTxFrame = (tEplFrame *) EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer;
+                        // update IdentRes frame (NMT state, RS, PR flags)
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_bNmtStatus, (BYTE) NmtState);
+                        AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                        // send IdentRes
+                        Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES]);
+                        if (Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        TGT_DBG_SIGNAL_TRACE_POINT(7);
+                    }
+                }
+                else if (ReqServiceId == kEplDllReqServiceNmtRequest)
+                {   // NmtRequest
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL)
+                    {   // NmtRequest does exist
+                        // check if frame is not empty and not being filled
+                        if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_FILLING)
+                        {
+                            /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN)
+                            {   // pad frame
+                                EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN;
+                            }*/
+                            // memorize transmission
+                            pTxFrame = (tEplFrame*)1;
+                            // send NmtRequest
+                            Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ]);
+                            if (Ret != kEplSuccessful)
+                            {
+                                goto Exit;
+                            }
+
+                        }
+                    }
+
+                }
+                else if (ReqServiceId == kEplDllReqServiceUnspecified)
+                {   // unspecified invite
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL)
+                    {   // non-EPL frame does exist
+                        // check if frame is not empty and not being filled
+                        if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_FILLING)
+                        {
+                            /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN)
+                            {   // pad frame
+                                EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN;
+                            }*/
+                            // memorize transmission
+                            pTxFrame = (tEplFrame*)1;
+                            // send non-EPL frame
+                            Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL]);
+                            if (Ret != kEplSuccessful)
+                            {
+                                goto Exit;
+                            }
+
+                        }
+                    }
+
+                }
+                else if (ReqServiceId == kEplDllReqServiceNo)
+                {   // no async service requested -> do nothing
+                }
+            }
+
+#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
+            if (pTxFrame == NULL)
+            {   // signal process function readiness of PRes frame
+                Event.m_EventSink = kEplEventSinkDllk;
+                Event.m_EventType = kEplEventTypeDllkPresReady;
+                Event.m_uiSize = 0;
+                Event.m_pArg = NULL;
+                Ret = EplEventkPost(&Event);
+            }
+#endif
+
+            // inform PDO module
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+//            Ret = EplPdokCbSoa(&FrameInfo);
+#endif
+
+            // $$$ put SrcNodeId, NMT state and NetTime as HeartbeatEvent into eventqueue
+
+            // $$$ inform emergency protocol handling about flags
+            break;
+        }
+
+        case kEplMsgTypeAsnd:
+        {
+            // ASnd frame
+            NmtEvent = kEplNmtEventDllCeAsnd;
+
+            // ASnd service registered?
+            uiAsndServiceId = (unsigned int) AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            if ((EplDllkInstance_g.m_DllState >= kEplDllMsNonCyclic)
+                && ((((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndStatusResponse)
+                || (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse)))
+            {   // StatusRes or IdentRes received
+                uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
+                if ((EplDllkInstance_g.m_LastReqServiceId == ((tEplDllReqServiceId) uiAsndServiceId))
+                    && (uiNodeId == EplDllkInstance_g.m_uiLastTargetNodeId))
+                {   // mark request as responded
+                    EplDllkInstance_g.m_LastReqServiceId = kEplDllReqServiceNo;
+                }
+                if (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse)
+                {   // memorize MAC address of CN for PReq
+                tEplDllkNodeInfo*   pIntNodeInfo;
+
+                    pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId);
+                    if (pIntNodeInfo == NULL)
+                    {   // no node info structure available
+                        Ret = kEplDllNoNodeInfo;
+                    }
+                    else
+                    {
+                        EPL_MEMCPY(pIntNodeInfo->m_be_abMacAddr, pFrame->m_be_abSrcMac, 6);
+                    }
+                }
+
+                // forward Flag2 to asynchronous scheduler
+                bFlag1 = AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bFlag2);
+                Ret = EplDllkCalAsyncSetPendingRequests(uiNodeId,
+                    ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)),
+                    (bFlag1 & EPL_FRAME_FLAG2_RS));
+            }
+#endif
+
+            if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID)
+            {   // ASnd service ID is valid
+                if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterAny)
+                {   // ASnd service ID is registered
+                    // forward frame via async receive FIFO to userspace
+                    Ret = EplDllkCalAsyncFrameReceived(&FrameInfo);
+                }
+                else if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterLocal)
+                {   // ASnd service ID is registered, but only local node ID or broadcasts
+                    // shall be forwarded
+                    uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
+                    if ((uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)
+                        || (uiNodeId == EPL_C_ADR_BROADCAST))
+                    {   // ASnd frame is intended for us
+                        // forward frame via async receive FIFO to userspace
+                        Ret = EplDllkCalAsyncFrameReceived(&FrameInfo);
+                    }
+                }
+            }
+            break;
+        }
+
+        default:
+        {
+            break;
+        }
+    }
+
+    if (NmtEvent != kEplNmtEventNoEvent)
+    {   // event for DLL and NMT state machine generated
+        Ret = EplDllkChangeState(NmtEvent, NmtState);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        if ((NmtEvent != kEplNmtEventDllCeAsnd)
+            && ((NmtState <= kEplNmtCsPreOperational1) || (NmtEvent != kEplNmtEventDllCePres)))
+        {   // NMT state machine is not interested in ASnd frames and PRes frames when not CsNotActive or CsPreOp1
+            // inform NMT module
+            Event.m_EventSink = kEplEventSinkNmtk;
+            Event.m_EventType = kEplEventTypeNmtEvent;
+            Event.m_uiSize = sizeof (NmtEvent);
+            Event.m_pArg = &NmtEvent;
+            Ret = EplEventkPost(&Event);
+        }
+    }
+
+Exit:
+    if (Ret != kEplSuccessful)
+    {
+    DWORD   dwArg;
+
+        BENCHMARK_MOD_02_TOGGLE(9);
+
+        dwArg = EplDllkInstance_g.m_DllState | (NmtEvent << 8);
+
+        // Error event for API layer
+        Ret = EplEventkPostError(kEplEventSourceDllk,
+                        Ret,
+                        sizeof(dwArg),
+                        &dwArg);
+    }
+    BENCHMARK_MOD_02_RESET(3);
+    return;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCbFrameTransmitted()
+//
+// Description: called from EdrvInterruptHandler().
+//              It signals
+//
+// Parameters:  pRxBuffer_p             = receive buffer structure
+//
+// Returns:     (none)
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplEvent       Event;
+tEplDllAsyncReqPriority Priority;
+tEplNmtState    NmtState;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
+    && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)
+tEplFrameInfo   FrameInfo;
+#endif
+
+    NmtState = EplNmtkGetNmtState();
+
+    if (NmtState <= kEplNmtGsResetConfiguration)
+    {
+        goto Exit;
+    }
+
+    if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NMTREQ)
+    {   // frame from NMT request FIFO sent
+        // mark Tx-buffer as empty
+        pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+
+        // post event to DLL
+        Priority = kEplDllAsyncReqPrioNmt;
+        Event.m_EventSink = kEplEventSinkDllk;
+        Event.m_EventType = kEplEventTypeDllkFillTx;
+        EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+        Event.m_pArg = &Priority;
+        Event.m_uiSize = sizeof(Priority);
+        Ret = EplEventkPost(&Event);
+    }
+    else if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NONEPL)
+    {   // frame from generic priority FIFO sent
+        // mark Tx-buffer as empty
+        pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
+
+        // post event to DLL
+        Priority = kEplDllAsyncReqPrioGeneric;
+        Event.m_EventSink = kEplEventSinkDllk;
+        Event.m_EventType = kEplEventTypeDllkFillTx;
+        EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+        Event.m_pArg = &Priority;
+        Event.m_uiSize = sizeof(Priority);
+        Ret = EplEventkPost(&Event);
+    }
+#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
+    && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) \
+    || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    else if ((pTxBuffer_p->m_EplMsgType == kEplMsgTypePreq)
+        || (pTxBuffer_p->m_EplMsgType == kEplMsgTypePres))
+    {   // PRes resp. PReq frame sent
+
+        #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
+            && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE))
+        {
+            // inform PDO module
+            FrameInfo.m_pFrame = (tEplFrame *) pTxBuffer_p->m_pbBuffer;
+            FrameInfo.m_uiFrameSize = pTxBuffer_p->m_uiMaxBufferLen;
+            Ret = EplPdokCbPdoTransmitted(&FrameInfo);
+        }
+        #endif
+
+        #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        {
+            // if own Pres on MN, trigger SoA
+            if ((NmtState >= kEplNmtMsPreOperational2)
+                && (pTxBuffer_p == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]))
+            {
+                Ret = EplDllkChangeState(kEplNmtEventDllMeSoaTrig, NmtState);
+            }
+        }
+        #endif
+
+    #if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
+        goto Exit;
+    #endif
+    }
+#endif
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    else if (pTxBuffer_p->m_EplMsgType == kEplMsgTypeSoa)
+    {   // SoA frame sent
+    tEplNmtEvent NmtEvent = kEplNmtEventDllMeSoaSent;
+
+        // check if we are invited
+        if (EplDllkInstance_g.m_uiLastTargetNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)
+        {
+        tEplFrame      *pTxFrame;
+
+            if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceStatus)
+            {   // StatusRequest
+                if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL)
+                {   // StatusRes does exist
+
+                    pTxFrame = (tEplFrame *) EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer;
+                    // update StatusRes frame (NMT state, EN, EC, RS, PR flags)
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bNmtStatus, (BYTE) NmtState);
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bFlag1, EplDllkInstance_g.m_bFlag1);
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                    // send StatusRes
+                    Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES]);
+                    if (Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+                    TGT_DBG_SIGNAL_TRACE_POINT(8);
+
+                }
+            }
+            else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceIdent)
+            {   // IdentRequest
+                if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL)
+                {   // IdentRes does exist
+                    pTxFrame = (tEplFrame *) EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer;
+                    // update IdentRes frame (NMT state, RS, PR flags)
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_bNmtStatus, (BYTE) NmtState);
+                    AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse.m_le_bFlag2, EplDllkInstance_g.m_bFlag2);
+                    // send IdentRes
+                    Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES]);
+                    if (Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+                    TGT_DBG_SIGNAL_TRACE_POINT(7);
+                }
+            }
+            else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceNmtRequest)
+            {   // NmtRequest
+                if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL)
+                {   // NmtRequest does exist
+                    // check if frame is not empty and not being filled
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_FILLING)
+                    {
+                        // check if this frame is a NMT command,
+                        // then forward this frame back to NmtMnu module,
+                        // because it needs the time, when this frame is
+                        // actually sent, to start the timer for monitoring
+                        // the NMT state change.
+
+                        pTxFrame = (tEplFrame *) EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer;
+                        if ((AmiGetByteFromLe(&pTxFrame->m_le_bMessageType)
+                                == (BYTE) kEplMsgTypeAsnd)
+                            && (AmiGetByteFromLe(&pTxFrame->m_Data.m_Asnd.m_le_bServiceId)
+                                == (BYTE) kEplDllAsndNmtCommand))
+                        {   // post event directly to NmtMnu module
+                            Event.m_EventSink = kEplEventSinkNmtMnu;
+                            Event.m_EventType = kEplEventTypeNmtMnuNmtCmdSent;
+                            Event.m_uiSize = EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen;
+                            Event.m_pArg = pTxFrame;
+                            Ret = EplEventkPost(&Event);
+
+                        }
+
+                        // send NmtRequest
+                        Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ]);
+                        if (Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+
+                    }
+                }
+
+            }
+            else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceUnspecified)
+            {   // unspecified invite
+                if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL)
+                {   // non-EPL frame does exist
+                    // check if frame is not empty and not being filled
+                    if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_FILLING)
+                    {
+                        // send non-EPL frame
+                        Ret = EdrvSendTxMsg(&EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL]);
+                        if (Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+
+                    }
+                }
+            }
+            // ASnd frame was sent, remove the request
+            EplDllkInstance_g.m_LastReqServiceId = kEplDllReqServiceNo;
+        }
+
+        // forward event to ErrorHandler and PDO module
+        Event.m_EventSink = kEplEventSinkNmtk;
+        Event.m_EventType = kEplEventTypeNmtEvent;
+        Event.m_uiSize = sizeof (NmtEvent);
+        Event.m_pArg = &NmtEvent;
+        Ret = EplEventkPost(&Event);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+#endif
+
+#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
+    else
+    {   // d.k.: Why that else? on CN it is entered on IdentRes and StatusRes
+        goto Exit;
+    }
+
+    // signal process function readiness of PRes frame
+    Event.m_EventSink = kEplEventSinkDllk;
+    Event.m_EventType = kEplEventTypeDllkPresReady;
+    Event.m_uiSize = 0;
+    Event.m_pArg = NULL;
+    Ret = EplEventkPost(&Event);
+
+#endif
+
+Exit:
+    if (Ret != kEplSuccessful)
+    {
+    DWORD   dwArg;
+
+        BENCHMARK_MOD_02_TOGGLE(9);
+
+        dwArg = EplDllkInstance_g.m_DllState | (pTxBuffer_p->m_EplMsgType << 16);
+
+        // Error event for API layer
+        Ret = EplEventkPostError(kEplEventSourceDllk,
+                        Ret,
+                        sizeof(dwArg),
+                        &dwArg);
+    }
+
+    return;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCheckFrame()
+//
+// Description: check frame and set missing information
+//
+// Parameters:  pFrame_p                = ethernet frame
+//              uiFrameSize_p           = size of frame
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p, unsigned int uiFrameSize_p)
+{
+tEplMsgType     MsgType;
+WORD            wEtherType;
+
+    // check frame
+    if (pFrame_p != NULL)
+    {
+        // check SrcMAC
+        if (AmiGetQword48FromBe(pFrame_p->m_be_abSrcMac) == 0)
+        {
+            // source MAC address
+            EPL_MEMCPY(&pFrame_p->m_be_abSrcMac[0], &EplDllkInstance_g.m_be_abSrcMac[0], 6);
+        }
+
+        // check ethertype
+        wEtherType = AmiGetWordFromBe(&pFrame_p->m_be_wEtherType);
+        if (wEtherType == 0)
+        {
+            // assume EPL frame
+            wEtherType = EPL_C_DLL_ETHERTYPE_EPL;
+            AmiSetWordToBe(&pFrame_p->m_be_wEtherType, wEtherType);
+        }
+
+        if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL)
+        {
+            // source node ID
+            AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId, (BYTE) EplDllkInstance_g.m_DllConfigParam.m_uiNodeId);
+
+            // check message type
+            MsgType = AmiGetByteFromLe(&pFrame_p->m_le_bMessageType);
+            if (MsgType == 0)
+            {
+                MsgType = kEplMsgTypeAsnd;
+                AmiSetByteToLe(&pFrame_p->m_le_bMessageType, (BYTE) MsgType);
+            }
+
+            if (MsgType == kEplMsgTypeAsnd)
+            {
+                // destination MAC address
+                AmiSetQword48ToBe(&pFrame_p->m_be_abDstMac[0], EPL_C_DLL_MULTICAST_ASND);
+            }
+
+        }
+    }
+
+    return kEplSuccessful;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCbCnTimer()
+//
+// Description: called by timer module. It monitors the EPL cycle when it is a CN.
+//
+// Parameters:  pEventArg_p             = timer event argument
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg* pEventArg_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplNmtState    NmtState;
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle)
+    {   // zombie callback
+        // just exit
+        goto Exit;
+    }
+#endif
+
+    NmtState = EplNmtkGetNmtState();
+
+    if (NmtState <= kEplNmtGsResetConfiguration)
+    {
+        goto Exit;
+    }
+
+    Ret = EplDllkChangeState(kEplNmtEventDllCeFrameTimeout, NmtState);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // 2008/10/15 d.k. reprogramming of timer not necessary,
+    // because it will be programmed, when SoC is received.
+/*
+    // reprogram timer
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    if ((NmtState > kEplNmtCsPreOperational1)
+        && (EplDllkInstance_g.m_ullFrameTimeout != 0))
+    {
+        Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle, EplDllkInstance_g.m_ullFrameTimeout, EplDllkCbCnTimer, 0L, FALSE);
+    }
+#endif
+*/
+
+Exit:
+    if (Ret != kEplSuccessful)
+    {
+    DWORD   dwArg;
+
+        BENCHMARK_MOD_02_TOGGLE(9);
+
+        dwArg = EplDllkInstance_g.m_DllState | (kEplNmtEventDllCeFrameTimeout << 8);
+
+        // Error event for API layer
+        Ret = EplEventkPostError(kEplEventSourceDllk,
+                        Ret,
+                        sizeof(dwArg),
+                        &dwArg);
+    }
+
+    return Ret;
+}
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCbMnTimerCycle()
+//
+// Description: called by timer module. It triggers the SoC when it is a MN.
+//
+// Parameters:  pEventArg_p             = timer event argument
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg* pEventArg_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplNmtState    NmtState;
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle)
+    {   // zombie callback
+        // just exit
+        goto Exit;
+    }
+#endif
+
+    NmtState = EplNmtkGetNmtState();
+
+    if (NmtState <= kEplNmtGsResetConfiguration)
+    {
+        goto Exit;
+    }
+
+    Ret = EplDllkChangeState(kEplNmtEventDllMeSocTrig, NmtState);
+
+Exit:
+    if (Ret != kEplSuccessful)
+    {
+    DWORD   dwArg;
+
+        BENCHMARK_MOD_02_TOGGLE(9);
+
+        dwArg = EplDllkInstance_g.m_DllState | (kEplNmtEventDllMeSocTrig << 8);
+
+        // Error event for API layer
+        Ret = EplEventkPostError(kEplEventSourceDllk,
+                        Ret,
+                        sizeof(dwArg),
+                        &dwArg);
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCbMnTimerResponse()
+//
+// Description: called by timer module. It monitors the PRes timeout.
+//
+// Parameters:  pEventArg_p             = timer event argument
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg* pEventArg_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplNmtState    NmtState;
+
+#if EPL_TIMER_USE_HIGHRES != FALSE
+    if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlResponse)
+    {   // zombie callback
+        // just exit
+        goto Exit;
+    }
+#endif
+
+    NmtState = EplNmtkGetNmtState();
+
+    if (NmtState <= kEplNmtGsResetConfiguration)
+    {
+        goto Exit;
+    }
+
+    Ret = EplDllkChangeState(kEplNmtEventDllMePresTimeout, NmtState);
+
+Exit:
+    if (Ret != kEplSuccessful)
+    {
+    DWORD   dwArg;
+
+        BENCHMARK_MOD_02_TOGGLE(9);
+
+        dwArg = EplDllkInstance_g.m_DllState | (kEplNmtEventDllMePresTimeout << 8);
+
+        // Error event for API layer
+        Ret = EplEventkPostError(kEplEventSourceDllk,
+                        Ret,
+                        sizeof(dwArg),
+                        &dwArg);
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkGetNodeInfo()
+//
+// Description: returns node info structure of the specified node.
+//
+// Parameters:  uiNodeId_p              = node ID
+//
+// Returns:     tEplDllkNodeInfo*       = pointer to internal node info structure
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplDllkNodeInfo* EplDllkGetNodeInfo(unsigned int uiNodeId_p)
+{
+    // $$$ d.k.: use hash algorithm to retrieve the appropriate node info structure
+    //           if size of array is less than 254.
+    uiNodeId_p--;   // node ID starts at 1 but array at 0
+    if (uiNodeId_p >= tabentries (EplDllkInstance_g.m_aNodeInfo))
+    {
+        return NULL;
+    }
+    else
+    {
+        return &EplDllkInstance_g.m_aNodeInfo[uiNodeId_p];
+    }
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkMnSendSoa()
+//
+// Description: it updates and transmits the SoA.
+//
+// Parameters:  NmtState_p              = current NMT state
+//              pDllStateProposed_p     = proposed DLL state
+//              fEnableInvitation_p     = enable invitation for asynchronous phase
+//                                        it will be disabled for EPL_C_DLL_PREOP1_START_CYCLES SoAs
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
+                                   tEplDllState* pDllStateProposed_p,
+                                   BOOL fEnableInvitation_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEdrvTxBuffer  *pTxBuffer = NULL;
+tEplFrame      *pTxFrame;
+tEplDllkNodeInfo*   pNodeInfo;
+
+    *pDllStateProposed_p = kEplDllMsNonCyclic;
+
+    pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOA];
+    if (pTxBuffer->m_pbBuffer != NULL)
+    {   // SoA does exist
+        pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+
+        if (fEnableInvitation_p != FALSE)
+        {   // fetch target of asynchronous phase
+            if (EplDllkInstance_g.m_bFlag2 == 0)
+            {   // own queues are empty
+                EplDllkInstance_g.m_LastReqServiceId = kEplDllReqServiceNo;
+            }
+            else if (((tEplDllAsyncReqPriority) (EplDllkInstance_g.m_bFlag2 >> EPL_FRAME_FLAG2_PR_SHIFT)) == kEplDllAsyncReqPrioNmt)
+            {   // frames in own NMT request queue available
+                EplDllkInstance_g.m_LastReqServiceId = kEplDllReqServiceNmtRequest;
+            }
+            else
+            {
+                EplDllkInstance_g.m_LastReqServiceId = kEplDllReqServiceUnspecified;
+            }
+            Ret = EplDllkCalAsyncGetSoaRequest(&EplDllkInstance_g.m_LastReqServiceId, &EplDllkInstance_g.m_uiLastTargetNodeId);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+            if (EplDllkInstance_g.m_LastReqServiceId != kEplDllReqServiceNo)
+            {   // asynchronous phase will be assigned to one node
+                if (EplDllkInstance_g.m_uiLastTargetNodeId == EPL_C_ADR_INVALID)
+                {   // exchange invalid node ID with local node ID
+                    EplDllkInstance_g.m_uiLastTargetNodeId = EplDllkInstance_g.m_DllConfigParam.m_uiNodeId;
+                    // d.k. DLL state WaitAsndTrig is not helpful;
+                    //      so just step over to WaitSocTrig,
+                    //      because own ASnd is sent automatically in CbFrameTransmitted() after SoA.
+                    //*pDllStateProposed_p = kEplDllMsWaitAsndTrig;
+                    *pDllStateProposed_p = kEplDllMsWaitSocTrig;
+                }
+                else
+                {   // assignment to CN
+                    *pDllStateProposed_p = kEplDllMsWaitAsnd;
+                }
+
+                pNodeInfo = EplDllkGetNodeInfo(EplDllkInstance_g.m_uiLastTargetNodeId);
+                if (pNodeInfo == NULL)
+                {   // no node info structure available
+                    Ret = kEplDllNoNodeInfo;
+                    goto Exit;
+                }
+
+                // update frame (EA, ER flags)
+                AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1,
+                    pNodeInfo->m_bSoaFlag1 & (EPL_FRAME_FLAG1_EA | EPL_FRAME_FLAG1_ER));
+            }
+            else
+            {   // no assignment of asynchronous phase
+                *pDllStateProposed_p = kEplDllMsWaitSocTrig;
+                EplDllkInstance_g.m_uiLastTargetNodeId = EPL_C_ADR_INVALID;
+            }
+
+            // update frame (target)
+            AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bReqServiceId, (BYTE) EplDllkInstance_g.m_LastReqServiceId);
+            AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bReqServiceTarget, (BYTE) EplDllkInstance_g.m_uiLastTargetNodeId);
+
+        }
+        else
+        {   // invite nobody
+            // update frame (target)
+            AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bReqServiceId, (BYTE) 0);
+            AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bReqServiceTarget, (BYTE) 0);
+        }
+
+        // update frame (NMT state)
+        AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus, (BYTE) NmtState_p);
+
+        // send SoA frame
+        Ret = EdrvSendTxMsg(pTxBuffer);
+    }
+
+Exit:
+     return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkMnSendSoc()
+//
+// Description: it updates and transmits the SoA.
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDllkMnSendSoc(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEdrvTxBuffer*  pTxBuffer = NULL;
+tEplFrame*      pTxFrame;
+tEplEvent       Event;
+
+    pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOC];
+    if (pTxBuffer->m_pbBuffer != NULL)
+    {   // SoC does exist
+        pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+
+        // $$$ update NetTime
+
+        // send SoC frame
+        Ret = EdrvSendTxMsg(pTxBuffer);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        // trigger synchronous task
+        Event.m_EventSink = kEplEventSinkSync;
+        Event.m_EventType = kEplEventTypeSync;
+        Event.m_uiSize = 0;
+        Ret = EplEventkPost(&Event);
+    }
+
+Exit:
+     return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkMnSendPreq()
+//
+// Description: it updates and transmits the PReq for the next isochronous CN
+//              or own PRes if enabled.
+//
+// Parameters:  NmtState_p              = current NMT state
+//              pDllStateProposed_p     = proposed DLL state
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
+                                    tEplDllState* pDllStateProposed_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEdrvTxBuffer  *pTxBuffer = NULL;
+tEplFrame      *pTxFrame;
+BYTE            bFlag1 = 0;
+
+
+    if (EplDllkInstance_g.m_pCurNodeInfo == NULL)
+    {   // start with first isochronous CN
+        EplDllkInstance_g.m_pCurNodeInfo = EplDllkInstance_g.m_pFirstNodeInfo;
+    }
+    else
+    {   // iterate to next isochronous CN
+        EplDllkInstance_g.m_pCurNodeInfo = EplDllkInstance_g.m_pCurNodeInfo->m_pNextNodeInfo;
+    }
+
+    if (EplDllkInstance_g.m_pCurNodeInfo == NULL)
+    {   // last isochronous CN reached
+        Ret = EplDllkMnSendSoa(NmtState_p, pDllStateProposed_p, TRUE);
+        goto Exit;
+    }
+    else
+    {
+        pTxBuffer = EplDllkInstance_g.m_pCurNodeInfo->m_pPreqTxBuffer;
+        bFlag1 = EplDllkInstance_g.m_pCurNodeInfo->m_bSoaFlag1 & EPL_FRAME_FLAG1_EA;
+        *pDllStateProposed_p = kEplDllMsWaitPres;
+
+        // start PRes Timer
+        // $$$ d.k.: maybe move this call to CbFrameTransmitted(), because the time should run from there
+#if EPL_TIMER_USE_HIGHRES != FALSE
+        Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlResponse,
+            EplDllkInstance_g.m_pCurNodeInfo->m_dwPresTimeout,
+            EplDllkCbMnTimerResponse,
+            0L,
+            FALSE);
+#endif
+    }
+
+    if (pTxBuffer == NULL)
+    {   // PReq does not exist
+        Ret = kEplDllTxBufNotReady;
+        goto Exit;
+    }
+
+    pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
+
+    if (pTxFrame != NULL)
+    {   // PReq does exist
+        if (NmtState_p == kEplNmtMsOperational)
+        {   // leave RD flag untouched
+            bFlag1 |= AmiGetByteFromLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1) & EPL_FRAME_FLAG1_RD;
+        }
+
+        if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])
+        {   // PRes of MN will be sent
+            // update NMT state
+            AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus, (BYTE) NmtState_p);
+            *pDllStateProposed_p = kEplDllMsWaitSoaTrig;
+        }
+
+        // $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary
+        // update frame (Flag1)
+        AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, bFlag1);
+
+        // calculate frame size from payload size
+        pTxBuffer->m_uiTxMsgLen = AmiGetWordFromLe(&pTxFrame->m_Data.m_Preq.m_le_wSize) + 24;
+
+        // send PReq frame
+        Ret = EdrvSendTxMsg(pTxBuffer);
+    }
+    else
+    {
+        Ret = kEplDllTxFrameInvalid;
+    }
+
+Exit:
+     return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkAsyncFrameNotReceived()
+//
+// Description: passes empty ASnd frame to receive FIFO.
+//              It will be called only for frames with registered AsndServiceIds
+//              (only kEplDllAsndFilterAny).
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId ReqServiceId_p, unsigned int uiNodeId_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+BYTE            abBuffer[18];
+tEplFrame*      pFrame = (tEplFrame*) abBuffer;
+tEplFrameInfo   FrameInfo;
+
+    // check if previous SoA invitation was not answered
+    switch (ReqServiceId_p)
+    {
+        case kEplDllReqServiceIdent:
+        case kEplDllReqServiceStatus:
+            // ASnd service registered?
+            if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny)
+            {   // ASnd service ID is registered
+                AmiSetByteToLe(&pFrame->m_le_bSrcNodeId, (BYTE) uiNodeId_p);
+                // EPL MsgType ASnd
+                AmiSetByteToLe(&pFrame->m_le_bMessageType, (BYTE) kEplMsgTypeAsnd);
+                // ASnd Service ID
+                AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId, (BYTE) ReqServiceId_p);
+                // create frame info structure
+                FrameInfo.m_pFrame = pFrame;
+                FrameInfo.m_uiFrameSize = 18;   // empty non existing ASnd frame
+                // forward frame via async receive FIFO to userspace
+                Ret = EplDllkCalAsyncFrameReceived(&FrameInfo);
+            }
+            break;
+        default:
+            // no invitation issued or it was successfully answered or it is uninteresting
+            break;
+    }
+
+    return Ret;
+}
+
+
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+// EOF
+
diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c
new file mode 100644 (file)
index 0000000..de67e5b
--- /dev/null
@@ -0,0 +1,1193 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for kernel DLL Communication Abstraction Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDllkCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.7 $  $Date: 2008/11/13 17:13:09 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/15 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "kernel/EplDllkCal.h"
+#include "kernel/EplDllk.h"
+#include "kernel/EplEventk.h"
+
+#include "EplDllCal.h"
+#ifndef EPL_NO_FIFO
+#include "SharedBuff.h"
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef min
+#define min(a,b)            (((a) < (b)) ? (a) : (b))
+#endif
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplDllkCal                                          */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPL_DLLKCAL_MAX_QUEUES  5   // CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+#ifndef EPL_NO_FIFO
+//    tShbInstance    m_ShbInstanceRx;      // FIFO for Rx ASnd frames
+    tShbInstance    m_ShbInstanceTxNmt;   // FIFO for Tx frames with NMT request priority
+    tShbInstance    m_ShbInstanceTxGen;   // FIFO for Tx frames with generic priority
+#else
+    unsigned int    m_uiFrameSizeNmt;
+    BYTE            m_abFrameNmt[1500];
+    unsigned int    m_uiFrameSizeGen;
+    BYTE            m_abFrameGen[1500];
+#endif
+
+    tEplDllkCalStatistics   m_Statistics;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // IdentRequest queue with CN node IDs
+    unsigned int    m_auiQueueIdentReq[EPL_D_NMT_MaxCNNumber_U8 + 1];   // 1 entry is reserved to distinguish between full and empty
+    unsigned int    m_uiWriteIdentReq;
+    unsigned int    m_uiReadIdentReq;
+
+    // StatusRequest queue with CN node IDs
+    unsigned int    m_auiQueueStatusReq[EPL_D_NMT_MaxCNNumber_U8 + 1];  // 1 entry is reserved to distinguish between full and empty
+    unsigned int    m_uiWriteStatusReq;
+    unsigned int    m_uiReadStatusReq;
+
+    unsigned int    m_auiQueueCnRequests[254 * 2];
+        // first 254 entries represent the generic requests of the corresponding node
+        // second 254 entries represent the NMT requests of the corresponding node
+    unsigned int    m_uiNextQueueCnRequest;
+    unsigned int    m_uiNextRequestQueue;
+#endif
+
+} tEplDllkCalInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+// if no dynamic memory allocation shall be used
+// define structures statically
+static tEplDllkCalInstance     EplDllkCalInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAddInstance()
+//
+// Description: add and initialize new instance of DLL CAL module
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAddInstance()
+{
+tEplKernel      Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+unsigned int    fShbNewCreated;
+
+/*    ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_RX, EPL_DLLCAL_BUFFER_ID_RX,
+        &EplDllkCalInstance_g.m_ShbInstanceRx, &fShbNewCreated);
+    // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
+
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+*/
+    ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_TX_NMT, EPL_DLLCAL_BUFFER_ID_TX_NMT,
+        &EplDllkCalInstance_g.m_ShbInstanceTxNmt, &fShbNewCreated);
+    // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
+
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+
+/*    ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal);
+    // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
+
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+*/
+    ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_TX_GEN, EPL_DLLCAL_BUFFER_ID_TX_GEN,
+        &EplDllkCalInstance_g.m_ShbInstanceTxGen, &fShbNewCreated);
+    // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
+
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+
+/*    ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxGen, EplDllkCalTxGenSignalHandler, kShbPriorityNormal);
+    // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
+
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+*/
+#else
+    EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+    EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalDelInstance()
+//
+// Description: deletes instance of DLL CAL module
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalDelInstance()
+{
+tEplKernel      Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+
+/*    ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceRx);
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+    EplDllkCalInstance_g.m_ShbInstanceRx = NULL;
+*/
+    ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceTxNmt);
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+    EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL;
+
+    ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceTxGen);
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+    }
+    EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL;
+
+#else
+    EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+    EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalProcess
+//
+// Description: process the passed configuration
+//
+// Parameters:  pEvent_p                = event containing configuration options
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    switch (pEvent_p->m_EventType)
+    {
+        case kEplEventTypeDllkServFilter:
+        {
+        tEplDllCalAsndServiceIdFilter*  pServFilter;
+
+            pServFilter = (tEplDllCalAsndServiceIdFilter*) pEvent_p->m_pArg;
+            Ret = EplDllkSetAsndServiceIdFilter(pServFilter->m_ServiceId, pServFilter->m_Filter);
+            break;
+        }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        case kEplEventTypeDllkIssueReq:
+        {
+        tEplDllCalIssueRequest*  pIssueReq;
+
+            pIssueReq = (tEplDllCalIssueRequest*) pEvent_p->m_pArg;
+            Ret = EplDllkCalIssueRequest(pIssueReq->m_Service, pIssueReq->m_uiNodeId, pIssueReq->m_bSoaFlag1);
+            break;
+        }
+
+        case kEplEventTypeDllkAddNode:
+        {
+        tEplDllNodeInfo*    pNodeInfo;
+
+            pNodeInfo = (tEplDllNodeInfo*) pEvent_p->m_pArg;
+            Ret = EplDllkAddNode(pNodeInfo);
+            break;
+        }
+
+        case kEplEventTypeDllkDelNode:
+        {
+        unsigned int*   puiNodeId;
+
+            puiNodeId = (unsigned int*) pEvent_p->m_pArg;
+            Ret = EplDllkDeleteNode(*puiNodeId);
+            break;
+        }
+
+        case kEplEventTypeDllkSoftDelNode:
+        {
+        unsigned int*   puiNodeId;
+
+            puiNodeId = (unsigned int*) pEvent_p->m_pArg;
+            Ret = EplDllkSoftDeleteNode(*puiNodeId);
+            break;
+        }
+#endif
+
+        case kEplEventTypeDllkIdentity:
+        {
+        tEplDllIdentParam*  pIdentParam;
+
+            pIdentParam = (tEplDllIdentParam*) pEvent_p->m_pArg;
+            if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize)
+            {
+                pIdentParam->m_uiSizeOfStruct = pEvent_p->m_uiSize;
+            }
+            Ret = EplDllkSetIdentity(pIdentParam);
+            break;
+        }
+
+        case kEplEventTypeDllkConfig:
+        {
+        tEplDllConfigParam* pConfigParam;
+
+            pConfigParam = (tEplDllConfigParam*) pEvent_p->m_pArg;
+            if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize)
+            {
+                pConfigParam->m_uiSizeOfStruct = pEvent_p->m_uiSize;
+            }
+            Ret = EplDllkConfig(pConfigParam);
+            break;
+        }
+
+        default:
+            break;
+    }
+
+//Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncGetTxCount()
+//
+// Description: returns count of Tx frames of FIFO with highest priority
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p, unsigned int * puiCount_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+unsigned long   ulFrameCount;
+
+    // get frame count of Tx FIFO with NMT request priority
+    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulFrameCount);
+    // returns kShbOk, kShbInvalidArg
+
+    // error handling
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    if (ulFrameCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulFrameCount;
+    }
+
+    if (ulFrameCount != 0)
+    {   // NMT requests are in queue
+        *pPriority_p = kEplDllAsyncReqPrioNmt;
+        *puiCount_p = (unsigned int) ulFrameCount;
+        goto Exit;
+    }
+
+    // get frame count of Tx FIFO with generic priority
+    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulFrameCount);
+    // returns kShbOk, kShbInvalidArg
+
+    // error handling
+    if (ShbError != kShbOk)
+    {
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    if (ulFrameCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulFrameCount;
+    }
+
+    *pPriority_p = kEplDllAsyncReqPrioGeneric;
+    *puiCount_p = (unsigned int) ulFrameCount;
+
+Exit:
+#else
+    if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0)
+    {
+        *pPriority_p = kEplDllAsyncReqPrioNmt;
+        *puiCount_p = 1;
+    }
+    else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0)
+    {
+        *pPriority_p = kEplDllAsyncReqPrioGeneric;
+        *puiCount_p = 1;
+    }
+    else
+    {
+        *pPriority_p = kEplDllAsyncReqPrioGeneric;
+        *puiCount_p = 0;
+    }
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncGetTxFrame()
+//
+// Description: returns Tx frames from FIFO with specified priority
+//
+// Parameters:  pFrame_p                = IN: pointer to buffer
+//              puiFrameSize_p          = IN: max size of buffer
+//                                        OUT: actual size of frame
+//              Priority_p              = IN: priority
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncGetTxFrame(void * pFrame_p, unsigned int * puiFrameSize_p, tEplDllAsyncReqPriority Priority_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+unsigned long   ulFrameSize;
+
+    switch (Priority_p)
+    {
+        case kEplDllAsyncReqPrioNmt:    // NMT request priority
+            ShbError = ShbCirReadDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxNmt, (BYTE *) pFrame_p, *puiFrameSize_p, &ulFrameSize);
+            // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
+            break;
+
+        default:    // generic priority
+            ShbError = ShbCirReadDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxGen, (BYTE *) pFrame_p, *puiFrameSize_p, &ulFrameSize);
+            // returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
+            break;
+
+    }
+
+    // error handling
+    if (ShbError != kShbOk)
+    {
+        if (ShbError == kShbNoReadableData)
+        {
+            Ret = kEplDllAsyncTxBufferEmpty;
+        }
+        else
+        {   // other error
+            Ret = kEplNoResource;
+        }
+        goto Exit;
+    }
+
+    *puiFrameSize_p = (unsigned int) ulFrameSize;
+
+Exit:
+#else
+    switch (Priority_p)
+    {
+        case kEplDllAsyncReqPrioNmt:    // NMT request priority
+            *puiFrameSize_p = min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeNmt);
+            EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameNmt, *puiFrameSize_p);
+            EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+            break;
+
+        default:    // generic priority
+            *puiFrameSize_p = min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeGen);
+            EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameGen, *puiFrameSize_p);
+            EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+            break;
+    }
+
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncFrameReceived()
+//
+// Description: passes ASnd frame to receive FIFO.
+//              It will be called only for frames with registered AsndServiceIds.
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+tEplEvent   Event;
+
+    Event.m_EventSink = kEplEventSinkDlluCal;
+    Event.m_EventType = kEplEventTypeAsndRx;
+    Event.m_pArg = pFrameInfo_p->m_pFrame;
+    Event.m_uiSize = pFrameInfo_p->m_uiFrameSize;
+    // pass NetTime of frame to userspace
+    Event.m_NetTime = pFrameInfo_p->m_NetTime;
+
+    Ret = EplEventkPost(&Event);
+    if (Ret != kEplSuccessful)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++;
+    }
+    else
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++;
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncSend()
+//
+// Description: puts the given frame into the transmit FIFO with the specified
+//              priority.
+//
+// Parameters:  pFrameInfo_p            = frame info structure
+//              Priority_p              = priority
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+tEplEvent       Event;
+#ifndef EPL_NO_FIFO
+tShbError   ShbError;
+
+    switch (Priority_p)
+    {
+        case kEplDllAsyncReqPrioNmt:    // NMT request priority
+            ShbError = ShbCirWriteDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
+            // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
+            break;
+
+        default:    // generic priority
+            ShbError = ShbCirWriteDataBlock (EplDllkCalInstance_g.m_ShbInstanceTxGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
+            // returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
+            break;
+
+    }
+
+    // error handling
+    switch (ShbError)
+    {
+        case kShbOk:
+            break;
+
+        case kShbExceedDataSizeLimit:
+            Ret = kEplDllAsyncTxBufferFull;
+            break;
+
+        case kShbBufferFull:
+            Ret = kEplDllAsyncTxBufferFull;
+            break;
+
+        case kShbInvalidArg:
+        default:
+            Ret = kEplNoResource;
+            break;
+    }
+
+#else
+
+    switch (Priority_p)
+    {
+        case kEplDllAsyncReqPrioNmt:    // NMT request priority
+            if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0)
+            {
+                EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
+                EplDllkCalInstance_g.m_uiFrameSizeNmt = pFrameInfo_p->m_uiFrameSize;
+            }
+            else
+            {
+                Ret = kEplDllAsyncTxBufferFull;
+                goto Exit;
+            }
+            break;
+
+        default:    // generic priority
+            if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0)
+            {
+                EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen, pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
+                EplDllkCalInstance_g.m_uiFrameSizeGen = pFrameInfo_p->m_uiFrameSize;
+            }
+            else
+            {
+                Ret = kEplDllAsyncTxBufferFull;
+                goto Exit;
+            }
+            break;
+    }
+
+#endif
+
+    // post event to DLL
+    Event.m_EventSink = kEplEventSinkDllk;
+    Event.m_EventType = kEplEventTypeDllkFillTx;
+    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+    Event.m_pArg = &Priority_p;
+    Event.m_uiSize = sizeof(Priority_p);
+    Ret = EplEventkPost(&Event);
+
+#ifdef EPL_NO_FIFO
+Exit:
+#endif
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncClearBuffer()
+//
+// Description: clears the transmit buffer
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncClearBuffer(void)
+{
+tEplKernel  Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+tShbError   ShbError;
+
+    ShbError = ShbCirResetBuffer (EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000, NULL);
+    ShbError = ShbCirResetBuffer (EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000, NULL);
+
+#else
+    EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
+    EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
+#endif
+
+//    EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics));
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncClearQueues()
+//
+// Description: clears the transmit buffer
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+tEplKernel EplDllkCalAsyncClearQueues(void)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    // clear MN asynchronous queues
+    EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
+    EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
+    EplDllkCalInstance_g.m_uiReadIdentReq = 0;
+    EplDllkCalInstance_g.m_uiWriteIdentReq = 0;
+    EplDllkCalInstance_g.m_uiReadStatusReq = 0;
+    EplDllkCalInstance_g.m_uiWriteStatusReq = 0;
+
+    return Ret;
+}
+#endif
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalGetStatistics()
+//
+// Description: returns statistics of the asynchronous queues.
+//
+// Parameters:  ppStatistics            = statistics structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
+{
+tEplKernel  Ret = kEplSuccessful;
+#ifndef EPL_NO_FIFO
+tShbError   ShbError;
+
+    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt);
+    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen);
+//    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceRx, &EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount);
+
+#else
+    if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1;
+    }
+    else
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0;
+    }
+    if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1;
+    }
+    else
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0;
+    }
+#endif
+
+    *ppStatistics = &EplDllkCalInstance_g.m_Statistics;
+    return Ret;
+}
+
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalIssueRequest()
+//
+// Description: issues a StatusRequest or a IdentRequest to the specified node.
+//
+// Parameters:  Service_p               = request service ID
+//              uiNodeId_p              = node ID
+//              bSoaFlag1_p             = flag1 for this node (transmit in SoA and PReq)
+//                                        If 0xFF this flag is ignored.
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p, unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    if (bSoaFlag1_p != 0xFF)
+    {
+        Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+
+    // add node to appropriate request queue
+    switch (Service_p)
+    {
+        case kEplDllReqServiceIdent:
+        {
+            if (((EplDllkCalInstance_g.m_uiWriteIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq))
+                == EplDllkCalInstance_g.m_uiReadIdentReq)
+            {   // queue is full
+                Ret = kEplDllAsyncTxBufferFull;
+                goto Exit;
+            }
+            EplDllkCalInstance_g.m_auiQueueIdentReq[EplDllkCalInstance_g.m_uiWriteIdentReq] = uiNodeId_p;
+            EplDllkCalInstance_g.m_uiWriteIdentReq =
+                (EplDllkCalInstance_g.m_uiWriteIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq);
+            break;
+        }
+
+        case kEplDllReqServiceStatus:
+        {
+            if (((EplDllkCalInstance_g.m_uiWriteStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq))
+                == EplDllkCalInstance_g.m_uiReadStatusReq)
+            {   // queue is full
+                Ret = kEplDllAsyncTxBufferFull;
+                goto Exit;
+            }
+            EplDllkCalInstance_g.m_auiQueueStatusReq[EplDllkCalInstance_g.m_uiWriteStatusReq] = uiNodeId_p;
+            EplDllkCalInstance_g.m_uiWriteStatusReq =
+                (EplDllkCalInstance_g.m_uiWriteStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq);
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplDllInvalidParam;
+            goto Exit;
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncGetSoaRequest()
+//
+// Description: returns next request for SoA. This function is called by DLLk module.
+//
+// Parameters:  pReqServiceId_p         = pointer to request service ID
+//                                        IN: available request for MN NMT or generic request queue (Flag2.PR)
+//                                            or kEplDllReqServiceNo if queues are empty
+//                                        OUT: next request
+//              puiNodeId_p             = OUT: pointer to node ID of next request
+//                                             = EPL_C_ADR_INVALID, if request is self addressed
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId* pReqServiceId_p, unsigned int* puiNodeId_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiCount;
+
+//    *pReqServiceId_p = kEplDllReqServiceNo;
+
+    for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--)
+    {
+        switch (EplDllkCalInstance_g.m_uiNextRequestQueue)
+        {
+            case 0:
+            {   // CnGenReq
+                for (;EplDllkCalInstance_g.m_uiNextQueueCnRequest < (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2);
+                    EplDllkCalInstance_g.m_uiNextQueueCnRequest++)
+                {
+                    if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0)
+                    {   // non empty queue found
+                        // remove one request from queue
+                        EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest]--;
+                        *puiNodeId_p = EplDllkCalInstance_g.m_uiNextQueueCnRequest + 1;
+                        *pReqServiceId_p = kEplDllReqServiceUnspecified;
+                        EplDllkCalInstance_g.m_uiNextQueueCnRequest++;
+                        if (EplDllkCalInstance_g.m_uiNextQueueCnRequest >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
+                        {   // last node reached
+                            // continue with CnNmtReq queue at next SoA
+                            EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
+                        }
+                        goto Exit;
+                    }
+                }
+                // all CnGenReq queues are empty -> continue with CnNmtReq queue
+                EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
+                break;
+            }
+
+            case 1:
+            {   // CnNmtReq
+                for (;EplDllkCalInstance_g.m_uiNextQueueCnRequest < tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests);
+                    EplDllkCalInstance_g.m_uiNextQueueCnRequest++)
+                {
+                    if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0)
+                    {   // non empty queue found
+                        // remove one request from queue
+                        EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest]--;
+                        *puiNodeId_p = EplDllkCalInstance_g.m_uiNextQueueCnRequest + 1 - (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2);
+                        *pReqServiceId_p = kEplDllReqServiceNmtRequest;
+                        EplDllkCalInstance_g.m_uiNextQueueCnRequest++;
+                        if (EplDllkCalInstance_g.m_uiNextQueueCnRequest > tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests))
+                        {   // last node reached
+                            // restart CnGenReq queue
+                            EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
+                            // continue with MnGenReq queue at next SoA
+                            EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
+                        }
+                        goto Exit;
+                    }
+                }
+                // restart CnGenReq queue
+                EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
+                // all CnNmtReq queues are empty -> continue with MnGenReq queue
+                EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
+                break;
+            }
+
+            case 2:
+            {   // MnNmtReq and MnGenReq
+                // next queue will be MnIdentReq queue
+                EplDllkCalInstance_g.m_uiNextRequestQueue = 3;
+                if (*pReqServiceId_p != kEplDllReqServiceNo)
+                {
+                    *puiNodeId_p = EPL_C_ADR_INVALID;   // DLLk must exchange this with the actual node ID
+                    goto Exit;
+                }
+                break;
+            }
+
+            case 3:
+            {   // MnIdentReq
+                // next queue will be MnStatusReq queue
+                EplDllkCalInstance_g.m_uiNextRequestQueue = 4;
+                if (EplDllkCalInstance_g.m_uiReadIdentReq != EplDllkCalInstance_g.m_uiWriteIdentReq)
+                {   // queue is not empty
+                    *puiNodeId_p = EplDllkCalInstance_g.m_auiQueueIdentReq[EplDllkCalInstance_g.m_uiReadIdentReq];
+                    EplDllkCalInstance_g.m_uiReadIdentReq =
+                        (EplDllkCalInstance_g.m_uiReadIdentReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueIdentReq);
+                    *pReqServiceId_p = kEplDllReqServiceIdent;
+                    goto Exit;
+                }
+                break;
+            }
+
+            case 4:
+            {   // MnStatusReq
+                // next queue will be CnGenReq queue
+                EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
+                if (EplDllkCalInstance_g.m_uiReadStatusReq != EplDllkCalInstance_g.m_uiWriteStatusReq)
+                {   // queue is not empty
+                    *puiNodeId_p = EplDllkCalInstance_g.m_auiQueueStatusReq[EplDllkCalInstance_g.m_uiReadStatusReq];
+                    EplDllkCalInstance_g.m_uiReadStatusReq =
+                        (EplDllkCalInstance_g.m_uiReadStatusReq + 1) % tabentries (EplDllkCalInstance_g.m_auiQueueStatusReq);
+                    *pReqServiceId_p = kEplDllReqServiceStatus;
+                    goto Exit;
+                }
+                break;
+            }
+
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDllkCalAsyncSetPendingRequests()
+//
+// Description: sets the pending asynchronous frame requests of the specified node.
+//              This will add the node to the asynchronous request scheduler.
+//
+// Parameters:  uiNodeId_p              = node ID
+//              AsyncReqPrio_p          = asynchronous request priority
+//              uiCount_p               = count of asynchronous frames
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p, tEplDllAsyncReqPriority AsyncReqPrio_p, unsigned int uiCount_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    // add node to appropriate request queue
+    switch (AsyncReqPrio_p)
+    {
+        case kEplDllAsyncReqPrioNmt:
+        {
+            uiNodeId_p--;
+            if (uiNodeId_p >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
+            {
+                Ret = kEplDllInvalidParam;
+                goto Exit;
+            }
+            uiNodeId_p += tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2;
+            EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = uiCount_p;
+            break;
+        }
+
+        default:
+        {
+            uiNodeId_p--;
+            if (uiNodeId_p >= (tabentries (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2))
+            {
+                Ret = kEplDllInvalidParam;
+                goto Exit;
+            }
+            EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] = uiCount_p;
+            break;
+        }
+    }
+
+Exit:
+    return Ret;
+}
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//  Callback handler for new data signaling
+//---------------------------------------------------------------------------
+
+#ifndef EPL_NO_FIFO
+/*static void  EplDllkCalTxNmtSignalHandler (
+    tShbInstance pShbRxInstance_p,
+    unsigned long ulDataSize_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplEvent       Event;
+tEplDllAsyncReqPriority Priority;
+#ifndef EPL_NO_FIFO
+tShbError   ShbError;
+unsigned long   ulBlockCount;
+
+
+    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount);
+    if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount;
+    }
+
+#endif
+
+    // post event to DLL
+    Priority = kEplDllAsyncReqPrioNmt;
+    Event.m_EventSink = kEplEventSinkDllk;
+    Event.m_EventType = kEplEventTypeDllkFillTx;
+    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+    Event.m_pArg = &Priority;
+    Event.m_uiSize = sizeof(Priority);
+    Ret = EplEventkPost(&Event);
+
+}
+
+static void  EplDllkCalTxGenSignalHandler (
+    tShbInstance pShbRxInstance_p,
+    unsigned long ulDataSize_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplEvent       Event;
+tEplDllAsyncReqPriority Priority;
+#ifndef EPL_NO_FIFO
+tShbError   ShbError;
+unsigned long   ulBlockCount;
+
+
+    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount);
+    if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
+    {
+        EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount;
+    }
+
+#endif
+
+    // post event to DLL
+    Priority = kEplDllAsyncReqPrioGeneric;
+    Event.m_EventSink = kEplEventSinkDllk;
+    Event.m_EventType = kEplEventTypeDllkFillTx;
+    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+    Event.m_pArg = &Priority;
+    Event.m_uiSize = sizeof(Priority);
+    Ret = EplEventkPost(&Event);
+
+}
+*/
+#endif
+
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplDlluCal.c b/drivers/staging/epl/EplDlluCal.c
new file mode 100644 (file)
index 0000000..595e9c7
--- /dev/null
@@ -0,0 +1,534 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for DLL Communication Abstraction Layer module in EPL user part
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDlluCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.7 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/20 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "user/EplDlluCal.h"
+#include "user/EplEventu.h"
+
+#include "EplDllCal.h"
+
+// include only if direct call between user- and kernelspace is enabled
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+#include "kernel/EplDllkCal.h"
+#endif
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplDlluCal                                          */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplDlluCbAsnd  m_apfnDlluCbAsnd[EPL_DLL_MAX_ASND_SERVICE_ID];
+
+} tEplDlluCalInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+// if no dynamic memory allocation shall be used
+// define structures statically
+static tEplDlluCalInstance     EplDlluCalInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, tEplDllAsndFilter Filter_p);
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalAddInstance()
+//
+// Description: add and initialize new instance of DLL CAL module
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalAddInstance()
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplDlluCalInstance_g, 0, sizeof (EplDlluCalInstance_g));
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalDelInstance()
+//
+// Description: deletes an instance of DLL CAL module
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalDelInstance()
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplDlluCalInstance_g, 0, sizeof (EplDlluCalInstance_g));
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalProcess
+//
+// Description: process the passed asynch frame
+//
+// Parameters:  pEvent_p                = event containing frame to be processed
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalProcess(tEplEvent * pEvent_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplMsgType     MsgType;
+unsigned int    uiAsndServiceId;
+tEplFrameInfo   FrameInfo;
+
+    if (pEvent_p->m_EventType == kEplEventTypeAsndRx)
+    {
+        FrameInfo.m_pFrame = (tEplFrame*) pEvent_p->m_pArg;
+        FrameInfo.m_uiFrameSize = pEvent_p->m_uiSize;
+        // extract NetTime
+        FrameInfo.m_NetTime = pEvent_p->m_NetTime;
+
+        MsgType = (tEplMsgType)AmiGetByteFromLe(&FrameInfo.m_pFrame->m_le_bMessageType);
+        if (MsgType != kEplMsgTypeAsnd)
+        {
+            Ret = kEplInvalidOperation;
+            goto Exit;
+        }
+
+        uiAsndServiceId = (unsigned int) AmiGetByteFromLe(&FrameInfo.m_pFrame->m_Data.m_Asnd.m_le_bServiceId);
+        if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID)
+        {   // ASnd service ID is valid
+            if (EplDlluCalInstance_g.m_apfnDlluCbAsnd[uiAsndServiceId] != NULL)
+            {   // handler was registered
+                Ret = EplDlluCalInstance_g.m_apfnDlluCbAsnd[uiAsndServiceId](&FrameInfo);
+            }
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalRegAsndService()
+//
+// Description: registers the specified handler for the specified
+//              AsndServiceId with the specified node ID filter.
+//
+// Parameters:  ServiceId_p             = ASnd Service ID
+//              pfnDlluCbAsnd_p         = callback function
+//              Filter_p                = node ID filter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalRegAsndService(tEplDllAsndServiceId ServiceId_p, tEplDlluCbAsnd pfnDlluCbAsnd_p, tEplDllAsndFilter Filter_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    if (ServiceId_p < tabentries (EplDlluCalInstance_g.m_apfnDlluCbAsnd))
+    {
+        // memorize function pointer
+        EplDlluCalInstance_g.m_apfnDlluCbAsnd[ServiceId_p] = pfnDlluCbAsnd_p;
+
+        if (pfnDlluCbAsnd_p == NULL)
+        {   // close filter
+            Filter_p = kEplDllAsndFilterNone;
+        }
+
+        // set filter in DLL module in kernel part
+        Ret = EplDlluCalSetAsndServiceIdFilter(ServiceId_p, Filter_p);
+
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalAsyncSend()
+//
+// Description: sends the frame with the specified priority.
+//
+// Parameters:  pFrameInfo_p            = frame
+//                                        m_uiFrameSize does not include the
+//                                        ethernet header (14 bytes)
+//              Priority_p              = priority
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+    pFrameInfo_p->m_uiFrameSize += 14;  // add size of ethernet header
+    Ret = EplDllkCalAsyncSend(pFrameInfo_p, Priority_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalIssueRequest()
+//
+// Description: issues a StatusRequest or a IdentRequest to the specified node.
+//
+// Parameters:  Service_p               = request service ID
+//              uiNodeId_p              = node ID
+//              bSoaFlag1_p             = flag1 for this node (transmit in SoA and PReq)
+//                                        If 0xFF this flag is ignored.
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p, unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    // add node to appropriate request queue
+    switch (Service_p)
+    {
+        case kEplDllReqServiceIdent:
+        case kEplDllReqServiceStatus:
+        {
+        tEplEvent   Event;
+        tEplDllCalIssueRequest  IssueReq;
+
+            Event.m_EventSink = kEplEventSinkDllkCal;
+            Event.m_EventType = kEplEventTypeDllkIssueReq;
+            IssueReq.m_Service = Service_p;
+            IssueReq.m_uiNodeId = uiNodeId_p;
+            IssueReq.m_bSoaFlag1 = bSoaFlag1_p;
+            Event.m_pArg = &IssueReq;
+            Event.m_uiSize = sizeof (IssueReq);
+
+            Ret = EplEventuPost(&Event);
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplDllInvalidParam;
+            goto Exit;
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalAddNode()
+//
+// Description: adds the specified node to the isochronous phase.
+//
+// Parameters:  pNodeInfo_p             = pointer of node info structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalAddNode(tEplDllNodeInfo * pNodeInfo_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+tEplEvent   Event;
+
+    Event.m_EventSink = kEplEventSinkDllkCal;
+    Event.m_EventType = kEplEventTypeDllkAddNode;
+    Event.m_pArg = pNodeInfo_p;
+    Event.m_uiSize = sizeof (tEplDllNodeInfo);
+
+    Ret = EplEventuPost(&Event);
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalDeleteNode()
+//
+// Description: removes the specified node from the isochronous phase.
+//
+// Parameters:  uiNodeId_p              = node ID
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+tEplEvent   Event;
+
+    Event.m_EventSink = kEplEventSinkDllkCal;
+    Event.m_EventType = kEplEventTypeDllkDelNode;
+    Event.m_pArg = &uiNodeId_p;
+    Event.m_uiSize = sizeof (uiNodeId_p);
+
+    Ret = EplEventuPost(&Event);
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalSoftDeleteNode()
+//
+// Description: removes the specified node softly from the isochronous phase.
+//
+// Parameters:  uiNodeId_p              = node ID
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+tEplEvent   Event;
+
+    Event.m_EventSink = kEplEventSinkDllkCal;
+    Event.m_EventType = kEplEventTypeDllkSoftDelNode;
+    Event.m_pArg = &uiNodeId_p;
+    Event.m_uiSize = sizeof (uiNodeId_p);
+
+    Ret = EplEventuPost(&Event);
+
+    return Ret;
+}
+
+
+#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplDlluCalSetAsndServiceIdFilter()
+//
+// Description: forwards call to EplDllkSetAsndServiceIdFilter() in kernel part
+//
+// Parameters:  ServiceId_p             = ASnd Service ID
+//              Filter_p                = node ID filter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, tEplDllAsndFilter Filter_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+tEplEvent   Event;
+tEplDllCalAsndServiceIdFilter   ServFilter;
+
+    Event.m_EventSink = kEplEventSinkDllkCal;
+    Event.m_EventType = kEplEventTypeDllkServFilter;
+    ServFilter.m_ServiceId = ServiceId_p;
+    ServFilter.m_Filter = Filter_p;
+    Event.m_pArg = &ServFilter;
+    Event.m_uiSize = sizeof (ServFilter);
+
+    Ret = EplEventuPost(&Event);
+
+    return Ret;
+}
+
+
+#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplErrDef.h b/drivers/staging/epl/EplErrDef.h
new file mode 100644 (file)
index 0000000..5261692
--- /dev/null
@@ -0,0 +1,302 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  definitions for all EPL-function return codes
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplErrDef.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.9 $  $Date: 2008/06/23 14:56:33 $
+
+                $State: Exp $
+
+                Build Environment:
+                    all
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2005/12/05 -as:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#ifndef _EPL_ERRORDEF_H_
+#define _EPL_ERRORDEF_H_
+
+
+//---------------------------------------------------------------------------
+// return codes
+//---------------------------------------------------------------------------
+
+typedef enum
+{
+    // area for generic errors 0x0000 - 0x000F
+    kEplSuccessful              = 0x0000,       // no error/successful run
+    kEplIllegalInstance         = 0x0001,       // the called Instanz does not exist
+    kEplInvalidInstanceParam    = 0x0002,       //
+    kEplNoFreeInstance          = 0x0003,       // XxxAddInstance was called but no free instance is available
+    kEplWrongSignature          = 0x0004,       // wrong signature while writing to object 0x1010 or 0x1011
+    kEplInvalidOperation        = 0x0005,       // operation not allowed in this situation
+    kEplInvalidNodeId           = 0x0007,       // invalid NodeId was specified
+    kEplNoResource              = 0x0008,       // resource could not be created (Windows, PxROS, ...)
+    kEplShutdown                = 0x0009,       // stack is shutting down
+    kEplReject                  = 0x000A,       // reject the subsequent command
+
+    // area for EDRV module 0x0010 - 0x001F
+//    kEplEdrvNoFrame             = 0x0010,       // no CAN message was received
+//    kEplEdrvMsgHigh             = 0x0011,       // CAN message with high priority was received
+//    kEplEdrvMsgLow              = 0x0012,       // CAN message with low priority was received
+    kEplEdrvInitError           = 0x0013,       // initialisation error
+    kEplEdrvNoFreeBufEntry      = 0x0014,       // no free entry in internal buffer table for Tx frames
+    kEplEdrvBufNotExisting      = 0x0015,       // specified Tx buffer does not exist
+//    kEplEdrvNoFreeChannel       = 0x0014,       // CAN controller has not a free channel
+//    kEplEdrvTxBuffHighOverrun   = 0x0015,       // buffer for high priority CAN transmit messages has overrun
+//    kEplEdrvTxBuffLowOverrun    = 0x0016,       // buffer for low priority CAN transmit messages has overrun
+//    kEplEdrvIllegalBdi          = 0x0017,       // unsupported baudrate within baudrate table
+//    kEplEdrvBusy                = 0x0018,       // remote frame can not be updated because no bus contact or CAN
+                                                // transmission is activ
+//    kEplEdrvInvalidDriverType   = 0x0019,       // (PC: Windows or Linux) invalid driver type
+//    kEplEdrvDriverNotFound      = 0x001A,       // (PC: Windows or Linux) driver (DLL) could not be found
+//    kEplEdrvInvalidBaseAddress  = 0x001B,       // (PC: Windows or Linux) driver could not found the CAN controller
+//    kEplEdrvInvalidParam        = 0x001C,       // invalid param in function call
+
+    // area for COB module 0x0020 - 0x002F
+/*    kEplCobNoFreeEntry          = 0x0020,       // no free entry in RX- or TX-COB table
+    kEplCobAlreadyExist         = 0x0021,       // COB-ID already exists in RX- resp. TX-COB table
+    */
+    kEplDllIllegalHdl           = 0x0022,       // illegal handle for a TxFrame was passed
+    kEplDllCbAsyncRegistered    = 0x0023,       // handler for non-EPL frames was already registered before
+//    kEplDllAsyncRxBufferFull    = 0x0024,       // receive buffer for asynchronous frames is full
+    kEplDllAsyncTxBufferEmpty   = 0x0025,       // transmit buffer for asynchronous frames is empty
+    kEplDllAsyncTxBufferFull    = 0x0026,       // transmit buffer for asynchronous frames is full
+    kEplDllNoNodeInfo           = 0x0027,       // MN: too less space in the internal node info structure
+    kEplDllInvalidParam         = 0x0028,       // invalid parameters passed to function
+    kEplDllTxBufNotReady        = 0x002E,       // TxBuffer (e.g. for PReq) is not ready yet
+    kEplDllTxFrameInvalid       = 0x002F,       // TxFrame (e.g. for PReq) is invalid or does not exist
+/*    kEplCobIllegalCanId         = 0x0023,       // COB-ID is not allowed (like 0x000 is reserved for NMT, ...)
+    kEplCobInvalidCanId         = 0x0024,       // COB-ID is switched off
+    kEplCobCdrvStateSet         = 0x0025,       // at least one bit of CAN driver state is set
+    kEplCobNoFreeEntryHighBuf   = 0x0026,       // no free entry in high priotity RX- or TX-COB table
+    kEplCobOwnId                = 0x0027,       // COB-ID already exists in own module which calls CobDefine() or CobCheck()
+*/
+    // area for OBD module 0x0030 - 0x003F
+    kEplObdIllegalPart          = 0x0030,       // unknown OD part
+    kEplObdIndexNotExist        = 0x0031,       // object index does not exist in OD
+    kEplObdSubindexNotExist     = 0x0032,       // subindex does not exist in object index
+    kEplObdReadViolation        = 0x0033,       // read access to a write-only object
+    kEplObdWriteViolation       = 0x0034,       // write access to a read-only object
+    kEplObdAccessViolation      = 0x0035,       // access not allowed
+    kEplObdUnknownObjectType    = 0x0036,       // object type not defined/known
+    kEplObdVarEntryNotExist     = 0x0037,       // object does not contain VarEntry structure
+    kEplObdValueTooLow          = 0x0038,       // value to write to an object is too low
+    kEplObdValueTooHigh         = 0x0039,       // value to write to an object is too high
+    kEplObdValueLengthError     = 0x003A,       // value to write is to long or to short
+//    kEplObdIllegalFloat         = 0x003B,       // illegal float variable
+//    kEplObdWrongOdBuilderKey    = 0x003F,       // OD was generated with demo version of tool ODBuilder
+
+    // area for NMT module 0x0040 - 0x004F
+    kEplNmtUnknownCommand       = 0x0040,       // unknown NMT command
+    kEplNmtInvalidFramePointer  = 0x0041,       // pointer to the frame is not valid
+    kEplNmtInvalidEvent         = 0x0042,       // invalid event send to NMT-modul
+    kEplNmtInvalidState         = 0x0043,       // unknown state in NMT-State-Maschine
+    kEplNmtInvalidParam         = 0x0044,       // invalid parameters specified
+
+    // area for SDO/UDP module 0x0050 - 0x005F
+    kEplSdoUdpMissCb            = 0x0050,       // missing callback-function pointer during inti of
+                                                // module
+    kEplSdoUdpNoSocket          = 0x0051,       // error during init of socket
+    kEplSdoUdpSocketError       = 0x0052,       // error during usage of socket
+    kEplSdoUdpThreadError       = 0x0053,       // error during start of listen thread
+    kEplSdoUdpNoFreeHandle      = 0x0054,       // no free connection handle for Udp
+    kEplSdoUdpSendError         = 0x0055,       // Error during send of frame
+    kEplSdoUdpInvalidHdl        = 0x0056,       // the connection handle is invalid
+
+    // area for SDO Sequence layer module 0x0060 - 0x006F
+    kEplSdoSeqMissCb            = 0x0060,       // no callback-function assign
+    kEplSdoSeqNoFreeHandle      = 0x0061,       // no free handle for connection
+    kEplSdoSeqInvalidHdl        = 0x0062,       // invalid handle in SDO sequence layer
+    kEplSdoSeqUnsupportedProt   = 0x0063,       // unsupported Protocol selected
+    kEplSdoSeqNoFreeHistory     = 0x0064,       // no free entry in history
+    kEplSdoSeqFrameSizeError    = 0x0065,       // the size of the frames is not correct
+    kEplSdoSeqRequestAckNeeded  = 0x0066,       // indeicates that the history buffer is full
+                                                // and a ack request is needed
+    kEplSdoSeqInvalidFrame      = 0x0067,       // frame not valid
+    kEplSdoSeqConnectionBusy    = 0x0068,       // connection is busy -> retry later
+    kEplSdoSeqInvalidEvent      = 0x0069,       // invalid event received
+
+    // area for SDO Command Layer Module 0x0070 - 0x007F
+    kEplSdoComUnsupportedProt   = 0x0070,       // unsupported Protocol selected
+    kEplSdoComNoFreeHandle      = 0x0071,       // no free handle for connection
+    kEplSdoComInvalidServiceType= 0x0072,       // invalid SDO service type specified
+    kEplSdoComInvalidHandle     = 0x0073,       // handle invalid
+    kEplSdoComInvalidSendType   = 0x0074,       // the stated to of frame to send is
+                                                // not possible
+    kEplSdoComNotResponsible    = 0x0075,       // internal error: command layer handle is
+                                                // not responsible for this event from sequence layer
+    kEplSdoComHandleExists      = 0x0076,       // handle to same node already exists
+    kEplSdoComHandleBusy        = 0x0077,       // transfer via this handle is already running
+    kEplSdoComInvalidParam      = 0x0078,       // invalid parameters passed to function
+
+    // area for EPL Event-Modul 0x0080 - 0x008F
+    kEplEventUnknownSink        = 0x0080,     // unknown sink for event
+    kEplEventPostError          = 0x0081,     // error during post of event
+
+
+
+    // area for EPL Timer Modul 0x0090 - 0x009F
+    kEplTimerInvalidHandle      = 0x0090,     // invalid handle for timer
+    kEplTimerNoTimerCreated     = 0x0091,     // no timer was created caused by
+                                                // an error
+
+    // area for EPL SDO/Asnd Module 0x00A0 - 0x0AF
+    kEplSdoAsndInvalidNodeId    = 0x00A0,     //0 node id is invalid
+    kEplSdoAsndNoFreeHandle     = 0x00A1,     // no free handle for connection
+    kEplSdoAsndInvalidHandle    = 0x00A2,     // handle for connection is invalid
+
+
+    // area for PDO module 0x00B0 - 0x00BF
+    kEplPdoNotExist             = 0x00B0,       // selected PDO does not exist
+    kEplPdoLengthExceeded       = 0x00B1,       // length of PDO mapping exceedes 64 bis
+    kEplPdoGranularityMismatch  = 0x00B2,       // configured PDO granularity is not equal to supported granularity
+    kEplPdoInitError            = 0x00B3,       // error during initialisation of PDO module
+    kEplPdoErrorPdoEncode       = 0x00B4,       // error during encoding a PDO
+    kEplPdoErrorPdoDecode       = 0x00B5,       // error during decoding a PDO
+    kEplPdoErrorSend            = 0x00B6,       // error during sending a PDO
+    kEplPdoErrorSyncWin         = 0x00B7,       // the SYNC window runs out during sending SYNC-PDOs
+    kEplPdoErrorMapp            = 0x00B8,       // invalid PDO mapping
+    kEplPdoVarNotFound          = 0x00B9,       // variable was not found in function PdoSignalVar()
+    kEplPdoErrorEmcyPdoLen      = 0x00BA,       // the length of a received PDO is unequal to the expected value
+    kEplPdoWriteConstObject     = 0x00BB,       // constant object can not be written
+                                                // (only TxType, Inhibit-, Event Time for CANopen Kit)
+
+    // area for LSS slave module
+/*    kEplLsssResetNode           = 0x0080,       // NMT command "reset node" has to be processed after LSS configuration
+                                                // new of NodeId
+    kEplLsssInvalidNodeId       = 0x0081,       // no valid NodeId is configured -> wait until it is configured with
+                                                // LSS service before calling CcmConnectToNet()
+*/
+    // area for emergency consumer module 0x0090 - 0x009F
+/*    kEplEmccNoFreeProducerEntry = 0x0090,       // no free entry to add a Emergency Producer
+    kEplEmccNodeIdNotExist      = 0x0091,       // selected NodeId was never added
+    kEplEmccNodeIdInvalid       = 0x0092,       // selected NodeId is outside of range (0x01 until 0x7F)
+    kEplEmccNodeIdExist         = 0x0093,       // selected NodeId already exist
+*/
+    // area for dynamic OD 0x00A0 - 0x00AF
+/*    kEplDynNoMemory             = 0x00A0,       // no memory available
+    kEplDynInvalidConfig        = 0x00A1,       // invalid configuration in segment container
+*/
+    // area for hertbeat consumer module 0x00B0 - 0x00BF
+/*    kEplHbcEntryNotExist        = 0x00B0,       // Heartbeat Producer node not configured
+    kEplHbcEntryAlreadyExist    = 0x00B1,       // NodeId was already defined in heartbeat consumer table (object 0x1016)
+*/
+    // Configuration manager module 0x00C0 - 0x00CF
+    kEplCfgMaConfigError        = 0x00C0,       // error in configuration manager
+    kEplCfgMaSdocTimeOutError   = 0x00C1,       // error in configuration manager, Sdo timeout
+    kEplCfgMaInvalidDcf         = 0x00C2,       // configration file not valid
+    kEplCfgMaUnsupportedDcf     = 0x00C3,       // unsupported Dcf format
+    kEplCfgMaConfigWithErrors   = 0x00C4,       // configuration finished with errors
+    kEplCfgMaNoFreeConfig       = 0x00C5,       // no free configuration entry
+    kEplCfgMaNoConfigData       = 0x00C6,       // no configuration data present
+    kEplCfgMaUnsuppDatatypeDcf  = 0x00C7,       // unsupported datatype found in dcf
+                                                // -> this entry was not configured
+
+
+    // area for LSS master module 0x00D0 - 0x00DF
+/*    kEplLssmIllegalMode         = 0x00D0,       // illegal LSS mode (operation / configuration)
+    kEplLssmIllegalState        = 0x00D1,       // function was called in illegal state of LSS master
+    kEplLssmBusy                = 0x00D2,       // LSS process is busy with an previous service
+    kEplLssmIllegalCmd          = 0x00D3,       // illegal command code was set for function LssmInquireIdentity()
+    kEplLssmTimeout             = 0x00D4,       // LSS slave did not answer a LSS service
+    kEplLssmErrorInConfirm      = 0x00D5,       // LSS slave replied an error code for a LSS service
+*/
+    // area for CCM modules 0x00E0 - 0xEF
+/*    kEplCcmStoreUnvalidState    = 0x00E0,       // memory device not available due device state
+    kEplCcmStoreHwError         = 0x00E1,       // hw error due device access
+*/
+    // area for SRDO module 0x0100 - 0x011F
+/*    kEplSrdoNotExist            = 0x0100,       // selected SRDO does not exist
+    kEplSrdoGranularityMismatch = 0x0101,       // configured SRDO granularity is not equal to supported granularity
+    kEplSrdoCfgTimingError      = 0x0102,       // configuration is not ok (Timing)
+    kEplSrdoCfgIdError          = 0x0103,       // configuration is not ok (CobIds)
+    kEplSrdoCfgCrcError         = 0x0104,       // configuration is not ok (CRC)
+    kEplSrdoNmtError            = 0x0105,       // an action was tried in a wrong NMT state
+    kEplSrdoInvalidCfg          = 0x0106,       // an action was tried with an invald SRDO configuration
+    kEplSrdoInvalid             = 0x0107,       // an action was tried with an invald SRDO
+    kEplSrdoRxTxConflict        = 0x0108,       // an transmission was tried with an receive SRDO (or the other way)
+    kEplSrdoIllegalCanId        = 0x0109,       // the CanId is invalid
+    kEplSrdoCanIdAlreadyInUse   = 0x010A,       // the CanId is already in use
+    kEplSrdoNotInOrder          = 0x010B,       // the two messages of a SRDO are not in order
+    kEplSrdoSctTimeout          = 0x010C,       // timeout of SCT
+    kEplSrdoSrvtTimeout         = 0x010D,       // timeout of SRVT
+    kEplSrdoCanIdNotValid       = 0x010E,       // one of received CAN-IDs are not equal to configured one
+    kEplSrdoDlcNotValid         = 0x010F,       // one of received CAN-DLC are not equal to configured one
+    kEplSrdoErrorMapp           = 0x0110,       // wrong values in mapping found
+    kEplSrdoDataError           = 0x0111,       // data of CAN messages are not invers
+    kEplSrdoLengthExceeded      = 0x0112,       // length of SRDO mapping exceedes 64 bit per CAN-message
+    kEplSrdoNotHandledInApp     = 0x0113,       // the SRDO error was not handled in AppSrdoError()
+    kEplSrdoOverrun             = 0x0114        // a RxSRDO was received but the pevious one was not else processed
+*/
+
+    kEplApiTaskDeferred         = 0x0140,       // EPL performs task in background and informs the application (or vice-versa), when it is finished
+    kEplApiInvalidParam         = 0x0142,       // passed invalid parameters to a function (e.g. invalid node id)
+
+    // area untill 0x07FF is reserved
+    // area for user application from 0x0800 to 0x7FFF
+
+} tEplKernel;
+
+
+#endif
+//EOF
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
+
diff --git a/drivers/staging/epl/EplErrorHandlerk.c b/drivers/staging/epl/EplErrorHandlerk.c
new file mode 100644 (file)
index 0000000..121f026
--- /dev/null
@@ -0,0 +1,800 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for error handler module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplErrorHandlerk.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.9 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/10/02 d.k.:   start of the implementation
+
+****************************************************************************/
+
+#include "kernel/EplErrorHandlerk.h"
+#include "EplNmt.h"
+#include "kernel/EplEventk.h"
+#include "kernel/EplObdk.h"         // function prototyps of the EplOBD-Modul
+#include "kernel/EplDllk.h"
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
+#error "EPL ErrorHandler module needs EPL module OBDK!"
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    DWORD           m_dwCumulativeCnt;  // subindex 1
+    DWORD           m_dwThresholdCnt;   // subindex 2
+    DWORD           m_dwThreshold;      // subindex 3
+
+} tEplErrorHandlerkErrorCounter;
+
+typedef struct
+{
+    tEplErrorHandlerkErrorCounter   m_CnLossSoc;    // object 0x1C0B
+    tEplErrorHandlerkErrorCounter   m_CnLossPreq;   // object 0x1C0D
+    tEplErrorHandlerkErrorCounter   m_CnCrcErr;     // object 0x1C0F
+    unsigned long                   m_ulDllErrorEvents;
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    tEplErrorHandlerkErrorCounter   m_MnCrcErr;                     // object 0x1C00
+    tEplErrorHandlerkErrorCounter   m_MnCycTimeExceed;              // object 0x1C02
+    DWORD                           m_adwMnCnLossPresCumCnt[254];   // object 0x1C07
+    DWORD                           m_adwMnCnLossPresThrCnt[254];   // object 0x1C08
+    DWORD                           m_adwMnCnLossPresThreshold[254];// object 0x1C09
+    BOOL                            m_afMnCnLossPresEvent[254];
+#endif
+
+} tEplErrorHandlerkInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static tEplErrorHandlerkInstance EplErrorHandlerkInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel EplErrorHandlerkLinkErrorCounter(
+                                tEplErrorHandlerkErrorCounter* pErrorCounter_p,
+                                unsigned int uiIndex_p);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+static tEplKernel EplErrorHandlerkLinkArray(
+                                DWORD*      pdwValue_p,
+                                unsigned int uiValueCount_p,
+                                unsigned int uiIndex_p);
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <Epl-Kernelspace-Error-Handler>                     */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplErrorHandlerkInit
+//
+// Description: function initialize the first instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplErrorHandlerkInit(void)
+{
+tEplKernel Ret;
+
+
+    Ret = EplErrorHandlerkAddInstance();
+
+
+return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplErrorHandlerkAddInstance
+//
+// Description: function add one more instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
+{
+tEplKernel      Ret;
+
+    Ret = kEplSuccessful;
+
+    // reset only event variable,
+    // all other instance members are reset by OD or may keep their current value
+    // d.k.: this is necessary for the cumulative counters, which shall not be reset
+    EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0;
+
+    // link counters to OD
+    // $$$ d.k. if OD resides in userspace, fetch pointer to shared memory,
+    //          which shall have the same structure as the instance (needs to be declared globally).
+    //          Other idea: error counter shall belong to the process image
+    //          (reset of counters by SDO write are a little bit tricky).
+
+    Ret = EplErrorHandlerkLinkErrorCounter(
+            &EplErrorHandlerkInstance_g.m_CnLossSoc,
+            0x1C0B);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplErrorHandlerkLinkErrorCounter(
+            &EplErrorHandlerkInstance_g.m_CnLossPreq,
+            0x1C0D);
+    // ignore return code, because object 0x1C0D is conditional
+
+    Ret = EplErrorHandlerkLinkErrorCounter(
+            &EplErrorHandlerkInstance_g.m_CnCrcErr,
+            0x1C0F);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    Ret = EplErrorHandlerkLinkErrorCounter(
+            &EplErrorHandlerkInstance_g.m_MnCrcErr,
+            0x1C00);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplErrorHandlerkLinkErrorCounter(
+            &EplErrorHandlerkInstance_g.m_MnCycTimeExceed,
+            0x1C02);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplErrorHandlerkLinkArray(
+            EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt,
+            tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt),
+            0x1C07);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplErrorHandlerkLinkArray(
+            EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt,
+            tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt),
+            0x1C08);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplErrorHandlerkLinkArray(
+            EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold,
+            tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold),
+            0x1C09);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#endif
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplErrorHandlerkDelInstance
+//
+// Description: function delete instance an free the bufferstructure
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplErrorHandlerkDelInstance()
+{
+tEplKernel      Ret;
+
+    Ret = kEplSuccessful;
+
+
+return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplErrorHandlerkProcess
+//
+// Description: processes error events from DLL
+//
+//
+//
+// Parameters:  pEvent_p = pointer to event-structur from buffer
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent* pEvent_p)
+{
+tEplKernel              Ret;
+unsigned long           ulDllErrorEvents;
+tEplEvent               Event;
+tEplNmtEvent            NmtEvent;
+
+    Ret = kEplSuccessful;
+
+    // check m_EventType
+    switch(pEvent_p->m_EventType)
+    {
+        case kEplEventTypeDllError:
+        {
+        tEplErrorHandlerkEvent* pErrHandlerEvent = (tEplErrorHandlerkEvent*)pEvent_p->m_pArg;
+
+            ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents;
+
+            // check the several error events
+            if ((EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold > 0)
+                && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0))
+            {   // loss of SoC event occured
+                // increment cumulative counter by 1
+                EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwCumulativeCnt++;
+                // increment threshold counter by 8
+                EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt += 8;
+                if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt
+                    >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold)
+                {   // threshold is reached
+                    // $$$ d.k.: generate error history entry E_DLL_LOSS_SOC_TH
+
+                    // post event to NMT state machine
+                    NmtEvent = kEplNmtEventNmtCycleError;
+                    Event.m_EventSink = kEplEventSinkNmtk;
+                    Event.m_EventType = kEplEventTypeNmtEvent;
+                    Event.m_pArg = &NmtEvent;
+                    Event.m_uiSize = sizeof (NmtEvent);
+                    Ret = EplEventkPost(&Event);
+                }
+                EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
+                    EPL_DLL_ERR_CN_LOSS_SOC;
+            }
+
+            if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold > 0)
+                && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0))
+            {   // loss of PReq event occured
+                // increment cumulative counter by 1
+                EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwCumulativeCnt++;
+                // increment threshold counter by 8
+                EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt += 8;
+                if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt
+                    >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold)
+                {   // threshold is reached
+                    // $$$ d.k.: generate error history entry E_DLL_LOSS_PREQ_TH
+
+                    // post event to NMT state machine
+                    NmtEvent = kEplNmtEventNmtCycleError;
+                    Event.m_EventSink = kEplEventSinkNmtk;
+                    Event.m_EventType = kEplEventTypeNmtEvent;
+                    Event.m_pArg = &NmtEvent;
+                    Event.m_uiSize = sizeof (NmtEvent);
+                    Ret = EplEventkPost(&Event);
+                }
+            }
+
+            if ((EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt > 0)
+                && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0))
+            {   // PReq correctly received
+                // decrement threshold counter by 1
+                EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt--;
+            }
+
+            if ((EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold > 0)
+                && ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0))
+            {   // CRC error event occured
+                // increment cumulative counter by 1
+                EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwCumulativeCnt++;
+                // increment threshold counter by 8
+                EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt += 8;
+                if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt
+                    >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold)
+                {   // threshold is reached
+                    // $$$ d.k.: generate error history entry E_DLL_CRC_TH
+
+                    // post event to NMT state machine
+                    NmtEvent = kEplNmtEventNmtCycleError;
+                    Event.m_EventSink = kEplEventSinkNmtk;
+                    Event.m_EventType = kEplEventTypeNmtEvent;
+                    Event.m_pArg = &NmtEvent;
+                    Event.m_uiSize = sizeof (NmtEvent);
+                    Ret = EplEventkPost(&Event);
+                }
+                EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
+                    EPL_DLL_ERR_CN_CRC;
+            }
+
+            if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0)
+            {   // invalid format error occured (only direct reaction)
+                // $$$ d.k.: generate error history entry E_DLL_INVALID_FORMAT
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+                if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive)
+                {   // MN is active
+                    if (pErrHandlerEvent->m_uiNodeId != 0)
+                    {
+                    tEplHeartbeatEvent  HeartbeatEvent;
+
+                        // remove node from isochronous phase
+                        Ret = EplDllkDeleteNode(pErrHandlerEvent->m_uiNodeId);
+
+                        // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
+                        HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId;
+                        HeartbeatEvent.m_NmtState = kEplNmtCsNotActive;
+                        HeartbeatEvent.m_wErrorCode = EPL_E_DLL_INVALID_FORMAT;
+                        Event.m_EventSink = kEplEventSinkNmtMnu;
+                        Event.m_EventType = kEplEventTypeHeartbeat;
+                        Event.m_uiSize = sizeof (HeartbeatEvent);
+                        Event.m_pArg = &HeartbeatEvent;
+                        Ret = EplEventkPost(&Event);
+                    }
+                    // $$$ and else should lead to InternComError
+                }
+                else
+#endif
+                {   // CN is active
+                    // post event to NMT state machine
+                    NmtEvent = kEplNmtEventInternComError;
+                    Event.m_EventSink = kEplEventSinkNmtk;
+                    Event.m_EventType = kEplEventTypeNmtEvent;
+                    Event.m_pArg = &NmtEvent;
+                    Event.m_uiSize = sizeof (NmtEvent);
+                    Ret = EplEventkPost(&Event);
+                }
+            }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            if ((EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold > 0)
+                && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0))
+            {   // CRC error event occured
+                // increment cumulative counter by 1
+                EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwCumulativeCnt++;
+                // increment threshold counter by 8
+                EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt += 8;
+                if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt
+                    >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold)
+                {   // threshold is reached
+                    // $$$ d.k.: generate error history entry E_DLL_CRC_TH
+
+                    // post event to NMT state machine
+                    NmtEvent = kEplNmtEventNmtCycleError;
+                    Event.m_EventSink = kEplEventSinkNmtk;
+                    Event.m_EventType = kEplEventTypeNmtEvent;
+                    Event.m_pArg = &NmtEvent;
+                    Event.m_uiSize = sizeof (NmtEvent);
+                    Ret = EplEventkPost(&Event);
+                }
+                EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
+                    EPL_DLL_ERR_MN_CRC;
+            }
+
+            if ((EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold > 0)
+                && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0))
+            {   // cycle time exceeded event occured
+                // increment cumulative counter by 1
+                EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwCumulativeCnt++;
+                // increment threshold counter by 8
+                EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt += 8;
+                if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt
+                    >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold)
+                {   // threshold is reached
+                    // $$$ d.k.: generate error history entry E_DLL_CYCLE_EXCEED_TH
+
+                    // post event to NMT state machine
+                    NmtEvent = kEplNmtEventNmtCycleError;
+                    Event.m_EventSink = kEplEventSinkNmtk;
+                    Event.m_EventType = kEplEventTypeNmtEvent;
+                    Event.m_pArg = &NmtEvent;
+                    Event.m_uiSize = sizeof (NmtEvent);
+                    Ret = EplEventkPost(&Event);
+                }
+                // $$$ d.k.: else generate error history entry E_DLL_CYCLE_EXCEED
+                EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
+                    EPL_DLL_ERR_MN_CYCTIMEEXCEED;
+            }
+
+            if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0)
+            {   // CN loss PRes event occured
+            unsigned int uiNodeId;
+
+                uiNodeId = pErrHandlerEvent->m_uiNodeId - 1;
+                if ((uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt))
+                    && (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId] > 0))
+                {
+                    // increment cumulative counter by 1
+                    EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt[uiNodeId]++;
+                    // increment threshold counter by 8
+                    EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] += 8;
+                    if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId]
+                        >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId])
+                    {   // threshold is reached
+                    tEplHeartbeatEvent  HeartbeatEvent;
+
+                        // $$$ d.k.: generate error history entry E_DLL_LOSS_PRES_TH
+
+                        // remove node from isochronous phase
+                        Ret = EplDllkDeleteNode(pErrHandlerEvent->m_uiNodeId);
+
+                        // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
+                        HeartbeatEvent.m_uiNodeId = pErrHandlerEvent->m_uiNodeId;
+                        HeartbeatEvent.m_NmtState = kEplNmtCsNotActive;
+                        HeartbeatEvent.m_wErrorCode = EPL_E_DLL_LOSS_PRES_TH;
+                        Event.m_EventSink = kEplEventSinkNmtMnu;
+                        Event.m_EventType = kEplEventTypeHeartbeat;
+                        Event.m_uiSize = sizeof (HeartbeatEvent);
+                        Event.m_pArg = &HeartbeatEvent;
+                        Ret = EplEventkPost(&Event);
+                    }
+                    EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] = TRUE;
+                }
+            }
+#endif
+
+            break;
+        }
+
+        // NMT event
+        case kEplEventTypeNmtEvent:
+        {
+            if ((*(tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa)
+            {   // SoA event of CN -> decrement threshold counters
+
+                if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) == 0)
+                {   // decrement loss of SoC threshold counter, because it didn't occur last cycle
+                    if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt > 0)
+                    {
+                        EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt--;
+                    }
+                }
+
+                if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) == 0)
+                {   // decrement CRC threshold counter, because it didn't occur last cycle
+                    if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt > 0)
+                    {
+                        EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt--;
+                    }
+                }
+            }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            else if ((*(tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent)
+            {   // SoA event of MN -> decrement threshold counters
+            tEplDllkNodeInfo*   pIntNodeInfo;
+            unsigned int        uiNodeId;
+
+                Ret = EplDllkGetFirstNodeInfo(&pIntNodeInfo);
+                if (Ret != kEplSuccessful)
+                {
+                    break;
+                }
+                // iterate through node info structure list
+                while (pIntNodeInfo != NULL)
+                {
+                    uiNodeId = pIntNodeInfo->m_uiNodeId - 1;
+                    if (uiNodeId < tabentries(EplErrorHandlerkInstance_g.m_adwMnCnLossPresCumCnt))
+                    {
+                        if  (EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] == FALSE)
+                        {
+                            if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] > 0)
+                            {
+                                EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId]--;
+                            }
+                        }
+                        else
+                        {
+                            EplErrorHandlerkInstance_g.m_afMnCnLossPresEvent[uiNodeId] = FALSE;
+                        }
+                    }
+                    pIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo;
+                }
+
+                if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) == 0)
+                {   // decrement CRC threshold counter, because it didn't occur last cycle
+                    if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt > 0)
+                    {
+                        EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt--;
+                    }
+                }
+
+                if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) == 0)
+                {   // decrement cycle exceed threshold counter, because it didn't occur last cycle
+                    if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt > 0)
+                    {
+                        EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt--;
+                    }
+                }
+            }
+#endif
+
+            // reset error events
+            EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0L;
+
+            break;
+        }
+
+
+        // unknown type
+        default:
+        {
+        }
+
+    } // end of switch(pEvent_p->m_EventType)
+
+
+    return Ret;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplErrorHandlerkLinkErrorCounter
+//
+// Description: link specified error counter structure to OD entry
+//
+// Parameters:  pErrorCounter_p         = pointer to error counter structure
+//              uiIndex_p               = OD index
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplErrorHandlerkLinkErrorCounter(
+                                tEplErrorHandlerkErrorCounter* pErrorCounter_p,
+                                unsigned int uiIndex_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplVarParam        VarParam;
+
+    VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
+    VarParam.m_Size = sizeof(DWORD);
+    VarParam.m_uiIndex = uiIndex_p;
+    VarParam.m_uiSubindex = 0x01;
+    VarParam.m_ValidFlag = kVarValidAll;
+    Ret = EplObdDefineVar(&VarParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
+    VarParam.m_Size = sizeof(DWORD);
+    VarParam.m_uiIndex = uiIndex_p;
+    VarParam.m_uiSubindex = 0x02;
+    VarParam.m_ValidFlag = kVarValidAll;
+    Ret = EplObdDefineVar(&VarParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
+    VarParam.m_Size = sizeof(DWORD);
+    VarParam.m_uiIndex = uiIndex_p;
+    VarParam.m_uiSubindex = 0x03;
+    VarParam.m_ValidFlag = kVarValidAll;
+    Ret = EplObdDefineVar(&VarParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplErrorHandlerkLinkErrorCounter
+//
+// Description: link specified error counter structure to OD entry
+//
+// Parameters:  pErrorCounter_p         = pointer to error counter structure
+//              uiIndex_p               = OD index
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+static tEplKernel EplErrorHandlerkLinkArray(
+                                DWORD*      pdwValue_p,
+                                unsigned int uiValueCount_p,
+                                unsigned int uiIndex_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplVarParam    VarParam;
+tEplObdSize     EntrySize;
+BYTE            bIndexEntries;
+
+    EntrySize = (tEplObdSize)  sizeof(bIndexEntries);
+    Ret = EplObdReadEntry (
+                            uiIndex_p,
+                            0x00,
+                            (void GENERIC*) &bIndexEntries,
+                            &EntrySize );
+
+    if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00))
+    {
+        // Object doesn't exist or invalid entry number
+        Ret = kEplObdIndexNotExist;
+        goto Exit;
+    }
+
+    if (bIndexEntries < uiValueCount_p)
+    {
+        uiValueCount_p = bIndexEntries;
+    }
+
+    VarParam.m_Size = sizeof(DWORD);
+    VarParam.m_uiIndex = uiIndex_p;
+    VarParam.m_ValidFlag = kVarValidAll;
+
+    for (VarParam.m_uiSubindex = 0x01; VarParam.m_uiSubindex <= uiValueCount_p; VarParam.m_uiSubindex++)
+    {
+        VarParam.m_pData = pdwValue_p;
+        Ret = EplObdDefineVar(&VarParam);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        pdwValue_p++;
+    }
+
+Exit:
+    return Ret;
+}
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplEvent.h b/drivers/staging/epl/EplEvent.h
new file mode 100644 (file)
index 0000000..5c26202
--- /dev/null
@@ -0,0 +1,303 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for event module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplEvent.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/12 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_EVENT_H_
+#define _EPL_EVENT_H_
+
+#include "EplInc.h"
+#include "EplNmt.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// name and size of event queues
+#define EPL_EVENT_NAME_SHB_KERNEL_TO_USER   "ShbKernelToUser"
+#ifndef EPL_EVENT_SIZE_SHB_KERNEL_TO_USER
+#define EPL_EVENT_SIZE_SHB_KERNEL_TO_USER   32768   // 32 kByte
+#endif
+
+#define EPL_EVENT_NAME_SHB_USER_TO_KERNEL   "ShbUserToKernel"
+#ifndef EPL_EVENT_SIZE_SHB_USER_TO_KERNEL
+#define EPL_EVENT_SIZE_SHB_USER_TO_KERNEL   32768   // 32 kByte
+#endif
+
+
+// max size of event argument
+#ifndef EPL_MAX_EVENT_ARG_SIZE
+#define EPL_MAX_EVENT_ARG_SIZE      256 // because of PDO
+#endif
+
+#define EPL_DLL_ERR_MN_CRC           0x00000001L  // object 0x1C00
+#define EPL_DLL_ERR_MN_COLLISION     0x00000002L  // object 0x1C01
+#define EPL_DLL_ERR_MN_CYCTIMEEXCEED 0x00000004L  // object 0x1C02
+#define EPL_DLL_ERR_MN_LOSS_LINK     0x00000008L  // object 0x1C03
+#define EPL_DLL_ERR_MN_CN_LATE_PRES  0x00000010L  // objects 0x1C04-0x1C06
+#define EPL_DLL_ERR_MN_CN_LOSS_PRES  0x00000080L  // objects 0x1C07-0x1C09
+#define EPL_DLL_ERR_CN_COLLISION     0x00000400L  // object 0x1C0A
+#define EPL_DLL_ERR_CN_LOSS_SOC      0x00000800L  // object 0x1C0B
+#define EPL_DLL_ERR_CN_LOSS_SOA      0x00001000L  // object 0x1C0C
+#define EPL_DLL_ERR_CN_LOSS_PREQ     0x00002000L  // object 0x1C0D
+#define EPL_DLL_ERR_CN_RECVD_PREQ    0x00004000L  // decrement object 0x1C0D/2
+#define EPL_DLL_ERR_CN_SOC_JITTER    0x00008000L  // object 0x1C0E
+#define EPL_DLL_ERR_CN_CRC           0x00010000L  // object 0x1C0F
+#define EPL_DLL_ERR_CN_LOSS_LINK     0x00020000L  // object 0x1C10
+#define EPL_DLL_ERR_MN_LOSS_STATRES  0x00040000L  // objects 0x1C15-0x1C17 (should be operated by NmtMnu module)
+#define EPL_DLL_ERR_BAD_PHYS_MODE    0x00080000L  // no object
+#define EPL_DLL_ERR_MAC_BUFFER       0x00100000L  // no object (NMT_GT6)
+#define EPL_DLL_ERR_INVALID_FORMAT   0x00200000L  // no object (NMT_GT6)
+#define EPL_DLL_ERR_ADDRESS_CONFLICT 0x00400000L  // no object (remove CN from configuration)
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+// EventType determines the argument of the event
+typedef enum
+{
+    kEplEventTypeNmtEvent       = 0x01, // NMT event
+                                        // arg is pointer to tEplNmtEvent
+    kEplEventTypePdoRx          = 0x02, // PDO frame received event (PRes/PReq)
+                                        // arg is pointer to tEplFrame
+    kEplEventTypePdoTx          = 0x03, // PDO frame transmitted event (PRes/PReq)
+                                        // arg is pointer to tEplFrameInfo
+    kEplEventTypePdoSoa         = 0x04, // SoA frame received event (isochronous phase completed)
+                                        // arg is pointer to nothing
+    kEplEventTypeSync           = 0x05, // Sync event (e.g. SoC or anticipated SoC)
+                                        // arg is pointer to nothing
+    kEplEventTypeTimer          = 0x06, // Timer event
+                                        // arg is pointer to tEplTimerEventArg
+    kEplEventTypeHeartbeat      = 0x07, // Heartbeat event
+                                        // arg is pointer to tEplHeartbeatEvent
+    kEplEventTypeDllkCreate     = 0x08, // DLL kernel create event
+                                        // arg is pointer to the new tEplNmtState
+    kEplEventTypeDllkDestroy    = 0x09, // DLL kernel destroy event
+                                        // arg is pointer to the old tEplNmtState
+    kEplEventTypeDllkFillTx     = 0x0A, // DLL kernel fill TxBuffer event
+                                        // arg is pointer to tEplDllAsyncReqPriority
+    kEplEventTypeDllkPresReady  = 0x0B, // DLL kernel PRes ready event
+                                        // arg is pointer to nothing
+    kEplEventTypeError          = 0x0C, // Error event for API layer
+                                        // arg is pointer to tEplEventError
+    kEplEventTypeNmtStateChange = 0x0D, // indicate change of NMT-State
+                                        // arg is pointer to tEplEventNmtStateChange
+    kEplEventTypeDllError       = 0x0E, // DLL error event for Error handler
+                                        // arg is pointer to tEplErrorHandlerkEvent
+    kEplEventTypeAsndRx         = 0x0F, // received ASnd frame for DLL user module
+                                        // arg is pointer to tEplFrame
+    kEplEventTypeDllkServFilter = 0x10, // configure ServiceIdFilter
+                                        // arg is pointer to tEplDllCalServiceIdFilter
+    kEplEventTypeDllkIdentity   = 0x11, // configure Identity
+                                        // arg is pointer to tEplDllIdentParam
+    kEplEventTypeDllkConfig     = 0x12, // configure ConfigParam
+                                        // arg is pointer to tEplDllConfigParam
+    kEplEventTypeDllkIssueReq   = 0x13, // issue Ident/Status request
+                                        // arg is pointer to tEplDllCalIssueRequest
+    kEplEventTypeDllkAddNode    = 0x14, // add node to isochronous phase
+                                        // arg is pointer to tEplDllNodeInfo
+    kEplEventTypeDllkDelNode    = 0x15, // remove node from isochronous phase
+                                        // arg is pointer to unsigned int
+    kEplEventTypeDllkSoftDelNode= 0x16, // remove node softly from isochronous phase
+                                        // arg is pointer to unsigned int
+    kEplEventTypeDllkStartReducedCycle = 0x17, // start reduced EPL cycle on MN
+                                        // arg is pointer to nothing
+    kEplEventTypeNmtMnuNmtCmdSent      = 0x18, // NMT command was actually sent
+                                        // arg is pointer to tEplFrame
+
+} tEplEventType;
+
+
+// EventSink determines the consumer of the event
+typedef enum
+{
+    kEplEventSinkSync           = 0x00, // Sync event for application or kernel EPL module
+    kEplEventSinkNmtk           = 0x01, // events for Nmtk module
+    kEplEventSinkDllk           = 0x02, // events for Dllk module
+    kEplEventSinkDlluCal        = 0x03, // events for DlluCal module
+    kEplEventSinkDllkCal        = 0x04, // events for DllkCal module
+    kEplEventSinkPdok           = 0x05, // events for Pdok module
+    kEplEventSinkNmtu           = 0x06, // events for Nmtu module
+    kEplEventSinkErrk           = 0x07, // events for Error handler module
+    kEplEventSinkErru           = 0x08, // events for Error signaling module
+    kEplEventSinkSdoAsySeq      = 0x09, // events for asyncronous SDO Sequence Layer module
+    kEplEventSinkNmtMnu         = 0x0A, // events for NmtMnu module
+    kEplEventSinkLedu           = 0x0B, // events for Ledu module
+    kEplEventSinkApi            = 0x0F, // events for API module
+
+} tEplEventSink;
+
+
+// EventSource determines the source of an errorevent
+typedef enum
+{
+    // kernelspace modules
+    kEplEventSourceDllk         = 0x01, // Dllk module
+    kEplEventSourceNmtk         = 0x02, // Nmtk module
+    kEplEventSourceObdk         = 0x03, // Obdk module
+    kEplEventSourcePdok         = 0x04, // Pdok module
+    kEplEventSourceTimerk       = 0x05, // Timerk module
+    kEplEventSourceEventk       = 0x06, // Eventk module
+    kEplEventSourceSyncCb       = 0x07, // sync-Cb
+    kEplEventSourceErrk         = 0x08, // Error handler module
+
+    // userspace modules
+    kEplEventSourceDllu         = 0x10, // Dllu module
+    kEplEventSourceNmtu         = 0x11, // Nmtu module
+    kEplEventSourceNmtCnu       = 0x12, // NmtCnu module
+    kEplEventSourceNmtMnu       = 0x13, // NmtMnu module
+    kEplEventSourceObdu         = 0x14, // Obdu module
+    kEplEventSourceSdoUdp       = 0x15, // Sdo/Udp module
+    kEplEventSourceSdoAsnd      = 0x16, // Sdo/Asnd module
+    kEplEventSourceSdoAsySeq    = 0x17, // Sdo asynchronus Sequence Layer module
+    kEplEventSourceSdoCom       = 0x18, // Sdo command layer module
+    kEplEventSourceTimeru       = 0x19, // Timeru module
+    kEplEventSourceCfgMau       = 0x1A, // CfgMau module
+    kEplEventSourceEventu       = 0x1B, // Eventu module
+    kEplEventSourceEplApi       = 0x1C, // Api module
+    kEplEventSourceLedu         = 0x1D, // Ledu module
+
+} tEplEventSource;
+
+
+// structure of EPL event (element order must not be changed!)
+typedef struct
+{
+    tEplEventType     m_EventType /*:28*/; // event type
+    tEplEventSink     m_EventSink /*:4*/;  // event sink
+    tEplNetTime       m_NetTime;       // timestamp
+    unsigned int      m_uiSize;        // size of argument
+    void            * m_pArg;          // argument of event
+
+} tEplEvent;
+
+
+// short structure of EPL event without argument and its size (element order must not be changed!)
+typedef struct
+{
+    tEplEventType     m_EventType /*:28*/; // event type
+    tEplEventSink     m_EventSink /*:4*/;  // event sink
+    tEplNetTime       m_NetTime;       // timestamp
+
+} tEplEventShort;
+
+
+typedef struct
+{
+    unsigned int    m_uiIndex;
+    unsigned int    m_uiSubIndex;
+
+} tEplEventObdError;
+
+
+// structure for kEplEventTypeError
+typedef struct
+{
+    tEplEventSource m_EventSource;              // module which posted this error event
+    tEplKernel      m_EplError;                 // EPL error which occured
+    union
+    {
+        BYTE                    m_bArg;
+        DWORD                   m_dwArg;
+        tEplEventSource         m_EventSource;  // from Eventk/u module (originating error source)
+        tEplEventObdError       m_ObdError;     // from Obd module
+//        tEplErrHistoryEntry     m_HistoryEntry; // from Nmtk/u module
+
+    } m_Arg;
+
+} tEplEventError;
+
+
+// structure for kEplEventTypeDllError
+typedef struct
+{
+    unsigned long   m_ulDllErrorEvents;   // EPL_DLL_ERR_*
+    unsigned int    m_uiNodeId;
+    tEplNmtState    m_NmtState;
+
+} tEplErrorHandlerkEvent;
+
+
+// callback function to get informed about sync event
+typedef tEplKernel (PUBLIC* tEplSyncCb) (void);
+
+// callback function for generic events
+typedef tEplKernel (PUBLIC* tEplProcessEventCb) (tEplEvent* pEplEvent_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+
+#endif  // #ifndef _EPL_EVENT_H_
+
+
diff --git a/drivers/staging/epl/EplEventk.c b/drivers/staging/epl/EplEventk.c
new file mode 100644 (file)
index 0000000..ea612c7
--- /dev/null
@@ -0,0 +1,858 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Epl-Kernelspace-Event-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplEventk.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.9 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/20 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "kernel/EplEventk.h"
+#include "kernel/EplNmtk.h"
+#include "kernel/EplDllk.h"
+#include "kernel/EplDllkCal.h"
+#include "kernel/EplErrorHandlerk.h"
+#include "Benchmark.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+#include "kernel/EplPdok.h"
+#include "kernel/EplPdokCal.h"
+#endif
+
+#ifdef EPL_NO_FIFO
+    #include "user/EplEventu.h"
+#else
+    #include "SharedBuff.h"
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+#ifndef EPL_NO_FIFO
+    tShbInstance    m_pShbKernelToUserInstance;
+    tShbInstance    m_pShbUserToKernelInstance;
+#else
+
+#endif
+    tEplSyncCb      m_pfnCbSync;
+    unsigned int    m_uiUserToKernelFullCount;
+
+} tEplEventkInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+static tEplEventkInstance EplEventkInstance_g;
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+// callback function for incoming events
+#ifndef EPL_NO_FIFO
+static void  EplEventkRxSignalHandlerCb (
+    tShbInstance pShbRxInstance_p,
+    unsigned long ulDataSize_p);
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <Epl-Kernelspace-Event>                             */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkInit
+//
+// Description: function initializes the first instance
+//
+// Parameters:  pfnCbSync_p = callback-function for sync event
+//
+// Returns:     tEpKernel   = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
+{
+tEplKernel Ret;
+
+    Ret = EplEventkAddInstance(pfnCbSync_p);
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkAddInstance
+//
+// Description: function adds one more instance
+//
+// Parameters:  pfnCbSync_p = callback-function for sync event
+//
+// Returns:     tEpKernel   = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
+{
+tEplKernel      Ret;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+unsigned int    fShbNewCreated;
+#endif
+
+    Ret = kEplSuccessful;
+
+    // init instance structure
+    EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
+
+    // save cb-function
+    EplEventkInstance_g.m_pfnCbSync = pfnCbSync_p;
+
+#ifndef EPL_NO_FIFO
+    // init shared loop buffer
+    // kernel -> user
+    ShbError = ShbCirAllocBuffer (EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
+                                  EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
+                                  &EplEventkInstance_g.m_pShbKernelToUserInstance,
+                                  &fShbNewCreated);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventkAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    // user -> kernel
+    ShbError = ShbCirAllocBuffer (EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
+                                  EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
+                                  &EplEventkInstance_g.m_pShbUserToKernelInstance,
+                                  &fShbNewCreated);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventkAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    // register eventhandler
+    ShbError = ShbCirSetSignalHandlerNewData (EplEventkInstance_g.m_pShbUserToKernelInstance,
+                                    EplEventkRxSignalHandlerCb,
+                                    kshbPriorityHigh);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventkAddInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+Exit:
+#endif
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkDelInstance
+//
+// Description: function deletes instance and frees the buffers
+//
+// Parameters:  void
+//
+// Returns:     tEpKernel   = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplEventkDelInstance()
+{
+tEplKernel      Ret;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+#endif
+
+    Ret = kEplSuccessful;
+
+#ifndef EPL_NO_FIFO
+    // set eventhandler to NULL
+    ShbError = ShbCirSetSignalHandlerNewData (EplEventkInstance_g.m_pShbUserToKernelInstance,
+                                    NULL,
+                                    kShbPriorityNormal);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventkDelInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+    }
+
+    // free buffer User -> Kernel
+    ShbError = ShbCirReleaseBuffer (EplEventkInstance_g.m_pShbUserToKernelInstance);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventkDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+    }
+    else
+    {
+        EplEventkInstance_g.m_pShbUserToKernelInstance = NULL;
+    }
+
+    // free buffer  Kernel -> User
+    ShbError = ShbCirReleaseBuffer (EplEventkInstance_g.m_pShbKernelToUserInstance);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventkDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+    }
+    else
+    {
+        EplEventkInstance_g.m_pShbKernelToUserInstance = NULL;
+    }
+#endif
+
+return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkProcess
+//
+// Description: Kernelthread that dispatches events in kernel part
+//
+// Parameters:  pEvent_p    = pointer to event-structure from buffer
+//
+// Returns:     tEpKernel   = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplEventkProcess(tEplEvent* pEvent_p)
+{
+tEplKernel              Ret;
+tEplEventSource         EventSource;
+
+    Ret = kEplSuccessful;
+
+    // error handling if event queue is full
+    if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0)
+    {   // UserToKernel event queue has run out of space -> kEplNmtEventInternComError
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+        tEplEvent   Event;
+        tEplNmtEvent NmtEvent;
+#endif
+#ifndef EPL_NO_FIFO
+        tShbError   ShbError;
+#endif
+
+        // directly call NMTk process function, because event queue is full
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+        NmtEvent = kEplNmtEventInternComError;
+        Event.m_EventSink = kEplEventSinkNmtk;
+        Event.m_NetTime.m_dwNanoSec = 0;
+        Event.m_NetTime.m_dwSec = 0;
+        Event.m_EventType = kEplEventTypeNmtEvent;
+        Event.m_pArg = &NmtEvent;
+        Event.m_uiSize = sizeof(NmtEvent);
+        Ret = EplNmtkProcess(&Event);
+#endif
+
+        // NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION)
+        // now, it is safe to reset the counter and empty the event queue
+#ifndef EPL_NO_FIFO
+        ShbError = ShbCirResetBuffer (EplEventkInstance_g.m_pShbUserToKernelInstance, 1000, NULL);
+#endif
+
+        EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
+        TGT_DBG_SIGNAL_TRACE_POINT(22);
+
+        // also discard the current event (it doesn't matter if we lose another event)
+        goto Exit;
+    }
+
+    // check m_EventSink
+    switch(pEvent_p->m_EventSink)
+    {
+        case kEplEventSinkSync:
+        {
+            if (EplEventkInstance_g.m_pfnCbSync != NULL)
+            {
+                Ret = EplEventkInstance_g.m_pfnCbSync();
+                if (Ret == kEplSuccessful)
+                {
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+                    // mark TPDOs as valid
+                    Ret = EplPdokCalSetTpdosValid(TRUE);
+#endif
+                }
+                else if ((Ret != kEplReject) && (Ret != kEplShutdown))
+                {
+                    EventSource = kEplEventSourceSyncCb;
+
+                    // Error event for API layer
+                    EplEventkPostError(kEplEventSourceEventk,
+                                    Ret,
+                                    sizeof(EventSource),
+                                    &EventSource);
+                }
+            }
+            break;
+        }
+
+        // NMT-Kernel-Modul
+        case kEplEventSinkNmtk:
+        {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+            Ret = EplNmtkProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceNmtk;
+
+                // Error event for API layer
+                EplEventkPostError(kEplEventSourceEventk,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+#endif
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent)
+                && ((*((tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa)
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+                || (*((tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent)
+#endif
+                ))
+            {   // forward SoA event to error handler
+                Ret = EplErrorHandlerkProcess(pEvent_p);
+                if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+                {
+                    EventSource = kEplEventSourceErrk;
+
+                    // Error event for API layer
+                    EplEventkPostError(kEplEventSourceEventk,
+                                    Ret,
+                                    sizeof(EventSource),
+                                    &EventSource);
+                }
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+                // forward SoA event to PDO module
+                pEvent_p->m_EventType = kEplEventTypePdoSoa;
+                Ret = EplPdokProcess(pEvent_p);
+                if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+                {
+                    EventSource = kEplEventSourcePdok;
+
+                    // Error event for API layer
+                    EplEventkPostError(kEplEventSourceEventk,
+                                    Ret,
+                                    sizeof(EventSource),
+                                    &EventSource);
+                }
+#endif
+
+            }
+            break;
+#endif
+        }
+
+        // events for Dllk module
+        case kEplEventSinkDllk:
+        {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            Ret = EplDllkProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceDllk;
+
+                // Error event for API layer
+                EplEventkPostError(kEplEventSourceEventk,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+#endif
+            break;
+        }
+
+        // events for DllkCal module
+        case kEplEventSinkDllkCal:
+        {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            Ret = EplDllkCalProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceDllk;
+
+                // Error event for API layer
+                EplEventkPostError(kEplEventSourceEventk,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+#endif
+            break;
+        }
+
+        //
+        case kEplEventSinkPdok:
+        {
+            // PDO-Module
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+            Ret = EplPdokProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourcePdok;
+
+                // Error event for API layer
+                EplEventkPostError(kEplEventSourceEventk,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+#endif
+            break;
+        }
+
+        // events for Error handler module
+        case kEplEventSinkErrk:
+        {
+            // only call error handler if DLL is present
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            Ret = EplErrorHandlerkProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceErrk;
+
+                // Error event for API layer
+                EplEventkPostError(kEplEventSourceEventk,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+            break;
+#endif
+        }
+
+        // unknown sink
+        default:
+        {
+            Ret = kEplEventUnknownSink;
+        }
+
+    } // end of switch(pEvent_p->m_EventSink)
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkPost
+//
+// Description: post events from kernel part
+//
+// Parameters:  pEvent_p    = pointer to event-structure from buffer
+//
+// Returns:     tEpKernel   = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
+{
+tEplKernel      Ret;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+tShbCirChunk    ShbCirChunk;
+unsigned long   ulDataSize;
+unsigned int    fBufferCompleted;
+#endif
+
+    Ret = kEplSuccessful;
+
+
+    // the event must be posted by using the abBuffer
+    // it is neede because the Argument must by copied
+    // to the buffer too and not only the pointer
+
+#ifndef EPL_NO_FIFO
+    // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
+    ulDataSize = sizeof(tEplEvent) + ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
+#endif
+
+    // decide in which buffer the event have to write
+    switch(pEvent_p->m_EventSink)
+    {
+        // kernelspace modules
+        case kEplEventSinkSync:
+        case kEplEventSinkNmtk:
+        case kEplEventSinkDllk:
+        case kEplEventSinkDllkCal:
+        case kEplEventSinkPdok:
+        case kEplEventSinkErrk:
+        {
+#ifndef EPL_NO_FIFO
+            // post message
+            BENCHMARK_MOD_27_SET(2);
+            ShbError = ShbCirAllocDataBlock (EplEventkInstance_g.m_pShbUserToKernelInstance,
+                                   &ShbCirChunk,
+                                   ulDataSize);
+            switch (ShbError)
+            {
+                case kShbOk:
+                    break;
+
+                case kShbBufferFull:
+                {
+                    EplEventkInstance_g.m_uiUserToKernelFullCount++;
+                    Ret = kEplEventPostError;
+                    goto Exit;
+                }
+
+                default:
+                {
+                    EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n", ShbError);
+                    Ret = kEplEventPostError;
+                    goto Exit;
+                }
+            }
+            ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbUserToKernelInstance,
+                                   &ShbCirChunk,
+                                   pEvent_p,
+                                   sizeof (tEplEvent),
+                                   &fBufferCompleted);
+            if (ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            if (fBufferCompleted == FALSE)
+            {
+                ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbUserToKernelInstance,
+                                       &ShbCirChunk,
+                                       pEvent_p->m_pArg,
+                                       (unsigned long) pEvent_p->m_uiSize,
+                                       &fBufferCompleted);
+                if ((ShbError != kShbOk) || (fBufferCompleted == FALSE))
+                {
+                    EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n", ShbError);
+                    Ret = kEplEventPostError;
+                    goto Exit;
+                }
+            }
+            BENCHMARK_MOD_27_RESET(2);
+
+#else
+            Ret = EplEventkProcess(pEvent_p);
+#endif
+
+            break;
+        }
+
+        // userspace modules
+        case kEplEventSinkNmtu:
+        case kEplEventSinkNmtMnu:
+        case kEplEventSinkSdoAsySeq:
+        case kEplEventSinkApi:
+        case kEplEventSinkDlluCal:
+        case kEplEventSinkErru:
+        {
+#ifndef EPL_NO_FIFO
+            // post message
+//            BENCHMARK_MOD_27_SET(3);    // 74 Âµs until reset
+            ShbError = ShbCirAllocDataBlock (EplEventkInstance_g.m_pShbKernelToUserInstance,
+                                   &ShbCirChunk,
+                                   ulDataSize);
+            if(ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbKernelToUserInstance,
+                                   &ShbCirChunk,
+                                   pEvent_p,
+                                   sizeof (tEplEvent),
+                                   &fBufferCompleted);
+            if(ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            if (fBufferCompleted == FALSE)
+            {
+                ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbKernelToUserInstance,
+                                       &ShbCirChunk,
+                                       pEvent_p->m_pArg,
+                                       (unsigned long) pEvent_p->m_uiSize,
+                                       &fBufferCompleted);
+                if ((ShbError != kShbOk) || (fBufferCompleted == FALSE))
+                {
+                    EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n", ShbError);
+                    Ret = kEplEventPostError;
+                    goto Exit;
+                }
+            }
+//            BENCHMARK_MOD_27_RESET(3);  // 82 Âµs until ShbCirGetReadDataSize() in EplEventu
+
+#else
+            Ret = EplEventuProcess(pEvent_p);
+#endif
+
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplEventUnknownSink;
+        }
+
+
+    }// end of switch(pEvent_p->m_EventSink)
+
+#ifndef EPL_NO_FIFO
+Exit:
+#endif
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkPostError
+//
+// Description: post error event from kernel part to API layer
+//
+// Parameters:  EventSource_p   = source-module of the error event
+//              EplError_p      = code of occured error
+//              ArgSize_p       = size of the argument
+//              pArg_p          = pointer to the argument
+//
+// Returns:     tEpKernel       = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
+                                     tEplKernel      EplError_p,
+                                     unsigned int    uiArgSize_p,
+                                     void*           pArg_p)
+{
+tEplKernel  Ret;
+BYTE        abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+tEplEventError* pEventError = (tEplEventError*) abBuffer;
+tEplEvent   EplEvent;
+
+    Ret = kEplSuccessful;
+
+    // create argument
+    pEventError->m_EventSource = EventSource_p;
+    pEventError->m_EplError = EplError_p;
+    EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
+
+    // create event
+    EplEvent.m_EventType = kEplEventTypeError;
+    EplEvent.m_EventSink = kEplEventSinkApi;
+    EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
+    EplEvent.m_uiSize = (sizeof(EventSource_p)+ sizeof(EplError_p)+ uiArgSize_p);
+    EplEvent.m_pArg = &abBuffer[0];
+
+    // post errorevent
+    Ret = EplEventkPost(&EplEvent);
+
+    return Ret;
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventkRxSignalHandlerCb()
+//
+// Description: Callback-function for events from user and kernel part
+//
+// Parameters:  pShbRxInstance_p    = Instance-pointer of buffer
+//              ulDataSize_p        = size of data
+//
+// Returns: void
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#ifndef EPL_NO_FIFO
+static void  EplEventkRxSignalHandlerCb (
+                tShbInstance pShbRxInstance_p,
+                unsigned long ulDataSize_p)
+{
+tEplEvent      *pEplEvent;
+tShbError       ShbError;
+//unsigned long   ulBlockCount;
+//unsigned long   ulDataSize;
+BYTE            abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+                // d.k.: abDataBuffer contains the complete tEplEvent structure
+                //       and behind this the argument
+
+    TGT_DBG_SIGNAL_TRACE_POINT(20);
+
+    BENCHMARK_MOD_27_RESET(0);
+    // copy data from event queue
+    ShbError = ShbCirReadDataBlock (pShbRxInstance_p,
+                            &abDataBuffer[0],
+                            sizeof(abDataBuffer),
+                            &ulDataSize_p);
+    if(ShbError != kShbOk)
+    {
+        // error goto exit
+        goto Exit;
+    }
+
+    // resolve the pointer to the event structure
+    pEplEvent = (tEplEvent *) abDataBuffer;
+    // set Datasize
+    pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
+    if(pEplEvent->m_uiSize > 0)
+    {
+        // set pointer to argument
+        pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
+    }
+    else
+    {
+        //set pointer to NULL
+        pEplEvent->m_pArg = NULL;
+    }
+
+    BENCHMARK_MOD_27_SET(0);
+    // call processfunction
+    EplEventkProcess(pEplEvent);
+
+Exit:
+    return;
+}
+#endif
+
+// EOF
+
diff --git a/drivers/staging/epl/EplEventu.c b/drivers/staging/epl/EplEventu.c
new file mode 100644 (file)
index 0000000..cb0215a
--- /dev/null
@@ -0,0 +1,813 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Epl-Userspace-Event-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplEventu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/20 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplEventu.h"
+#include "user/EplNmtu.h"
+#include "user/EplNmtMnu.h"
+#include "user/EplSdoAsySequ.h"
+#include "user/EplDlluCal.h"
+#include "user/EplLedu.h"
+#include "Benchmark.h"
+
+#ifdef EPL_NO_FIFO
+    #include "kernel/EplEventk.h"
+#else
+    #include "SharedBuff.h"
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+#ifndef EPL_NO_FIFO
+    tShbInstance        m_pShbKernelToUserInstance;
+    tShbInstance        m_pShbUserToKernelInstance;
+#endif
+    tEplProcessEventCb  m_pfnApiProcessEventCb;
+
+}tEplEventuInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//#ifndef EPL_NO_FIFO
+static tEplEventuInstance EplEventuInstance_g;
+//#endif
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+#ifndef EPL_NO_FIFO
+// callback function for incomming events
+static void  EplEventuRxSignalHandlerCb (
+    tShbInstance pShbRxInstance_p,
+    unsigned long ulDataSize_p);
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <Epl-User-Event>                                    */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuInit
+//
+// Description: function initialize the first instance
+//
+//
+//
+// Parameters:  pfnApiProcessEventCb_p  = function pointer for API event callback
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
+{
+tEplKernel Ret;
+
+
+    Ret = EplEventuAddInstance(pfnApiProcessEventCb_p);
+
+
+return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuAddInstance
+//
+// Description: function add one more instance
+//
+//
+//
+// Parameters:  pfnApiProcessEventCb_p  = function pointer for API event callback
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p)
+{
+tEplKernel      Ret;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+unsigned int    fShbNewCreated;
+#endif
+
+    Ret = kEplSuccessful;
+
+
+    // init instance variables
+    EplEventuInstance_g.m_pfnApiProcessEventCb = pfnApiProcessEventCb_p;
+
+#ifndef EPL_NO_FIFO
+    // init shared loop buffer
+    // kernel -> user
+    ShbError = ShbCirAllocBuffer (EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
+                                  EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
+                                  &EplEventuInstance_g.m_pShbKernelToUserInstance,
+                                  &fShbNewCreated);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventuAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+
+    // user -> kernel
+    ShbError = ShbCirAllocBuffer (EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
+                                  EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
+                                  &EplEventuInstance_g.m_pShbUserToKernelInstance,
+                                  &fShbNewCreated);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventuAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    // register eventhandler
+    ShbError = ShbCirSetSignalHandlerNewData (EplEventuInstance_g.m_pShbKernelToUserInstance,
+                                    EplEventuRxSignalHandlerCb,
+                                    kShbPriorityNormal);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventuAddInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+Exit:
+#endif
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuDelInstance
+//
+// Description: function delete instance an free the bufferstructure
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplEventuDelInstance()
+{
+tEplKernel      Ret;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+#endif
+
+    Ret = kEplSuccessful;
+
+#ifndef EPL_NO_FIFO
+    // set eventhandler to NULL
+    ShbError = ShbCirSetSignalHandlerNewData (EplEventuInstance_g.m_pShbKernelToUserInstance,
+                                    NULL,
+                                    kShbPriorityNormal);
+    if(ShbError != kShbOk)
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventuDelInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+    }
+
+    // free buffer User -> Kernel
+    ShbError = ShbCirReleaseBuffer (EplEventuInstance_g.m_pShbUserToKernelInstance);
+    if((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs))
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventuDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+    }
+    else
+    {
+        EplEventuInstance_g.m_pShbUserToKernelInstance = NULL;
+    }
+
+    // free buffer  Kernel -> User
+    ShbError = ShbCirReleaseBuffer (EplEventuInstance_g.m_pShbKernelToUserInstance);
+    if((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs))
+    {
+        EPL_DBGLVL_EVENTK_TRACE1("EplEventuDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n", ShbError);
+        Ret = kEplNoResource;
+    }
+    else
+    {
+        EplEventuInstance_g.m_pShbKernelToUserInstance = NULL;
+    }
+
+#endif
+
+return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuProcess
+//
+// Description: Kernelthread that dispatches events in kernelspace
+//
+//
+//
+// Parameters:  pEvent_p = pointer to event-structur from buffer
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplEventuProcess(tEplEvent* pEvent_p)
+{
+tEplKernel              Ret;
+tEplEventSource         EventSource;
+
+    Ret = kEplSuccessful;
+
+    // check m_EventSink
+    switch(pEvent_p->m_EventSink)
+    {
+        // NMT-User-Module
+        case kEplEventSinkNmtu:
+        {
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+            Ret = EplNmtuProcessEvent(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceNmtu;
+
+                // Error event for API layer
+                EplEventuPostError(kEplEventSourceEventu,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+#endif
+            break;
+        }
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        // NMT-MN-User-Module
+        case kEplEventSinkNmtMnu:
+        {
+            Ret = EplNmtMnuProcessEvent(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceNmtMnu;
+
+                // Error event for API layer
+                EplEventuPostError(kEplEventSourceEventu,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+            break;
+        }
+#endif
+
+#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)   \
+     || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0))
+        // events for asynchronus SDO Sequence Layer
+        case kEplEventSinkSdoAsySeq:
+        {
+            Ret = EplSdoAsySeqProcessEvent(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceSdoAsySeq;
+
+                // Error event for API layer
+                EplEventuPostError(kEplEventSourceEventu,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+            break;
+        }
+#endif
+
+        // LED user part module
+        case kEplEventSinkLedu:
+        {
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+            Ret = EplLeduProcessEvent(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceLedu;
+
+                // Error event for API layer
+                EplEventuPostError(kEplEventSourceEventu,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+#endif
+            break;
+        }
+
+        // event for EPL api
+        case kEplEventSinkApi:
+        {
+            if (EplEventuInstance_g.m_pfnApiProcessEventCb != NULL)
+            {
+                Ret = EplEventuInstance_g.m_pfnApiProcessEventCb(pEvent_p);
+                if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+                {
+                    EventSource = kEplEventSourceEplApi;
+
+                    // Error event for API layer
+                    EplEventuPostError(kEplEventSourceEventu,
+                                    Ret,
+                                    sizeof(EventSource),
+                                    &EventSource);
+                }
+            }
+            break;
+
+        }
+
+        case kEplEventSinkDlluCal:
+        {
+            Ret = EplDlluCalProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceDllu;
+
+                // Error event for API layer
+                EplEventuPostError(kEplEventSourceEventu,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+            break;
+
+        }
+
+        case kEplEventSinkErru:
+        {
+            /*
+            Ret = EplErruProcess(pEvent_p);
+            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
+            {
+                EventSource = kEplEventSourceErru;
+
+                // Error event for API layer
+                EplEventuPostError(kEplEventSourceEventu,
+                                Ret,
+                                sizeof(EventSource),
+                                &EventSource);
+            }
+            */
+            break;
+
+        }
+
+        // unknown sink
+        default:
+        {
+            Ret = kEplEventUnknownSink;
+        }
+
+    } // end of switch(pEvent_p->m_EventSink)
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuPost
+//
+// Description: post events from userspace
+//
+//
+//
+// Parameters:  pEvent_p = pointer to event-structur from buffer
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
+{
+tEplKernel      Ret;
+#ifndef EPL_NO_FIFO
+tShbError       ShbError;
+tShbCirChunk    ShbCirChunk;
+unsigned long   ulDataSize;
+unsigned int    fBufferCompleted;
+#endif
+
+    Ret = kEplSuccessful;
+
+
+#ifndef EPL_NO_FIFO
+    // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
+    ulDataSize = sizeof(tEplEvent) + ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
+#endif
+
+    // decide in which buffer the event have to write
+    switch(pEvent_p->m_EventSink)
+    {
+        // kernelspace modules
+        case kEplEventSinkSync:
+        case kEplEventSinkNmtk:
+        case kEplEventSinkDllk:
+        case kEplEventSinkDllkCal:
+        case kEplEventSinkPdok:
+        case kEplEventSinkErrk:
+        {
+#ifndef EPL_NO_FIFO
+            // post message
+            ShbError = ShbCirAllocDataBlock (EplEventuInstance_g.m_pShbUserToKernelInstance,
+                                   &ShbCirChunk,
+                                   ulDataSize);
+            if (ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventuPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            ShbError = ShbCirWriteDataChunk (EplEventuInstance_g.m_pShbUserToKernelInstance,
+                                   &ShbCirChunk,
+                                   pEvent_p,
+                                   sizeof (tEplEvent),
+                                   &fBufferCompleted);
+            if (ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventuPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            if (fBufferCompleted == FALSE)
+            {
+                ShbError = ShbCirWriteDataChunk (EplEventuInstance_g.m_pShbUserToKernelInstance,
+                                       &ShbCirChunk,
+                                       pEvent_p->m_pArg,
+                                       (unsigned long) pEvent_p->m_uiSize,
+                                       &fBufferCompleted);
+                if ((ShbError != kShbOk) || (fBufferCompleted == FALSE))
+                {
+                    EPL_DBGLVL_EVENTK_TRACE1("EplEventuPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n", ShbError);
+                    Ret = kEplEventPostError;
+                    goto Exit;
+                }
+            }
+#else
+            Ret = EplEventkProcess(pEvent_p);
+#endif
+
+            break;
+        }
+
+        // userspace modules
+        case kEplEventSinkNmtMnu:
+        case kEplEventSinkNmtu:
+        case kEplEventSinkSdoAsySeq:
+        case kEplEventSinkApi:
+        case kEplEventSinkDlluCal:
+        case kEplEventSinkErru:
+        case kEplEventSinkLedu:
+        {
+#ifndef EPL_NO_FIFO
+            // post message
+            ShbError = ShbCirAllocDataBlock (EplEventuInstance_g.m_pShbKernelToUserInstance,
+                                   &ShbCirChunk,
+                                   ulDataSize);
+            if(ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventuPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            ShbError = ShbCirWriteDataChunk (EplEventuInstance_g.m_pShbKernelToUserInstance,
+                                   &ShbCirChunk,
+                                   pEvent_p,
+                                   sizeof (tEplEvent),
+                                   &fBufferCompleted);
+            if(ShbError != kShbOk)
+            {
+                EPL_DBGLVL_EVENTK_TRACE1("EplEventuPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n", ShbError);
+                Ret = kEplEventPostError;
+                goto Exit;
+            }
+            if (fBufferCompleted == FALSE)
+            {
+                ShbError = ShbCirWriteDataChunk (EplEventuInstance_g.m_pShbKernelToUserInstance,
+                                       &ShbCirChunk,
+                                       pEvent_p->m_pArg,
+                                       (unsigned long) pEvent_p->m_uiSize,
+                                       &fBufferCompleted);
+                if ((ShbError != kShbOk) || (fBufferCompleted == FALSE))
+                {
+                    EPL_DBGLVL_EVENTK_TRACE1("EplEventuPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n", ShbError);
+                    Ret = kEplEventPostError;
+                    goto Exit;
+                }
+            }
+
+#else
+            Ret = EplEventuProcess(pEvent_p);
+#endif
+
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplEventUnknownSink;
+        }
+
+
+    }// end of switch(pEvent_p->m_EventSink)
+
+#ifndef EPL_NO_FIFO
+Exit:
+#endif
+    return Ret;
+
+}
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuPostError
+//
+// Description: post errorevent from userspace
+//
+//
+//
+// Parameters:  EventSource_p   = source-module of the errorevent
+//              EplError_p     = code of occured error
+//              uiArgSize_p     = size of the argument
+//              pArg_p          = pointer to the argument
+//
+//
+// Returns:      tEpKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
+                                     tEplKernel      EplError_p,
+                                     unsigned int    uiArgSize_p,
+                                     void*           pArg_p)
+{
+tEplKernel  Ret;
+BYTE        abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+tEplEventError* pEventError = (tEplEventError*) abBuffer;
+tEplEvent   EplEvent;
+
+    Ret = kEplSuccessful;
+
+    // create argument
+    pEventError->m_EventSource = EventSource_p;
+    pEventError->m_EplError = EplError_p;
+    EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
+
+    // create event
+    EplEvent.m_EventType = kEplEventTypeError;
+    EplEvent.m_EventSink = kEplEventSinkApi;
+    EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
+    EplEvent.m_uiSize = (sizeof(EventSource_p)+ sizeof(EplError_p)+ uiArgSize_p);
+    EplEvent.m_pArg = &abBuffer[0];
+
+    // post errorevent
+    Ret = EplEventuPost(&EplEvent);
+
+    return Ret;
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEventuRxSignalHandlerCb()
+//
+// Description: Callback-function for evets from kernelspace
+//
+//
+//
+// Parameters:  pShbRxInstance_p    = Instance-pointer for buffer
+//              ulDataSize_p        = size of data
+//
+//
+// Returns: void
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#ifndef EPL_NO_FIFO
+static void  EplEventuRxSignalHandlerCb (
+    tShbInstance pShbRxInstance_p,
+    unsigned long ulDataSize_p)
+{
+tEplEvent      *pEplEvent;
+tShbError       ShbError;
+//unsigned long   ulBlockCount;
+//unsigned long   ulDataSize;
+BYTE            abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+                // d.k.: abDataBuffer contains the complete tEplEvent structure
+                //       and behind this the argument
+
+    TGT_DBG_SIGNAL_TRACE_POINT(21);
+
+// d.k. not needed because it is already done in SharedBuff
+/*    do
+    {
+        BENCHMARK_MOD_28_SET(1);    // 4 Âµs until reset
+        // get messagesize
+        ShbError = ShbCirGetReadDataSize (pShbRxInstance_p, &ulDataSize);
+        if(ShbError != kShbOk)
+        {
+            // error goto exit
+            goto Exit;
+        }
+
+        BENCHMARK_MOD_28_RESET(1);  // 14 Âµs until set
+*/
+        // copy data from event queue
+        ShbError = ShbCirReadDataBlock (pShbRxInstance_p,
+                                &abDataBuffer[0],
+                                sizeof(abDataBuffer),
+                                &ulDataSize_p);
+        if(ShbError != kShbOk)
+        {
+            // error goto exit
+            goto Exit;
+        }
+
+        // resolve the pointer to the event structure
+        pEplEvent = (tEplEvent *) abDataBuffer;
+        // set Datasize
+        pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
+        if(pEplEvent->m_uiSize > 0)
+        {
+            // set pointer to argument
+            pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
+        }
+        else
+        {
+            //set pointer to NULL
+            pEplEvent->m_pArg = NULL;
+        }
+
+        BENCHMARK_MOD_28_SET(1);
+        // call processfunction
+        EplEventuProcess(pEplEvent);
+
+        BENCHMARK_MOD_28_RESET(1);
+        // read number of left messages to process
+// d.k. not needed because it is already done in SharedBuff
+/*        ShbError = ShbCirGetReadBlockCount (pShbRxInstance_p, &ulBlockCount);
+        if (ShbError != kShbOk)
+        {
+            // error goto exit
+            goto Exit;
+        }
+    } while (ulBlockCount > 0);
+*/
+Exit:
+    return;
+}
+#endif
+
+// EOF
+
diff --git a/drivers/staging/epl/EplFrame.h b/drivers/staging/epl/EplFrame.h
new file mode 100644 (file)
index 0000000..1e5cb3d
--- /dev/null
@@ -0,0 +1,374 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for EPL frames
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplFrame.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/06/23 14:56:33 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_FRAME_H_
+#define _EPL_FRAME_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+// defines for EplFrame.m_wFlag
+#define EPL_FRAME_FLAG1_RD          0x01    // ready                                    (PReq, PRes)
+#define EPL_FRAME_FLAG1_ER          0x02    // exception reset (error signalling)       (SoA)
+#define EPL_FRAME_FLAG1_EA          0x04    // exception acknowledge (error signalling) (PReq, SoA)
+#define EPL_FRAME_FLAG1_EC          0x08    // exception clear (error signalling)       (StatusRes)
+#define EPL_FRAME_FLAG1_EN          0x10    // exception new (error signalling)         (PRes, StatusRes)
+#define EPL_FRAME_FLAG1_MS          0x20    // multiplexed slot                         (PReq)
+#define EPL_FRAME_FLAG1_PS          0x40    // prescaled slot                           (SoC)
+#define EPL_FRAME_FLAG1_MC          0x80    // multiplexed cycle completed              (SoC)
+#define EPL_FRAME_FLAG2_RS          0x07    // number of pending requests to send       (PRes, StatusRes, IdentRes)
+#define EPL_FRAME_FLAG2_PR          0x38    // priority of requested asynch. frame      (PRes, StatusRes, IdentRes)
+#define EPL_FRAME_FLAG2_PR_SHIFT    3       // shift of priority of requested asynch. frame
+
+// error history/status entry types
+#define EPL_ERR_ENTRYTYPE_STATUS        0x8000
+#define EPL_ERR_ENTRYTYPE_HISTORY       0x0000
+#define EPL_ERR_ENTRYTYPE_EMCY          0x4000
+#define EPL_ERR_ENTRYTYPE_MODE_ACTIVE   0x1000
+#define EPL_ERR_ENTRYTYPE_MODE_CLEARED  0x2000
+#define EPL_ERR_ENTRYTYPE_MODE_OCCURRED 0x3000
+#define EPL_ERR_ENTRYTYPE_MODE_MASK     0x3000
+#define EPL_ERR_ENTRYTYPE_PROF_VENDOR   0x0001
+#define EPL_ERR_ENTRYTYPE_PROF_EPL      0x0002
+#define EPL_ERR_ENTRYTYPE_PROF_MASK     0x0FFF
+
+// defines for EPL version / PDO version
+#define EPL_VERSION_SUB             0x0F  // sub version
+#define EPL_VERSION_MAIN            0xF0  // main version
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+// $$$ d.k.: move this definition to global.h
+// byte-align structures
+#ifdef _MSC_VER
+#    pragma pack( push, packing )
+#    pragma pack( 1 )
+#    define PACK_STRUCT
+#elif defined( __GNUC__ )
+#    define PACK_STRUCT    __attribute__((packed))
+#else
+#    error you must byte-align these structures with the appropriate compiler directives
+#endif
+
+
+typedef struct
+{
+    // Offset 17
+    BYTE                    m_le_bRes1;                     // reserved
+    // Offset 18
+    BYTE                    m_le_bFlag1;                    // Flags: MC, PS
+    // Offset 19
+    BYTE                    m_le_bFlag2;                    // Flags: res
+    // Offset 20
+    tEplNetTime             m_le_NetTime;                   // supported if D_NMT_NetTimeIsRealTime_BOOL is set
+    // Offset 28
+    QWORD                   m_le_RelativeTime;              // in us (supported if D_NMT_RelativeTime_BOOL is set)
+
+} PACK_STRUCT tEplSocFrame;
+
+typedef struct
+{
+    // Offset 17
+    BYTE                    m_le_bRes1;                     // reserved
+    // Offset 18
+    BYTE                    m_le_bFlag1;                    // Flags: MS, EA, RD
+    // Offset 19
+    BYTE                    m_le_bFlag2;                    // Flags: res
+    // Offset 20
+    BYTE                    m_le_bPdoVersion;
+    // Offset 21
+    BYTE                    m_le_bRes2;                     // reserved
+    // Offset 22
+    WORD                    m_le_wSize;
+    // Offset 24
+    BYTE                    m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16*/];
+
+} PACK_STRUCT tEplPreqFrame;
+
+typedef struct
+{
+    // Offset 17
+    BYTE                    m_le_bNmtStatus;                // NMT state
+    // Offset 18
+    BYTE                    m_le_bFlag1;                    // Flags: MS, EN, RD
+    // Offset 19
+    BYTE                    m_le_bFlag2;                    // Flags: PR, RS
+    // Offset 20
+    BYTE                    m_le_bPdoVersion;
+    // Offset 21
+    BYTE                    m_le_bRes2;                     // reserved
+    // Offset 22
+    WORD                    m_le_wSize;
+    // Offset 24
+    BYTE                    m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16
+                                        / D_NMT_IsochrTxMaxPayload_U16*/];
+
+} PACK_STRUCT tEplPresFrame;
+
+typedef struct
+{
+    // Offset 17
+    BYTE                    m_le_bNmtStatus;                // NMT state
+    // Offset 18
+    BYTE                    m_le_bFlag1;                    // Flags: EA, ER
+    // Offset 19
+    BYTE                    m_le_bFlag2;                    // Flags: res
+    // Offset 20
+    BYTE                    m_le_bReqServiceId;
+    // Offset 21
+    BYTE                    m_le_bReqServiceTarget;
+    // Offset 22
+    BYTE                    m_le_bEplVersion;
+
+} PACK_STRUCT tEplSoaFrame;
+
+typedef struct
+{
+    WORD            m_wEntryType;
+    WORD            m_wErrorCode;
+    tEplNetTime     m_TimeStamp;
+    BYTE            m_abAddInfo[8];
+
+} PACK_STRUCT tEplErrHistoryEntry;
+
+typedef struct
+{
+    // Offset 18
+    BYTE                    m_le_bFlag1;                    // Flags: EN, EC
+    BYTE                    m_le_bFlag2;                    // Flags: PR, RS
+    BYTE                    m_le_bNmtStatus;                // NMT state
+    BYTE                    m_le_bRes1[3];
+    QWORD                   m_le_qwStaticError;             // static error bit field
+    tEplErrHistoryEntry     m_le_aErrHistoryEntry[14];
+
+} PACK_STRUCT tEplStatusResponse;
+
+typedef struct
+{
+    // Offset 18
+    BYTE                    m_le_bFlag1;                    // Flags: res
+    BYTE                    m_le_bFlag2;                    // Flags: PR, RS
+    BYTE                    m_le_bNmtStatus;                // NMT state
+    BYTE                    m_le_bIdentRespFlags;           // Flags: FW
+    BYTE                    m_le_bEplProfileVersion;
+    BYTE                    m_le_bRes1;
+    DWORD                   m_le_dwFeatureFlags;            // NMT_FeatureFlags_U32
+    WORD                    m_le_wMtu;                      // NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
+    WORD                    m_le_wPollInSize;               // NMT_CycleTiming_REC.PReqActPayload_U16
+    WORD                    m_le_wPollOutSize;              // NMT_CycleTiming_REC.PResActPayload_U16
+    DWORD                   m_le_dwResponseTime;            // NMT_CycleTiming_REC.PResMaxLatency_U32
+    WORD                    m_le_wRes2;
+    DWORD                   m_le_dwDeviceType;              // NMT_DeviceType_U32
+    DWORD                   m_le_dwVendorId;                // NMT_IdentityObject_REC.VendorId_U32
+    DWORD                   m_le_dwProductCode;             // NMT_IdentityObject_REC.ProductCode_U32
+    DWORD                   m_le_dwRevisionNumber;          // NMT_IdentityObject_REC.RevisionNo_U32
+    DWORD                   m_le_dwSerialNumber;            // NMT_IdentityObject_REC.SerialNo_U32
+    QWORD                   m_le_qwVendorSpecificExt1;
+    DWORD                   m_le_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+    DWORD                   m_le_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+    DWORD                   m_le_dwApplicationSwDate;       // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+    DWORD                   m_le_dwApplicationSwTime;       // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+    DWORD                   m_le_dwIpAddress;
+    DWORD                   m_le_dwSubnetMask;
+    DWORD                   m_le_dwDefaultGateway;
+    BYTE                    m_le_sHostname[32];
+    BYTE                    m_le_abVendorSpecificExt2[48];
+
+} PACK_STRUCT tEplIdentResponse;
+
+typedef struct
+{
+    // Offset 18
+    BYTE                    m_le_bNmtCommandId;
+    BYTE                    m_le_bRes1;
+    BYTE                    m_le_abNmtCommandData[32];
+
+} PACK_STRUCT tEplNmtCommandService;
+
+typedef struct
+{
+    BYTE                    m_le_bReserved;
+    BYTE                    m_le_bTransactionId;
+    BYTE                    m_le_bFlags;
+    BYTE                    m_le_bCommandId;
+    WORD                    m_le_wSegmentSize;
+    WORD                    m_le_wReserved;
+    BYTE                    m_le_abCommandData[8];  // just reserve a minimum number of bytes as a placeholder
+
+}PACK_STRUCT tEplAsySdoCom;
+
+
+// asynchronous SDO Sequence Header
+typedef struct
+{
+    BYTE           m_le_bRecSeqNumCon;
+    BYTE           m_le_bSendSeqNumCon;
+    BYTE           m_le_abReserved[2];
+    tEplAsySdoCom  m_le_abSdoSeqPayload;
+
+} PACK_STRUCT tEplAsySdoSeq;
+
+typedef struct
+{
+    // Offset 18
+    BYTE                    m_le_bNmtCommandId;
+    BYTE                    m_le_bTargetNodeId;
+    BYTE                    m_le_abNmtCommandData[32];
+
+} PACK_STRUCT tEplNmtRequestService;
+
+
+typedef union
+{
+    // Offset 18
+    tEplStatusResponse      m_StatusResponse;
+    tEplIdentResponse       m_IdentResponse;
+    tEplNmtCommandService   m_NmtCommandService;
+    tEplNmtRequestService   m_NmtRequestService;
+    tEplAsySdoSeq           m_SdoSequenceFrame;
+    BYTE                    m_le_abPayload[256 /*D_NMT_ASndTxMaxPayload_U16
+                                        / D_NMT_ASndRxMaxPayload_U16*/];
+
+} tEplAsndPayload;
+
+typedef struct
+{
+    // Offset 17
+    BYTE                    m_le_bServiceId;
+    // Offset 18
+    tEplAsndPayload         m_Payload;
+
+} PACK_STRUCT tEplAsndFrame;
+
+typedef union
+{
+    // Offset 17
+    tEplSocFrame            m_Soc;
+    tEplPreqFrame           m_Preq;
+    tEplPresFrame           m_Pres;
+    tEplSoaFrame            m_Soa;
+    tEplAsndFrame           m_Asnd;
+
+} tEplFrameData;
+
+typedef struct
+{
+    // Offset 0
+    BYTE                    m_be_abDstMac[6];               // MAC address of the addressed nodes
+    // Offset 6
+    BYTE                    m_be_abSrcMac[6];               // MAC address of the transmitting node
+    // Offset 12
+    WORD                    m_be_wEtherType;                // Ethernet message type (big endian)
+    // Offset 14
+    BYTE                    m_le_bMessageType;              // EPL message type
+    // Offset 15
+    BYTE                    m_le_bDstNodeId;                // EPL node ID of the addressed nodes
+    // Offset 16
+    BYTE                    m_le_bSrcNodeId;                // EPL node ID of the transmitting node
+    // Offset 17
+    tEplFrameData           m_Data;
+
+} PACK_STRUCT tEplFrame;
+
+// un-byte-align structures
+#ifdef _MSC_VER
+#    pragma pack( pop, packing )
+#endif
+
+
+typedef enum
+{
+    kEplMsgTypeNonEpl = 0x00,
+    kEplMsgTypeSoc    = 0x01,
+    kEplMsgTypePreq   = 0x03,
+    kEplMsgTypePres   = 0x04,
+    kEplMsgTypeSoa    = 0x05,
+    kEplMsgTypeAsnd   = 0x06,
+
+} tEplMsgType;
+
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPL_FRAME_H_
+
+
diff --git a/drivers/staging/epl/EplIdentu.c b/drivers/staging/epl/EplIdentu.c
new file mode 100644 (file)
index 0000000..5ab7eba
--- /dev/null
@@ -0,0 +1,497 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Identu-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplIdentu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/21 09:00:38 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/11/15 d.k.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplIdentu.h"
+#include "user/EplDlluCal.h"
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <xxxxx>                                             */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplIdentResponse*   m_apIdentResponse[254];    // the IdentResponse are managed dynamically
+    tEplIdentuCbResponse m_apfnCbResponse[254];
+
+} tEplIdentuInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplIdentuInstance   EplIdentuInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuInit
+//
+// Description: init first instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
+{
+tEplKernel Ret;
+
+    Ret = EplIdentuAddInstance();
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuAddInstance
+//
+// Description: init other instances of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof (EplIdentuInstance_g));
+
+    // register IdentResponse callback function
+    Ret = EplDlluCalRegAsndService(kEplDllAsndIdentResponse, EplIdentuCbIdentResponse, kEplDllAsndFilterAny);
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuDelInstance
+//
+// Description: delete instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // deregister IdentResponse callback function
+    Ret = EplDlluCalRegAsndService(kEplDllAsndIdentResponse, NULL, kEplDllAsndFilterNone);
+
+    Ret = EplIdentuReset();
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuReset
+//
+// Description: resets this instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
+{
+tEplKernel  Ret;
+int         iIndex;
+
+    Ret = kEplSuccessful;
+
+    for (iIndex = 0; iIndex < tabentries (EplIdentuInstance_g.m_apIdentResponse); iIndex++)
+    {
+        if (EplIdentuInstance_g.m_apIdentResponse[iIndex] != NULL)
+        {   // free memory
+            EPL_FREE(EplIdentuInstance_g.m_apIdentResponse[iIndex]);
+        }
+    }
+
+    EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof (EplIdentuInstance_g));
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuGetIdentResponse
+//
+// Description: returns the IdentResponse for the specified node.
+//
+// Parameters:  uiNodeId_p                  = IN: node ID
+//              ppIdentResponse_p           = OUT: pointer to pointer of IdentResponse
+//                                            equals NULL, if no IdentResponse available
+//
+// Return:      tEplKernel                  = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplIdentuGetIdentResponse(
+                                    unsigned int        uiNodeId_p,
+                                    tEplIdentResponse** ppIdentResponse_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // decrement node ID, because array is zero based
+    uiNodeId_p--;
+    if (uiNodeId_p < tabentries (EplIdentuInstance_g.m_apIdentResponse))
+    {
+        *ppIdentResponse_p = EplIdentuInstance_g.m_apIdentResponse[uiNodeId_p];
+    }
+    else
+    {   // invalid node ID specified
+        *ppIdentResponse_p = NULL;
+        Ret = kEplInvalidNodeId;
+    }
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuRequestIdentResponse
+//
+// Description: returns the IdentResponse for the specified node.
+//
+// Parameters:  uiNodeId_p                  = IN: node ID
+//              pfnCbResponse_p             = IN: function pointer to callback function
+//                                            which will be called if IdentResponse is received
+//
+// Return:      tEplKernel                  = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplIdentuRequestIdentResponse(
+                                    unsigned int        uiNodeId_p,
+                                    tEplIdentuCbResponse pfnCbResponse_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // decrement node ID, because array is zero based
+    uiNodeId_p--;
+    if (uiNodeId_p < tabentries (EplIdentuInstance_g.m_apfnCbResponse))
+    {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        if (EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL)
+        {   // request already issued (maybe by someone else)
+            Ret = kEplInvalidOperation;
+        }
+        else
+        {
+            EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] = pfnCbResponse_p;
+            Ret = EplDlluCalIssueRequest(kEplDllReqServiceIdent, (uiNodeId_p + 1), 0xFF);
+        }
+#else
+        Ret = kEplInvalidOperation;
+#endif
+    }
+    else
+    {   // invalid node ID specified
+        Ret = kEplInvalidNodeId;
+    }
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuGetRunningRequests
+//
+// Description: returns a bit field with the running requests for node-ID 1-32
+//              just for debugging purposes
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
+{
+DWORD       dwReqs = 0;
+unsigned int    uiIndex;
+
+    for (uiIndex = 0; uiIndex < 32; uiIndex++)
+    {
+        if (EplIdentuInstance_g.m_apfnCbResponse[uiIndex] != NULL)
+        {
+            dwReqs |= (1 << uiIndex);
+        }
+    }
+
+    return dwReqs;
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplIdentuCbIdentResponse
+//
+// Description: callback funktion for IdentResponse
+//
+//
+//
+// Parameters:  pFrameInfo_p            = Frame with the IdentResponse
+//
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiNodeId;
+unsigned int    uiIndex;
+tEplIdentuCbResponse    pfnCbResponse;
+
+    uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);
+
+    uiIndex = uiNodeId - 1;
+
+    if (uiIndex < tabentries (EplIdentuInstance_g.m_apfnCbResponse))
+    {
+        // memorize pointer to callback function
+        pfnCbResponse = EplIdentuInstance_g.m_apfnCbResponse[uiIndex];
+        // reset callback function pointer so that caller may issue next request immediately
+        EplIdentuInstance_g.m_apfnCbResponse[uiIndex] = NULL;
+
+        if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_IDENTRES)
+        {   // IdentResponse not received or it has invalid size
+            if (pfnCbResponse == NULL)
+            {   // response was not requested
+                goto Exit;
+            }
+            Ret = pfnCbResponse(uiNodeId, NULL);
+        }
+        else
+        {   // IdentResponse received
+            if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL)
+            {   // memory for IdentResponse must be allocated
+                EplIdentuInstance_g.m_apIdentResponse[uiIndex] = EPL_MALLOC(sizeof (tEplIdentResponse));
+                if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL)
+                {   // malloc failed
+                    if (pfnCbResponse == NULL)
+                    {   // response was not requested
+                        goto Exit;
+                    }
+                    Ret = pfnCbResponse(uiNodeId, &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse);
+                    goto Exit;
+                }
+            }
+            // copy IdentResponse to instance structure
+            EPL_MEMCPY(EplIdentuInstance_g.m_apIdentResponse[uiIndex], &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_IdentResponse, sizeof(tEplIdentResponse));
+            if (pfnCbResponse == NULL)
+            {   // response was not requested
+                goto Exit;
+            }
+            Ret = pfnCbResponse(uiNodeId, EplIdentuInstance_g.m_apIdentResponse[uiIndex]);
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+// EOF
+
diff --git a/drivers/staging/epl/EplInc.h b/drivers/staging/epl/EplInc.h
new file mode 100644 (file)
index 0000000..cfe90e9
--- /dev/null
@@ -0,0 +1,398 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  basic include file for internal EPL stack modules
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplInc.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_INC_H_
+#define _EPL_INC_H_
+
+// ============================================================================
+// include files
+// ============================================================================
+#if defined(WIN32) || defined(_WIN32)
+
+    #ifdef UNDER_RTSS
+        // RTX header
+        #include <windows.h>
+        #include <process.h>
+        #include <rtapi.h>
+
+    #elif __BORLANDC__
+        // borland C header
+        #include <windows.h>
+        #include <process.h>
+
+    #elif WINCE
+        #include <windows.h>
+
+    #else
+        // MSVC needs to include windows.h at first
+        // the following defines ar necessary for function prototypes for waitable timers
+        #define _WIN32_WINDOWS 0x0401
+        #define _WIN32_WINNT   0x0400
+        #include <windows.h>
+        #include <process.h>
+    #endif
+
+#endif
+
+// defines for module integration
+// possible other include file needed
+// These constants defines modules which can be included in the Epl application.
+// Use this constants for define EPL_MODULE_INTEGRATION in file EplCfg.h.
+#define EPL_MODULE_OBDK        0x00000001L // OBD kernel part module
+#define EPL_MODULE_PDOK        0x00000002L // PDO kernel part module
+#define EPL_MODULE_NMT_MN      0x00000004L // NMT MN module
+#define EPL_MODULE_SDOS        0x00000008L // SDO Server module
+#define EPL_MODULE_SDOC        0x00000010L // SDO Client module
+#define EPL_MODULE_SDO_ASND    0x00000020L // SDO over Asnd module
+#define EPL_MODULE_SDO_UDP     0x00000040L // SDO over UDP module
+#define EPL_MODULE_SDO_PDO     0x00000080L // SDO in PDO module
+#define EPL_MODULE_NMT_CN      0x00000100L // NMT CN module
+#define EPL_MODULE_NMTU        0x00000200L // NMT user part module
+#define EPL_MODULE_NMTK        0x00000400L // NMT kernel part module
+#define EPL_MODULE_DLLK        0x00000800L // DLL kernel part module
+#define EPL_MODULE_DLLU        0x00001000L // DLL user part module
+#define EPL_MODULE_OBDU        0x00002000L // OBD user part module
+#define EPL_MODULE_CFGMA       0x00004000L // Configuartioan Manager module
+#define EPL_MODULE_VETH        0x00008000L // virtual ethernet driver module
+#define EPL_MODULE_PDOU        0x00010000L // PDO user part module
+#define EPL_MODULE_LEDU        0x00020000L // LED user part module
+
+#include "EplCfg.h"     // EPL configuration file (configuration from application)
+
+#include "global.h"     // global definitions
+
+#include "EplDef.h"     // EPL configuration file (default configuration)
+#include "EplInstDef.h" // defines macros for instance types and table
+#include "Debug.h"      // debug definitions
+
+#include "EplErrDef.h"  // EPL error codes for API funtions
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+// IEEE 1588 conformant net time structure
+typedef struct
+{
+    DWORD                   m_dwSec;
+    DWORD                   m_dwNanoSec;
+
+} tEplNetTime;
+
+
+#include "EplTarget.h"  // target specific functions and definitions
+
+#include "EplAmi.h"
+
+// -------------------------------------------------------------------------
+// macros
+// -------------------------------------------------------------------------
+
+#define EPL_SPEC_VERSION                    0x20    // ETHERNET Powerlink V. 2.0
+#define EPL_STACK_VERSION(ver,rev,rel)      ((((DWORD)(ver)) & 0xFF)|((((DWORD)(rev))&0xFF)<<8)|(((DWORD)(rel))<<16))
+#define EPL_OBJ1018_VERSION(ver,rev,rel)    ((((DWORD)(ver))<<16) |(((DWORD)(rev))&0xFFFF))
+#define EPL_STRING_VERSION(ver,rev,rel)     "V" #ver "." #rev " r" #rel
+
+#include "EplVersion.h"
+
+// defines for EPL FeatureFlags
+#define EPL_FEATURE_ISOCHR          0x00000001
+#define EPL_FEATURE_SDO_UDP         0x00000002
+#define EPL_FEATURE_SDO_ASND        0x00000004
+#define EPL_FEATURE_SDO_PDO         0x00000008
+#define EPL_FEATURE_NMT_INFO        0x00000010
+#define EPL_FEATURE_NMT_EXT         0x00000020
+#define EPL_FEATURE_PDO_DYN         0x00000040
+#define EPL_FEATURE_NMT_UDP         0x00000080
+#define EPL_FEATURE_CFGMA           0x00000100
+#define EPL_FEATURE_DLL_MULTIPLEX   0x00000200
+#define EPL_FEATURE_NODEID_SW       0x00000400
+#define EPL_FEATURE_NMT_BASICETH    0x00000800
+#define EPL_FEATURE_RT1             0x00001000
+#define EPL_FEATURE_RT2             0x00002000
+
+
+// generate EPL NMT_FeatureFlags_U32
+#ifndef EPL_DEF_FEATURE_ISOCHR
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+        #define EPL_DEF_FEATURE_ISOCHR          (EPL_FEATURE_ISOCHR)
+    #else
+        #define EPL_DEF_FEATURE_ISOCHR          0
+    #endif
+#endif
+
+#ifndef EPL_DEF_FEATURE_SDO_ASND
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+        #define EPL_DEF_FEATURE_SDO_ASND        (EPL_FEATURE_SDO_ASND)
+    #else
+        #define EPL_DEF_FEATURE_SDO_ASND        0
+    #endif
+#endif
+
+#ifndef EPL_DEF_FEATURE_SDO_UDP
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+        #define EPL_DEF_FEATURE_SDO_UDP         (EPL_FEATURE_SDO_UDP)
+    #else
+        #define EPL_DEF_FEATURE_SDO_UDP         0
+    #endif
+#endif
+
+#ifndef EPL_DEF_FEATURE_SDO_PDO
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_PDO)) != 0)
+        #define EPL_DEF_FEATURE_SDO_PDO         (EPL_FEATURE_SDO_PDO)
+    #else
+        #define EPL_DEF_FEATURE_SDO_PDO         0
+    #endif
+#endif
+
+#ifndef EPL_DEF_FEATURE_PDO_DYN
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+        #define EPL_DEF_FEATURE_PDO_DYN         (EPL_FEATURE_PDO_DYN)
+    #else
+        #define EPL_DEF_FEATURE_PDO_DYN         0
+    #endif
+#endif
+
+#ifndef EPL_DEF_FEATURE_CFGMA
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
+        #define EPL_DEF_FEATURE_CFGMA           (EPL_FEATURE_CFGMA)
+    #else
+        #define EPL_DEF_FEATURE_CFGMA           0
+    #endif
+#endif
+
+#define EPL_DEF_FEATURE_FLAGS                   (EPL_DEF_FEATURE_ISOCHR \
+                                                | EPL_DEF_FEATURE_SDO_ASND \
+                                                | EPL_DEF_FEATURE_SDO_UDP \
+                                                | EPL_DEF_FEATURE_SDO_PDO \
+                                                | EPL_DEF_FEATURE_PDO_DYN \
+                                                | EPL_DEF_FEATURE_CFGMA)
+
+
+#ifndef tabentries
+#define tabentries(a)   (sizeof(a)/sizeof(*(a)))
+#endif
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// definitions for DLL export
+#if ((DEV_SYSTEM == _DEV_WIN32_) || (DEV_SYSTEM == _DEV_WIN_CE_)) && defined (COP_LIB)
+
+    #define EPLDLLEXPORT    __declspec (dllexport)
+
+#else
+
+    #define EPLDLLEXPORT
+
+#endif
+
+
+// ============================================================================
+// common debug macros
+// ============================================================================
+// for using macro DEBUG_TRACEx()
+//
+// Example:
+//      DEBUG_TRACE1 (EPL_DBGLVL_OBD, "Value is %d\n" , wObjectIndex);
+//
+// This message only will be printed if:
+//      - NDEBUG is not defined     AND !!!
+//      - flag 0x00000004L is set in DEF_DEBUG_LVL (can be defined in copcfg.h)
+//
+// default level is defined in copdef.h
+
+// debug-level and TRACE-macros         // standard-level   // flags for DEF_DEBUG_LVL
+#define EPL_DBGLVL_EDRV                 DEBUG_LVL_01        // 0x00000001L
+#define EPL_DBGLVL_EDRV_TRACE0          DEBUG_LVL_01_TRACE0
+#define EPL_DBGLVL_EDRV_TRACE1          DEBUG_LVL_01_TRACE1
+#define EPL_DBGLVL_EDRV_TRACE2          DEBUG_LVL_01_TRACE2
+#define EPL_DBGLVL_EDRV_TRACE3          DEBUG_LVL_01_TRACE3
+#define EPL_DBGLVL_EDRV_TRACE4          DEBUG_LVL_01_TRACE4
+
+#define EPL_DBGLVL_DLL                  DEBUG_LVL_02        // 0x00000002L
+#define EPL_DBGLVL_DLL_TRACE0           DEBUG_LVL_02_TRACE0
+#define EPL_DBGLVL_DLL_TRACE1           DEBUG_LVL_02_TRACE1
+#define EPL_DBGLVL_DLL_TRACE2           DEBUG_LVL_02_TRACE2
+#define EPL_DBGLVL_DLL_TRACE3           DEBUG_LVL_02_TRACE3
+#define EPL_DBGLVL_DLL_TRACE4           DEBUG_LVL_02_TRACE4
+
+#define EPL_DBGLVL_OBD                  DEBUG_LVL_03        // 0x00000004L
+#define EPL_DBGLVL_OBD_TRACE0           DEBUG_LVL_03_TRACE0
+#define EPL_DBGLVL_OBD_TRACE1           DEBUG_LVL_03_TRACE1
+#define EPL_DBGLVL_OBD_TRACE2           DEBUG_LVL_03_TRACE2
+#define EPL_DBGLVL_OBD_TRACE3           DEBUG_LVL_03_TRACE3
+#define EPL_DBGLVL_OBD_TRACE4           DEBUG_LVL_03_TRACE4
+
+#define EPL_DBGLVL_NMTK                 DEBUG_LVL_04        // 0x00000008L
+#define EPL_DBGLVL_NMTK_TRACE0          DEBUG_LVL_04_TRACE0
+#define EPL_DBGLVL_NMTK_TRACE1          DEBUG_LVL_04_TRACE1
+#define EPL_DBGLVL_NMTK_TRACE2          DEBUG_LVL_04_TRACE2
+#define EPL_DBGLVL_NMTK_TRACE3          DEBUG_LVL_04_TRACE3
+#define EPL_DBGLVL_NMTK_TRACE4          DEBUG_LVL_04_TRACE4
+
+#define EPL_DBGLVL_NMTCN                DEBUG_LVL_05        // 0x00000010L
+#define EPL_DBGLVL_NMTCN_TRACE0         DEBUG_LVL_05_TRACE0
+#define EPL_DBGLVL_NMTCN_TRACE1         DEBUG_LVL_05_TRACE1
+#define EPL_DBGLVL_NMTCN_TRACE2         DEBUG_LVL_05_TRACE2
+#define EPL_DBGLVL_NMTCN_TRACE3         DEBUG_LVL_05_TRACE3
+#define EPL_DBGLVL_NMTCN_TRACE4         DEBUG_LVL_05_TRACE4
+
+#define EPL_DBGLVL_NMTU                 DEBUG_LVL_06        // 0x00000020L
+#define EPL_DBGLVL_NMTU_TRACE0          DEBUG_LVL_06_TRACE0
+#define EPL_DBGLVL_NMTU_TRACE1          DEBUG_LVL_06_TRACE1
+#define EPL_DBGLVL_NMTU_TRACE2          DEBUG_LVL_06_TRACE2
+#define EPL_DBGLVL_NMTU_TRACE3          DEBUG_LVL_06_TRACE3
+#define EPL_DBGLVL_NMTU_TRACE4          DEBUG_LVL_06_TRACE4
+
+#define EPL_DBGLVL_NMTMN                DEBUG_LVL_07        // 0x00000040L
+#define EPL_DBGLVL_NMTMN_TRACE0         DEBUG_LVL_07_TRACE0
+#define EPL_DBGLVL_NMTMN_TRACE1         DEBUG_LVL_07_TRACE1
+#define EPL_DBGLVL_NMTMN_TRACE2         DEBUG_LVL_07_TRACE2
+#define EPL_DBGLVL_NMTMN_TRACE3         DEBUG_LVL_07_TRACE3
+#define EPL_DBGLVL_NMTMN_TRACE4         DEBUG_LVL_07_TRACE4
+
+//...
+
+#define EPL_DBGLVL_SDO                  DEBUG_LVL_25        // 0x01000000
+#define EPL_DBGLVL_SDO_TRACE0           DEBUG_LVL_25_TRACE0
+#define EPL_DBGLVL_SDO_TRACE1           DEBUG_LVL_25_TRACE1
+#define EPL_DBGLVL_SDO_TRACE2           DEBUG_LVL_25_TRACE2
+#define EPL_DBGLVL_SDO_TRACE3           DEBUG_LVL_25_TRACE3
+#define EPL_DBGLVL_SDO_TRACE4           DEBUG_LVL_25_TRACE4
+
+#define EPL_DBGLVL_VETH                 DEBUG_LVL_26        // 0x02000000
+#define EPL_DBGLVL_VETH_TRACE0          DEBUG_LVL_26_TRACE0
+#define EPL_DBGLVL_VETH_TRACE1          DEBUG_LVL_26_TRACE1
+#define EPL_DBGLVL_VETH_TRACE2          DEBUG_LVL_26_TRACE2
+#define EPL_DBGLVL_VETH_TRACE3          DEBUG_LVL_26_TRACE3
+#define EPL_DBGLVL_VETH_TRACE4          DEBUG_LVL_26_TRACE4
+
+#define EPL_DBGLVL_EVENTK               DEBUG_LVL_27        // 0x04000000
+#define EPL_DBGLVL_EVENTK_TRACE0        DEBUG_LVL_27_TRACE0
+#define EPL_DBGLVL_EVENTK_TRACE1        DEBUG_LVL_27_TRACE1
+#define EPL_DBGLVL_EVENTK_TRACE2        DEBUG_LVL_27_TRACE2
+#define EPL_DBGLVL_EVENTK_TRACE3        DEBUG_LVL_27_TRACE3
+#define EPL_DBGLVL_EVENTK_TRACE4        DEBUG_LVL_27_TRACE4
+
+#define EPL_DBGLVL_EVENTU               DEBUG_LVL_28        // 0x08000000
+#define EPL_DBGLVL_EVENTU_TRACE0        DEBUG_LVL_28_TRACE0
+#define EPL_DBGLVL_EVENTU_TRACE1        DEBUG_LVL_28_TRACE1
+#define EPL_DBGLVL_EVENTU_TRACE2        DEBUG_LVL_28_TRACE2
+#define EPL_DBGLVL_EVENTU_TRACE3        DEBUG_LVL_28_TRACE3
+#define EPL_DBGLVL_EVENTU_TRACE4        DEBUG_LVL_28_TRACE4
+
+// SharedBuff
+#define EPL_DBGLVL_SHB                  DEBUG_LVL_29        // 0x10000000
+#define EPL_DBGLVL_SHB_TRACE0           DEBUG_LVL_29_TRACE0
+#define EPL_DBGLVL_SHB_TRACE1           DEBUG_LVL_29_TRACE1
+#define EPL_DBGLVL_SHB_TRACE2           DEBUG_LVL_29_TRACE2
+#define EPL_DBGLVL_SHB_TRACE3           DEBUG_LVL_29_TRACE3
+#define EPL_DBGLVL_SHB_TRACE4           DEBUG_LVL_29_TRACE4
+
+#define EPL_DBGLVL_ASSERT               DEBUG_LVL_ASSERT    // 0x20000000L
+#define EPL_DBGLVL_ASSERT_TRACE0        DEBUG_LVL_ASSERT_TRACE0
+#define EPL_DBGLVL_ASSERT_TRACE1        DEBUG_LVL_ASSERT_TRACE1
+#define EPL_DBGLVL_ASSERT_TRACE2        DEBUG_LVL_ASSERT_TRACE2
+#define EPL_DBGLVL_ASSERT_TRACE3        DEBUG_LVL_ASSERT_TRACE3
+#define EPL_DBGLVL_ASSERT_TRACE4        DEBUG_LVL_ASSERT_TRACE4
+
+#define EPL_DBGLVL_ERROR                DEBUG_LVL_ERROR     // 0x40000000L
+#define EPL_DBGLVL_ERROR_TRACE0         DEBUG_LVL_ERROR_TRACE0
+#define EPL_DBGLVL_ERROR_TRACE1         DEBUG_LVL_ERROR_TRACE1
+#define EPL_DBGLVL_ERROR_TRACE2         DEBUG_LVL_ERROR_TRACE2
+#define EPL_DBGLVL_ERROR_TRACE3         DEBUG_LVL_ERROR_TRACE3
+#define EPL_DBGLVL_ERROR_TRACE4         DEBUG_LVL_ERROR_TRACE4
+
+#define EPL_DBGLVL_ALWAYS               DEBUG_LVL_ALWAYS    // 0x80000000L
+#define EPL_DBGLVL_ALWAYS_TRACE0        DEBUG_LVL_ALWAYS_TRACE0
+#define EPL_DBGLVL_ALWAYS_TRACE1        DEBUG_LVL_ALWAYS_TRACE1
+#define EPL_DBGLVL_ALWAYS_TRACE2        DEBUG_LVL_ALWAYS_TRACE2
+#define EPL_DBGLVL_ALWAYS_TRACE3        DEBUG_LVL_ALWAYS_TRACE3
+#define EPL_DBGLVL_ALWAYS_TRACE4        DEBUG_LVL_ALWAYS_TRACE4
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPL_INC_H_
+
+
diff --git a/drivers/staging/epl/EplInstDef.h b/drivers/staging/epl/EplInstDef.h
new file mode 100644 (file)
index 0000000..ab9bafa
--- /dev/null
@@ -0,0 +1,386 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  definitions for generating instances
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplInstDef.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    ...
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  r.d.: first implementation
+
+****************************************************************************/
+
+#ifndef _EPLINSTDEF_H_
+#define _EPLINSTDEF_H_
+
+
+// =========================================================================
+// types and macros for generating instances
+// =========================================================================
+
+typedef enum
+{
+    kStateUnused    = 0,
+    kStateDeleted   = 1,
+    kStateUsed      = 0xFF
+
+} tInstState;
+
+//------------------------------------------------------------------------------------------
+
+typedef void MEM* tEplPtrInstance;
+typedef BYTE      tEplInstanceHdl;
+
+// define const for illegale values
+#define CCM_ILLINSTANCE      NULL
+#define CCM_ILLINSTANCE_HDL  0xFF
+
+//------------------------------------------------------------------------------------------
+// if more than one instance then use this macros
+#if (EPL_MAX_INSTANCES > 1)
+
+    //--------------------------------------------------------------------------------------
+    // macro definition for instance table definition
+    //--------------------------------------------------------------------------------------
+
+    // memory attributes for instance table
+    #define INST_NEAR                               // faster access to variables
+    #define INST_FAR                                // variables wich have to located in xdata
+    #define STATIC                                  // prevent warnings for variables with same name
+
+    #define INSTANCE_TYPE_BEGIN     typedef struct {
+    #define INSTANCE_TYPE_END       } tEplInstanceInfo;
+
+
+    //--------------------------------------------------------------------------------------
+    // macro definition for API interface
+    //--------------------------------------------------------------------------------------
+
+    // declaration:
+
+    // macros for declaration within function header or prototype of API functions
+    #define CCM_DECL_INSTANCE_HDL                   tEplInstanceHdl InstanceHandle
+    #define CCM_DECL_INSTANCE_HDL_                  tEplInstanceHdl InstanceHandle,
+
+    // macros for declaration of pointer to instance handle within function header or prototype of API functions
+    #define CCM_DECL_PTR_INSTANCE_HDL               tEplInstanceHdl MEM* pInstanceHandle
+    #define CCM_DECL_PTR_INSTANCE_HDL_              tEplInstanceHdl MEM* pInstanceHandle,
+
+    // macros for declaration instance as lokacl variable within functions
+    #define CCM_DECL_INSTANCE_PTR_LOCAL             tCcmInstanceInfo MEM* pInstance;
+    #define CCM_DECL_PTR_INSTANCE_HDL_LOCAL         tEplInstanceHdl  MEM* pInstanceHandle;
+
+    // reference:
+
+    // macros for reference of instance handle for function parameters
+    #define CCM_INSTANCE_HDL                        InstanceHandle
+    #define CCM_INSTANCE_HDL_                       InstanceHandle,
+
+    // macros for reference of instance parameter for function parameters
+    #define CCM_INSTANCE_PARAM(par)                 par
+    #define CCM_INSTANCE_PARAM_(par)                par,
+
+    // macros for reference of instance parameter for writing or reading values
+    #define CCM_INST_ENTRY                          (*((tEplPtrInstance)pInstance))
+
+    // processing:
+
+    // macros for process instance handle
+    #define CCM_CHECK_INSTANCE_HDL()                if (InstanceHandle >= EPL_MAX_INSTANCES) \
+                                                        {return (kEplIllegalInstance);}
+
+
+    // macros for process pointer to instance handle
+    #define CCM_CHECK_PTR_INSTANCE_HDL()            if (pInstanceHandle == NULL) \
+                                                        {return (kEplInvalidInstanceParam);}
+
+    // This macro returned the handle and pointer to next free instance.
+    #define CCM_GET_FREE_INSTANCE_AND_HDL()         pInstance = CcmGetFreeInstanceAndHandle (pInstanceHandle); \
+                                                    ASSERT (*pInstanceHandle != CCM_ILLINSTANCE_HDL);
+
+    #define CCM_CHECK_INSTANCE_PTR()                if (pInstance == CCM_ILLINSTANCE) \
+                                                        {return (kEplNoFreeInstance);}
+
+    #define CCM_GET_INSTANCE_PTR()                  pInstance = CcmGetInstancePtr (InstanceHandle);
+    #define CCM_GET_FREE_INSTANCE_PTR()             pInstance = GetFreeInstance (); \
+                                                    ASSERT (pInstance != CCM_ILLINSTANCE);
+
+
+    //--------------------------------------------------------------------------------------
+    // macro definition for stack interface
+    //--------------------------------------------------------------------------------------
+
+    // macros for declaration within the function header, prototype or local var list
+    // Declaration of pointers within function paramater list must defined as void MEM*
+    // pointer.
+    #define EPL_MCO_DECL_INSTANCE_PTR                   void MEM* pInstance
+    #define EPL_MCO_DECL_INSTANCE_PTR_                  void MEM* pInstance,
+    #define EPL_MCO_DECL_INSTANCE_PTR_LOCAL             tEplPtrInstance  pInstance;
+
+    // macros for reference of pointer to instance
+    // These macros are used for parameter passing to called function.
+    #define EPL_MCO_INSTANCE_PTR                        pInstance
+    #define EPL_MCO_INSTANCE_PTR_                       pInstance,
+    #define EPL_MCO_ADDR_INSTANCE_PTR_                  &pInstance,
+
+    // macro for access of struct members of one instance
+    // An access to a member of instance table must be casted by the local
+    // defined type of instance table.
+    #define EPL_MCO_INST_ENTRY                          (*(tEplPtrInstance)pInstance)
+    #define EPL_MCO_GLB_VAR(var)                        (((tEplPtrInstance)pInstance)->var)
+
+    // macros for process pointer to instance
+    #define EPL_MCO_GET_INSTANCE_PTR()                  pInstance = (tEplPtrInstance) GetInstancePtr (InstanceHandle);
+    #define EPL_MCO_GET_FREE_INSTANCE_PTR()             pInstance = (tEplPtrInstance) GetFreeInstance (); \
+                                                    ASSERT (pInstance != CCM_ILLINSTANCE);
+
+    // This macro should be used to check the passed pointer to an public function
+    #define EPL_MCO_CHECK_INSTANCE_STATE()              ASSERT (pInstance != NULL); \
+                                                    ASSERT (((tEplPtrInstance)pInstance)->m_InstState == kStateUsed);
+
+    // macros for declaration of pointer to instance pointer
+    #define EPL_MCO_DECL_PTR_INSTANCE_PTR               void MEM*  MEM* pInstancePtr
+    #define EPL_MCO_DECL_PTR_INSTANCE_PTR_              void MEM*  MEM* pInstancePtr,
+
+    // macros for reference of pointer to instance pointer
+    // These macros are used for parameter passing to called function.
+    #define EPL_MCO_PTR_INSTANCE_PTR                    pInstancePtr
+    #define EPL_MCO_PTR_INSTANCE_PTR_                   pInstancePtr,
+
+    // macros for process pointer to instance pointer
+    #define EPL_MCO_CHECK_PTR_INSTANCE_PTR()            ASSERT (pInstancePtr != NULL);
+    #define EPL_MCO_SET_PTR_INSTANCE_PTR()              (*pInstancePtr = pInstance);
+
+    #define EPL_MCO_INSTANCE_PARAM(a)                   (a)
+    #define EPL_MCO_INSTANCE_PARAM_(a)                  (a),
+    #define EPL_MCO_INSTANCE_PARAM_IDX_()               EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex))
+    #define EPL_MCO_INSTANCE_PARAM_IDX()                EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex))
+    #define EPL_MCO_WRITE_INSTANCE_STATE(a)             EPL_MCO_GLB_VAR (m_InstState) = a;
+
+    // this macro deletes all instance entries as unused
+    #define EPL_MCO_DELETE_INSTANCE_TABLE()                                    \
+    {                                                                      \
+        tEplInstanceInfo MEM*   pInstance       = &aEplInstanceTable_g[0]; \
+        tFastByte               InstNumber      = 0;                       \
+        tFastByte               i               = EPL_MAX_INSTANCES;       \
+        do {                                                               \
+            pInstance->m_InstState = (BYTE) kStateUnused;                  \
+            pInstance->m_bInstIndex = (BYTE) InstNumber;                   \
+            pInstance++; InstNumber++; i--;                                \
+        } while (i != 0);                                                  \
+    }
+
+    // definition of functions which has to be defined in each module of CANopen stack
+    #define EPL_MCO_DEFINE_INSTANCE_FCT() \
+        static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p);  \
+        static tEplPtrInstance GetFreeInstance (void);
+    #define EPL_MCO_DECL_INSTANCE_FCT()                                            \
+        static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p) { \
+            return &aEplInstanceTable_g[InstHandle_p]; }                       \
+        static tEplPtrInstance GetFreeInstance (void) {                        \
+            tEplInstanceInfo MEM*   pInstance   = &aEplInstanceTable_g[0];     \
+            tFastByte               i           = EPL_MAX_INSTANCES;           \
+            do { if (pInstance->m_InstState != kStateUsed) {                   \
+                    return (tEplPtrInstance) pInstance; }                      \
+                pInstance++; i--; }                                            \
+            while (i != 0);                                                    \
+            return CCM_ILLINSTANCE; }
+
+    // this macro defines the instance table. Each entry is reserved for an instance of CANopen.
+    #define EPL_MCO_DECL_INSTANCE_VAR() \
+        static tEplInstanceInfo MEM aEplInstanceTable_g [EPL_MAX_INSTANCES];
+
+    // this macro defines member variables in instance table which are needed in
+    // all modules of Epl stack
+    #define EPL_MCO_DECL_INSTANCE_MEMBER() \
+        STATIC  BYTE                            m_InstState; \
+        STATIC  BYTE                            m_bInstIndex;
+
+    #define EPL_MCO_INSTANCE_PARAM_IDX_()           EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex))
+    #define EPL_MCO_INSTANCE_PARAM_IDX()            EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex))
+
+#else       // only one instance is used
+
+    // Memory attributes for instance table.
+    #define INST_NEAR   NEAR                        // faster access to variables
+    #define INST_FAR    MEM                         // variables wich have to located in xdata
+    #define STATIC      static                      // prevent warnings for variables with same name
+
+    #define INSTANCE_TYPE_BEGIN
+    #define INSTANCE_TYPE_END
+
+// macros for declaration, initializing and member access for instance handle
+// This class of macros are used by API function to inform CCM-modul which
+// instance is to be used.
+
+    // macros for reference of instance handle
+    // These macros are used for parameter passing to CANopen API function.
+    #define CCM_INSTANCE_HDL
+    #define CCM_INSTANCE_HDL_
+
+    #define CCM_DECL_INSTANCE_PTR_LOCAL
+
+    // macros for declaration within the function header or prototype
+    #define CCM_DECL_INSTANCE_HDL                   void
+    #define CCM_DECL_INSTANCE_HDL_
+
+    // macros for process instance handle
+    #define CCM_CHECK_INSTANCE_HDL()
+
+    // macros for declaration of pointer to instance handle
+    #define CCM_DECL_PTR_INSTANCE_HDL               void
+    #define CCM_DECL_PTR_INSTANCE_HDL_
+
+    // macros for process pointer to instance handle
+    #define CCM_CHECK_PTR_INSTANCE_HDL()
+
+    // This macro returned the handle and pointer to next free instance.
+    #define CCM_GET_FREE_INSTANCE_AND_HDL()
+
+    #define CCM_CHECK_INSTANCE_PTR()
+
+    #define CCM_GET_INSTANCE_PTR()
+    #define CCM_GET_FREE_INSTANCE_PTR()
+
+    #define CCM_INSTANCE_PARAM(par)
+    #define CCM_INSTANCE_PARAM_(par)
+
+    #define CCM_INST_ENTRY                          aCcmInstanceTable_g[0]
+
+// macros for declaration, initializing and member access for instance pointer
+// This class of macros are used by CANopen internal function to point to one instance.
+
+    // macros for declaration within the function header, prototype or local var list
+    #define EPL_MCO_DECL_INSTANCE_PTR                   void
+    #define EPL_MCO_DECL_INSTANCE_PTR_
+    #define EPL_MCO_DECL_INSTANCE_PTR_LOCAL
+
+    // macros for reference of pointer to instance
+    // These macros are used for parameter passing to called function.
+    #define EPL_MCO_INSTANCE_PTR
+    #define EPL_MCO_INSTANCE_PTR_
+    #define EPL_MCO_ADDR_INSTANCE_PTR_
+
+    // macros for process pointer to instance
+    #define EPL_MCO_GET_INSTANCE_PTR()
+    #define EPL_MCO_GET_FREE_INSTANCE_PTR()
+
+    // This macro should be used to check the passed pointer to an public function
+    #define EPL_MCO_CHECK_INSTANCE_STATE()
+
+    // macros for declaration of pointer to instance pointer
+    #define EPL_MCO_DECL_PTR_INSTANCE_PTR               void
+    #define EPL_MCO_DECL_PTR_INSTANCE_PTR_
+
+    // macros for reference of pointer to instance pointer
+    // These macros are used for parameter passing to called function.
+    #define EPL_MCO_PTR_INSTANCE_PTR
+    #define EPL_MCO_PTR_INSTANCE_PTR_
+
+    // macros for process pointer to instance pointer
+    #define EPL_MCO_CHECK_PTR_INSTANCE_PTR()
+    #define EPL_MCO_SET_PTR_INSTANCE_PTR()
+
+    #define EPL_MCO_INSTANCE_PARAM(a)
+    #define EPL_MCO_INSTANCE_PARAM_(a)
+    #define EPL_MCO_INSTANCE_PARAM_IDX_()
+    #define EPL_MCO_INSTANCE_PARAM_IDX()
+
+    // macro for access of struct members of one instance
+    #define EPL_MCO_INST_ENTRY                          aEplInstanceTable_g[0]
+    #define EPL_MCO_GLB_VAR(var)                        (var)
+    #define EPL_MCO_WRITE_INSTANCE_STATE(a)
+
+    // this macro deletes all instance entries as unused
+    #define EPL_MCO_DELETE_INSTANCE_TABLE()
+
+    // definition of functions which has to be defined in each module of CANopen stack
+    #define EPL_MCO_DEFINE_INSTANCE_FCT()
+    #define EPL_MCO_DECL_INSTANCE_FCT()
+
+    // this macro defines the instance table. Each entry is reserved for an instance of CANopen.
+    #define EPL_MCO_DECL_INSTANCE_VAR()
+
+    // this macro defines member variables in instance table which are needed in
+    // all modules of CANopen stack
+    #define EPL_MCO_DECL_INSTANCE_MEMBER()
+
+#endif
+
+
+/*
+#if (CDRV_MAX_INSTANCES > 1)
+
+    #define CDRV_REENTRANT                          REENTRANT
+
+#else
+
+    #define CDRV_REENTRANT
+
+#endif
+*/
+
+
+#endif // _EPLINSTDEF_H_
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
+
diff --git a/drivers/staging/epl/EplLed.h b/drivers/staging/epl/EplLed.h
new file mode 100644 (file)
index 0000000..390d6db
--- /dev/null
@@ -0,0 +1,104 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for status and error LED
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplLed.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.1 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2008/11/17 d.k.:   start of the implementation
+
+
+****************************************************************************/
+
+
+#ifndef _EPLLED_H_
+#define _EPLLED_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+typedef enum
+{
+    kEplLedTypeStatus   = 0x00,
+    kEplLedTypeError    = 0x01,
+
+} tEplLedType;
+
+
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPLLED_H_
+
+
diff --git a/drivers/staging/epl/EplNmt.h b/drivers/staging/epl/EplNmt.h
new file mode 100644 (file)
index 0000000..7b9e58e
--- /dev/null
@@ -0,0 +1,248 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  global include file for EPL-NMT-Modules
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmt.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#ifndef _EPLNMT_H_
+#define _EPLNMT_H_
+
+#include "EplInc.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// define super-states and masks to identify a super-state
+#define EPL_NMT_GS_POWERED          0x0008  // super state
+#define EPL_NMT_GS_INITIALISATION   0x0009  // super state
+#define EPL_NMT_GS_COMMUNICATING    0x000C  // super state
+#define EPL_NMT_CS_EPLMODE          0x000D  // super state
+#define EPL_NMT_MS_EPLMODE          0x000D  // super state
+
+#define EPL_NMT_SUPERSTATE_MASK     0x000F  // mask to select state
+
+#define EPL_NMT_TYPE_UNDEFINED      0x0000  // type of NMT state is still undefined
+#define EPL_NMT_TYPE_CS             0x0100  // CS type of NMT state
+#define EPL_NMT_TYPE_MS             0x0200  // MS type of NMT state
+#define EPL_NMT_TYPE_MASK           0x0300  // mask to select type of NMT state (i.e. CS or MS)
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+// the lower Byte of the NMT-State is encoded
+// like the values in the EPL-Standard
+// the higher byte is used to encode MN
+// (Bit 1 of the higher byte = 1) or CN (Bit 0 of the
+// higher byte  = 1)
+// the super-states are not mentioned in this
+// enum because they are no real states
+// --> there are masks defined to indentify the
+// super-states
+
+typedef enum
+{
+    kEplNmtGsOff                    = 0x0000,
+    kEplNmtGsInitialising           = 0x0019,
+    kEplNmtGsResetApplication       = 0x0029,
+    kEplNmtGsResetCommunication     = 0x0039,
+    kEplNmtGsResetConfiguration     = 0x0079,
+    kEplNmtCsNotActive              = 0x011C,
+    kEplNmtCsPreOperational1        = 0x011D,
+    kEplNmtCsStopped                = 0x014D,
+    kEplNmtCsPreOperational2        = 0x015D,
+    kEplNmtCsReadyToOperate         = 0x016D,
+    kEplNmtCsOperational            = 0x01FD,
+    kEplNmtCsBasicEthernet          = 0x011E,
+    kEplNmtMsNotActive              = 0x021C,
+    kEplNmtMsPreOperational1        = 0x021D,
+    kEplNmtMsPreOperational2        = 0x025D,
+    kEplNmtMsReadyToOperate         = 0x026D,
+    kEplNmtMsOperational            = 0x02FD,
+    kEplNmtMsBasicEthernet          = 0x021E
+
+} tEplNmtState;
+
+// NMT-events
+typedef enum
+{
+    // Events from DLL
+    // Events defined by EPL V2 specification
+    kEplNmtEventNoEvent             =   0x00,
+//    kEplNmtEventDllMePres           =   0x01,
+    kEplNmtEventDllMePresTimeout    =   0x02,
+//    kEplNmtEventDllMeAsnd           =   0x03,
+//    kEplNmtEventDllMeAsndTimeout    =   0x04,
+    kEplNmtEventDllMeSoaSent        =   0x04,
+    kEplNmtEventDllMeSocTrig        =   0x05,
+    kEplNmtEventDllMeSoaTrig        =   0x06,
+    kEplNmtEventDllCeSoc            =   0x07,
+    kEplNmtEventDllCePreq           =   0x08,
+    kEplNmtEventDllCePres           =   0x09,
+    kEplNmtEventDllCeSoa            =   0x0A,
+    kEplNmtEventDllCeAsnd           =   0x0B,
+    kEplNmtEventDllCeFrameTimeout   =   0x0C,
+
+    // Events triggered by NMT-Commands
+    kEplNmtEventSwReset             =   0x10, // NMT_GT1, NMT_GT2, NMT_GT8
+    kEplNmtEventResetNode           =   0x11,
+    kEplNmtEventResetCom            =   0x12,
+    kEplNmtEventResetConfig         =   0x13,
+    kEplNmtEventEnterPreOperational2=   0x14,
+    kEplNmtEventEnableReadyToOperate=   0x15,
+    kEplNmtEventStartNode           =   0x16, // NMT_CT7
+    kEplNmtEventStopNode            =   0x17,
+
+    // Events triggered by higher layer
+    kEplNmtEventEnterResetApp       =   0x20,
+    kEplNmtEventEnterResetCom       =   0x21,
+    kEplNmtEventInternComError      =   0x22, // NMT_GT6, internal communication error -> enter ResetCommunication
+    kEplNmtEventEnterResetConfig    =   0x23,
+    kEplNmtEventEnterCsNotActive    =   0x24,
+    kEplNmtEventEnterMsNotActive    =   0x25,
+    kEplNmtEventTimerBasicEthernet  =   0x26, // NMT_CT3; timer triggered state change (NotActive -> BasicEth)
+    kEplNmtEventTimerMsPreOp1       =   0x27, // enter PreOp1 on MN (NotActive -> MsPreOp1)
+    kEplNmtEventNmtCycleError       =   0x28, // NMT_CT11, NMT_MT6; error during cycle -> enter PreOp1
+    kEplNmtEventTimerMsPreOp2       =   0x29, // enter PreOp2 on MN (MsPreOp1 -> MsPreOp2 if kEplNmtEventAllMandatoryCNIdent)
+    kEplNmtEventAllMandatoryCNIdent =   0x2A, // enter PreOp2 on MN if kEplNmtEventTimerMsPreOp2
+    kEplNmtEventEnterReadyToOperate =   0x2B, // application ready for the state ReadyToOp
+    kEplNmtEventEnterMsOperational  =   0x2C, // enter Operational on MN
+    kEplNmtEventSwitchOff           =   0x2D, // enter state Off
+    kEplNmtEventCriticalError       =   0x2E, // enter state Off because of critical error
+
+} tEplNmtEvent;
+
+
+// type for argument of event kEplEventTypeNmtStateChange
+typedef struct
+{
+    tEplNmtState    m_NewNmtState;
+    tEplNmtEvent    m_NmtEvent;
+
+} tEplEventNmtStateChange;
+
+
+// structure for kEplEventTypeHeartbeat
+typedef struct
+{
+    unsigned int    m_uiNodeId;         // NodeId
+    tEplNmtState    m_NmtState;         // NMT state (remember distinguish between MN / CN)
+    WORD            m_wErrorCode;       // EPL error code in case of NMT state NotActive
+
+} tEplHeartbeatEvent;
+
+
+typedef enum
+{
+    kEplNmtNodeEventFound       = 0x00,
+    kEplNmtNodeEventUpdateSw    = 0x01, // application shall update software on CN
+    kEplNmtNodeEventCheckConf   = 0x02, // application / Configuration Manager shall check and update configuration on CN
+    kEplNmtNodeEventUpdateConf  = 0x03, // application / Configuration Manager shall update configuration on CN (check was done by NmtMn module)
+    kEplNmtNodeEventVerifyConf  = 0x04, // application / Configuration Manager shall verify configuration of CN
+    kEplNmtNodeEventReadyToStart= 0x05, // issued if EPL_NMTST_NO_STARTNODE set
+                                        // application must call EplNmtMnuSendNmtCommand(kEplNmtCmdStartNode) manually
+    kEplNmtNodeEventNmtState    = 0x06,
+    kEplNmtNodeEventError       = 0x07, // NMT error of CN
+
+} tEplNmtNodeEvent;
+
+
+typedef enum
+{
+    kEplNmtNodeCommandBoot      = 0x01, // if EPL_NODEASSIGN_START_CN not set it must be issued after kEplNmtNodeEventFound
+    kEplNmtNodeCommandSwOk      = 0x02, // application updated software on CN successfully
+    kEplNmtNodeCommandSwUpdated = 0x03, // application updated software on CN successfully
+    kEplNmtNodeCommandConfOk    = 0x04, // application / Configuration Manager has updated configuration on CN successfully
+    kEplNmtNodeCommandConfReset = 0x05, // application / Configuration Manager has updated configuration on CN successfully
+                                        // and CN needs ResetConf so that the configuration gets actived
+    kEplNmtNodeCommandConfErr   = 0x06, // application / Configuration Manager failed on updating configuration on CN
+    kEplNmtNodeCommandStart     = 0x07, // if EPL_NMTST_NO_STARTNODE set it must be issued after kEplNmtNodeEventReadyToStart
+
+} tEplNmtNodeCommand;
+
+
+typedef enum
+{
+    kEplNmtBootEventBootStep1Finish = 0x00, // PreOp2 is possible
+    kEplNmtBootEventBootStep2Finish = 0x01, // ReadyToOp is possible
+    kEplNmtBootEventCheckComFinish  = 0x02, // Operational is possible
+    kEplNmtBootEventOperational     = 0x03, // all mandatory CNs are Operational
+    kEplNmtBootEventError           = 0x04, // boot process halted because of an error
+
+} tEplNmtBootEvent;
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPLNMT_H_
+
+
diff --git a/drivers/staging/epl/EplNmtCnu.c b/drivers/staging/epl/EplNmtCnu.c
new file mode 100644 (file)
index 0000000..7effc7c
--- /dev/null
@@ -0,0 +1,691 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for NMT-CN-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtCnu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "user/EplNmtCnu.h"
+#include "user/EplDlluCal.h"
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    unsigned int                m_uiNodeId;
+    tEplNmtuCheckEventCallback  m_pfnCheckEventCb;
+
+} tEplNmtCnuInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static tEplNmtCnuInstance   EplNmtCnuInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
+
+static BOOL EplNmtCnuNodeIdList(BYTE* pbNmtCommandDate_p);
+
+static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuInit
+//
+// Description: init the first instance of the module
+//
+//
+//
+// Parameters:      uiNodeId_p = NodeId of the local node
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
+{
+tEplKernel Ret;
+
+    Ret = EplNmtCnuAddInstance(uiNodeId_p);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuAddInstance
+//
+// Description: init the add new instance of the module
+//
+//
+//
+// Parameters:      uiNodeId_p = NodeId of the local node
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplNmtCnuInstance_g, 0, sizeof (EplNmtCnuInstance_g));
+
+    // save nodeid
+    EplNmtCnuInstance_g.m_uiNodeId = uiNodeId_p;
+
+    // register callback-function for NMT-commands
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
+                                   EplNmtCnuCommandCb,
+                                   kEplDllAsndFilterLocal);
+#endif
+
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuDelInstance
+//
+// Description: delte instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    // deregister callback function from DLL
+    Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
+                                   NULL,
+                                   kEplDllAsndFilterNone);
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuSendNmtRequest
+//
+// Description: Send an NMT-Request to the MN
+//
+//
+//
+// Parameters:      uiNodeId_p = NodeId of the local node
+//                  NmtCommand_p = requested NMT-Command
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(
+                                    unsigned int uiNodeId_p,
+                                    tEplNmtCommand NmtCommand_p)
+{
+tEplKernel      Ret;
+tEplFrameInfo   NmtRequestFrameInfo;
+tEplFrame       NmtRequestFrame;
+
+
+    Ret = kEplSuccessful;
+
+    // build frame
+    EPL_MEMSET(&NmtRequestFrame.m_be_abDstMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abDstMac)); // set by DLL
+    EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL
+    AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType, EPL_C_DLL_ETHERTYPE_EPL);
+    AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
+    AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType, (BYTE)kEplMsgTypeAsnd);
+    AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId, (BYTE) kEplDllAsndNmtRequest);
+    AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bNmtCommandId,
+        (BYTE)NmtCommand_p);
+    AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId,
+        (BYTE)uiNodeId_p); // target for the nmt command
+    EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_abNmtCommandData[0], 0x00, sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_abNmtCommandData));
+
+
+
+    // build info-structure
+    NmtRequestFrameInfo.m_NetTime.m_dwNanoSec = 0;
+    NmtRequestFrameInfo.m_NetTime.m_dwSec = 0;
+    NmtRequestFrameInfo.m_pFrame = &NmtRequestFrame;
+    NmtRequestFrameInfo.m_uiFrameSize = EPL_C_DLL_MINSIZE_NMTREQ; // sizeof(NmtRequestFrame);
+
+    // send NMT-Request
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalAsyncSend(&NmtRequestFrameInfo,    // pointer to frameinfo
+                           kEplDllAsyncReqPrioNmt); // priority
+#endif
+
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuRegisterStateChangeCb
+//
+// Description: register Callback-function go get informed about a
+//              NMT-Change-State-Event
+//
+//
+//
+// Parameters:  pfnEplNmtStateChangeCb_p = functionpointer
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuRegisterCheckEventCb(
+            tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // save callback-function in modul global var
+    EplNmtCnuInstance_g.m_pfnCheckEventCb = pfnEplNmtCheckEventCb_p;
+
+    return Ret;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuCommandCb
+//
+// Description: callback funktion for NMT-Commands
+//
+//
+//
+// Parameters:      pFrameInfo_p = Frame with the NMT-Commando
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplNmtCommand  NmtCommand;
+BOOL            fNodeIdInList;
+tEplNmtEvent    NmtEvent = kEplNmtEventNoEvent;
+
+
+    if(pFrameInfo_p == NULL)
+    {
+        Ret = kEplNmtInvalidFramePointer;
+        goto Exit;
+    }
+
+    NmtCommand = EplNmtCnuGetNmtCommand(pFrameInfo_p);
+
+    // check NMT-Command
+    switch(NmtCommand)
+    {
+
+        //------------------------------------------------------------------------
+        // plain NMT state commands
+        case kEplNmtCmdStartNode:
+        {   // send NMT-Event to state maschine kEplNmtEventStartNode
+            NmtEvent = kEplNmtEventStartNode;
+            break;
+        }
+
+        case kEplNmtCmdStopNode:
+        {   // send NMT-Event to state maschine kEplNmtEventStopNode
+            NmtEvent = kEplNmtEventStopNode;
+            break;
+        }
+
+        case kEplNmtCmdEnterPreOperational2:
+        {   // send NMT-Event to state maschine kEplNmtEventEnterPreOperational2
+            NmtEvent = kEplNmtEventEnterPreOperational2;
+            break;
+        }
+
+        case kEplNmtCmdEnableReadyToOperate:
+        {   // send NMT-Event to state maschine kEplNmtEventEnableReadyToOperate
+            NmtEvent = kEplNmtEventEnableReadyToOperate;
+            break;
+        }
+
+        case kEplNmtCmdResetNode:
+        {   // send NMT-Event to state maschine kEplNmtEventResetNode
+            NmtEvent = kEplNmtEventResetNode;
+            break;
+        }
+
+        case kEplNmtCmdResetCommunication:
+        {   // send NMT-Event to state maschine kEplNmtEventResetCom
+            NmtEvent = kEplNmtEventResetCom;
+            break;
+        }
+
+        case kEplNmtCmdResetConfiguration:
+        {   // send NMT-Event to state maschine kEplNmtEventResetConfig
+            NmtEvent = kEplNmtEventResetConfig;
+            break;
+        }
+
+        case kEplNmtCmdSwReset:
+        {   // send NMT-Event to state maschine kEplNmtEventSwReset
+            NmtEvent = kEplNmtEventSwReset;
+            break;
+        }
+
+        //------------------------------------------------------------------------
+        // extended NMT state commands
+
+        case kEplNmtCmdStartNodeEx:
+        {
+            // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&(pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]));
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventStartNode;
+            }
+            break;
+        }
+
+        case kEplNmtCmdStopNodeEx:
+        {   // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventStopNode;
+            }
+            break;
+        }
+
+        case kEplNmtCmdEnterPreOperational2Ex:
+        {   // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventEnterPreOperational2;
+            }
+            break;
+        }
+
+        case kEplNmtCmdEnableReadyToOperateEx:
+        {   // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventEnableReadyToOperate;
+            }
+            break;
+        }
+
+        case kEplNmtCmdResetNodeEx:
+        {// check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventResetNode;
+            }
+            break;
+        }
+
+        case kEplNmtCmdResetCommunicationEx:
+        {   // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventResetCom;
+            }
+            break;
+        }
+
+        case kEplNmtCmdResetConfigurationEx:
+        {   // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventResetConfig;
+            }
+            break;
+        }
+
+        case kEplNmtCmdSwResetEx:
+        {   // check if own nodeid is in EPL node list
+            fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
+            if(fNodeIdInList != FALSE)
+            {   // own nodeid in list
+                // send event to process command
+                NmtEvent = kEplNmtEventSwReset;
+            }
+            break;
+        }
+
+        //------------------------------------------------------------------------
+        // NMT managing commands
+
+        // TODO: add functions to process managing command (optional)
+
+        case kEplNmtCmdNetHostNameSet:
+        {
+            break;
+        }
+
+        case kEplNmtCmdFlushArpEntry:
+        {
+            break;
+        }
+
+        //------------------------------------------------------------------------
+        // NMT info services
+
+        // TODO: forward event with infos to the application (optional)
+
+        case kEplNmtCmdPublishConfiguredCN:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishActiveCN:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishPreOperational1:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishPreOperational2:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishReadyToOperate:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishOperational:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishStopped:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishEmergencyNew:
+        {
+            break;
+        }
+
+        case kEplNmtCmdPublishTime:
+        {
+            break;
+        }
+
+        //-----------------------------------------------------------------------
+        // error from MN
+        // -> requested command not supported by MN
+        case kEplNmtCmdInvalidService:
+        {
+
+            // TODO: errorevent to application
+            break;
+        }
+
+        //------------------------------------------------------------------------
+        // default
+        default:
+        {
+            Ret = kEplNmtUnknownCommand;
+            goto Exit;
+        }
+
+    }// end of switch(NmtCommand)
+
+    if (NmtEvent != kEplNmtEventNoEvent)
+    {
+        if (EplNmtCnuInstance_g.m_pfnCheckEventCb != NULL)
+        {
+            Ret = EplNmtCnuInstance_g.m_pfnCheckEventCb(NmtEvent);
+            if (Ret == kEplReject)
+            {
+                Ret = kEplSuccessful;
+                goto Exit;
+            }
+            else if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+        }
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+        Ret = EplNmtuNmtEvent(NmtEvent);
+#endif
+    }
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuGetNmtCommand()
+//
+// Description: returns the NMT-Command from the frame
+//
+//
+//
+// Parameters:      pFrameInfo_p = pointer to the Frame
+//                                 with the NMT-Command
+//
+//
+// Returns:         tEplNmtCommand = NMT-Command
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
+{
+tEplNmtCommand          NmtCommand;
+tEplNmtCommandService*  pNmtCommandService;
+
+    pNmtCommandService = &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService;
+
+    NmtCommand = (tEplNmtCommand)AmiGetByteFromLe(&pNmtCommandService->m_le_bNmtCommandId);
+
+    return NmtCommand;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtCnuNodeIdList()
+//
+// Description: check if the own nodeid is set in EPL Node List
+//
+//
+//
+// Parameters:      pbNmtCommandDate_p = pointer to the data of the NMT Command
+//
+//
+// Returns:         BOOL = TRUE if nodeid is set in EPL Node List
+//                         FALSE if nodeid not set in EPL Node List
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static BOOL EplNmtCnuNodeIdList(BYTE* pbNmtCommandDate_p)
+{
+BOOL            fNodeIdInList;
+unsigned int    uiByteOffset;
+BYTE            bBitOffset;
+BYTE            bNodeListByte;
+
+    // get byte-offset of the own nodeid in NodeIdList
+    // devide though 8
+    uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
+    // get bitoffset
+    bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
+
+    bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
+    if((bNodeListByte & bBitOffset) == 0)
+    {
+        fNodeIdInList = FALSE;
+    }
+    else
+    {
+        fNodeIdInList = TRUE;
+    }
+
+return  fNodeIdInList;
+}
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplNmtMnu.c b/drivers/staging/epl/EplNmtMnu.c
new file mode 100644 (file)
index 0000000..8045360
--- /dev/null
@@ -0,0 +1,2798 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for NMT-MN-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtMnu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.18 $  $Date: 2008/11/19 09:52:24 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplNmtMnu.h"
+#include "user/EplTimeru.h"
+#include "user/EplIdentu.h"
+#include "user/EplStatusu.h"
+#include "user/EplObdu.h"
+#include "user/EplDlluCal.h"
+#include "Benchmark.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
+#error "EPL NmtMnu module needs EPL module OBDU or OBDK!"
+#endif
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+#define EPL_NMTMNU_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
+    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtMnu << 28) | (Event_p << 24) \
+                             | (uiNodeId_p << 16) | wErrorCode_p)
+
+
+// defines for flags in node info structure
+#define EPL_NMTMNU_NODE_FLAG_ISOCHRON       0x0001  // CN is being accessed isochronously
+#define EPL_NMTMNU_NODE_FLAG_NOT_SCANNED    0x0002  // CN was not scanned once -> decrement SignalCounter and reset flag
+#define EPL_NMTMNU_NODE_FLAG_HALTED         0x0004  // boot process for this CN is halted
+#define EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED 0x0008  // NMT command was just issued, wrong NMT states will be tolerated
+#define EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ  0x0300  // counter for StatusRequest timer handle
+#define EPL_NMTMNU_NODE_FLAG_COUNT_LONGER   0x0C00  // counter for longer timeouts timer handle
+#define EPL_NMTMNU_NODE_FLAG_INC_STATREQ    0x0100  // increment for StatusRequest timer handle
+#define EPL_NMTMNU_NODE_FLAG_INC_LONGER     0x0400  // increment for longer timeouts timer handle
+                    // These counters will be incremented at every timer start
+                    // and copied to timerarg. When the timer event occures
+                    // both will be compared and if unequal the timer event
+                    // will be discarded, because it is an old one.
+
+// defines for timer arguments to draw a distinction between serveral events
+#define EPL_NMTMNU_TIMERARG_NODE_MASK   0x000000FFL // mask that contains the node-ID
+#define EPL_NMTMNU_TIMERARG_IDENTREQ    0x00010000L // timer event is for IdentRequest
+#define EPL_NMTMNU_TIMERARG_STATREQ     0x00020000L // timer event is for StatusRequest
+#define EPL_NMTMNU_TIMERARG_LONGER      0x00040000L // timer event is for longer timeouts
+#define EPL_NMTMNU_TIMERARG_STATE_MON   0x00080000L // timer event for StatusRequest to monitor execution of NMT state changes
+#define EPL_NMTMNU_TIMERARG_COUNT_SR    0x00000300L // counter for StatusRequest
+#define EPL_NMTMNU_TIMERARG_COUNT_LO    0x00000C00L // counter for longer timeouts
+                    // The counters must have the same position as in the node flags above.
+
+#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
+    pNodeInfo_p->m_wFlags = \
+        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
+         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
+        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
+    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p | \
+        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
+    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
+
+#define EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
+    pNodeInfo_p->m_wFlags = \
+        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
+         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
+        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
+    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p | \
+        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
+    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
+
+#define EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
+    pNodeInfo_p->m_wFlags = \
+        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_LONGER) \
+         & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) \
+        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
+    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p | \
+        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
+    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
+
+#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
+    pNodeInfo_p->m_wFlags = \
+        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
+         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
+        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
+    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATE_MON | uiNodeId_p | \
+        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
+    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
+
+
+// defines for global flags
+#define EPL_NMTMNU_FLAG_HALTED          0x0001  // boot process is halted
+#define EPL_NMTMNU_FLAG_APP_INFORMED    0x0002  // application was informed about possible NMT state change
+
+// return pointer to node info structure for specified node ID
+// d.k. may be replaced by special (hash) function if node ID array is smaller than 254
+#define EPL_NMTMNU_GET_NODEINFO(uiNodeId_p) (&EplNmtMnuInstance_g.m_aNodeInfo[uiNodeId_p - 1])
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef enum
+{
+    kEplNmtMnuIntNodeEventNoIdentResponse   = 0x00,
+    kEplNmtMnuIntNodeEventIdentResponse     = 0x01,
+    kEplNmtMnuIntNodeEventBoot              = 0x02,
+    kEplNmtMnuIntNodeEventExecReset         = 0x03,
+    kEplNmtMnuIntNodeEventConfigured        = 0x04,
+    kEplNmtMnuIntNodeEventNoStatusResponse  = 0x05,
+    kEplNmtMnuIntNodeEventStatusResponse    = 0x06,
+    kEplNmtMnuIntNodeEventHeartbeat         = 0x07,
+    kEplNmtMnuIntNodeEventNmtCmdSent        = 0x08,
+    kEplNmtMnuIntNodeEventTimerIdentReq     = 0x09,
+    kEplNmtMnuIntNodeEventTimerStatReq      = 0x0A,
+    kEplNmtMnuIntNodeEventTimerStateMon     = 0x0B,
+    kEplNmtMnuIntNodeEventTimerLonger       = 0x0C,
+    kEplNmtMnuIntNodeEventError             = 0x0D,
+
+} tEplNmtMnuIntNodeEvent;
+
+
+typedef enum
+{
+    kEplNmtMnuNodeStateUnknown      = 0x00,
+    kEplNmtMnuNodeStateIdentified   = 0x01,
+    kEplNmtMnuNodeStateResetConf    = 0x02, // CN reset after configuration update
+    kEplNmtMnuNodeStateConfigured   = 0x03, // BootStep1 completed
+    kEplNmtMnuNodeStateReadyToOp    = 0x04, // BootStep2 completed
+    kEplNmtMnuNodeStateComChecked   = 0x05, // Communication checked successfully
+    kEplNmtMnuNodeStateOperational  = 0x06, // CN is in NMT state OPERATIONAL
+
+} tEplNmtMnuNodeState;
+
+
+typedef struct
+{
+    tEplTimerHdl        m_TimerHdlStatReq;  // timer to delay StatusRequests and IdentRequests
+    tEplTimerHdl        m_TimerHdlLonger;   // 2nd timer for NMT command EnableReadyToOp and CheckCommunication
+    tEplNmtMnuNodeState m_NodeState;    // internal node state (kind of sub state of NMT state)
+    DWORD               m_dwNodeCfg;    // subindex from 0x1F81
+    WORD                m_wFlags;       // flags: CN is being accessed isochronously
+
+} tEplNmtMnuNodeInfo;
+
+
+typedef struct
+{
+    tEplNmtMnuNodeInfo  m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
+    tEplTimerHdl        m_TimerHdlNmtState;     // timeout for stay in NMT state
+    unsigned int        m_uiMandatorySlaveCount;
+    unsigned int        m_uiSignalSlaveCount;
+    unsigned long       m_ulStatusRequestDelay; // in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE)
+    unsigned long       m_ulTimeoutReadyToOp;   // in [ms] (object 0x1F89/5)
+    unsigned long       m_ulTimeoutCheckCom;    // in [ms] (object 0x1006 * MultiplexedCycleCount)
+    WORD                m_wFlags;               // global flags
+    DWORD               m_dwNmtStartup;         // object 0x1F80 NMT_StartUp_U32
+    tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
+    tEplNmtMnuCbBootEvent m_pfnCbBootEvent;
+
+} tEplNmtMnuInstance;
+
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplNmtMnuInstance   EplNmtMnuInstance_g;
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p);
+
+static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(
+                                    unsigned int        uiNodeId_p,
+                                    tEplIdentResponse*  pIdentResponse_p);
+
+static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(
+                                    unsigned int        uiNodeId_p,
+                                    tEplStatusResponse* pStatusResponse_p);
+
+static tEplKernel EplNmtMnuCheckNmtState(
+                                    unsigned int        uiNodeId_p,
+                                    tEplNmtMnuNodeInfo* pNodeInfo_p,
+                                    tEplNmtState        NodeNmtState_p,
+                                    WORD                wErrorCode_p,
+                                    tEplNmtState        LocalNmtState_p);
+
+static tEplKernel EplNmtMnuStartBootStep1(void);
+
+static tEplKernel EplNmtMnuStartBootStep2(void);
+
+static tEplKernel EplNmtMnuStartCheckCom(void);
+
+static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p, tEplNmtMnuNodeInfo* pNodeInfo_p);
+
+static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p, tEplNmtMnuNodeInfo* pNodeInfo_p);
+
+static tEplKernel EplNmtMnuStartNodes(void);
+
+static tEplKernel EplNmtMnuProcessInternalEvent(
+                                    unsigned int        uiNodeId_p,
+                                    tEplNmtState        NodeNmtState_p,
+                                    WORD                wErrorCode_p,
+                                    tEplNmtMnuIntNodeEvent NodeEvent_p);
+
+static tEplKernel EplNmtMnuReset(void);
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuInit
+//
+// Description: init first instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
+                         tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
+{
+tEplKernel Ret;
+
+    Ret = EplNmtMnuAddInstance(pfnCbNodeEvent_p, pfnCbBootEvent_p);
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuAddInstance
+//
+// Description: init other instances of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
+                                tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplNmtMnuInstance_g, 0, sizeof (EplNmtMnuInstance_g));
+
+    if ((pfnCbNodeEvent_p == NULL) || (pfnCbBootEvent_p == NULL))
+    {
+        Ret = kEplNmtInvalidParam;
+        goto Exit;
+    }
+    EplNmtMnuInstance_g.m_pfnCbNodeEvent = pfnCbNodeEvent_p;
+    EplNmtMnuInstance_g.m_pfnCbBootEvent = pfnCbBootEvent_p;
+
+    // initialize StatusRequest delay
+    EplNmtMnuInstance_g.m_ulStatusRequestDelay = 5000L;
+
+    // register NmtMnResponse callback function
+    Ret = EplDlluCalRegAsndService(kEplDllAsndNmtRequest, EplNmtMnuCbNmtRequest, kEplDllAsndFilterLocal);
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuDelInstance
+//
+// Description: delete instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplNmtMnuDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // deregister NmtMnResponse callback function
+    Ret = EplDlluCalRegAsndService(kEplDllAsndNmtRequest, NULL, kEplDllAsndFilterNone);
+
+    Ret = EplNmtMnuReset();
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuSendNmtCommandEx
+//
+// Description: sends the specified NMT command to the specified node.
+//
+// Parameters:  uiNodeId_p              = node ID to which the NMT command will be sent
+//              NmtCommand_p            = NMT command
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
+                                    tEplNmtCommand  NmtCommand_p,
+                                    void* pNmtCommandData_p,
+                                    unsigned int uiDataSize_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplFrameInfo   FrameInfo;
+BYTE            abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
+tEplFrame*      pFrame = (tEplFrame*) abBuffer;
+BOOL            fSoftDeleteNode = FALSE;
+
+    if ((uiNodeId_p == 0) || (uiNodeId_p > EPL_C_ADR_BROADCAST))
+    {   // invalid node ID specified
+        Ret = kEplInvalidNodeId;
+        goto Exit;
+    }
+
+    if ((pNmtCommandData_p != NULL) && (uiDataSize_p > (EPL_C_DLL_MINSIZE_NMTCMDEXT - EPL_C_DLL_MINSIZE_NMTCMD)))
+    {
+        Ret = kEplNmtInvalidParam;
+        goto Exit;
+    }
+
+    // $$$ d.k. may be check in future versions if the caller wants to perform prohibited state transitions
+    //     the CN should not perform these transitions, but the expected NMT state will be changed and never fullfilled.
+
+    // build frame
+    EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
+    AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) uiNodeId_p);
+    AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId, (BYTE) kEplDllAsndNmtCommand);
+    AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_bNmtCommandId,
+        (BYTE)NmtCommand_p);
+    if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0))
+    {   // copy command data to frame
+        EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0], pNmtCommandData_p, uiDataSize_p);
+    }
+
+    // build info structure
+    FrameInfo.m_NetTime.m_dwNanoSec = 0;
+    FrameInfo.m_NetTime.m_dwSec = 0;
+    FrameInfo.m_pFrame = pFrame;
+    FrameInfo.m_uiFrameSize = sizeof(abBuffer);
+
+    // send NMT-Request
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalAsyncSend(&FrameInfo,    // pointer to frameinfo
+                           kEplDllAsyncReqPrioNmt); // priority
+#endif
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    EPL_DBGLVL_NMTMN_TRACE2("NMTCmd(%02X->%02X)\n", NmtCommand_p, uiNodeId_p);
+
+    switch (NmtCommand_p)
+    {
+        case kEplNmtCmdStartNode:
+        case kEplNmtCmdEnterPreOperational2:
+        case kEplNmtCmdEnableReadyToOperate:
+        {
+            // nothing left to do,
+            // because any further processing is done
+            // when the NMT command is actually sent
+            goto Exit;
+        }
+
+        case kEplNmtCmdStopNode:
+        {
+            fSoftDeleteNode = TRUE;
+            break;
+        }
+
+        case kEplNmtCmdResetNode:
+        case kEplNmtCmdResetCommunication:
+        case kEplNmtCmdResetConfiguration:
+        case kEplNmtCmdSwReset:
+        {
+            break;
+        }
+
+        default:
+            goto Exit;
+    }
+
+    // remove CN from isochronous phase;
+    // This must be done here and not when NMT command is actually sent
+    // because it will be too late and may cause unwanted errors
+    if (uiNodeId_p != EPL_C_ADR_BROADCAST)
+    {
+        if (fSoftDeleteNode == FALSE)
+        {   // remove CN immediately from isochronous phase
+            Ret = EplDlluCalDeleteNode(uiNodeId_p);
+        }
+        else
+        {   // remove CN from isochronous phase softly
+            Ret = EplDlluCalSoftDeleteNode(uiNodeId_p);
+        }
+    }
+    else
+    {   // do it for all active CNs
+        for (uiNodeId_p = 1; uiNodeId_p <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiNodeId_p++)
+        {
+            if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId_p)->m_dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0)
+            {
+                if (fSoftDeleteNode == FALSE)
+                {   // remove CN immediately from isochronous phase
+                    Ret = EplDlluCalDeleteNode(uiNodeId_p);
+                }
+                else
+                {   // remove CN from isochronous phase softly
+                    Ret = EplDlluCalSoftDeleteNode(uiNodeId_p);
+                }
+            }
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuSendNmtCommand
+//
+// Description: sends the specified NMT command to the specified node.
+//
+// Parameters:  uiNodeId_p              = node ID to which the NMT command will be sent
+//              NmtCommand_p            = NMT command
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
+                                    tEplNmtCommand  NmtCommand_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    Ret = EplNmtMnuSendNmtCommandEx(uiNodeId_p, NmtCommand_p, NULL, 0);
+
+//Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuTriggerStateChange
+//
+// Description: triggers the specified node command for the specified node.
+//
+// Parameters:  uiNodeId_p              = node ID for which the node command will be executed
+//              NodeCommand_p           = node command
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
+                                       tEplNmtNodeCommand  NodeCommand_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplNmtMnuIntNodeEvent  NodeEvent;
+tEplObdSize         ObdSize;
+BYTE                bNmtState;
+WORD                wErrorCode = EPL_E_NO_ERROR;
+
+    if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST))
+    {
+        Ret = kEplInvalidNodeId;
+        goto Exit;
+    }
+
+    switch (NodeCommand_p)
+    {
+        case kEplNmtNodeCommandBoot:
+        {
+            NodeEvent = kEplNmtMnuIntNodeEventBoot;
+            break;
+        }
+
+        case kEplNmtNodeCommandConfOk:
+        {
+            NodeEvent = kEplNmtMnuIntNodeEventConfigured;
+            break;
+        }
+
+        case kEplNmtNodeCommandConfErr:
+        {
+            NodeEvent = kEplNmtMnuIntNodeEventError;
+            wErrorCode = EPL_E_NMT_BPO1_CF_VERIFY;
+            break;
+        }
+
+        case kEplNmtNodeCommandConfReset:
+        {
+            NodeEvent = kEplNmtMnuIntNodeEventExecReset;
+            break;
+        }
+
+        default:
+        {   // invalid node command
+            goto Exit;
+        }
+    }
+
+    // fetch current NMT state
+    ObdSize = 1;
+    Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtState, &ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
+                                        (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                        wErrorCode,
+                                        NodeEvent);
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuCbNmtStateChange
+//
+// Description: callback function for NMT state changes
+//
+// Parameters:  NmtStateChange_p        = NMT state change event
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    // do work which must be done in that state
+    switch (NmtStateChange_p.m_NewNmtState)
+    {
+        // EPL stack is not running
+/*        case kEplNmtGsOff:
+            break;
+
+        // first init of the hardware
+        case kEplNmtGsInitialising:
+            break;
+
+        // init of the manufacturer-specific profile area and the
+        // standardised device profile area
+        case kEplNmtGsResetApplication:
+        {
+            break;
+        }
+
+        // init of the communication profile area
+        case kEplNmtGsResetCommunication:
+        {
+            break;
+        }
+*/
+        // build the configuration with infos from OD
+        case kEplNmtGsResetConfiguration:
+        {
+        DWORD           dwTimeout;
+        tEplObdSize     ObdSize;
+
+            // read object 0x1F80 NMT_StartUp_U32
+            ObdSize = 4;
+            Ret = EplObduReadEntry(0x1F80, 0, &EplNmtMnuInstance_g.m_dwNmtStartup, &ObdSize);
+            if (Ret != kEplSuccessful)
+            {
+                break;
+            }
+
+            // compute StatusReqDelay = object 0x1006 * EPL_C_NMT_STATREQ_CYCLE
+            ObdSize = sizeof (dwTimeout);
+            Ret = EplObduReadEntry(0x1006, 0, &dwTimeout, &ObdSize);
+            if (Ret != kEplSuccessful)
+            {
+                break;
+            }
+            if (dwTimeout != 0L)
+            {
+                EplNmtMnuInstance_g.m_ulStatusRequestDelay = dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
+                if (EplNmtMnuInstance_g.m_ulStatusRequestDelay == 0L)
+                {
+                    EplNmtMnuInstance_g.m_ulStatusRequestDelay = 1L;    // at least 1 ms
+                }
+
+                // $$$ fetch and use MultiplexedCycleCount from OD
+                EplNmtMnuInstance_g.m_ulTimeoutCheckCom = dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
+                if (EplNmtMnuInstance_g.m_ulTimeoutCheckCom == 0L)
+                {
+                    EplNmtMnuInstance_g.m_ulTimeoutCheckCom = 1L;    // at least 1 ms
+                }
+            }
+
+            // fetch ReadyToOp Timeout from OD
+            ObdSize = sizeof (dwTimeout);
+            Ret = EplObduReadEntry(0x1F89, 5, &dwTimeout, &ObdSize);
+            if (Ret != kEplSuccessful)
+            {
+                break;
+            }
+            if (dwTimeout != 0L)
+            {
+                // convert [us] to [ms]
+                dwTimeout /= 1000L;
+                if (dwTimeout == 0L)
+                {
+                    dwTimeout = 1L;    // at least 1 ms
+                }
+                EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = dwTimeout;
+            }
+            else
+            {
+                EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = 0L;
+            }
+            break;
+        }
+/*
+        //-----------------------------------------------------------
+        // CN part of the state machine
+
+        // node liste for EPL-Frames and check timeout
+        case kEplNmtCsNotActive:
+        {
+            break;
+        }
+
+        // node process only async frames
+        case kEplNmtCsPreOperational1:
+        {
+            break;
+        }
+
+        // node process isochronus and asynchronus frames
+        case kEplNmtCsPreOperational2:
+        {
+            break;
+        }
+
+        // node should be configured und application is ready
+        case kEplNmtCsReadyToOperate:
+        {
+            break;
+        }
+
+        // normal work state
+        case kEplNmtCsOperational:
+        {
+            break;
+        }
+
+        // node stopped by MN
+        // -> only process asynchronus frames
+        case kEplNmtCsStopped:
+        {
+            break;
+        }
+
+        // no EPL cycle
+        // -> normal ethernet communication
+        case kEplNmtCsBasicEthernet:
+        {
+            break;
+        }
+*/
+        //-----------------------------------------------------------
+        // MN part of the state machine
+
+        // node listens for EPL-Frames and check timeout
+        case kEplNmtMsNotActive:
+        {
+            break;
+        }
+
+        // node processes only async frames
+        case kEplNmtMsPreOperational1:
+        {
+        DWORD           dwTimeout;
+        tEplTimerArg    TimerArg;
+        tEplObdSize     ObdSize;
+        tEplEvent       Event;
+
+            // clear global flags, e.g. reenable boot process
+            EplNmtMnuInstance_g.m_wFlags = 0;
+
+            // reset IdentResponses and running IdentRequests and StatusRequests
+            Ret = EplIdentuReset();
+            Ret = EplStatusuReset();
+
+            // reset timers
+            Ret = EplNmtMnuReset();
+
+            // 2008/11/18 d.k. reset internal node info is not necessary,
+            //                 because timer flags are important and other
+            //                 things are reset by EplNmtMnuStartBootStep1().
+/*
+            EPL_MEMSET(EplNmtMnuInstance_g.m_aNodeInfo,
+                       0,
+                       sizeof (EplNmtMnuInstance_g.m_aNodeInfo));
+*/
+
+            // inform DLL about NMT state change,
+            // so that it can clear the asynchonous queues and start the reduced cycle
+            Event.m_EventSink = kEplEventSinkDllk;
+            Event.m_EventType = kEplEventTypeDllkStartReducedCycle;
+            EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+            Event.m_pArg = NULL;
+            Event.m_uiSize = 0;
+            Ret = EplEventuPost(&Event);
+            if (Ret != kEplSuccessful)
+            {
+                break;
+            }
+
+            // reset all nodes
+            // d.k.: skip this step if was just done before, e.g. because of a ResetNode command from a diagnostic node
+            if (NmtStateChange_p.m_NmtEvent == kEplNmtEventTimerMsPreOp1)
+            {
+                BENCHMARK_MOD_07_TOGGLE(9);
+
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
+                                                EPL_C_ADR_BROADCAST,
+                                                kEplNmtCmdResetNode);
+
+                Ret = EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST, kEplNmtCmdResetNode);
+                if (Ret != kEplSuccessful)
+                {
+                    break;
+                }
+            }
+            // start network scan
+            Ret = EplNmtMnuStartBootStep1();
+
+            // start timer for 0x1F89/2 MNTimeoutPreOp1_U32
+            ObdSize = sizeof (dwTimeout);
+            Ret = EplObduReadEntry(0x1F89, 2, &dwTimeout, &ObdSize);
+            if (Ret != kEplSuccessful)
+            {
+                break;
+            }
+            if (dwTimeout != 0L)
+            {
+                dwTimeout /= 1000L;
+                if (dwTimeout == 0L)
+                {
+                    dwTimeout = 1L; // at least 1 ms
+                }
+                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
+                TimerArg.m_ulArg = 0;
+                Ret = EplTimeruModifyTimerMs(&EplNmtMnuInstance_g.m_TimerHdlNmtState, dwTimeout, TimerArg);
+            }
+            break;
+        }
+
+        // node processes isochronous and asynchronous frames
+        case kEplNmtMsPreOperational2:
+        {
+            // add identified CNs to isochronous phase
+            // send EnableReadyToOp to all identified CNs
+            Ret = EplNmtMnuStartBootStep2();
+
+            // wait for NMT state change of CNs
+            break;
+        }
+
+        // node should be configured und application is ready
+        case kEplNmtMsReadyToOperate:
+        {
+            // check if PRes of CNs are OK
+            // d.k. that means wait CycleLength * MultiplexCycleCount (i.e. start timer)
+            //      because Dllk checks PRes of CNs automatically in ReadyToOp
+            Ret = EplNmtMnuStartCheckCom();
+            break;
+        }
+
+        // normal work state
+        case kEplNmtMsOperational:
+        {
+            // send StartNode to CNs
+            // wait for NMT state change of CNs
+            Ret = EplNmtMnuStartNodes();
+            break;
+        }
+
+        // no EPL cycle
+        // -> normal ethernet communication
+        case kEplNmtMsBasicEthernet:
+        {
+            break;
+        }
+
+        default:
+        {
+//            TRACE0("EplNmtMnuCbNmtStateChange(): unhandled NMT state\n");
+        }
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuCbCheckEvent
+//
+// Description: callback funktion for NMT events before they are actually executed.
+//              The EPL API layer must forward NMT events from NmtCnu module.
+//              This module will reject some NMT commands while MN.
+//
+// Parameters:  NmtEvent_p              = outstanding NMT event for approval
+//
+// Returns:     tEplKernel              = error code
+//                      kEplReject      = reject the NMT event
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuProcessEvent
+//
+// Description: processes events from event queue
+//
+// Parameters:  pEvent_p        = pointer to event
+//
+// Returns:     tEplKernel      = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(
+            tEplEvent* pEvent_p)
+{
+tEplKernel      Ret;
+
+    Ret = kEplSuccessful;
+
+    // process event
+    switch(pEvent_p->m_EventType)
+    {
+        // timer event
+        case kEplEventTypeTimer:
+        {
+        tEplTimerEventArg*  pTimerEventArg = (tEplTimerEventArg*)pEvent_p->m_pArg;
+        unsigned int        uiNodeId;
+
+            uiNodeId = (unsigned int) (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_NODE_MASK);
+            if (uiNodeId != 0)
+            {
+            tEplObdSize         ObdSize;
+            BYTE                bNmtState;
+            tEplNmtMnuNodeInfo* pNodeInfo;
+
+                pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);
+
+                ObdSize = 1;
+                Ret = EplObduReadEntry(0x1F8E, uiNodeId, &bNmtState, &ObdSize);
+                if (Ret != kEplSuccessful)
+                {
+                    break;
+                }
+
+                if ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_IDENTREQ) != 0L)
+                {
+                    if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
+                        != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR))
+                    {   // this is an old (already deleted or modified) timer
+                        // but not the current timer
+                        // so discard it
+                        EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerIdentReq,
+                                                        uiNodeId,
+                                                        ((pNodeInfo->m_NodeState << 8)
+                                                         | 0xFF));
+
+                        break;
+                    }
+/*
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerIdentReq,
+                                                    uiNodeId,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | 0x80
+                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
+                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
+*/
+                    Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
+                                                        (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                                        EPL_E_NO_ERROR,
+                                                        kEplNmtMnuIntNodeEventTimerIdentReq);
+                }
+
+                else if ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_STATREQ) != 0L)
+                {
+                    if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
+                        != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR))
+                    {   // this is an old (already deleted or modified) timer
+                        // but not the current timer
+                        // so discard it
+                        EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
+                                                        uiNodeId,
+                                                        ((pNodeInfo->m_NodeState << 8)
+                                                         | 0xFF));
+
+                        break;
+                    }
+/*
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
+                                                    uiNodeId,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | 0x80
+                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
+                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
+*/
+                    Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
+                                                        (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                                        EPL_E_NO_ERROR,
+                                                        kEplNmtMnuIntNodeEventTimerStatReq);
+                }
+
+                else if ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_STATE_MON) != 0L)
+                {
+                    if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
+                        != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR))
+                    {   // this is an old (already deleted or modified) timer
+                        // but not the current timer
+                        // so discard it
+                        EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStateMon,
+                                                        uiNodeId,
+                                                        ((pNodeInfo->m_NodeState << 8)
+                                                         | 0xFF));
+
+                        break;
+                    }
+/*
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
+                                                    uiNodeId,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | 0x80
+                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
+                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
+*/
+                    Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
+                                                        (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                                        EPL_E_NO_ERROR,
+                                                        kEplNmtMnuIntNodeEventTimerStateMon);
+                }
+
+                else if ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_LONGER) != 0L)
+                {
+                    if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER)
+                        != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO))
+                    {   // this is an old (already deleted or modified) timer
+                        // but not the current timer
+                        // so discard it
+                        EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerLonger,
+                                                        uiNodeId,
+                                                        ((pNodeInfo->m_NodeState << 8)
+                                                         | 0xFF));
+
+                        break;
+                    }
+/*
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerLonger,
+                                                    uiNodeId,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | 0x80
+                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) >> 6)
+                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO) >> 8)));
+*/
+                    Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
+                                                        (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                                        EPL_E_NO_ERROR,
+                                                        kEplNmtMnuIntNodeEventTimerLonger);
+                }
+
+            }
+            else
+            {   // global timer event
+            }
+            break;
+        }
+
+        case kEplEventTypeHeartbeat:
+        {
+        tEplHeartbeatEvent* pHeartbeatEvent = (tEplHeartbeatEvent*)pEvent_p->m_pArg;
+
+            Ret = EplNmtMnuProcessInternalEvent(pHeartbeatEvent->m_uiNodeId,
+                                                pHeartbeatEvent->m_NmtState,
+                                                pHeartbeatEvent->m_wErrorCode,
+                                                kEplNmtMnuIntNodeEventHeartbeat);
+            break;
+        }
+
+        case kEplEventTypeNmtMnuNmtCmdSent:
+        {
+        tEplFrame* pFrame = (tEplFrame*)pEvent_p->m_pArg;
+        unsigned int        uiNodeId;
+        tEplNmtCommand      NmtCommand;
+        BYTE                bNmtState;
+
+            uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
+            NmtCommand = (tEplNmtCommand) AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_bNmtCommandId);
+
+            switch (NmtCommand)
+            {
+                case kEplNmtCmdStartNode:
+                    bNmtState = (BYTE) (kEplNmtCsOperational & 0xFF);
+                    break;
+
+                case kEplNmtCmdStopNode:
+                    bNmtState = (BYTE) (kEplNmtCsStopped & 0xFF);
+                    break;
+
+                case kEplNmtCmdEnterPreOperational2:
+                    bNmtState = (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+                    break;
+
+                case kEplNmtCmdEnableReadyToOperate:
+                    // d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command
+                    //      and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE
+                    bNmtState = (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+                    break;
+
+                case kEplNmtCmdResetNode:
+                case kEplNmtCmdResetCommunication:
+                case kEplNmtCmdResetConfiguration:
+                case kEplNmtCmdSwReset:
+                    bNmtState = (BYTE) (kEplNmtCsNotActive & 0xFF);
+                    // EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
+                    // after next unresponded IdentRequest/StatusRequest
+                    break;
+
+                default:
+                    goto Exit;
+            }
+
+            // process as internal event which update expected NMT state in OD
+            if (uiNodeId != EPL_C_ADR_BROADCAST)
+            {
+                Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
+                                                    (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                                    0,
+                                                    kEplNmtMnuIntNodeEventNmtCmdSent);
+
+            }
+            else
+            {   // process internal event for all active nodes (except myself)
+
+                for (uiNodeId = 1; uiNodeId <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiNodeId++)
+                {
+                    if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId)->m_dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0)
+                    {
+                        Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
+                                                            (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS),
+                                                            0,
+                                                            kEplNmtMnuIntNodeEventNmtCmdSent);
+
+                        if (Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                    }
+                }
+            }
+
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplNmtInvalidEvent;
+        }
+
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuGetRunningTimerStatReq
+//
+// Description: returns a bit field with running StatReq timers
+//              just for debugging purposes
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int* puiMandatorySlaveCount_p,
+                                             unsigned int* puiSignalSlaveCount_p,
+                                             WORD* pwFlags_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    if ((puiMandatorySlaveCount_p == NULL)
+        || (puiSignalSlaveCount_p == NULL)
+        || (pwFlags_p == NULL))
+    {
+        Ret = kEplNmtInvalidParam;
+        goto Exit;
+    }
+
+    *puiMandatorySlaveCount_p = EplNmtMnuInstance_g.m_uiMandatorySlaveCount;
+    *puiSignalSlaveCount_p = EplNmtMnuInstance_g.m_uiSignalSlaveCount;
+    *pwFlags_p = EplNmtMnuInstance_g.m_wFlags;
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuGetRunningTimerStatReq
+//
+// Description: returns a bit field with running StatReq timers
+//              just for debugging purposes
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+/*
+DWORD EplNmtMnuGetRunningTimerStatReq(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiIndex;
+tEplNmtMnuNodeInfo* pNodeInfo;
+
+    pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
+    for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
+    {
+        if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateConfigured)
+        {
+            // reset flag "scanned once"
+            pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_SCANNED;
+
+            Ret = EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+            EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
+            // signal slave counter shall be decremented if StatusRequest was sent once to a CN
+            // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
+        }
+    }
+
+Exit:
+    return Ret;
+}
+*/
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuCbNmtRequest
+//
+// Description: callback funktion for NmtRequest
+//
+// Parameters:  pFrameInfo_p            = Frame with the NmtRequest
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    // $$$ perform NMTRequest
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuCbIdentResponse
+//
+// Description: callback funktion for IdentResponse
+//
+// Parameters:  uiNodeId_p              = node ID for which IdentReponse was received
+//              pIdentResponse_p        = pointer to IdentResponse
+//                                        is NULL if node did not answer
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(
+                                  unsigned int        uiNodeId_p,
+                                  tEplIdentResponse* pIdentResponse_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    if (pIdentResponse_p == NULL)
+    {   // node did not answer
+        Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
+                                            kEplNmtCsNotActive,
+                                            EPL_E_NMT_NO_IDENT_RES, // was EPL_E_NO_ERROR
+                                            kEplNmtMnuIntNodeEventNoIdentResponse);
+    }
+    else
+    {   // node answered IdentRequest
+    tEplObdSize ObdSize;
+    DWORD       dwDevType;
+    WORD        wErrorCode = EPL_E_NO_ERROR;
+    tEplNmtState NmtState = (tEplNmtState) (AmiGetByteFromLe(&pIdentResponse_p->m_le_bNmtStatus) | EPL_NMT_TYPE_CS);
+
+        // check IdentResponse $$$ move to ProcessIntern, because this function may be called also if CN
+
+        // check DeviceType (0x1F84)
+        ObdSize = 4;
+        Ret = EplObduReadEntry(0x1F84, uiNodeId_p, &dwDevType, &ObdSize);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        if (dwDevType != 0L)
+        {   // actually compare it with DeviceType from IdentResponse
+            if (AmiGetDwordFromLe(&pIdentResponse_p->m_le_dwDeviceType) != dwDevType)
+            {   // wrong DeviceType
+                NmtState = kEplNmtCsNotActive;
+                wErrorCode = EPL_E_NMT_BPO1_DEVICE_TYPE;
+            }
+        }
+
+        Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
+                                            NmtState,
+                                            wErrorCode,
+                                            kEplNmtMnuIntNodeEventIdentResponse);
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuCbStatusResponse
+//
+// Description: callback funktion for StatusResponse
+//
+// Parameters:  uiNodeId_p              = node ID for which IdentReponse was received
+//              pIdentResponse_p        = pointer to IdentResponse
+//                                        is NULL if node did not answer
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(
+                                  unsigned int        uiNodeId_p,
+                                  tEplStatusResponse* pStatusResponse_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    if (pStatusResponse_p == NULL)
+    {   // node did not answer
+        Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
+                                            kEplNmtCsNotActive,
+                                            EPL_E_NMT_NO_STATUS_RES, // was EPL_E_NO_ERROR
+                                            kEplNmtMnuIntNodeEventNoStatusResponse);
+    }
+    else
+    {   // node answered StatusRequest
+        Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
+                                            (tEplNmtState) (AmiGetByteFromLe(&pStatusResponse_p->m_le_bNmtStatus) | EPL_NMT_TYPE_CS),
+                                            EPL_E_NO_ERROR,
+                                            kEplNmtMnuIntNodeEventStatusResponse);
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuStartBootStep1
+//
+// Description: starts BootStep1
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuStartBootStep1(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiSubIndex;
+unsigned int    uiLocalNodeId;
+DWORD           dwNodeCfg;
+tEplObdSize     ObdSize;
+
+    // $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32
+
+    // start network scan
+    EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
+    EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
+    // check 0x1F81
+    uiLocalNodeId = EplObduGetNodeId();
+    for (uiSubIndex = 1; uiSubIndex <= 254; uiSubIndex++)
+    {
+        ObdSize = 4;
+        Ret = EplObduReadEntry(0x1F81, uiSubIndex, &dwNodeCfg, &ObdSize);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        if (uiSubIndex != uiLocalNodeId)
+        {
+            // reset flags "not scanned" and "isochronous"
+            EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags &= ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON | EPL_NMTMNU_NODE_FLAG_NOT_SCANNED);
+
+            if (uiSubIndex == EPL_C_ADR_DIAG_DEF_NODE_ID)
+            {   // diagnostic node must be scanned by MN in any case
+                dwNodeCfg |= (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS);
+                // and it must be isochronously accessed
+                dwNodeCfg &= ~EPL_NODEASSIGN_ASYNCONLY_NODE;
+            }
+
+            // save node config in local node info structure
+            EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_dwNodeCfg = dwNodeCfg;
+            EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_NodeState = kEplNmtMnuNodeStateUnknown;
+
+            if ((dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0)
+            {   // node is configured as CN
+                // identify the node
+                Ret = EplIdentuRequestIdentResponse(uiSubIndex, EplNmtMnuCbIdentResponse);
+                if (Ret != kEplSuccessful)
+                {
+                    goto Exit;
+                }
+
+                // set flag "not scanned"
+                EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags |= EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
+                // signal slave counter shall be decremented if IdentRequest was sent once to a CN
+
+                if ((dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+                {   // node is a mandatory CN
+                    EplNmtMnuInstance_g.m_uiMandatorySlaveCount++;
+                    // mandatory slave counter shall be decremented if mandatory CN was configured successfully
+                }
+            }
+        }
+        else
+        {   // subindex of MN
+            if ((dwNodeCfg & (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS)) != 0)
+            {   // MN shall send PRes
+            tEplDllNodeInfo DllNodeInfo;
+
+                EPL_MEMSET(&DllNodeInfo, 0, sizeof (DllNodeInfo));
+                DllNodeInfo.m_uiNodeId = uiLocalNodeId;
+
+                Ret = EplDlluCalAddNode(&DllNodeInfo);
+            }
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuStartBootStep2
+//
+// Description: starts BootStep2.
+//              That means add nodes to isochronous phase and send
+//              NMT EnableReadyToOp.
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuStartBootStep2(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiIndex;
+tEplNmtMnuNodeInfo* pNodeInfo;
+
+
+    if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0)
+    {   // boot process is not halted
+        // add nodes to isochronous phase and send NMT EnableReadyToOp
+        EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
+        EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
+        // reset flag that application was informed about possible state change
+        EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
+
+        pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
+        for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
+        {
+            if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateConfigured)
+            {
+                Ret = EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
+                if (Ret != kEplSuccessful)
+                {
+                    goto Exit;
+                }
+
+                // set flag "not scanned"
+                pNodeInfo->m_wFlags |= EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
+                // signal slave counter shall be decremented if StatusRequest was sent once to a CN
+
+                if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+                {   // node is a mandatory CN
+                    EplNmtMnuInstance_g.m_uiMandatorySlaveCount++;
+                }
+
+                // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
+            }
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuNodeBootStep2
+//
+// Description: starts BootStep2 for the specified node.
+//              This means the CN is added to isochronous phase if not
+//              async-only and it gets the NMT command EnableReadyToOp.
+//              The CN must be in node state Configured, when it enters
+//              BootStep2. When BootStep2 finishes, the CN is in node state
+//              ReadyToOp.
+//              If TimeoutReadyToOp in object 0x1F89/5 is configured,
+//              TimerHdlLonger will be started with this timeout.
+//
+// Parameters:  uiNodeId_p              = node ID
+//              pNodeInfo_p             = pointer to internal node info structure
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p, tEplNmtMnuNodeInfo* pNodeInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplDllNodeInfo DllNodeInfo;
+DWORD           dwNodeCfg;
+tEplObdSize     ObdSize;
+tEplTimerArg    TimerArg;
+
+    dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
+    if ((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0)
+    {   // add node to isochronous phase
+        DllNodeInfo.m_uiNodeId = uiNodeId_p;
+        ObdSize = 4;
+        Ret = EplObduReadEntry(0x1F92, uiNodeId_p, &DllNodeInfo.m_dwPresTimeout, &ObdSize);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        ObdSize = 2;
+        Ret = EplObduReadEntry(0x1F8B, uiNodeId_p, &DllNodeInfo.m_wPreqPayloadLimit, &ObdSize);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        ObdSize = 2;
+        Ret = EplObduReadEntry(0x1F8D, uiNodeId_p, &DllNodeInfo.m_wPresPayloadLimit, &ObdSize);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        pNodeInfo_p->m_wFlags |= EPL_NMTMNU_NODE_FLAG_ISOCHRON;
+
+        Ret = EplDlluCalAddNode(&DllNodeInfo);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+    }
+
+    EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
+                                    uiNodeId_p,
+                                    kEplNmtCmdEnableReadyToOperate);
+
+    Ret = EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdEnableReadyToOperate);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    if (EplNmtMnuInstance_g.m_ulTimeoutReadyToOp != 0L)
+    {   // start timer
+        // when the timer expires the CN must be ReadyToOp
+        EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(
+                pNodeInfo_p, uiNodeId_p, TimerArg);
+//        TimerArg.m_EventSink = kEplEventSinkNmtMnu;
+//        TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
+        Ret = EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger, EplNmtMnuInstance_g.m_ulTimeoutReadyToOp, TimerArg);
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuStartCheckCom
+//
+// Description: starts CheckCommunication
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuStartCheckCom(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiIndex;
+tEplNmtMnuNodeInfo* pNodeInfo;
+
+
+    if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0)
+    {   // boot process is not halted
+        // wait some time and check that no communication error occurs
+        EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
+        EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
+        // reset flag that application was informed about possible state change
+        EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
+
+        pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
+        for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
+        {
+            if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateReadyToOp)
+            {
+                Ret = EplNmtMnuNodeCheckCom(uiIndex, pNodeInfo);
+                if (Ret == kEplReject)
+                {   // timer was started
+                    // wait until it expires
+                    if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+                    {   // node is a mandatory CN
+                        EplNmtMnuInstance_g.m_uiMandatorySlaveCount++;
+                    }
+                }
+                else if (Ret != kEplSuccessful)
+                {
+                    goto Exit;
+                }
+
+                // set flag "not scanned"
+                pNodeInfo->m_wFlags |= EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
+                // signal slave counter shall be decremented if timeout elapsed and regardless of an error
+                // mandatory slave counter shall be decremented if timeout elapsed and no error occured
+            }
+        }
+    }
+
+    Ret = kEplSuccessful;
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuNodeCheckCom
+//
+// Description: checks communication of the specified node.
+//              That means wait some time and if no error occured everything
+//              is OK.
+//
+// Parameters:  uiNodeId_p              = node ID
+//              pNodeInfo_p             = pointer to internal node info structure
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p, tEplNmtMnuNodeInfo* pNodeInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+DWORD           dwNodeCfg;
+tEplTimerArg    TimerArg;
+
+    dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
+    if (((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0)
+        && (EplNmtMnuInstance_g.m_ulTimeoutCheckCom != 0L))
+    {   // CN is not async-only and timeout for CheckCom was set
+
+        // check communication,
+        // that means wait some time and if no error occured everything is OK;
+
+        // start timer (when the timer expires the CN must be still ReadyToOp)
+        EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(
+                pNodeInfo_p, uiNodeId_p, TimerArg);
+//        TimerArg.m_EventSink = kEplEventSinkNmtMnu;
+//        TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
+        Ret = EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger, EplNmtMnuInstance_g.m_ulTimeoutCheckCom, TimerArg);
+
+        // update mandatory slave counter, because timer was started
+        if (Ret == kEplSuccessful)
+        {
+            Ret = kEplReject;
+        }
+    }
+    else
+    {   // timer was not started
+        // assume everything is OK
+        pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateComChecked;
+    }
+
+//Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuStartNodes
+//
+// Description: really starts all nodes which are ReadyToOp and CheckCom did not fail
+//
+// Parameters:  (none)
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuStartNodes(void)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiIndex;
+tEplNmtMnuNodeInfo* pNodeInfo;
+
+
+    if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0)
+    {   // boot process is not halted
+        // send NMT command Start Node
+        EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
+        EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
+        // reset flag that application was informed about possible state change
+        EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
+
+        pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
+        for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
+        {
+            if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateComChecked)
+            {
+                if ((EplNmtMnuInstance_g.m_dwNmtStartup & EPL_NMTST_STARTALLNODES) == 0)
+                {
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
+                                                    uiIndex,
+                                                    kEplNmtCmdStartNode);
+
+                    Ret = EplNmtMnuSendNmtCommand(uiIndex, kEplNmtCmdStartNode);
+                    if (Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+                }
+
+                if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+                {   // node is a mandatory CN
+                    EplNmtMnuInstance_g.m_uiMandatorySlaveCount++;
+                }
+
+                // set flag "not scanned"
+                pNodeInfo->m_wFlags |= EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
+                // signal slave counter shall be decremented if StatusRequest was sent once to a CN
+                // mandatory slave counter shall be decremented if mandatory CN is OPERATIONAL
+            }
+        }
+
+        // $$$ inform application if EPL_NMTST_NO_STARTNODE is set
+
+        if ((EplNmtMnuInstance_g.m_dwNmtStartup & EPL_NMTST_STARTALLNODES) != 0)
+        {
+            EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
+                                            EPL_C_ADR_BROADCAST,
+                                            kEplNmtCmdStartNode);
+
+            Ret = EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST, kEplNmtCmdStartNode);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuProcessInternalEvent
+//
+// Description: processes internal node events
+//
+// Parameters:  uiNodeId_p              = node ID
+//              NodeNmtState_p          = NMT state of CN
+//              NodeEvent_p             = occured events
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuProcessInternalEvent(
+                                    unsigned int        uiNodeId_p,
+                                    tEplNmtState        NodeNmtState_p,
+                                    WORD                wErrorCode_p,
+                                    tEplNmtMnuIntNodeEvent NodeEvent_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplNmtState        NmtState;
+tEplNmtMnuNodeInfo* pNodeInfo;
+tEplTimerArg        TimerArg;
+
+    pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId_p);
+    NmtState = EplNmtuGetNmtState();
+    if (NmtState <= kEplNmtMsNotActive)
+    {   // MN is not active
+        goto Exit;
+    }
+
+    switch (NodeEvent_p)
+    {
+        case kEplNmtMnuIntNodeEventIdentResponse:
+        {
+        BYTE    bNmtState;
+
+            EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                            uiNodeId_p,
+                                            pNodeInfo->m_NodeState);
+
+            if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)
+            {
+                pNodeInfo->m_NodeState = kEplNmtMnuNodeStateIdentified;
+            }
+
+            // reset flags ISOCHRON and NMT_CMD_ISSUED
+            pNodeInfo->m_wFlags &= ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON
+                                     | EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED);
+
+            if ((NmtState == kEplNmtMsPreOperational1)
+                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
+            {
+                // decrement only signal slave count
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+            }
+
+            // update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
+            bNmtState = (BYTE) (kEplNmtCsPreOperational1 & 0xFF);
+            Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1);
+
+            // check NMT state of CN
+            Ret = EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, NodeNmtState_p, wErrorCode_p, NmtState);
+            if (Ret != kEplSuccessful)
+            {
+                if (Ret == kEplReject)
+                {
+                    Ret = kEplSuccessful;
+                }
+                break;
+            }
+
+            // request StatusResponse immediately,
+            // because we want a fast boot-up of CNs
+            Ret = EplStatusuRequestStatusResponse(uiNodeId_p, EplNmtMnuCbStatusResponse);
+            if (Ret != kEplSuccessful)
+            {
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                uiNodeId_p,
+                                                Ret);
+
+                if (Ret == kEplInvalidOperation)
+                {   // the only situation when this should happen is, when
+                    // StatusResponse was already requested from within
+                    // the StatReq timer event.
+                    // so ignore this error.
+                    Ret = kEplSuccessful;
+                }
+                else
+                {
+                    break;
+                }
+            }
+
+            if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)
+            {
+                // inform application
+                Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
+                                                           kEplNmtNodeEventFound,
+                                                           NodeNmtState_p,
+                                                           EPL_E_NO_ERROR,
+                                                           (pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0);
+                if (Ret == kEplReject)
+                {   // interrupt boot process on user request
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                    uiNodeId_p,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | Ret));
+
+                    Ret = kEplSuccessful;
+                    break;
+                }
+                else if (Ret != kEplSuccessful)
+                {
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                    uiNodeId_p,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | Ret));
+
+                    break;
+                }
+            }
+
+            // continue BootStep1
+        }
+
+        case kEplNmtMnuIntNodeEventBoot:
+        {
+
+            // $$$ check identification (vendor ID, product code, revision no, serial no)
+
+            if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateIdentified)
+            {
+                // $$$ check software
+
+                // check/start configuration
+                // inform application
+                Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
+                                                           kEplNmtNodeEventCheckConf,
+                                                           NodeNmtState_p,
+                                                           EPL_E_NO_ERROR,
+                                                           (pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0);
+                if (Ret == kEplReject)
+                {   // interrupt boot process on user request
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventBoot,
+                                                    uiNodeId_p,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | Ret));
+
+                    Ret = kEplSuccessful;
+                    break;
+                }
+                else if (Ret != kEplSuccessful)
+                {
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventBoot,
+                                                    uiNodeId_p,
+                                                    ((pNodeInfo->m_NodeState << 8)
+                                                     | Ret));
+
+                    break;
+                }
+            }
+            else if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)
+            {   // wrong CN state
+                // ignore event
+                break;
+            }
+
+            // $$$ d.k.: currently we assume configuration is OK
+
+            // continue BootStep1
+        }
+
+        case kEplNmtMnuIntNodeEventConfigured:
+        {
+            if ((pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified)
+                && (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf))
+            {   // wrong CN state
+                // ignore event
+                break;
+            }
+
+            pNodeInfo->m_NodeState = kEplNmtMnuNodeStateConfigured;
+
+            if (NmtState == kEplNmtMsPreOperational1)
+            {
+                if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+                {   // decrement mandatory CN counter
+                    EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
+                }
+            }
+            else
+            {
+                // put optional node to next step (BootStep2)
+                Ret = EplNmtMnuNodeBootStep2(uiNodeId_p, pNodeInfo);
+            }
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventNoIdentResponse:
+        {
+            if ((NmtState == kEplNmtMsPreOperational1)
+                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
+            {
+                // decrement only signal slave count
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+            }
+
+            if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)
+            {
+                pNodeInfo->m_NodeState = kEplNmtMnuNodeStateUnknown;
+            }
+
+            // $$$ d.k. check start time for 0x1F89/2 MNTimeoutPreOp1_U32
+            // $$$ d.k. check individual timeout 0x1F89/6 MNIdentificationTimeout_U32
+            // if mandatory node and timeout elapsed -> halt boot procedure
+            // trigger IdentRequest again (if >= PreOp2, after delay)
+            if (NmtState >= kEplNmtMsPreOperational2)
+            {   // start timer
+                EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(
+                        pNodeInfo, uiNodeId_p, TimerArg);
+//                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
+//                TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p;
+/*
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventNoIdentResponse,
+                                                uiNodeId_p,
+                                                ((pNodeInfo->m_NodeState << 8)
+                                                 | 0x80
+                                                 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
+                                                 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
+*/
+                Ret = EplTimeruModifyTimerMs(&pNodeInfo->m_TimerHdlStatReq, EplNmtMnuInstance_g.m_ulStatusRequestDelay, TimerArg);
+            }
+            else
+            {   // trigger IdentRequest immediately
+                Ret = EplIdentuRequestIdentResponse(uiNodeId_p, EplNmtMnuCbIdentResponse);
+            }
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventStatusResponse:
+        {
+            if ((NmtState >= kEplNmtMsPreOperational2)
+                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
+            {
+                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+            }
+
+            // check NMT state of CN
+            Ret = EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, NodeNmtState_p, wErrorCode_p, NmtState);
+            if (Ret != kEplSuccessful)
+            {
+                if (Ret == kEplReject)
+                {
+                    Ret = kEplSuccessful;
+                }
+                break;
+            }
+
+            if (NmtState == kEplNmtMsPreOperational1)
+            {
+                // request next StatusResponse immediately
+                Ret = EplStatusuRequestStatusResponse(uiNodeId_p, EplNmtMnuCbStatusResponse);
+                if (Ret != kEplSuccessful)
+                {
+                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                    uiNodeId_p,
+                                                    Ret);
+                }
+
+            }
+            else if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_ISOCHRON) == 0)
+            {   // start timer
+                // not isochronously accessed CN (e.g. async-only or stopped CN)
+                EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(
+                        pNodeInfo, uiNodeId_p, TimerArg);
+//                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
+//                TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p;
+/*
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventStatusResponse,
+                                                uiNodeId_p,
+                                                ((pNodeInfo->m_NodeState << 8)
+                                                 | 0x80
+                                                 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
+                                                 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
+*/
+                Ret = EplTimeruModifyTimerMs(&pNodeInfo->m_TimerHdlStatReq, EplNmtMnuInstance_g.m_ulStatusRequestDelay, TimerArg);
+            }
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventNoStatusResponse:
+        {
+            // function CheckNmtState sets node state to unknown if necessary
+/*
+            if ((NmtState >= kEplNmtMsPreOperational2)
+                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
+            {
+                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+            }
+*/
+            // check NMT state of CN
+            Ret = EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, NodeNmtState_p, wErrorCode_p, NmtState);
+            if (Ret != kEplSuccessful)
+            {
+                if (Ret == kEplReject)
+                {
+                    Ret = kEplSuccessful;
+                }
+                break;
+            }
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventError:
+        {   // currently only issued on kEplNmtNodeCommandConfErr
+
+            if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified)
+            {   // wrong CN state
+                // ignore event
+                break;
+            }
+
+            // check NMT state of CN
+            Ret = EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, kEplNmtCsNotActive, wErrorCode_p, NmtState);
+            if (Ret != kEplSuccessful)
+            {
+                if (Ret == kEplReject)
+                {
+                    Ret = kEplSuccessful;
+                }
+                break;
+            }
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventExecReset:
+        {
+            if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified)
+            {   // wrong CN state
+                // ignore event
+                break;
+            }
+
+            pNodeInfo->m_NodeState = kEplNmtMnuNodeStateResetConf;
+
+            EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                            uiNodeId_p,
+                                            (((NodeNmtState_p & 0xFF) << 8)
+                                            | kEplNmtCmdResetConfiguration));
+
+            // send NMT reset configuration to CN for activation of configuration
+            Ret = EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdResetConfiguration);
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventHeartbeat:
+        {
+/*
+            if ((NmtState >= kEplNmtMsPreOperational2)
+                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
+            {
+                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
+                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+            }
+*/
+            // check NMT state of CN
+            Ret = EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, NodeNmtState_p, wErrorCode_p, NmtState);
+            if (Ret != kEplSuccessful)
+            {
+                if (Ret == kEplReject)
+                {
+                    Ret = kEplSuccessful;
+                }
+                break;
+            }
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventTimerIdentReq:
+        {
+            EPL_DBGLVL_NMTMN_TRACE1("TimerStatReq->IdentReq(%02X)\n", uiNodeId_p);
+            // trigger IdentRequest again
+            Ret = EplIdentuRequestIdentResponse(uiNodeId_p, EplNmtMnuCbIdentResponse);
+            if (Ret != kEplSuccessful)
+            {
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                uiNodeId_p,
+                                                (((NodeNmtState_p & 0xFF) << 8)
+                                                 | Ret));
+                if (Ret == kEplInvalidOperation)
+                {   // this can happen because of a bug in EplTimeruLinuxKernel.c
+                    // so ignore this error.
+                    Ret = kEplSuccessful;
+                }
+            }
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventTimerStateMon:
+        {
+            // reset NMT state change flag
+            // because from now on the CN must have the correct NMT state
+            pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
+
+            // continue with normal StatReq processing
+        }
+
+        case kEplNmtMnuIntNodeEventTimerStatReq:
+        {
+            EPL_DBGLVL_NMTMN_TRACE1("TimerStatReq->StatReq(%02X)\n", uiNodeId_p);
+            // request next StatusResponse
+            Ret = EplStatusuRequestStatusResponse(uiNodeId_p, EplNmtMnuCbStatusResponse);
+            if (Ret != kEplSuccessful)
+            {
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                uiNodeId_p,
+                                                (((NodeNmtState_p & 0xFF) << 8)
+                                                 | Ret));
+                if (Ret == kEplInvalidOperation)
+                {   // the only situation when this should happen is, when
+                    // StatusResponse was already requested while processing
+                    // event IdentResponse.
+                    // so ignore this error.
+                    Ret = kEplSuccessful;
+                }
+            }
+
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventTimerLonger:
+        {
+            switch (pNodeInfo->m_NodeState)
+            {
+                case kEplNmtMnuNodeStateConfigured:
+                {   // node should be ReadyToOp but it is not
+
+                    // check NMT state which shall be intentionally wrong, so that ERROR_TREATMENT will be started
+                    Ret = EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo, kEplNmtCsNotActive, EPL_E_NMT_BPO2, NmtState);
+                    if (Ret != kEplSuccessful)
+                    {
+                        if (Ret == kEplReject)
+                        {
+                            Ret = kEplSuccessful;
+                        }
+                        break;
+                    }
+
+                    break;
+                }
+
+                case kEplNmtMnuNodeStateReadyToOp:
+                {   // CheckCom finished successfully
+
+                    pNodeInfo->m_NodeState = kEplNmtMnuNodeStateComChecked;
+
+                    if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0)
+                    {
+                        // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
+                        EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+                        pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+                    }
+
+                    if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+                    {
+                        // decrement mandatory slave counter
+                        EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
+                    }
+                    if (NmtState != kEplNmtMsReadyToOperate)
+                    {
+                        EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
+                                                        uiNodeId_p,
+                                                        (((NodeNmtState_p & 0xFF) << 8)
+                                                        | kEplNmtCmdStartNode));
+
+                        // start optional CN
+                        Ret = EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdStartNode);
+                    }
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+            break;
+        }
+
+        case kEplNmtMnuIntNodeEventNmtCmdSent:
+        {
+        BYTE    bNmtState;
+
+            // update expected NMT state with the one that results
+            // from the sent NMT command
+            bNmtState = (BYTE) (NodeNmtState_p & 0xFF);
+
+            // write object 0x1F8F NMT_MNNodeExpState_AU8
+            Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            if (NodeNmtState_p == kEplNmtCsNotActive)
+            {   // restart processing with IdentRequest
+                EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(
+                        pNodeInfo, uiNodeId_p, TimerArg);
+            }
+            else
+            {   // monitor NMT state change with StatusRequest after
+                // the corresponding delay;
+                // until then wrong NMT states will be ignored
+                EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON(
+                        pNodeInfo, uiNodeId_p, TimerArg);
+
+                // set NMT state change flag
+                pNodeInfo->m_wFlags |= EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
+            }
+
+            Ret = EplTimeruModifyTimerMs(&pNodeInfo->m_TimerHdlStatReq, EplNmtMnuInstance_g.m_ulStatusRequestDelay, TimerArg);
+
+            // finish processing, because NmtState_p is the expected and not the current state
+            goto Exit;
+        }
+
+        default:
+        {
+            break;
+        }
+    }
+
+    // check if network is ready to change local NMT state and this was not done before
+    if ((EplNmtMnuInstance_g.m_wFlags & (EPL_NMTMNU_FLAG_HALTED | EPL_NMTMNU_FLAG_APP_INFORMED)) == 0)
+    {   // boot process is not halted
+        switch (NmtState)
+        {
+            case kEplNmtMsPreOperational1:
+            {
+                if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == 0)
+                    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0))
+                {   // all optional CNs scanned once and all mandatory CNs configured successfully
+                    EplNmtMnuInstance_g.m_wFlags |= EPL_NMTMNU_FLAG_APP_INFORMED;
+                    // inform application
+                    Ret = EplNmtMnuInstance_g.m_pfnCbBootEvent(kEplNmtBootEventBootStep1Finish,
+                                                               NmtState,
+                                                               EPL_E_NO_ERROR);
+                    if (Ret != kEplSuccessful)
+                    {
+                        if (Ret == kEplReject)
+                        {
+                            // wait for application
+                            Ret = kEplSuccessful;
+                        }
+                        break;
+                    }
+                    // enter PreOp2
+                    Ret = EplNmtuNmtEvent(kEplNmtEventAllMandatoryCNIdent);
+                }
+                break;
+            }
+
+            case kEplNmtMsPreOperational2:
+            {
+                if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == 0)
+                    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0))
+                {   // all optional CNs checked once for ReadyToOp and all mandatory CNs are ReadyToOp
+                    EplNmtMnuInstance_g.m_wFlags |= EPL_NMTMNU_FLAG_APP_INFORMED;
+                    // inform application
+                    Ret = EplNmtMnuInstance_g.m_pfnCbBootEvent(kEplNmtBootEventBootStep2Finish,
+                                                               NmtState,
+                                                               EPL_E_NO_ERROR);
+                    if (Ret != kEplSuccessful)
+                    {
+                        if (Ret == kEplReject)
+                        {
+                            // wait for application
+                            Ret = kEplSuccessful;
+                        }
+                        break;
+                    }
+                    // enter ReadyToOp
+                    Ret = EplNmtuNmtEvent(kEplNmtEventEnterReadyToOperate);
+                }
+                break;
+            }
+
+            case kEplNmtMsReadyToOperate:
+            {
+                if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == 0)
+                    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0))
+                {   // all CNs checked for errorless communication
+                    EplNmtMnuInstance_g.m_wFlags |= EPL_NMTMNU_FLAG_APP_INFORMED;
+                    // inform application
+                    Ret = EplNmtMnuInstance_g.m_pfnCbBootEvent(kEplNmtBootEventCheckComFinish,
+                                                               NmtState,
+                                                               EPL_E_NO_ERROR);
+                    if (Ret != kEplSuccessful)
+                    {
+                        if (Ret == kEplReject)
+                        {
+                            // wait for application
+                            Ret = kEplSuccessful;
+                        }
+                        break;
+                    }
+                    // enter Operational
+                    Ret = EplNmtuNmtEvent(kEplNmtEventEnterMsOperational);
+                }
+                break;
+            }
+
+            case kEplNmtMsOperational:
+            {
+                if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount == 0)
+                    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0))
+                {   // all optional CNs scanned once and all mandatory CNs are OPERATIONAL
+                    EplNmtMnuInstance_g.m_wFlags |= EPL_NMTMNU_FLAG_APP_INFORMED;
+                    // inform application
+                    Ret = EplNmtMnuInstance_g.m_pfnCbBootEvent(kEplNmtBootEventOperational,
+                                                               NmtState,
+                                                               EPL_E_NO_ERROR);
+                    if (Ret != kEplSuccessful)
+                    {
+                        if (Ret == kEplReject)
+                        {
+                            // ignore error code
+                            Ret = kEplSuccessful;
+                        }
+                        break;
+                    }
+                }
+                break;
+            }
+
+            default:
+            {
+                break;
+            }
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuCheckNmtState
+//
+// Description: checks the NMT state, i.e. evaluates it with object 0x1F8F
+//              NMT_MNNodeExpState_AU8 and updates object 0x1F8E
+//              NMT_MNNodeCurrState_AU8.
+//              It manipulates m_NodeState in internal node info structure.
+//
+// Parameters:  uiNodeId_p              = node ID
+//              NodeNmtState_p          = NMT state of CN
+//
+// Returns:     tEplKernel              = error code
+//                  kEplReject          = CN was in wrong state and has been reset
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuCheckNmtState(
+                                    unsigned int        uiNodeId_p,
+                                    tEplNmtMnuNodeInfo* pNodeInfo_p,
+                                    tEplNmtState        NodeNmtState_p,
+                                    WORD                wErrorCode_p,
+                                    tEplNmtState        LocalNmtState_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplObdSize     ObdSize;
+BYTE            bNmtState;
+BYTE            bNmtStatePrev;
+tEplNmtState    ExpNmtState;
+
+    ObdSize = 1;
+    // read object 0x1F8F NMT_MNNodeExpState_AU8
+    Ret = EplObduReadEntry(0x1F8F, uiNodeId_p, &bNmtState, &ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // compute expected NMT state
+    ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
+    // compute BYTE of current NMT state
+    bNmtState = ((BYTE) NodeNmtState_p & 0xFF);
+
+    if (ExpNmtState == kEplNmtCsNotActive)
+    {   // ignore the current state, because the CN shall be not active
+        Ret = kEplReject;
+        goto Exit;
+    }
+    else if ((ExpNmtState == kEplNmtCsPreOperational2)
+         && (NodeNmtState_p == kEplNmtCsReadyToOperate))
+    {   // CN switched to ReadyToOp
+        // delete timer for timeout handling
+        Ret = EplTimeruDeleteTimer(&pNodeInfo_p->m_TimerHdlLonger);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateReadyToOp;
+
+        // update object 0x1F8F NMT_MNNodeExpState_AU8 to ReadyToOp
+        Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+        {   // node is a mandatory CN -> decrement counter
+            EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
+        }
+        if (LocalNmtState_p >= kEplNmtMsReadyToOperate)
+        {   // start procedure CheckCommunication for this node
+            Ret = EplNmtMnuNodeCheckCom(uiNodeId_p, pNodeInfo_p);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+
+            if ((LocalNmtState_p == kEplNmtMsOperational)
+                && (pNodeInfo_p->m_NodeState == kEplNmtMnuNodeStateComChecked))
+            {
+                EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
+                                                uiNodeId_p,
+                                                (((NodeNmtState_p & 0xFF) << 8)
+                                                | kEplNmtCmdStartNode));
+
+                // immediately start optional CN, because communication is always OK (e.g. async-only CN)
+                Ret = EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdStartNode);
+                if (Ret != kEplSuccessful)
+                {
+                    goto Exit;
+                }
+            }
+        }
+
+    }
+    else if ((ExpNmtState == kEplNmtCsReadyToOperate)
+             && (NodeNmtState_p == kEplNmtCsOperational))
+    {   // CN switched to OPERATIONAL
+        pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateOperational;
+
+        if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0)
+        {   // node is a mandatory CN -> decrement counter
+            EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
+        }
+
+    }
+    else if ((ExpNmtState != NodeNmtState_p)
+             && !((ExpNmtState == kEplNmtCsPreOperational1)
+                  && (NodeNmtState_p == kEplNmtCsPreOperational2)))
+    {   // CN is not in expected NMT state (without the exceptions above)
+    WORD wbeErrorCode;
+
+        if ((pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0)
+        {
+            // decrement only signal slave count if checked once
+            EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
+            pNodeInfo_p->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
+        }
+
+        if (pNodeInfo_p->m_NodeState == kEplNmtMnuNodeStateUnknown)
+        {   // CN is already in state unknown, which means that it got
+            // NMT reset command earlier
+            goto Exit;
+        }
+
+        // -> CN is in wrong NMT state
+        pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateUnknown;
+
+        if (wErrorCode_p == 0)
+        {   // assume wrong NMT state error
+            if ((pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED) != 0)
+            {   // NMT command has been just issued;
+                // ignore wrong NMT state until timer expires;
+                // other errors like LOSS_PRES_TH are still processed
+                goto Exit;
+            }
+
+            wErrorCode_p = EPL_E_NMT_WRONG_STATE;
+        }
+
+        BENCHMARK_MOD_07_TOGGLE(9);
+
+        // $$$ start ERROR_TREATMENT and inform application
+        Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
+                                                   kEplNmtNodeEventError,
+                                                   NodeNmtState_p,
+                                                   wErrorCode_p,
+                                                   (pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
+                                        uiNodeId_p,
+                                        (((NodeNmtState_p & 0xFF) << 8)
+                                        | kEplNmtCmdResetNode));
+
+        // reset CN
+        // store error code in NMT command data for diagnostic purpose
+        AmiSetWordToLe(&wbeErrorCode, wErrorCode_p);
+        Ret = EplNmtMnuSendNmtCommandEx(uiNodeId_p, kEplNmtCmdResetNode, &wbeErrorCode, sizeof (wbeErrorCode));
+        if (Ret == kEplSuccessful)
+        {
+            Ret = kEplReject;
+        }
+
+        goto Exit;
+    }
+
+    // check if NMT_MNNodeCurrState_AU8 has to be changed
+    ObdSize = 1;
+    Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtStatePrev, &ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+    if (bNmtState != bNmtStatePrev)
+    {
+        // update object 0x1F8E NMT_MNNodeCurrState_AU8
+        Ret = EplObduWriteEntry(0x1F8E, uiNodeId_p, &bNmtState, 1);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+        Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
+                                               kEplNmtNodeEventNmtState,
+                                               NodeNmtState_p,
+                                               wErrorCode_p,
+                                               (pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtMnuReset
+//
+// Description: reset internal structures, e.g. timers
+//
+// Parameters:  void
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplNmtMnuReset(void)
+{
+tEplKernel  Ret;
+int         iIndex;
+
+    Ret = EplTimeruDeleteTimer(&EplNmtMnuInstance_g.m_TimerHdlNmtState);
+
+    for (iIndex = 1; iIndex <= tabentries (EplNmtMnuInstance_g.m_aNodeInfo); iIndex++)
+    {
+        // delete timer handles
+        Ret = EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->m_TimerHdlStatReq);
+        Ret = EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->m_TimerHdlLonger);
+    }
+
+    return Ret;
+}
+
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplNmtk.c b/drivers/staging/epl/EplNmtk.c
new file mode 100644 (file)
index 0000000..8bfa59a
--- /dev/null
@@ -0,0 +1,1750 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for NMT-Kernelspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtk.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.12 $  $Date: 2008/11/13 17:13:09 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "kernel/EplNmtk.h"
+#include "kernel/EplTimerk.h"
+
+#include "kernel/EplDllk.h"     // for EplDllkProcess()
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+#define EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent_p, OldNmtState_p, NewNmtState_p) \
+    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtk << 28) | (NmtEvent_p << 16) \
+                             | ((OldNmtState_p & 0xFF) << 8) \
+                             | (NewNmtState_p & 0xFF))
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+// struct for instance table
+INSTANCE_TYPE_BEGIN
+
+    EPL_MCO_DECL_INSTANCE_MEMBER ()
+
+    STATIC  volatile    tEplNmtState    INST_FAR    m_NmtState;
+    STATIC  volatile    BOOL            INST_FAR    m_fEnableReadyToOperate;
+    STATIC  volatile    BOOL            INST_FAR    m_fAppReadyToOperate;
+    STATIC  volatile    BOOL            INST_FAR    m_fTimerMsPreOp2;
+    STATIC  volatile    BOOL            INST_FAR    m_fAllMandatoryCNIdent;
+    STATIC  volatile    BOOL            INST_FAR    m_fFrozen;
+
+INSTANCE_TYPE_END
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+// This macro replace the unspecific pointer to an instance through
+// the modul specific type for the local instance table. This macro
+// must defined in each modul.
+//#define tEplPtrInstance             tEplInstanceInfo MEM*
+
+EPL_MCO_DECL_INSTANCE_VAR ()
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+EPL_MCO_DEFINE_INSTANCE_FCT ()
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <NMT_Kernel-Module>                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: This module realize the NMT-State-Machine of the EPL-Stack
+//
+//
+/***************************************************************************/
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+//---------------------------------------------------------------------------
+//
+// Function:        EplNmtkInit
+//
+// Description: initializes the first instance
+//
+//
+//
+// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer
+//              uiNodeId_p = Node Id of the lokal node
+//
+//
+// Returns:     tEplKernel  =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+{
+tEplKernel Ret;
+
+    Ret = EplNmtkAddInstance (EPL_MCO_PTR_INSTANCE_PTR);
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplNmtkAddInstance
+//
+// Description: adds a new instance
+//
+//
+//
+// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer
+//
+//
+// Returns:     tEplKernel  =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+{
+EPL_MCO_DECL_INSTANCE_PTR_LOCAL
+tEplKernel              Ret;
+//tEplEvent               Event;
+//tEplEventNmtStateChange NmtStateChange;
+
+     // check if pointer to instance pointer valid
+    // get free instance and set the globale instance pointer
+    // set also the instance addr to parameterlist
+    EPL_MCO_CHECK_PTR_INSTANCE_PTR ();
+    EPL_MCO_GET_FREE_INSTANCE_PTR ();
+    EPL_MCO_SET_PTR_INSTANCE_PTR ();
+
+    // sign instance as used
+    EPL_MCO_WRITE_INSTANCE_STATE (kStateUsed);
+
+
+    Ret = kEplSuccessful;
+
+    // initialize intern vaiables
+    // 2006/07/31 d.k.: set NMT-State to kEplNmtGsOff
+    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+    // set NMT-State to kEplNmtGsInitialising
+    //EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+
+    // set flags to FALSE
+    EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
+    EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
+    EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) = FALSE;
+    EPL_MCO_GLB_VAR(m_fAllMandatoryCNIdent) = FALSE;
+    EPL_MCO_GLB_VAR(m_fFrozen) = FALSE;
+
+//    EPL_MCO_GLB_VAR(m_TimerHdl) = 0;
+
+    // inform higher layer about state change
+    // 2006/07/31 d.k.: The EPL API layer/application has to start NMT state
+    //                  machine via NmtEventSwReset after initialisation of
+    //                  all modules has been completed. DLL has to be initialised
+    //                  after NMTk because NMT state shall not be uninitialised
+    //                  at that time.
+/*    NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState);
+    NmtStateChange.m_NmtEvent = kEplNmtEventNoEvent;
+    Event.m_EventSink = kEplEventSinkNmtu;
+    Event.m_EventType = kEplEventTypeNmtStateChange;
+    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+    Event.m_pArg = &NmtStateChange;
+    Event.m_uiSize = sizeof(NmtStateChange);
+    Ret = EplEventkPost(&Event);
+*/
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplNmtkDelInstance
+//
+// Description: delete instance
+//
+//
+//
+// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer
+//
+//
+// Returns:     tEplKernel  =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if (EPL_USE_DELETEINST_FUNC != FALSE)
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+{
+tEplKernel              Ret = kEplSuccessful;
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    // set NMT-State to kEplNmtGsOff
+    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+
+    // sign instance as unused
+    EPL_MCO_WRITE_INSTANCE_STATE (kStateUnused);
+
+    // delete timer
+//    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
+
+    return Ret;
+}
+#endif // (EPL_USE_DELETEINST_FUNC != FALSE)
+
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplNmtkProcess
+//
+// Description: main process function
+//              -> process NMT-State-Maschine und read NMT-Events from Queue
+//
+//
+//
+// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instance pointer
+//              pEvent_p    =   Epl-Event with NMT-event to process
+//
+//
+// Returns:     tEplKernel  =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
+                                              tEplEvent* pEvent_p)
+{
+tEplKernel              Ret;
+tEplNmtState            OldNmtState;
+tEplNmtEvent            NmtEvent;
+tEplEvent               Event;
+tEplEventNmtStateChange NmtStateChange;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    Ret = kEplSuccessful;
+
+    switch(pEvent_p->m_EventType)
+    {
+        case kEplEventTypeNmtEvent:
+        {
+            NmtEvent = *((tEplNmtEvent*)pEvent_p->m_pArg);
+            break;
+        }
+
+        case kEplEventTypeTimer:
+        {
+            NmtEvent = (tEplNmtEvent)((tEplTimerEventArg*)pEvent_p->m_pArg)->m_ulArg;
+            break;
+        }
+        default:
+        {
+            Ret = kEplNmtInvalidEvent;
+            goto Exit;
+        }
+    }
+
+    // save NMT-State
+    // needed for later comparison to
+    // inform hgher layer about state change
+    OldNmtState = EPL_MCO_GLB_VAR(m_NmtState);
+
+    // NMT-State-Maschine
+    switch(EPL_MCO_GLB_VAR(m_NmtState))
+    {
+        //-----------------------------------------------------------
+        // general part of the statemaschine
+
+        // first init of the hardware
+        case kEplNmtGsOff:
+        {
+            // leave this state only if higher layer says so
+            if(NmtEvent == kEplNmtEventSwReset)
+            {   // new state kEplNmtGsInitialising
+                EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+            }
+            break;
+        }
+
+        // first init of the hardware
+        case kEplNmtGsInitialising:
+        {
+            // leave this state only if higher layer says so
+
+            // check events
+            switch(NmtEvent)
+            {
+                // 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // new state kEplNmtGsResetApplication
+                case kEplNmtEventEnterResetApp:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+            break;
+        }
+
+        // init of the manufacturer-specific profile area and the
+        // standardised device profile area
+        case kEplNmtGsResetApplication:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // leave this state only if higher layer
+                // say so
+                case kEplNmtEventEnterResetCom:
+                {
+                    // new state kEplNmtGsResetCommunication
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+            break;
+        }
+
+        // init of the communication profile area
+        case kEplNmtGsResetCommunication:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // 2006/07/31 d.k.: react also on NMT reset commands in ResetComm state
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // leave this state only if higher layer
+                // say so
+                case kEplNmtEventEnterResetConfig:
+                {
+                    // new state kEplNmtGsResetCommunication
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+            break;
+        }
+
+        // build the configuration with infos from OD
+        case kEplNmtGsResetConfiguration:
+        {
+            // reset flags
+            EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
+            EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
+            EPL_MCO_GLB_VAR(m_fFrozen) = FALSE;
+
+            // check events
+            switch(NmtEvent)
+            {
+                // 2006/07/31 d.k.: react also on NMT reset commands in ResetConf state
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                case kEplNmtEventResetCom:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // leave this state only if higher layer says so
+                case kEplNmtEventEnterCsNotActive:
+                {   // Node should be CN
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsNotActive;
+                    break;
+
+                }
+
+                case kEplNmtEventEnterMsNotActive:
+                {   // Node should be CN
+                    #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
+                        // no MN functionality
+                        // TODO: -create error E_NMT_BA1_NO_MN_SUPPORT
+                        EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
+                    #else
+
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsNotActive;
+                    #endif
+                    break;
+
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+            break;
+        }
+
+        //-----------------------------------------------------------
+        // CN part of the statemaschine
+
+        // node liste for EPL-Frames and check timeout
+        case kEplNmtCsNotActive:
+        {
+
+            // check events
+            switch(NmtEvent)
+            {
+                // 2006/07/31 d.k.: react also on NMT reset commands in NotActive state
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
+                    break;
+                }
+
+                // NMT Command Reset Configuration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
+                    break;
+                }
+
+                // see if SoA or SoC received
+                // k.t. 20.07.2006: only SoA forces change of state
+                // see EPL V2 DS 1.0.0 p.267
+                // case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCeSoa:
+                {   // new state PRE_OPERATIONAL1
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
+                    break;
+                }
+                // timeout for SoA and Soc
+                case kEplNmtEventTimerBasicEthernet:
+                {
+                    // new state BASIC_ETHERNET
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsBasicEthernet;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }// end of switch(NmtEvent)
+
+            break;
+        }
+
+        // node processes only async frames
+        case kEplNmtCsPreOperational1:
+        {
+
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command Reset Configuration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // NMT Command StopNode
+                case kEplNmtEventStopNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped;
+                    break;
+                }
+
+                // check if SoC received
+                case kEplNmtEventDllCeSoc:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational2;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+
+            break;
+        }
+
+        // node processes isochronous and asynchronous frames
+        case kEplNmtCsPreOperational2:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command Reset Configuration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // NMT Command StopNode
+                case kEplNmtEventStopNode:
+                {
+                    // reset flags
+                    EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
+                    EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    // reset flags
+                    EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
+                    EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+
+                // check if application is ready to operate
+                case kEplNmtEventEnterReadyToOperate:
+                {
+                    // check if command NMTEnableReadyToOperate from MN was received
+                    if(EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) == TRUE)
+                    {   // reset flags
+                        EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
+                        EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
+                        // change state
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsReadyToOperate;
+                    }
+                    else
+                    {   // set Flag
+                        EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = TRUE;
+                    }
+                    break;
+                }
+
+                // NMT Commando EnableReadyToOperate
+                case kEplNmtEventEnableReadyToOperate:
+                {
+                    // check if application is ready
+                    if(EPL_MCO_GLB_VAR(m_fAppReadyToOperate) == TRUE)
+                    {   // reset flags
+                        EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
+                        EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
+                        // change state
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsReadyToOperate;
+                    }
+                    else
+                    {   // set Flag
+                        EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = TRUE;
+                    }
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+
+        // node should be configured und application is ready
+        case kEplNmtCsReadyToOperate:
+        {
+             // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // NMT Command StopNode
+                case kEplNmtEventStopNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+
+                // NMT Command StartNode
+                case kEplNmtEventStartNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsOperational;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+
+        // normal work state
+        case kEplNmtCsOperational:
+        {
+
+             // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // NMT Command StopNode
+                case kEplNmtEventStopNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsStopped;
+                    break;
+                }
+
+                // NMT Command EnterPreOperational2
+                case kEplNmtEventEnterPreOperational2:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational2;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+
+        // node stopped by MN
+        // -> only process asynchronous frames
+        case kEplNmtCsStopped:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // NMT Command EnterPreOperational2
+                case kEplNmtEventEnterPreOperational2:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational2;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+
+        // no epl cycle
+        // -> normal ethernet communication
+        case kEplNmtCsBasicEthernet:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // error occured
+                // d.k.: how does this error occur? on CRC errors
+/*                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+*/
+                case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCePreq:
+                case kEplNmtEventDllCePres:
+                case kEplNmtEventDllCeSoa:
+                {   // Epl-Frame on net -> stop any communication
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+
+            break;
+        }
+
+        //-----------------------------------------------------------
+        // MN part of the statemaschine
+
+        // MN listen to network
+        // -> if no EPL traffic go to next state
+        case kEplNmtMsNotActive:
+        {
+            #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
+                // no MN functionality
+                // TODO: -create error E_NMT_BA1_NO_MN_SUPPORT
+                EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
+            #else
+
+                // check events
+                switch(NmtEvent)
+                {
+                    // NMT Command SwitchOff
+                    case kEplNmtEventCriticalError:
+                    case kEplNmtEventSwitchOff:
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                        break;
+                    }
+
+                    // NMT Command SwReset
+                    case kEplNmtEventSwReset:
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                        break;
+                    }
+
+                    // NMT Command ResetNode
+                    case kEplNmtEventResetNode:
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                        break;
+                    }
+
+                    // NMT Command ResetCommunication
+                    // or internal Communication error
+                    case kEplNmtEventResetCom:
+                    case kEplNmtEventInternComError:
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                        break;
+                    }
+
+                    // NMT Command ResetConfiguration
+                    case kEplNmtEventResetConfig:
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                        break;
+                    }
+
+                    // EPL frames received
+                    case kEplNmtEventDllCeSoc:
+                    case kEplNmtEventDllCeSoa:
+                    {   // other MN in network
+                        // $$$ d.k.: generate error history entry
+                        EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
+                        break;
+                    }
+
+                    // timeout event
+                    case kEplNmtEventTimerBasicEthernet:
+                    {
+                        if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE)
+                        {   // new state BasicEthernet
+                            EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsBasicEthernet;
+                        }
+                        break;
+                    }
+
+                    // timeout event
+                    case kEplNmtEventTimerMsPreOp1:
+                    {
+                        if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE)
+                        {   // new state PreOp1
+                            EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1;
+                            EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) = FALSE;
+                            EPL_MCO_GLB_VAR(m_fAllMandatoryCNIdent) = FALSE;
+
+                        }
+                        break;
+                    }
+
+                    default:
+                    {
+                        break;
+                    }
+
+                }// end of switch(NmtEvent)
+
+            #endif // ((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
+
+            break;
+        }
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        // MN process reduces epl cycle
+        case kEplNmtMsPreOperational1:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // EPL frames received
+                case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCeSoa:
+                {   // other MN in network
+                    // $$$ d.k.: generate error history entry
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // error occured
+                // d.k. MSPreOp1->CSPreOp1: nonsense -> keep state
+                /*
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+                */
+
+                case kEplNmtEventAllMandatoryCNIdent:
+                {   // all mandatory CN identified
+                    if (EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) != FALSE)
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational2;
+                    }
+                    else
+                    {
+                        EPL_MCO_GLB_VAR(m_fAllMandatoryCNIdent) = TRUE;
+                    }
+                    break;
+                }
+
+                case kEplNmtEventTimerMsPreOp2:
+                {   // residence time for PreOp1 is elapsed
+                    if (EPL_MCO_GLB_VAR(m_fAllMandatoryCNIdent) != FALSE)
+                    {
+                        EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational2;
+                    }
+                    else
+                    {
+                        EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) = TRUE;
+                    }
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+
+        // MN process full epl cycle
+        case kEplNmtMsPreOperational2:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // EPL frames received
+                case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCeSoa:
+                {   // other MN in network
+                    // $$$ d.k.: generate error history entry
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1;
+                    break;
+                }
+
+                case kEplNmtEventEnterReadyToOperate:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsReadyToOperate;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+
+            break;
+        }
+
+        // all madatory nodes ready to operate
+        // -> MN process full epl cycle
+        case kEplNmtMsReadyToOperate:
+        {
+
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // EPL frames received
+                case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCeSoa:
+                {   // other MN in network
+                    // $$$ d.k.: generate error history entry
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1;
+                    break;
+                }
+
+                case kEplNmtEventEnterMsOperational:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsOperational;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+
+            break;
+        }
+
+        // normal eplcycle processing
+        case kEplNmtMsOperational:
+        {
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // EPL frames received
+                case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCeSoa:
+                {   // other MN in network
+                    // $$$ d.k.: generate error history entry
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // error occured
+                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtMsPreOperational1;
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+
+        //  normal ethernet traffic
+        case kEplNmtMsBasicEthernet:
+        {
+
+            // check events
+            switch(NmtEvent)
+            {
+                // NMT Command SwitchOff
+                case kEplNmtEventCriticalError:
+                case kEplNmtEventSwitchOff:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
+                    break;
+                }
+
+                // NMT Command SwReset
+                case kEplNmtEventSwReset:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
+                    break;
+                }
+
+                // NMT Command ResetNode
+                case kEplNmtEventResetNode:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+                    break;
+                }
+
+                // NMT Command ResetCommunication
+                // or internal Communication error
+                case kEplNmtEventResetCom:
+                case kEplNmtEventInternComError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // NMT Command ResetConfiguration
+                case kEplNmtEventResetConfig:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetConfiguration;
+                    break;
+                }
+
+                // EPL frames received
+                case kEplNmtEventDllCeSoc:
+                case kEplNmtEventDllCeSoa:
+                {   // other MN in network
+                    // $$$ d.k.: generate error history entry
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetCommunication;
+                    break;
+                }
+
+                // error occured
+                // d.k. BE->PreOp1 on cycle error? No
+/*                case kEplNmtEventNmtCycleError:
+                {
+                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
+                    break;
+                }
+*/
+                default:
+                {
+                    break;
+                }
+
+            }// end of switch(NmtEvent)
+            break;
+        }
+#endif //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+        default:
+        {
+            //DEBUG_EPL_DBGLVL_NMTK_TRACE0(EPL_DBGLVL_NMT ,"Error in EplNmtProcess: Unknown NMT-State");
+            //EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
+            Ret = kEplNmtInvalidState;
+            goto Exit;
+        }
+
+    }// end of switch(NmtEvent)
+
+    // inform higher layer about State-Change if needed
+    if(OldNmtState != EPL_MCO_GLB_VAR(m_NmtState))
+    {
+        EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent, OldNmtState, EPL_MCO_GLB_VAR(m_NmtState));
+
+        // d.k.: memorize NMT state before posting any events
+        NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState);
+
+        // inform DLL
+        if ((OldNmtState > kEplNmtGsResetConfiguration)
+            && (EPL_MCO_GLB_VAR(m_NmtState) <= kEplNmtGsResetConfiguration))
+        {
+            // send DLL DEINIT
+            Event.m_EventSink = kEplEventSinkDllk;
+            Event.m_EventType = kEplEventTypeDllkDestroy;
+            EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+            Event.m_pArg = &OldNmtState;
+            Event.m_uiSize = sizeof (OldNmtState);
+            // d.k.: directly call DLLk process function, because
+            //       1. execution of process function is still synchonized and serialized,
+            //       2. it is the same as without event queues (i.e. well tested),
+            //       3. DLLk will get those necessary events even if event queue is full,
+            //       4. event queue is very inefficient
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            Ret = EplDllkProcess(&Event);
+#else
+            Ret = EplEventkPost(&Event);
+#endif
+        }
+        else if ((OldNmtState <= kEplNmtGsResetConfiguration)
+            && (EPL_MCO_GLB_VAR(m_NmtState) > kEplNmtGsResetConfiguration))
+        {
+            // send DLL INIT
+            Event.m_EventSink = kEplEventSinkDllk;
+            Event.m_EventType = kEplEventTypeDllkCreate;
+            EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+            Event.m_pArg = &NmtStateChange.m_NewNmtState;
+            Event.m_uiSize = sizeof (NmtStateChange.m_NewNmtState);
+            // d.k.: directly call DLLk process function, because
+            //       1. execution of process function is still synchonized and serialized,
+            //       2. it is the same as without event queues (i.e. well tested),
+            //       3. DLLk will get those necessary events even if event queue is full
+            //       4. event queue is very inefficient
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            Ret = EplDllkProcess(&Event);
+#else
+            Ret = EplEventkPost(&Event);
+#endif
+        }
+        else if ((EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtCsBasicEthernet)
+                 || (EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtMsBasicEthernet))
+        {
+        tEplDllAsyncReqPriority AsyncReqPriority;
+
+            // send DLL Fill Async Tx Buffer, because state BasicEthernet was entered
+            Event.m_EventSink = kEplEventSinkDllk;
+            Event.m_EventType = kEplEventTypeDllkFillTx;
+            EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+            AsyncReqPriority = kEplDllAsyncReqPrioGeneric;
+            Event.m_pArg = &AsyncReqPriority;
+            Event.m_uiSize = sizeof (AsyncReqPriority);
+            // d.k.: directly call DLLk process function, because
+            //       1. execution of process function is still synchonized and serialized,
+            //       2. it is the same as without event queues (i.e. well tested),
+            //       3. DLLk will get those necessary events even if event queue is full
+            //       4. event queue is very inefficient
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+            Ret = EplDllkProcess(&Event);
+#else
+            Ret = EplEventkPost(&Event);
+#endif
+        }
+
+        // inform higher layer about state change
+        NmtStateChange.m_NmtEvent = NmtEvent;
+        Event.m_EventSink = kEplEventSinkNmtu;
+        Event.m_EventType = kEplEventTypeNmtStateChange;
+        EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
+        Event.m_pArg = &NmtStateChange;
+        Event.m_uiSize = sizeof(NmtStateChange);
+        Ret = EplEventkPost(&Event);
+        EPL_DBGLVL_NMTK_TRACE2("EplNmtkProcess(NMT-Event = 0x%04X): New NMT-State = 0x%03X\n", NmtEvent, NmtStateChange.m_NewNmtState);
+
+
+    }
+
+Exit:
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtkGetNmtState
+//
+// Description: return the actuell NMT-State and the bits
+//              to for MN- or CN-mode
+//
+//
+//
+// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instancepointer
+//
+//
+// Returns:     tEplNmtState = NMT-State
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+{
+tEplNmtState NmtState;
+
+    NmtState = EPL_MCO_GLB_VAR(m_NmtState);
+
+    return NmtState;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+EPL_MCO_DECL_INSTANCE_FCT ()
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplNmtkCal.c b/drivers/staging/epl/EplNmtkCal.c
new file mode 100644 (file)
index 0000000..2881c3c
--- /dev/null
@@ -0,0 +1,157 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for communication abstraction layer of the
+                NMT-Kernel-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtkCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/16 -k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "kernel/EplNmtkCal.h"
+
+
+// TODO: init function needed to prepare EplNmtkGetNmtState for
+//       io-controll-call from EplNmtuCal-Modul
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplNmtu.c b/drivers/staging/epl/EplNmtu.c
new file mode 100644 (file)
index 0000000..52a7e20
--- /dev/null
@@ -0,0 +1,681 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for NMT-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/10 17:17:42 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+****************************************************************************/
+
+
+#include "EplInc.h"
+#include "user/EplNmtu.h"
+#include "user/EplObdu.h"
+#include "user/EplTimeru.h"
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+#include "kernel/EplNmtk.h"
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplNmtuStateChangeCallback     m_pfnNmtChangeCb;
+    tEplTimerHdl                    m_TimerHdl;
+
+} tEplNmtuInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static tEplNmtuInstance EplNmtuInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuInit
+//
+// Description: init first instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit()
+{
+tEplKernel Ret;
+
+    Ret = EplNmtuAddInstance();
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuAddInstance
+//
+// Description: init other instances of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuDelInstance
+//
+// Description: delete instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
+
+    // delete timer
+    Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuNmtEvent
+//
+// Description: sends the NMT-Event to the NMT-State-Maschine
+//
+//
+//
+// Parameters:  NmtEvent_p  = NMT-Event to send
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
+{
+tEplKernel  Ret;
+tEplEvent   Event;
+
+    Event.m_EventSink = kEplEventSinkNmtk;
+    Event.m_NetTime.m_dwNanoSec = 0;
+    Event.m_NetTime.m_dwSec = 0;
+    Event.m_EventType = kEplEventTypeNmtEvent;
+    Event.m_pArg = &NmtEvent_p;
+    Event.m_uiSize = sizeof(NmtEvent_p);
+
+    Ret = EplEventuPost(&Event);
+
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuGetNmtState
+//
+// Description: returns the actuell NMT-State
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplNmtState  = NMT-State
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState()
+{
+tEplNmtState    NmtState;
+
+    // $$$ call function of communication abstraction layer
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+    NmtState = EplNmtkGetNmtState();
+#else
+    NmtState = 0;
+#endif
+
+    return NmtState;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuProcessEvent
+//
+// Description: processes events from event queue
+//
+//
+//
+// Parameters:  pEplEvent_p =   pointer to event
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(
+            tEplEvent* pEplEvent_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // process event
+    switch(pEplEvent_p->m_EventType)
+    {
+        // state change of NMT-Module
+        case kEplEventTypeNmtStateChange:
+        {
+        tEplEventNmtStateChange* pNmtStateChange;
+
+            // delete timer
+            Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
+
+            pNmtStateChange = (tEplEventNmtStateChange*)pEplEvent_p->m_pArg;
+
+            // call cb-functions to inform higher layer
+            if(EplNmtuInstance_g.m_pfnNmtChangeCb != NULL)
+            {
+                Ret = EplNmtuInstance_g.m_pfnNmtChangeCb(*pNmtStateChange);
+            }
+
+            if (Ret == kEplSuccessful)
+            {   // everything is OK, so switch to next state if necessary
+                switch (pNmtStateChange->m_NewNmtState)
+                {
+                    // EPL stack is not running
+                    case kEplNmtGsOff:
+                        break;
+
+                    // first init of the hardware
+                    case kEplNmtGsInitialising:
+                    {
+                        Ret = EplNmtuNmtEvent(kEplNmtEventEnterResetApp);
+                        break;
+                    }
+
+                    // init of the manufacturer-specific profile area and the
+                    // standardised device profile area
+                    case kEplNmtGsResetApplication:
+                    {
+                        Ret = EplNmtuNmtEvent(kEplNmtEventEnterResetCom);
+                        break;
+                    }
+
+                    // init of the communication profile area
+                    case kEplNmtGsResetCommunication:
+                    {
+                        Ret = EplNmtuNmtEvent(kEplNmtEventEnterResetConfig);
+                        break;
+                    }
+
+                    // build the configuration with infos from OD
+                    case kEplNmtGsResetConfiguration:
+                    {
+                    unsigned int uiNodeId;
+
+                        // get node ID from OD
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
+                        uiNodeId = EplObduGetNodeId(EPL_MCO_PTR_INSTANCE_PTR);
+#else
+                        uiNodeId = 0;
+#endif
+                        //check node ID if not should be master or slave
+                        if (uiNodeId == EPL_C_ADR_MN_DEF_NODE_ID)
+                        {   // node shall be MN
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+                            Ret = EplNmtuNmtEvent(kEplNmtEventEnterMsNotActive);
+#else
+                            TRACE0("EplNmtuProcess(): no MN functionality implemented\n");
+#endif
+                        }
+                        else
+                        {   // node shall be CN
+                            Ret = EplNmtuNmtEvent(kEplNmtEventEnterCsNotActive);
+                        }
+                        break;
+                    }
+
+                    //-----------------------------------------------------------
+                    // CN part of the state machine
+
+                    // node listens for EPL-Frames and check timeout
+                    case kEplNmtCsNotActive:
+                    {
+                    DWORD           dwBuffer;
+                    tEplObdSize     ObdSize;
+                    tEplTimerArg    TimerArg;
+
+                        // create timer to switch automatically to BasicEthernet if no MN available in network
+
+                        // read NMT_CNBasicEthernetTimerout_U32 from OD
+                        ObdSize = sizeof(dwBuffer);
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
+                        Ret = EplObduReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
+                                                0x1F99,
+                                                0x00,
+                                                &dwBuffer,
+                                                &ObdSize);
+#else
+                        Ret = kEplObdIndexNotExist;
+#endif
+                        if(Ret != kEplSuccessful)
+                        {
+                            break;
+                        }
+                        if (dwBuffer != 0)
+                        {   // BasicEthernet is enabled
+                            // convert us into ms
+                            dwBuffer = dwBuffer / 1000;
+                            if (dwBuffer == 0)
+                            {   // timer was below one ms
+                                // set one ms
+                                dwBuffer = 1;
+                            }
+                            TimerArg.m_EventSink = kEplEventSinkNmtk;
+                            TimerArg.m_ulArg = (unsigned long) kEplNmtEventTimerBasicEthernet;
+                            Ret = EplTimeruModifyTimerMs(&EplNmtuInstance_g.m_TimerHdl, (unsigned long) dwBuffer, TimerArg);
+                            // potential error is forwarded to event queue which generates error event
+                        }
+                        break;
+                    }
+
+                    // node processes only async frames
+                    case kEplNmtCsPreOperational1:
+                    {
+                        break;
+                    }
+
+                    // node processes isochronous and asynchronous frames
+                    case kEplNmtCsPreOperational2:
+                    {
+                        Ret = EplNmtuNmtEvent(kEplNmtEventEnterReadyToOperate);
+                        break;
+                    }
+
+                    // node should be configured und application is ready
+                    case kEplNmtCsReadyToOperate:
+                    {
+                        break;
+                    }
+
+                    // normal work state
+                    case kEplNmtCsOperational:
+                    {
+                        break;
+                    }
+
+                    // node stopped by MN
+                    // -> only process asynchronous frames
+                    case kEplNmtCsStopped:
+                    {
+                        break;
+                    }
+
+                    // no EPL cycle
+                    // -> normal ethernet communication
+                    case kEplNmtCsBasicEthernet:
+                    {
+                        break;
+                    }
+
+                    //-----------------------------------------------------------
+                    // MN part of the state machine
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+                    // node listens for EPL-Frames and check timeout
+                    case kEplNmtMsNotActive:
+                    {
+                    DWORD           dwBuffer;
+                    tEplObdSize     ObdSize;
+                    tEplTimerArg    TimerArg;
+
+                        // create timer to switch automatically to BasicEthernet/PreOp1 if no other MN active in network
+
+                        // check NMT_StartUp_U32.Bit13
+                        // read NMT_StartUp_U32 from OD
+                        ObdSize = sizeof(dwBuffer);
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
+                        Ret = EplObduReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
+                                                0x1F80,
+                                                0x00,
+                                                &dwBuffer,
+                                                &ObdSize);
+#else
+                        Ret = kEplObdIndexNotExist;
+#endif
+                        if(Ret != kEplSuccessful)
+                        {
+                            break;
+                        }
+
+                        if((dwBuffer & EPL_NMTST_BASICETHERNET) == 0)
+                        {   // NMT_StartUp_U32.Bit13 == 0
+                            // new state PreOperational1
+                            TimerArg.m_ulArg = (unsigned long) kEplNmtEventTimerMsPreOp1;
+                        }
+                        else
+                        {   // NMT_StartUp_U32.Bit13 == 1
+                            // new state BasicEthernet
+                            TimerArg.m_ulArg = (unsigned long) kEplNmtEventTimerBasicEthernet;
+                        }
+
+                        // read NMT_BootTime_REC.MNWaitNotAct_U32 from OD
+                        ObdSize = sizeof(dwBuffer);
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
+                        Ret = EplObduReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
+                                                0x1F89,
+                                                0x01,
+                                                &dwBuffer,
+                                                &ObdSize);
+#else
+                        Ret = kEplObdIndexNotExist;
+#endif
+                        if(Ret != kEplSuccessful)
+                        {
+                            break;
+                        }
+                        // convert us into ms
+                        dwBuffer = dwBuffer / 1000;
+                        if (dwBuffer == 0)
+                        {   // timer was below one ms
+                            // set one ms
+                            dwBuffer = 1;
+                        }
+                        TimerArg.m_EventSink = kEplEventSinkNmtk;
+                        Ret = EplTimeruModifyTimerMs(&EplNmtuInstance_g.m_TimerHdl, (unsigned long) dwBuffer, TimerArg);
+                        // potential error is forwarded to event queue which generates error event
+                        break;
+                    }
+
+                    // node processes only async frames
+                    case kEplNmtMsPreOperational1:
+                    {
+                    DWORD           dwBuffer = 0;
+                    tEplObdSize     ObdSize;
+                    tEplTimerArg    TimerArg;
+
+                        // create timer to switch automatically to PreOp2 if MN identified all mandatory CNs
+
+                        // read NMT_BootTime_REC.MNWaitPreOp1_U32 from OD
+                        ObdSize = sizeof(dwBuffer);
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
+                        Ret = EplObduReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
+                                                0x1F89,
+                                                0x03,
+                                                &dwBuffer,
+                                                &ObdSize);
+                        if(Ret != kEplSuccessful)
+                        {
+                            // ignore error, because this timeout is optional
+                            dwBuffer = 0;
+                        }
+#endif
+                        if (dwBuffer == 0)
+                        {   // delay is deactivated
+                            // immediately post timer event
+                            Ret = EplNmtuNmtEvent(kEplNmtEventTimerMsPreOp2);
+                            break;
+                        }
+                        // convert us into ms
+                        dwBuffer = dwBuffer / 1000;
+                        if (dwBuffer == 0)
+                        {   // timer was below one ms
+                            // set one ms
+                            dwBuffer = 1;
+                        }
+                        TimerArg.m_EventSink = kEplEventSinkNmtk;
+                        TimerArg.m_ulArg = (unsigned long) kEplNmtEventTimerMsPreOp2;
+                        Ret = EplTimeruModifyTimerMs(&EplNmtuInstance_g.m_TimerHdl, (unsigned long) dwBuffer, TimerArg);
+                        // potential error is forwarded to event queue which generates error event
+                        break;
+                    }
+
+                    // node processes isochronous and asynchronous frames
+                    case kEplNmtMsPreOperational2:
+                    {
+                        break;
+                    }
+
+                    // node should be configured und application is ready
+                    case kEplNmtMsReadyToOperate:
+                    {
+                        break;
+                    }
+
+                    // normal work state
+                    case kEplNmtMsOperational:
+                    {
+                        break;
+                    }
+
+                    // no EPL cycle
+                    // -> normal ethernet communication
+                    case kEplNmtMsBasicEthernet:
+                    {
+                        break;
+                    }
+#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+                    default:
+                    {
+                        TRACE1("EplNmtuProcess(): unhandled NMT state 0x%X\n", pNmtStateChange->m_NewNmtState);
+                    }
+                }
+            }
+            else if (Ret == kEplReject)
+            {   // application wants to change NMT state itself
+                // it's OK
+                Ret = kEplSuccessful;
+            }
+
+            EPL_DBGLVL_NMTU_TRACE0("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n");
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplNmtInvalidEvent;
+        }
+
+    }
+
+//Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtuRegisterStateChangeCb
+//
+// Description: register Callback-function go get informed about a
+//              NMT-Change-State-Event
+//
+//
+//
+// Parameters:  pfnEplNmtStateChangeCb_p = functionpointer
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuRegisterStateChangeCb(
+            tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // save callback-function in modul global var
+    EplNmtuInstance_g.m_pfnNmtChangeCb = pfnEplNmtStateChangeCb_p;
+
+    return Ret;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplNmtuCal.c b/drivers/staging/epl/EplNmtuCal.c
new file mode 100644 (file)
index 0000000..e76f250
--- /dev/null
@@ -0,0 +1,164 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for communication abstraction layer of the
+                NMT-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtuCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/16 -k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplNmtuCal.h"
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplNmtkCalGetNmtState
+//
+// Description: return current NMT-State
+//              -> encapsulate access to kernelspace
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplNmtState = current NMT-State
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState()
+{
+tEplNmtState NmtState;
+    // for test direkt call for EplNmtkGetNmtState()
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+    NmtState = EplNmtkGetNmtState();
+#else
+    NmtState = 0;
+#endif
+return NmtState;
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c
new file mode 100644 (file)
index 0000000..0f4db89
--- /dev/null
@@ -0,0 +1,3505 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for api function of EplOBD-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObd.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.12 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Microsoft VC7
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/02 k.t.:   start of the implementation, version 1.00
+                    ->based on CANopen OBD-Modul
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "kernel/EplObdk.h"         // function prototyps of the EplOBD-Modul
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// float definitions and macros
+#define _SHIFTED_EXPONENT_MASK_SP   0xff
+#define _BIAS_SP                    126
+#define T_SP                        23
+#define EXPONENT_DENORM_SP          (-_BIAS_SP)
+#define BASE_TO_THE_T_SP            ((float) 8388608.0)
+#define GET_EXPONENT_SP(x)          ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP)
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+// struct for instance table
+INSTANCE_TYPE_BEGIN
+
+    EPL_MCO_DECL_INSTANCE_MEMBER ()
+
+    STATIC      tEplObdInitParam               INST_FAR    m_ObdInitParam;
+    STATIC      tEplObdStoreLoadObjCallback    INST_NEAR   m_fpStoreLoadObjCallback;
+
+INSTANCE_TYPE_END
+
+// decomposition of float
+typedef union
+{
+    tEplObdReal32   m_flRealPart;
+    int             m_nIntegerPart;
+
+} tEplObdRealParts;
+
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+// This macro replace the unspecific pointer to an instance through
+// the modul specific type for the local instance table. This macro
+// must defined in each modul.
+//#define tEplPtrInstance             tEplInstanceInfo MEM*
+
+EPL_MCO_DECL_INSTANCE_VAR ()
+
+BYTE MEM            abEplObdTrashObject_g[8];
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+EPL_MCO_DEFINE_INSTANCE_FCT ()
+
+static tEplKernel EplObdCallObjectCallback (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdCallback     fpCallback_p,
+    tEplObdCbParam MEM* pCbParam_p);
+
+static tEplObdSize EplObdGetDataSizeIntern (tEplObdSubEntryPtr pSubIndexEntry_p);
+
+static tEplObdSize EplObdGetStrLen (void* pObjData_p,
+                                    tEplObdSize ObjLen_p,
+                                    tEplObdType ObjType_p);
+
+#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
+static tEplKernel EplObdCheckObjectRange (
+            tEplObdSubEntryPtr pSubindexEntry_p,
+            void * pData_p);
+#endif
+
+static tEplKernel EplObdGetVarEntry (
+            tEplObdSubEntryPtr    pSubindexEntry_p,
+            tEplObdVarEntry MEM** ppVarEntry_p);
+
+static tEplKernel  EplObdGetEntry (EPL_MCO_DECL_INSTANCE_PTR_
+            unsigned int          uiIndex_p,
+            unsigned int          uiSubindex_p,
+            tEplObdEntryPtr*      ppObdEntry_p,
+            tEplObdSubEntryPtr*   ppObdSubEntry_p);
+
+static tEplObdSize EplObdGetObjectSize (tEplObdSubEntryPtr pSubIndexEntry_p);
+
+static tEplKernel EplObdGetIndexIntern (
+    tEplObdInitParam MEM*     pInitParam_p,
+    unsigned int              uiIndex_p,
+    tEplObdEntryPtr*          ppObdEntry_p);
+
+static tEplKernel EplObdGetSubindexIntern (
+    tEplObdEntryPtr           pObdEntry_p,
+    unsigned int              uiSubIndex_p,
+    tEplObdSubEntryPtr*       ppObdSubEntry_p);
+
+static tEplKernel EplObdAccessOdPartIntern (EPL_MCO_DECL_INSTANCE_PTR_
+                            tEplObdPart     CurrentOdPart_p,
+                            tEplObdEntryPtr pObdEnty_p,
+                            tEplObdDir      Direction_p);
+
+static void *   EplObdGetObjectDefaultPtr (tEplObdSubEntryPtr pSubIndexEntry_p);
+static void MEM*       EplObdGetObjectCurrentPtr (tEplObdSubEntryPtr pSubIndexEntry_p);
+
+#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
+
+    static tEplKernel EplObdCallStoreCallback (EPL_MCO_DECL_INSTANCE_PTR_
+        tEplObdCbStoreParam MEM* pCbStoreParam_p);
+
+#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
+
+static void EplObdCopyObjectData (
+                        void MEM*       pDstData_p,
+                        void *   pSrcData_p,
+                        tEplObdSize     ObjSize_p,
+                        tEplObdType     ObjType_p);
+
+void * EplObdGetObjectDataPtrIntern (tEplObdSubEntryPtr pSubindexEntry_p);
+
+static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
+                                        BOOL*         pfEntryNumerical_p);
+
+static tEplKernel PUBLIC EplObdWriteEntryPre (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int  uiIndex_p,
+    unsigned int  uiSubIndex_p,
+    void * pSrcData_p,
+    void** ppDstData_p,
+    tEplObdSize   Size_p,
+    tEplObdEntryPtr*        ppObdEntry_p,
+    tEplObdSubEntryPtr*     ppSubEntry_p,
+    tEplObdCbParam MEM*     pCbParam_p,
+    tEplObdSize*  pObdSize_p);
+
+static tEplKernel PUBLIC EplObdWriteEntryPost (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdEntryPtr         pObdEntry_p,
+    tEplObdSubEntryPtr      pSubEntry_p,
+    tEplObdCbParam MEM*     pCbParam_p,
+    void * pSrcData_p,
+    void * pDstData_p,
+    tEplObdSize   ObdSize_p);
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdInit()
+//
+// Description: initializes the first instance
+//
+// Parameters:  pInitParam_p    = init parameter
+//
+// Return:      tEplKernel      =   errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObdInit (EPL_MCO_DECL_PTR_INSTANCE_PTR_
+                    tEplObdInitParam MEM* pInitParam_p)
+{
+
+tEplKernel Ret;
+EPL_MCO_DELETE_INSTANCE_TABLE ();
+
+    if (pInitParam_p == NULL)
+    {
+        Ret = kEplSuccessful;
+        goto Exit;
+    }
+
+    Ret = EplObdAddInstance (EPL_MCO_PTR_INSTANCE_PTR_
+        pInitParam_p);
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdAddInstance()
+//
+// Description: adds a new instance
+//
+// Parameters:  pInitParam_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance (EPL_MCO_DECL_PTR_INSTANCE_PTR_
+    tEplObdInitParam MEM* pInitParam_p)
+{
+
+EPL_MCO_DECL_INSTANCE_PTR_LOCAL
+tEplKernel Ret;
+
+    // check if pointer to instance pointer valid
+    // get free instance and set the globale instance pointer
+    // set also the instance addr to parameterlist
+    EPL_MCO_CHECK_PTR_INSTANCE_PTR ();
+    EPL_MCO_GET_FREE_INSTANCE_PTR ();
+    EPL_MCO_SET_PTR_INSTANCE_PTR ();
+
+    // save init parameters
+    EPL_MEMCPY (&EPL_MCO_GLB_VAR (m_ObdInitParam), pInitParam_p, sizeof (tEplObdInitParam));
+
+    // clear callback function for command LOAD and STORE
+    EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) = NULL;
+
+    // sign instance as used
+    EPL_MCO_WRITE_INSTANCE_STATE (kStateUsed);
+
+    // initialize object dictionary
+    // so all all VarEntries will be initialized to trash object and default values will be set to current data
+    Ret = EplObdAccessOdPart (EPL_MCO_INSTANCE_PTR_
+        kEplObdPartAll, kEplObdDirInit);
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdDeleteInstance()
+//
+// Description: delete instance
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if (EPL_USE_DELETEINST_FUNC != FALSE)
+EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance (EPL_MCO_DECL_INSTANCE_PTR)
+{
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    // sign instance as unused
+    EPL_MCO_WRITE_INSTANCE_STATE (kStateUnused);
+
+    return kEplSuccessful;
+
+}
+#endif // (EPL_USE_DELETEINST_FUNC != FALSE)
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdWriteEntry()
+//
+// Description: Function writes data to an OBD entry. Strings
+//              are stored with added '\0' character.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int  uiIndex_p,
+    unsigned int  uiSubIndex_p,
+    void * pSrcData_p,
+    tEplObdSize   Size_p)
+{
+
+tEplKernel              Ret;
+tEplObdEntryPtr         pObdEntry;
+tEplObdSubEntryPtr      pSubEntry;
+tEplObdCbParam MEM      CbParam;
+void MEM*               pDstData;
+tEplObdSize             ObdSize;
+
+
+    Ret = EplObdWriteEntryPre (EPL_MCO_INSTANCE_PTR_
+                               uiIndex_p,
+                               uiSubIndex_p,
+                               pSrcData_p,
+                               &pDstData,
+                               Size_p,
+                               &pObdEntry,
+                               &pSubEntry,
+                               &CbParam,
+                               &ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplObdWriteEntryPost (EPL_MCO_INSTANCE_PTR_
+                                pObdEntry,
+                                pSubEntry,
+                                &CbParam,
+                                pSrcData_p,
+                                pDstData,
+                                ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdReadEntry()
+//
+// Description: The function reads an object entry. The application
+//              can always read the data even if attrib kEplObdAccRead
+//              is not set. The attrib is only checked up for SDO transfer.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       = Index oof the OD entry to read
+//              uiSubIndex_p    = Subindex to read
+//              pDstData_p      = pointer to the buffer for data
+//              Offset_p        = offset in data for read access
+//              pSize_p         = IN: Size of the buffer
+//                                OUT: number of readed Bytes
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                                unsigned int        uiIndex_p,
+                                                unsigned int        uiSubIndex_p,
+                                                void *              pDstData_p,
+                                                tEplObdSize *       pSize_p)
+{
+
+tEplKernel                      Ret;
+tEplObdEntryPtr                 pObdEntry;
+tEplObdSubEntryPtr              pSubEntry;
+tEplObdCbParam  MEM             CbParam;
+void *                          pSrcData;
+tEplObdSize                     ObdSize;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    ASSERT (pDstData_p != NULL);
+    ASSERT (pSize_p != NULL);
+
+    // get address of index and subindex entry
+    Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
+        uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get pointer to object data
+     pSrcData = EplObdGetObjectDataPtrIntern (pSubEntry);
+
+    // check source pointer
+    if (pSrcData == NULL)
+    {
+        Ret = kEplObdReadViolation;
+        goto Exit;
+    }
+
+    //------------------------------------------------------------------------
+    // address of source data to structure of callback parameters
+    // so callback function can change this data before reading
+    CbParam.m_uiIndex   = uiIndex_p;
+    CbParam.m_uiSubIndex= uiSubIndex_p;
+    CbParam.m_pArg      = pSrcData;
+    CbParam.m_ObdEvent  = kEplObdEvPreRead;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry->m_fpCallback, &CbParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get size of data and check if application has reserved enough memory
+    ObdSize = EplObdGetDataSizeIntern (pSubEntry);
+    // check if offset given and calc correct number of bytes to read
+    if (*pSize_p < ObdSize)
+    {
+        Ret = kEplObdValueLengthError;
+        goto Exit;
+    }
+
+    // read value from object
+    EPL_MEMCPY (pDstData_p, pSrcData, ObdSize);
+    *pSize_p = ObdSize;
+
+    // write address of destination data to structure of callback parameters
+    // so callback function can change this data after reading
+    CbParam.m_pArg     = pDstData_p;
+    CbParam.m_ObdEvent = kEplObdEvPostRead;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry->m_fpCallback, &CbParam);
+
+Exit:
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdAccessOdPart()
+//
+// Description: restores default values of one part of OD
+//
+// Parameters:  ObdPart_p
+//              Direction_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdPart ObdPart_p,
+    tEplObdDir  Direction_p)
+{
+
+tEplKernel      Ret = kEplSuccessful;
+BOOL            fPartFount;
+tEplObdEntryPtr pObdEntry;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    //  part always has to be unequal to NULL
+    pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pPart);
+    ASSERTMSG (pObdEntry != NULL, "EplObdAccessOdPart(): no  OD part is defined!\n");
+
+    // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart
+    fPartFount = FALSE;
+
+    // access to  part
+    if ((ObdPart_p & kEplObdPartGen) != 0)
+    {
+        fPartFount = TRUE;
+
+        Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
+            kEplObdPartGen, pObdEntry, Direction_p);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+
+    // access to manufacturer part
+    pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pManufacturerPart);
+
+    if ( ((ObdPart_p & kEplObdPartMan) != 0) &&
+         (pObdEntry != NULL) )
+    {
+        fPartFount = TRUE;
+
+        Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
+            kEplObdPartMan, pObdEntry, Direction_p);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+
+    // access to device part
+    pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pDevicePart);
+
+    if ( ((ObdPart_p & kEplObdPartDev) != 0) &&
+         (pObdEntry != NULL) )
+    {
+        fPartFount = TRUE;
+
+        Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
+            kEplObdPartDev, pObdEntry, Direction_p);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+
+    #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+    {
+        // access to user part
+        pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pUserPart);
+
+        if ( ((ObdPart_p & kEplObdPartUsr) != 0) &&
+             (pObdEntry != NULL) )
+        {
+            fPartFount = TRUE;
+
+            Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
+                kEplObdPartUsr, pObdEntry, Direction_p);
+            if (Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+        }
+    }
+    #endif
+
+    // no access to an OD part was done? illegal OD part was specified!
+    if (fPartFount == FALSE)
+    {
+        Ret = kEplObdIllegalPart;
+    }
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdDefineVar()
+//
+// Description: defines a variable in OD
+//
+// Parameters:  pEplVarParam_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplVarParam MEM* pVarParam_p)
+{
+
+tEplKernel              Ret;
+tEplObdVarEntry MEM*    pVarEntry;
+tEplVarParamValid       VarValid;
+tEplObdSubEntryPtr      pSubindexEntry;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    ASSERT (pVarParam_p != NULL);   // is not allowed to be NULL
+
+    // get address of subindex entry
+    Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
+        pVarParam_p->m_uiIndex,
+        pVarParam_p->m_uiSubindex,
+        NULL, &pSubindexEntry);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get var entry
+    Ret = EplObdGetVarEntry (pSubindexEntry, &pVarEntry);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    VarValid =  pVarParam_p->m_ValidFlag;
+
+    // copy only this values, which valid flag is set
+    if ((VarValid & kVarValidSize) != 0)
+    {
+        if (pSubindexEntry->m_Type != kEplObdTypDomain)
+        {
+        tEplObdSize DataSize;
+
+            // check passed size parameter
+            DataSize = EplObdGetObjectSize(pSubindexEntry);
+            if (DataSize != pVarParam_p->m_Size)
+            {   // size of variable does not match
+                Ret = kEplObdValueLengthError;
+                goto Exit;
+            }
+        }
+        else
+        {   // size can be set only for objects of type DOMAIN
+            pVarEntry->m_Size = pVarParam_p->m_Size;
+        }
+    }
+
+    if ((VarValid & kVarValidData) != 0)
+    {
+       pVarEntry->m_pData = pVarParam_p->m_pData;
+    }
+/*
+    #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
+    {
+        if ((VarValid & kVarValidCallback) != 0)
+        {
+           pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback;
+        }
+
+        if ((VarValid & kVarValidArg) != 0)
+        {
+           pVarEntry->m_pArg = pVarParam_p->m_pArg;
+        }
+    }
+    #endif
+*/
+    // Ret is already set to kEplSuccessful from ObdGetVarIntern()
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetObjectDataPtr()
+//
+// Description: It returnes the current data pointer. But if object is an
+//              constant object it returnes the default pointer.
+//
+// Parameters:  uiIndex_p    =   Index of the entry
+//              uiSubindex_p =   Subindex of the entry
+//
+// Return:      void *    = pointer to object data
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT void * PUBLIC EplObdGetObjectDataPtr (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p)
+ {
+tEplKernel          Ret;
+void *       pData;
+tEplObdEntryPtr     pObdEntry;
+tEplObdSubEntryPtr  pObdSubEntry;
+
+
+    // get pointer to index structure
+    Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
+                                uiIndex_p,
+                                &pObdEntry);
+    if(Ret != kEplSuccessful)
+    {
+        pData = NULL;
+        goto Exit;
+    }
+
+    // get pointer to subindex structure
+    Ret = EplObdGetSubindexIntern (pObdEntry,
+                                uiSubIndex_p,
+                                &pObdSubEntry);
+    if(Ret != kEplSuccessful)
+    {
+        pData = NULL;
+        goto Exit;
+    }
+    // get Datapointer
+    pData = EplObdGetObjectDataPtrIntern(pObdSubEntry);
+
+Exit:
+    return pData;
+
+}
+
+
+#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdRegisterUserOd()
+//
+// Description: function registers the user OD
+//
+// Parameters:  pUserOd_p   =pointer to user ODd
+//
+// Return:     tEplKernel = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdEntryPtr pUserOd_p)
+{
+
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    EPL_MCO_GLB_VAR (m_ObdInitParam.m_pUserPart) = pUserOd_p;
+
+    return kEplSuccessful;
+
+}
+
+#endif
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdInitVarEntry()
+//
+// Description: function to initialize VarEntry dependened on object type
+//
+// Parameters:  pVarEntry_p = pointer to var entry structure
+//              Type_p      = object type
+//              ObdSize_p   = size of object data
+//
+// Returns:     none
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT void PUBLIC EplObdInitVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                             tEplObdVarEntry MEM* pVarEntry_p,
+                                             tEplObdType Type_p, tEplObdSize ObdSize_p)
+{
+/*
+    #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
+    {
+        // reset pointer to VAR callback and argument
+        pVarEntry_p->m_fpCallback  = NULL;
+        pVarEntry_p->m_pArg = NULL;
+    }
+    #endif
+*/
+
+// 10-dec-2004 r.d.: this function will not be used for strings
+    if ((Type_p == kEplObdTypDomain))
+//         (bType_p == kEplObdTypVString) /* ||
+//         (bType_p == kEplObdTypOString) ||
+//         (bType_p == kEplObdTypUString)    */ )
+    {
+        // variables which are defined as DOMAIN or VSTRING should not point to
+        // trash object, because this trash object contains only 8 bytes. DOMAINS or
+        // STRINGS can be longer.
+        pVarEntry_p->m_pData = NULL;
+        pVarEntry_p->m_Size  = 0;
+    }
+    else
+    {
+        // set address to variable data to trash object
+        // This prevents an access violation if user forgets to call EplObdDefineVar()
+        // for this variable but mappes it in a PDO.
+        pVarEntry_p->m_pData = &abEplObdTrashObject_g[0];
+        pVarEntry_p->m_Size  = ObdSize_p;
+    }
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetDataSize()
+//
+// Description: function to initialize VarEntry dependened on object type
+//
+//              gets the data size of an object
+//              for string objects it returnes the string length
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
+//              uiIndex_p   =   Index
+//              uiSubIndex_p=   Subindex
+//
+// Return:      tEplObdSize
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
+                                                  unsigned int uiIndex_p,
+                                                  unsigned int uiSubIndex_p)
+{
+tEplKernel          Ret;
+tEplObdSize         ObdSize;
+tEplObdEntryPtr     pObdEntry;
+tEplObdSubEntryPtr  pObdSubEntry;
+
+
+    // get pointer to index structure
+    Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
+                                uiIndex_p,
+                                &pObdEntry);
+    if(Ret != kEplSuccessful)
+    {
+        ObdSize = 0;
+        goto Exit;
+    }
+
+    // get pointer to subindex structure
+    Ret = EplObdGetSubindexIntern (pObdEntry,
+                                uiSubIndex_p,
+                                &pObdSubEntry);
+    if(Ret != kEplSuccessful)
+    {
+        ObdSize = 0;
+        goto Exit;
+    }
+
+    // get size
+    ObdSize = EplObdGetDataSizeIntern (pObdSubEntry);
+Exit:
+    return ObdSize;
+}
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetNodeId()
+//
+// Description: function returns nodeid from entry 0x1F93
+//
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR = Instancepointer
+//
+// Return:      unsigned int = Node Id
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
+{
+tEplKernel      Ret;
+tEplObdSize     ObdSize;
+BYTE            bNodeId;
+
+    bNodeId = 0;
+    ObdSize = sizeof(bNodeId);
+    Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
+                            EPL_OBD_NODE_ID_INDEX,
+                            EPL_OBD_NODE_ID_SUBINDEX,
+                            &bNodeId,
+                            &ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        bNodeId = EPL_C_ADR_INVALID;
+        goto Exit;
+    }
+
+Exit:
+    return (unsigned int) bNodeId;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdSetNodeId()
+//
+// Description: function sets nodeid in entry 0x1F93
+//
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
+//              uiNodeId_p  =   Node Id to set
+//              NodeIdType_p=   Type on which way the Node Id was set
+//
+// Return:      tEplKernel = Errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
+                                         unsigned int uiNodeId_p,
+                                         tEplObdNodeIdType NodeIdType_p)
+{
+tEplKernel  Ret;
+tEplObdSize ObdSize;
+BYTE        fHwBool;
+BYTE        bNodeId;
+
+    // check Node Id
+    if(uiNodeId_p == EPL_C_ADR_INVALID)
+    {
+        Ret = kEplInvalidNodeId;
+        goto Exit;
+    }
+    bNodeId = (BYTE)uiNodeId_p;
+    ObdSize = sizeof(BYTE);
+    // write NodeId to OD entry
+    Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
+                            EPL_OBD_NODE_ID_INDEX,
+                            EPL_OBD_NODE_ID_SUBINDEX,
+                            &bNodeId,
+                            ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
+    switch (NodeIdType_p)
+    {
+        // type unknown
+        case kEplObdNodeIdUnknown:
+        {
+            fHwBool = OBD_FALSE;
+            break;
+        }
+
+        case kEplObdNodeIdSoftware:
+        {
+            fHwBool = OBD_FALSE;
+            break;
+        }
+
+        case kEplObdNodeIdHardware:
+        {
+            fHwBool = OBD_TRUE;
+            break;
+        }
+
+        default:
+        {
+            fHwBool = OBD_FALSE;
+        }
+
+    }   // end of switch (NodeIdType_p)
+
+    // write flag
+    ObdSize = sizeof(fHwBool);
+    Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR
+                            EPL_OBD_NODE_ID_INDEX,
+                            EPL_OBD_NODE_ID_HWBOOL_SUBINDEX,
+                            &fHwBool,
+                            ObdSize);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdIsNumerical()
+//
+// Description: function checks if a entry is numerical or not
+//
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
+//              uiIndex_p           = Index
+//              uiSubIndex_p        = Subindex
+//              pfEntryNumerical_p  = pointer to BOOL for returnvalue
+//                                  -> TRUE if entry a numerical value
+//                                  -> FALSE if entry not a numerical value
+//
+// Return:      tEplKernel = Errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        BOOL*         pfEntryNumerical_p)
+{
+tEplKernel          Ret;
+tEplObdEntryPtr     pObdEntry;
+tEplObdSubEntryPtr  pObdSubEntry;
+
+
+    // get pointer to index structure
+    Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
+                                uiIndex_p,
+                                &pObdEntry);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get pointer to subindex structure
+    Ret = EplObdGetSubindexIntern (pObdEntry,
+                                uiSubIndex_p,
+                                &pObdSubEntry);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p);
+
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdReadEntryToLe()
+//
+// Description: The function reads an object entry from the byteoder
+//              of the system to the little endian byteorder for numerical values.
+//              For other types a normal read will be processed. This is usefull for
+//              the PDO and SDO module. The application
+//              can always read the data even if attrib kEplObdAccRead
+//              is not set. The attrib is only checked up for SDO transfer.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       = Index of the OD entry to read
+//              uiSubIndex_p    = Subindex to read
+//              pDstData_p      = pointer to the buffer for data
+//              Offset_p        = offset in data for read access
+//              pSize_p         = IN: Size of the buffer
+//                                OUT: number of readed Bytes
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int        uiIndex_p,
+                                        unsigned int        uiSubIndex_p,
+                                        void *              pDstData_p,
+                                        tEplObdSize *       pSize_p)
+{
+tEplKernel                      Ret;
+tEplObdEntryPtr                 pObdEntry;
+tEplObdSubEntryPtr              pSubEntry;
+tEplObdCbParam  MEM             CbParam;
+void *                          pSrcData;
+tEplObdSize                     ObdSize;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    ASSERT (pDstData_p != NULL);
+    ASSERT (pSize_p != NULL);
+
+    // get address of index and subindex entry
+    Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
+        uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get pointer to object data
+     pSrcData = EplObdGetObjectDataPtrIntern (pSubEntry);
+
+    // check source pointer
+    if (pSrcData == NULL)
+    {
+        Ret = kEplObdReadViolation;
+        goto Exit;
+    }
+
+    //------------------------------------------------------------------------
+    // address of source data to structure of callback parameters
+    // so callback function can change this data before reading
+    CbParam.m_uiIndex   = uiIndex_p;
+    CbParam.m_uiSubIndex= uiSubIndex_p;
+    CbParam.m_pArg      = pSrcData;
+    CbParam.m_ObdEvent  = kEplObdEvPreRead;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry->m_fpCallback, &CbParam);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get size of data and check if application has reserved enough memory
+    ObdSize = EplObdGetDataSizeIntern (pSubEntry);
+    // check if offset given and calc correct number of bytes to read
+    if (*pSize_p < ObdSize)
+    {
+        Ret = kEplObdValueLengthError;
+        goto Exit;
+    }
+
+    // check if numerical type
+    switch(pSubEntry->m_Type)
+    {
+        //-----------------------------------------------
+        // types without ami
+        case kEplObdTypVString:
+        case kEplObdTypOString:
+        case kEplObdTypDomain:
+        default:
+        {
+            // read value from object
+            EPL_MEMCPY (pDstData_p, pSrcData, ObdSize);
+            break;
+        }
+
+        //-----------------------------------------------
+        // numerical type which needs ami-write
+        // 8 bit or smaller values
+        case kEplObdTypBool:
+        case kEplObdTypInt8:
+        case kEplObdTypUInt8:
+        {
+            AmiSetByteToLe(pDstData_p, *((BYTE*)pSrcData));
+            break;
+        }
+
+        // 16 bit values
+        case kEplObdTypInt16:
+        case kEplObdTypUInt16:
+        {
+            AmiSetWordToLe(pDstData_p, *((WORD*)pSrcData));
+            break;
+        }
+
+        // 24 bit values
+        case kEplObdTypInt24:
+        case kEplObdTypUInt24:
+        {
+            AmiSetDword24ToLe(pDstData_p, *((DWORD*)pSrcData));
+            break;
+        }
+
+        // 32 bit values
+        case kEplObdTypInt32:
+        case kEplObdTypUInt32:
+        case kEplObdTypReal32:
+        {
+            AmiSetDwordToLe(pDstData_p, *((DWORD*)pSrcData));
+            break;
+        }
+
+        // 40 bit values
+        case kEplObdTypInt40:
+        case kEplObdTypUInt40:
+        {
+            AmiSetQword40ToLe(pDstData_p, *((QWORD*)pSrcData));
+            break;
+        }
+
+        // 48 bit values
+        case kEplObdTypInt48:
+        case kEplObdTypUInt48:
+        {
+            AmiSetQword48ToLe(pDstData_p, *((QWORD*)pSrcData));
+            break;
+        }
+
+        // 56 bit values
+        case kEplObdTypInt56:
+        case kEplObdTypUInt56:
+        {
+            AmiSetQword56ToLe(pDstData_p, *((QWORD*)pSrcData));
+            break;
+        }
+
+        // 64 bit values
+        case kEplObdTypInt64:
+        case kEplObdTypUInt64:
+        case kEplObdTypReal64:
+        {
+            AmiSetQword64ToLe(pDstData_p, *((QWORD*)pSrcData));
+            break;
+        }
+
+        // time of day
+        case kEplObdTypTimeOfDay:
+        case kEplObdTypTimeDiff:
+        {
+            AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay*)pSrcData));
+            break;
+        }
+
+    }// end of switch(pSubEntry->m_Type)
+
+    *pSize_p = ObdSize;
+
+
+    // write address of destination data to structure of callback parameters
+    // so callback function can change this data after reading
+    CbParam.m_pArg     = pDstData_p;
+    CbParam.m_ObdEvent = kEplObdEvPostRead;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry->m_fpCallback, &CbParam);
+
+Exit:
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdWriteEntryFromLe()
+//
+// Description: Function writes data to an OBD entry from a source with
+//              little endian byteorder to the od with system specuific
+//              byteorder. Not numerical values will only by copied. Strings
+//              are stored with added '\0' character.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        void *        pSrcData_p,
+                                        tEplObdSize   Size_p)
+{
+tEplKernel              Ret;
+tEplObdEntryPtr         pObdEntry;
+tEplObdSubEntryPtr      pSubEntry;
+tEplObdCbParam MEM      CbParam;
+void MEM*               pDstData;
+tEplObdSize             ObdSize;
+QWORD                   qwBuffer;
+void*                   pBuffer = &qwBuffer;
+
+
+    Ret = EplObdWriteEntryPre (EPL_MCO_INSTANCE_PTR_
+                               uiIndex_p,
+                               uiSubIndex_p,
+                               pSrcData_p,
+                               &pDstData,
+                               Size_p,
+                               &pObdEntry,
+                               &pSubEntry,
+                               &CbParam,
+                               &ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+
+    // check if numerical type
+    switch(pSubEntry->m_Type)
+    {
+        //-----------------------------------------------
+        // types without ami
+        default:
+        {   // do nothing, i.e. use the given source pointer
+            pBuffer = pSrcData_p;
+            break;
+        }
+
+        //-----------------------------------------------
+        // numerical type which needs ami-write
+        // 8 bit or smaller values
+        case kEplObdTypBool:
+        case kEplObdTypInt8:
+        case kEplObdTypUInt8:
+        {
+            *((BYTE*)pBuffer) = AmiGetByteFromLe(pSrcData_p);
+            break;
+        }
+
+        // 16 bit values
+        case kEplObdTypInt16:
+        case kEplObdTypUInt16:
+        {
+            *((WORD*)pBuffer) = AmiGetWordFromLe(pSrcData_p);
+            break;
+        }
+
+        // 24 bit values
+        case kEplObdTypInt24:
+        case kEplObdTypUInt24:
+        {
+            *((DWORD*)pBuffer) = AmiGetDword24FromLe(pSrcData_p);
+            break;
+        }
+
+        // 32 bit values
+        case kEplObdTypInt32:
+        case kEplObdTypUInt32:
+        case kEplObdTypReal32:
+        {
+            *((DWORD*)pBuffer) = AmiGetDwordFromLe(pSrcData_p);
+            break;
+        }
+
+        // 40 bit values
+        case kEplObdTypInt40:
+        case kEplObdTypUInt40:
+        {
+            *((QWORD*)pBuffer) = AmiGetQword40FromLe(pSrcData_p);
+            break;
+        }
+
+        // 48 bit values
+        case kEplObdTypInt48:
+        case kEplObdTypUInt48:
+        {
+            *((QWORD*)pBuffer) = AmiGetQword48FromLe(pSrcData_p);
+            break;
+        }
+
+        // 56 bit values
+        case kEplObdTypInt56:
+        case kEplObdTypUInt56:
+        {
+            *((QWORD*)pBuffer) = AmiGetQword56FromLe(pSrcData_p);
+            break;
+        }
+
+        // 64 bit values
+        case kEplObdTypInt64:
+        case kEplObdTypUInt64:
+        case kEplObdTypReal64:
+        {
+            *((QWORD*)pBuffer) = AmiGetQword64FromLe(pSrcData_p);
+            break;
+        }
+
+        // time of day
+        case kEplObdTypTimeOfDay:
+        case kEplObdTypTimeDiff:
+        {
+            AmiGetTimeOfDay(pBuffer, ((tTimeOfDay*)pSrcData_p));
+            break;
+        }
+
+    }// end of switch(pSubEntry->m_Type)
+
+
+    Ret = EplObdWriteEntryPost (EPL_MCO_INSTANCE_PTR_
+                                pObdEntry,
+                                pSubEntry,
+                                &CbParam,
+                                pBuffer,
+                                pDstData,
+                                ObdSize);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+Exit:
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetAccessType()
+//
+// Description: Function returns accesstype of the entry
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pAccessTyp_p    =   pointer to buffer to store accesstype
+//
+// Return:      tEplKernel     =   errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p,
+                                        tEplObdAccess* pAccessTyp_p)
+
+{
+tEplKernel          Ret;
+tEplObdEntryPtr     pObdEntry;
+tEplObdSubEntryPtr  pObdSubEntry;
+
+
+    // get pointer to index structure
+    Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
+                                uiIndex_p,
+                                &pObdEntry);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get pointer to subindex structure
+    Ret = EplObdGetSubindexIntern (pObdEntry,
+                                uiSubIndex_p,
+                                &pObdSubEntry);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get accessType
+    *pAccessTyp_p = pObdSubEntry->m_Access;
+
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdSearchVarEntry()
+//
+// Description: gets variable from OD
+//
+// Parameters:  uiIndex_p       =   index of the var entry to search
+//              uiSubindex_p    =   subindex of var entry to search
+//              ppVarEntry_p    =   pointer to the pointer to the varentry
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplObdSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int            uiIndex_p,
+    unsigned int            uiSubindex_p,
+    tEplObdVarEntry MEM**   ppVarEntry_p)
+{
+
+tEplKernel           Ret;
+tEplObdSubEntryPtr   pSubindexEntry;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    // get address of subindex entry
+    Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
+        uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry);
+    if (Ret == kEplSuccessful)
+    {
+        // get var entry
+        Ret = EplObdGetVarEntry (pSubindexEntry, ppVarEntry_p);
+    }
+
+    return Ret;
+
+}
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+EPL_MCO_DECL_INSTANCE_FCT ()
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdCallObjectCallback()
+//
+// Description: calls callback function of an object or of a variable
+//
+// Parameters:  fpCallback_p
+//              pCbParam_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplObdCallObjectCallback (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdCallback fpCallback_p,
+    tEplObdCbParam MEM* pCbParam_p)
+{
+
+tEplKernel           Ret;
+tEplObdCallback MEM  fpCallback;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    ASSERT (pCbParam_p != NULL);
+
+    Ret = kEplSuccessful;
+
+    // check address of callback function before calling it
+    if (fpCallback_p != NULL)
+    {
+        // KEIL C51 V6.01 has a bug.
+        // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback.
+        fpCallback = fpCallback_p;
+
+        // call callback function for this object
+        Ret = fpCallback (EPL_MCO_INSTANCE_PARAM_IDX_()
+            pCbParam_p);
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetDataSizeIntern()
+//
+// Description: gets the data size of an object
+//              for string objects it returnes the string length
+//
+// Parameters:  pSubIndexEntry_p
+//
+// Return:      tEplObdSize
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplObdSize EplObdGetDataSizeIntern (tEplObdSubEntryPtr pSubIndexEntry_p)
+{
+
+tEplObdSize DataSize;
+void MEM*   pData;
+
+    // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
+    // then the current pointer is always NULL. The function
+    // returns the length of default string.
+    DataSize = EplObdGetObjectSize (pSubIndexEntry_p);
+
+    if (pSubIndexEntry_p->m_Type == kEplObdTypVString)
+    {
+        // The pointer to current value can be received from EplObdGetObjectCurrentPtr()
+        pData = ((void MEM*) EplObdGetObjectCurrentPtr (pSubIndexEntry_p));
+        if (pData != NULL)
+        {
+            DataSize = EplObdGetStrLen ((void *) pData, DataSize, pSubIndexEntry_p->m_Type);
+        }
+
+    }
+
+    return DataSize;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetStrLen()
+//
+// Description: The function calculates the length of string. The '\0'
+//              character is included!!
+//
+// Parameters:  pObjData_p          = pointer to string
+//              ObjLen_p            = max. length of objectr entry
+//              bObjType_p          = object type (VSTRING, ...)
+//
+// Returns:     string length + 1
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplObdSize EplObdGetStrLen (void * pObjData_p,
+                                 tEplObdSize ObjLen_p,
+                                 tEplObdType ObjType_p)
+{
+
+tEplObdSize    StrLen = 0;
+BYTE *  pbString;
+
+    if (pObjData_p == NULL)
+    {
+        goto Exit;
+    }
+
+    //----------------------------------------
+    // Visible String: data format byte
+    if (ObjType_p == kEplObdTypVString)
+    {
+        pbString = pObjData_p;
+
+        for (StrLen = 0; StrLen < ObjLen_p; StrLen++)
+        {
+            if (*pbString == '\0')
+            {
+                StrLen++;
+                break;
+            }
+
+            pbString++;
+        }
+    }
+
+    //----------------------------------------
+    // other string types ...
+
+Exit:
+    return (StrLen);
+
+}
+
+
+
+#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdCheckObjectRange()
+//
+// Description: function to check value range of object data
+//
+// NOTICE: The pointer of data (pData_p) must point out to an even address,
+//         if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is
+//         always realiced because pointer m_pDefault points always to an
+//         array of the SPECIFIED type.
+//
+// Parameters:  pSubindexEntry_p
+//              pData_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplObdCheckObjectRange (
+            tEplObdSubEntryPtr pSubindexEntry_p,
+            void * pData_p)
+{
+
+tEplKernel      Ret;
+void *   pRangeData;
+
+    ASSERTMSG (pSubindexEntry_p != NULL,
+        "EplObdCheckObjectRange(): no address to subindex struct!\n");
+
+    Ret  = kEplSuccessful;
+
+    // check if data range has to be checked
+    if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0)
+    {
+        goto Exit;
+    }
+
+    // get address of default data
+    pRangeData = pSubindexEntry_p->m_pDefault;
+
+    // jump to called object type
+    switch ((tEplObdType) pSubindexEntry_p->m_Type)
+    {
+        // -----------------------------------------------------------------
+        // ObdType kEplObdTypBool will not be checked because there are only
+        // two possible values 0 or 1.
+
+        // -----------------------------------------------------------------
+        // ObdTypes which has to be check up because numerical values
+        case kEplObdTypInt8:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdInteger8 *) pData_p) < *((tEplObdInteger8 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdInteger8 *) pData_p) > *((tEplObdInteger8 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        case kEplObdTypUInt8:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdUnsigned8 *) pData_p) < *((tEplObdUnsigned8 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdUnsigned8*) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdUnsigned8 *) pData_p) > *((tEplObdUnsigned8 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        case kEplObdTypInt16:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdInteger16 *) pData_p) < *((tEplObdInteger16 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdInteger16 *) pData_p) > *((tEplObdInteger16 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        case kEplObdTypUInt16:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdUnsigned16 *) pData_p) < *((tEplObdUnsigned16 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdUnsigned16 *) pData_p) > *((tEplObdUnsigned16 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        case kEplObdTypInt32:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdInteger32 *) pData_p) < *((tEplObdInteger32 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdInteger32 *) pData_p) > *((tEplObdInteger32 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        case kEplObdTypUInt32:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdUnsigned32 *) pData_p) < *((tEplObdUnsigned32 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdUnsigned32 *) pData_p) > *((tEplObdUnsigned32 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        case kEplObdTypReal32:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdReal32 *) pData_p) < *((tEplObdReal32 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdReal32 *) pData_p) > *((tEplObdReal32 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt40:
+        case kEplObdTypInt48:
+        case kEplObdTypInt56:
+        case kEplObdTypInt64:
+
+            // switch to lower limit
+            pRangeData = ((signed QWORD *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((signed QWORD *) pData_p) < *((signed QWORD *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((signed QWORD *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((signed QWORD *) pData_p) > *((signed QWORD *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypUInt40:
+        case kEplObdTypUInt48:
+        case kEplObdTypUInt56:
+        case kEplObdTypUInt64:
+
+            // switch to lower limit
+            pRangeData = ((unsigned QWORD *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((unsigned QWORD *) pData_p) < *((unsigned QWORD *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((unsigned QWORD *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((unsigned QWORD *) pData_p) > *((unsigned QWORD *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypReal64:
+
+            // switch to lower limit
+            pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
+
+            // check if value is to low
+            if (*((tEplObdReal64 *) pData_p) < *((tEplObdReal64 *) pRangeData))
+            {
+                Ret = kEplObdValueTooLow;
+                break;
+            }
+
+            // switch to higher limit
+            pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
+
+            // check if value is to high
+            if (*((tEplObdReal64 *) pData_p) > *((tEplObdReal64 *) pRangeData))
+            {
+                Ret = kEplObdValueTooHigh;
+            }
+
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypTimeOfDay:
+        case kEplObdTypTimeDiff:
+            break;
+
+        // -----------------------------------------------------------------
+        // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because
+        // they have no numerical value.
+        default:
+
+            Ret = kEplObdUnknownObjectType;
+            break;
+    }
+
+Exit:
+
+    return Ret;
+
+}
+#endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdWriteEntryPre()
+//
+// Description: Function prepares write of data to an OBD entry. Strings
+//              are stored with added '\0' character.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplObdWriteEntryPre (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int  uiIndex_p,
+    unsigned int  uiSubIndex_p,
+    void * pSrcData_p,
+    void** ppDstData_p,
+    tEplObdSize   Size_p,
+    tEplObdEntryPtr*        ppObdEntry_p,
+    tEplObdSubEntryPtr*     ppSubEntry_p,
+    tEplObdCbParam MEM*     pCbParam_p,
+    tEplObdSize*  pObdSize_p)
+{
+
+tEplKernel              Ret;
+tEplObdEntryPtr         pObdEntry;
+tEplObdSubEntryPtr      pSubEntry;
+tEplObdAccess           Access;
+void MEM*               pDstData;
+tEplObdSize             ObdSize;
+BOOL                    fEntryNumerical;
+
+#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
+    tEplObdVStringDomain MEM    MemVStringDomain;
+    void MEM*                   pCurrData;
+#endif
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    ASSERT (pSrcData_p != NULL);    // should never be NULL
+
+    //------------------------------------------------------------------------
+    // get address of index and subindex entry
+    Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
+        uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // get pointer to object data
+    pDstData = (void MEM*) EplObdGetObjectDataPtrIntern (pSubEntry);
+
+    Access = (tEplObdAccess) pSubEntry->m_Access;
+
+    // check access for write
+    // access violation if adress to current value is NULL
+    if ( ((Access & kEplObdAccConst) != 0) ||
+         (pDstData == NULL) )
+    {
+        Ret = kEplObdAccessViolation;
+        goto Exit;
+    }
+
+    //------------------------------------------------------------------------
+    // get size of object
+    // -as ObdSize = ObdGetObjectSize (pSubEntry);
+
+    //------------------------------------------------------------------------
+    // To use the same callback function for ObdWriteEntry as well as for
+    // an SDO download call at first (kEplObdEvPre...) the callback function
+    // with the argument pointer to object size.
+    pCbParam_p->m_uiIndex    = uiIndex_p;
+    pCbParam_p->m_uiSubIndex = uiSubIndex_p;
+
+    // Because object size and object pointer are
+    // adapted by user callback function, re-read
+    // this values.
+    ObdSize = EplObdGetObjectSize (pSubEntry);
+    pDstData = (void MEM*) EplObdGetObjectDataPtrIntern (pSubEntry);
+
+    // 09-dec-2004 r.d.:
+    //      Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
+    //      for String or Domain which lets called module directly change
+    //      the data pointer or size. This prevents a recursive call to
+    //      the callback function if it calls EplObdGetEntry().
+    #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
+    if ( (pSubEntry->m_Type == kEplObdTypVString) ||
+         (pSubEntry->m_Type == kEplObdTypDomain)  ||
+         (pSubEntry->m_Type == kEplObdTypOString))
+    {
+        if (pSubEntry->m_Type == kEplObdTypVString)
+        {
+            // reserve one byte for 0-termination
+            // -as ObdSize -= 1;
+            Size_p += 1;
+        }
+
+        // fill out new arg-struct
+        MemVStringDomain.m_DownloadSize = Size_p;
+        MemVStringDomain.m_ObjSize      = ObdSize;
+        MemVStringDomain.m_pData        = pDstData;
+
+        pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain;
+        pCbParam_p->m_pArg     = &MemVStringDomain;
+        //  call user callback
+        Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+                pObdEntry->m_fpCallback, pCbParam_p);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        // write back new settings
+        pCurrData = pSubEntry->m_pCurrent;
+        if ((pSubEntry->m_Type == kEplObdTypVString)
+            ||(pSubEntry->m_Type ==  kEplObdTypOString))
+        {
+            ((tEplObdVString MEM*) pCurrData)->m_Size    = MemVStringDomain.m_ObjSize;
+            ((tEplObdVString MEM*) pCurrData)->m_pString = MemVStringDomain.m_pData;
+        }
+        else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
+        {
+            ((tEplObdVarEntry MEM*) pCurrData)->m_Size  = MemVStringDomain.m_ObjSize;
+            ((tEplObdVarEntry MEM*) pCurrData)->m_pData = (void MEM*) MemVStringDomain.m_pData;
+        }
+
+        // Because object size and object pointer are
+        // adapted by user callback function, re-read
+        // this values.
+        ObdSize  = MemVStringDomain.m_ObjSize;
+        pDstData = (void MEM*) MemVStringDomain.m_pData;
+    }
+    #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
+
+    // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size
+    // -as 16.11.04 CbParam.m_pArg     = &ObdSize;
+    // 09-dec-2004 r.d.: CbParam.m_pArg     = &Size_p;
+    pCbParam_p->m_pArg     = &ObdSize;
+    pCbParam_p->m_ObdEvent = kEplObdEvInitWrite;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry->m_fpCallback, pCbParam_p);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    if (Size_p > ObdSize)
+    {
+        Ret = kEplObdValueLengthError;
+        goto Exit;
+    }
+
+    if (pSubEntry->m_Type == kEplObdTypVString)
+    {
+        if (((char MEM*) pSrcData_p)[Size_p - 1] == '\0')
+        {   // last byte of source string contains null character
+
+            // reserve one byte in destination for 0-termination
+            Size_p  -= 1;
+        }
+        else if (Size_p >= ObdSize)
+        {   // source string is not 0-terminated
+            // and destination buffer is too short
+            Ret = kEplObdValueLengthError;
+            goto Exit;
+        }
+    }
+
+    Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    if ((fEntryNumerical != FALSE)
+        && (Size_p != ObdSize))
+    {
+        // type is numerical, therefor size has to fit, but it does not.
+        Ret = kEplObdValueLengthError;
+        goto Exit;
+    }
+
+    // use given size, because non-numerical objects can be written with shorter values
+    ObdSize = Size_p;
+
+    // set output parameters
+    *pObdSize_p = ObdSize;
+    *ppObdEntry_p = pObdEntry;
+    *ppSubEntry_p = pSubEntry;
+    *ppDstData_p = pDstData;
+
+    // all checks are done
+    // the caller may now convert the numerial source value to platform byte order in a temporary buffer
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdWriteEntryPost()
+//
+// Description: Function finishes write of data to an OBD entry. Strings
+//              are stored with added '\0' character.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplObdWriteEntryPost (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdEntryPtr         pObdEntry_p,
+    tEplObdSubEntryPtr      pSubEntry_p,
+    tEplObdCbParam MEM*     pCbParam_p,
+    void * pSrcData_p,
+    void * pDstData_p,
+    tEplObdSize   ObdSize_p)
+{
+
+tEplKernel              Ret;
+
+
+    // caller converted the source value to platform byte order
+    // now the range of the value may be checked
+
+    #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
+    {
+        // check data range
+        Ret = EplObdCheckObjectRange (pSubEntry_p, pSrcData_p);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+    }
+    #endif
+
+    // now call user callback function to check value
+    // write address of source data to structure of callback parameters
+    // so callback function can check this data
+    pCbParam_p->m_pArg     = pSrcData_p;
+    pCbParam_p->m_ObdEvent = kEplObdEvPreWrite;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry_p->m_fpCallback, pCbParam_p);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // copy object data to OBD
+    EPL_MEMCPY (pDstData_p, pSrcData_p, ObdSize_p);
+
+    // terminate string with 0
+    if (pSubEntry_p->m_Type == kEplObdTypVString)
+    {
+        ((char MEM*) pDstData_p)[ObdSize_p] = '\0';
+    }
+
+    // write address of destination to structure of callback parameters
+    // so callback function can change data subsequently
+    pCbParam_p->m_pArg     = pDstData_p;
+    pCbParam_p->m_ObdEvent = kEplObdEvPostWrite;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry_p->m_fpCallback, pCbParam_p);
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetObjectSize()
+//
+// Description: function to get size of object
+//              The function determines if an object type an fixed data type (BYTE, WORD, ...)
+//              or non fixed object (string, domain). This information is used to decide
+//              if download data are stored temporary or not. For objects with fixed data length
+//              and types a value range checking can process.
+//              For strings the function returns the whole object size not the
+//              length of string.
+//
+// Parameters:  pSubIndexEntry_p
+//
+// Return:      tEplObdSize
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplObdSize EplObdGetObjectSize (tEplObdSubEntryPtr pSubIndexEntry_p)
+{
+
+tEplObdSize DataSize = 0;
+void * pData;
+
+    switch (pSubIndexEntry_p->m_Type)
+    {
+        // -----------------------------------------------------------------
+        case kEplObdTypBool:
+
+            DataSize = 1;
+            break;
+
+        // -----------------------------------------------------------------
+        // ObdTypes which has to be check because numerical values
+        case kEplObdTypInt8:
+            DataSize = sizeof (tEplObdInteger8);
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypUInt8:
+            DataSize = sizeof (tEplObdUnsigned8);
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt16:
+            DataSize = sizeof (tEplObdInteger16);
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypUInt16:
+            DataSize = sizeof (tEplObdUnsigned16);
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt32:
+            DataSize = sizeof (tEplObdInteger32);
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypUInt32:
+            DataSize = sizeof (tEplObdUnsigned32);
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypReal32:
+            DataSize = sizeof (tEplObdReal32);
+            break;
+
+        // -----------------------------------------------------------------
+        // ObdTypes which has to be not checked because not NUM values
+        case kEplObdTypDomain:
+
+            pData = (void *) pSubIndexEntry_p->m_pCurrent;
+            if ((void MEM*) pData != (void MEM*) NULL)
+            {
+                DataSize = ((tEplObdVarEntry MEM*) pData)->m_Size;
+            }
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypVString:
+        //case kEplObdTypUString:
+
+            // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
+            // then the current pointer is always NULL. The function
+            // returns the length of default string.
+            pData = (void *) pSubIndexEntry_p->m_pCurrent;
+            if ((void MEM*) pData != (void MEM*) NULL)
+            {
+                // The max. size of strings defined by STRING-Macro is stored in
+                // tEplObdVString of current value.
+                // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
+                DataSize = ((tEplObdVString MEM*) pData)->m_Size;
+            }
+            else
+            {
+                // The current position is not decleared. The string
+                // is located in ROM, therefor use default pointer.
+                pData = (void *) pSubIndexEntry_p->m_pDefault;
+                if ((CONST void ROM*) pData != (CONST void ROM*) NULL)
+                {
+                   // The max. size of strings defined by STRING-Macro is stored in
+                   // tEplObdVString of default value.
+                   DataSize = ((CONST tEplObdVString ROM*) pData)->m_Size;
+                }
+            }
+
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypOString:
+
+            pData = (void *) pSubIndexEntry_p->m_pCurrent;
+            if ((void MEM*) pData != (void MEM*) NULL)
+            {
+                // The max. size of strings defined by STRING-Macro is stored in
+                // tEplObdVString of current value.
+                // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
+                DataSize = ((tEplObdOString MEM*) pData)->m_Size;
+            }
+            else
+            {
+                // The current position is not decleared. The string
+                // is located in ROM, therefor use default pointer.
+                pData = (void *) pSubIndexEntry_p->m_pDefault;
+                if ((CONST void ROM*) pData != (CONST void ROM*) NULL)
+                {
+                   // The max. size of strings defined by STRING-Macro is stored in
+                   // tEplObdVString of default value.
+                   DataSize = ((CONST tEplObdOString ROM*) pData)->m_Size;
+                }
+            }
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt24:
+        case kEplObdTypUInt24:
+
+            DataSize = 3;
+            break;
+
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt40:
+        case kEplObdTypUInt40:
+
+            DataSize = 5;
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt48:
+        case kEplObdTypUInt48:
+
+            DataSize = 6;
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt56:
+        case kEplObdTypUInt56:
+
+            DataSize = 7;
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypInt64:
+        case kEplObdTypUInt64:
+        case kEplObdTypReal64:
+
+            DataSize = 8;
+            break;
+
+        // -----------------------------------------------------------------
+        case kEplObdTypTimeOfDay:
+        case kEplObdTypTimeDiff:
+
+            DataSize = 6;
+            break;
+
+        // -----------------------------------------------------------------
+        default:
+            break;
+    }
+
+    return DataSize;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetObjectDefaultPtr()
+//
+// Description: function to get the default pointer (type specific)
+//
+// Parameters:  pSubIndexEntry_p    = pointer to subindex structure
+//
+// Returns:     (void *)   = pointer to default value
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static void * EplObdGetObjectDefaultPtr (tEplObdSubEntryPtr pSubIndexEntry_p)
+{
+
+void *   pDefault;
+tEplObdType     Type;
+
+    ASSERTMSG (pSubIndexEntry_p != NULL, "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n");
+
+    // get address to default data from default pointer
+    pDefault = pSubIndexEntry_p->m_pDefault;
+    if (pDefault != NULL)
+    {
+        // there are some special types, whose default pointer always is NULL or has to get from other structure
+        // get type from subindex structure
+        Type = pSubIndexEntry_p->m_Type;
+
+        // check if object type is a string value
+        if ((Type == kEplObdTypVString) /* ||
+            (Type == kEplObdTypUString) */ )
+        {
+
+            // EPL_OBD_SUBINDEX_RAM_VSTRING
+            //    tEplObdSize         m_Size;       --> size of default string
+            //    char *    m_pDefString; --> pointer to  default string
+            //    char *    m_pString;    --> pointer to string in RAM
+            //
+            pDefault = (void *) ((tEplObdVString *) pDefault)->m_pString;
+        }
+        else if(Type == kEplObdTypOString)
+        {
+             pDefault = (void *) ((tEplObdOString *) pDefault)->m_pString;
+        }
+    }
+
+    return pDefault;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetVarEntry()
+//
+// Description: gets a variable entry of an object
+//
+// Parameters:  pSubindexEntry_p
+//              ppVarEntry_p
+//
+// Return:      tCopKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplObdGetVarEntry (
+    tEplObdSubEntryPtr    pSubindexEntry_p,
+    tEplObdVarEntry MEM** ppVarEntry_p)
+{
+
+tEplKernel Ret = kEplObdVarEntryNotExist;
+
+    ASSERT (ppVarEntry_p != NULL);   // is not allowed to be NULL
+    ASSERT (pSubindexEntry_p != NULL);
+
+    // check VAR-Flag - only this object points to variables
+    if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0)
+    {
+        // check if object is an array
+        if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0)
+        {
+            *ppVarEntry_p = &((tEplObdVarEntry MEM*) pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
+        }
+        else
+        {
+            *ppVarEntry_p = (tEplObdVarEntry MEM*) pSubindexEntry_p->m_pCurrent;
+        }
+
+        Ret = kEplSuccessful;
+    }
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetEntry()
+//
+// Description: gets a index entry from OD
+//
+// Parameters:  uiIndex_p       =   Index number
+//              uiSubindex_p    =   Subindex number
+//              ppObdEntry_p    =   pointer to the pointer to the entry
+//              ppObdSubEntry_p =   pointer to the pointer to the subentry
+//
+// Return:      tEplKernel
+
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel  EplObdGetEntry (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int             uiIndex_p,
+    unsigned int             uiSubindex_p,
+    tEplObdEntryPtr*         ppObdEntry_p,
+    tEplObdSubEntryPtr*      ppObdSubEntry_p)
+{
+
+tEplObdEntryPtr         pObdEntry;
+tEplObdCbParam MEM      CbParam;
+tEplKernel              Ret;
+
+    // check for all API function if instance is valid
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    //------------------------------------------------------------------------
+    // get address of entry of index
+    Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), uiIndex_p, &pObdEntry);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    //------------------------------------------------------------------------
+    // get address of entry of subindex
+    Ret = EplObdGetSubindexIntern (pObdEntry, uiSubindex_p, ppObdSubEntry_p);
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    //------------------------------------------------------------------------
+    // call callback function to inform user/stack that an object will be searched
+    // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist
+    CbParam.m_uiIndex    = uiIndex_p;
+    CbParam.m_uiSubIndex = uiSubindex_p;
+    CbParam.m_pArg       = NULL;
+    CbParam.m_ObdEvent   = kEplObdEvCheckExist;
+    Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
+        pObdEntry->m_fpCallback, &CbParam);
+    if (Ret != kEplSuccessful)
+    {
+        Ret = kEplObdIndexNotExist;
+        goto Exit;
+    }
+
+    //------------------------------------------------------------------------
+    // it is allowed to set ppObdEntry_p to NULL
+    // if so, no address will be written to calling function
+    if (ppObdEntry_p != NULL)
+    {
+        *ppObdEntry_p = pObdEntry;
+    }
+
+Exit:
+
+    return Ret;
+
+}
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetObjectCurrentPtr()
+//
+// Description: function to get Current pointer (type specific)
+//
+// Parameters:  pSubIndexEntry_p
+//
+// Return:      void MEM*
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static void MEM* EplObdGetObjectCurrentPtr (tEplObdSubEntryPtr pSubIndexEntry_p)
+{
+
+void MEM*       pData;
+unsigned int    uiArrayIndex;
+tEplObdSize     Size;
+
+    pData = pSubIndexEntry_p->m_pCurrent;
+
+    // check if constant object
+    if (pData != NULL)
+    {
+        // check if object is an array
+        if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0)
+        {
+            // calculate correct data pointer
+            uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1;
+            if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0)
+            {
+                Size = sizeof (tEplObdVarEntry);
+            }
+            else
+            {
+                Size = EplObdGetObjectSize (pSubIndexEntry_p);
+            }
+            pData = ((BYTE MEM*) pData) + (Size * uiArrayIndex);
+        }
+
+        // check if VarEntry
+        if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0)
+        {
+            // The data pointer is stored in VarEntry->pData
+            pData = ((tEplObdVarEntry MEM*) pData)->m_pData;
+        }
+
+        // the default pointer is stored for strings in tEplObdVString
+        else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* ||
+            (pSubIndexEntry_p->m_Type == kEplObdTypUString)    */ )
+        {
+            pData = (void MEM*) ((tEplObdVString MEM*) pData)->m_pString;
+        }
+        else if (pSubIndexEntry_p->m_Type == kEplObdTypOString)
+        {
+            pData = (void MEM*) ((tEplObdOString MEM*) pData)->m_pString;
+        }
+    }
+
+    return pData;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetIndexIntern()
+//
+// Description: gets a index entry from OD
+//
+// Parameters:  pInitParam_p
+//              uiIndex_p
+//              ppObdEntry_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplObdGetIndexIntern (
+                        tEplObdInitParam MEM*    pInitParam_p,
+                        unsigned int             uiIndex_p,
+                        tEplObdEntryPtr*         ppObdEntry_p)
+{
+
+tEplObdEntryPtr pObdEntry;
+tEplKernel      Ret;
+unsigned int    uiIndex;
+
+#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+
+unsigned int  nLoop;
+
+    // if user OD is used then objekts also has to be searched in user OD
+    // there is less code need if we do this in a loop
+    nLoop = 2;
+
+#endif
+
+    ASSERTMSG (ppObdEntry_p != NULL, "EplObdGetIndexIntern(): pointer to index entry is NULL!\n");
+
+    Ret = kEplObdIndexNotExist;
+
+    // get start address of OD part
+    // start address depends on object index because
+    // object dictionary is divided in 3 parts
+    if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000))
+    {
+        pObdEntry = pInitParam_p->m_pPart;
+    }
+    else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000))
+    {
+        pObdEntry = pInitParam_p->m_pManufacturerPart;
+    }
+
+    // index range 0xA000 to 0xFFFF is reserved for DSP-405
+    // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3.
+    // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE.
+    // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000...
+    // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE.
+
+#if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE)
+    else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF))
+#else
+    else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF))
+#endif
+    {
+        pObdEntry = pInitParam_p->m_pDevicePart;
+    }
+
+
+#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+
+    // if index does not match in static OD then index only has to be searched in user OD
+    else
+    {
+        // begin from first entry of user OD part
+        pObdEntry = pInitParam_p->m_pUserPart;
+
+        // no user OD is available
+        if (pObdEntry == NULL)
+        {
+            goto Exit;
+        }
+
+        // loop must only run once
+        nLoop = 1;
+    }
+
+    do
+    {
+
+#else
+
+        // no user OD is available
+        // so other object can be found in OD
+        else
+        {
+            Ret = kEplObdIllegalPart;
+            goto Exit;
+        }
+
+#endif
+
+        // note:
+        // The end of Index table is marked with m_uiIndex = 0xFFFF.
+        // If this function will be called with wIndex_p = 0xFFFF, entry
+        // should not be found. Therefor it is important to use
+        // while{} instead of do{}while !!!
+
+        // get first index of index table
+        uiIndex = pObdEntry->m_uiIndex;
+
+        // search Index in OD part
+        while (uiIndex != EPL_OBD_TABLE_INDEX_END)
+        {
+            // go to the end of this function if index is found
+            if (uiIndex_p == uiIndex)
+            {
+                // write address of OD entry to calling function
+                *ppObdEntry_p = pObdEntry;
+                Ret = kEplSuccessful;
+                goto Exit;
+            }
+
+            // objects are sorted in OD
+            // if the current index in OD is greater than the index which is to search then break loop
+            // in this case user OD has to be search too
+            if (uiIndex_p < uiIndex)
+            {
+                break;
+            }
+
+            // next entry in index table
+            pObdEntry++;
+
+            // get next index of index table
+            uiIndex = pObdEntry->m_uiIndex;
+        }
+
+#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+
+        // begin from first entry of user OD part
+        pObdEntry = pInitParam_p->m_pUserPart;
+
+        // no user OD is available
+        if (pObdEntry == NULL)
+        {
+            goto Exit;
+        }
+
+        // switch next loop for user OD
+        nLoop--;
+
+    } while (nLoop > 0);
+
+#endif
+
+    // in this line Index was not found
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetSubindexIntern()
+//
+// Description: gets a subindex entry from a index entry
+//
+// Parameters:  pObdEntry_p
+//              bSubIndex_p
+//              ppObdSubEntry_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplObdGetSubindexIntern (
+    tEplObdEntryPtr           pObdEntry_p,
+    unsigned int              uiSubIndex_p,
+    tEplObdSubEntryPtr*       ppObdSubEntry_p)
+{
+
+tEplObdSubEntryPtr pSubEntry;
+unsigned int       nSubIndexCount;
+tEplKernel         Ret;
+
+    ASSERTMSG (pObdEntry_p != NULL, "EplObdGetSubindexIntern(): pointer to index is NULL!\n");
+    ASSERTMSG (ppObdSubEntry_p != NULL, "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n");
+
+    Ret = kEplObdSubindexNotExist;
+
+    // get start address of subindex table and count of subindices
+    pSubEntry     = pObdEntry_p->m_pSubIndex;
+    nSubIndexCount =  pObdEntry_p->m_uiCount;
+    ASSERTMSG ((pSubEntry != NULL) && (nSubIndexCount > 0),
+        "ObdGetSubindexIntern(): invalid subindex table within index table!\n");   // should never be NULL
+
+    // search subindex in subindex table
+    while (nSubIndexCount > 0)
+    {
+        // check if array is found
+        if ((pSubEntry->m_Access & kEplObdAccArray) != 0)
+        {
+            // check if subindex is in range
+            if (uiSubIndex_p < pObdEntry_p->m_uiCount)
+            {
+                // update subindex number (subindex entry of an array is always in RAM !!!)
+                pSubEntry->m_uiSubIndex = uiSubIndex_p;
+                *ppObdSubEntry_p = pSubEntry;
+                Ret = kEplSuccessful;
+                goto Exit;
+            }
+        }
+
+        // go to the end of this function if subindex is found
+        else if (uiSubIndex_p == pSubEntry->m_uiSubIndex)
+        {
+            *ppObdSubEntry_p = pSubEntry;
+            Ret = kEplSuccessful;
+            goto Exit;
+        }
+
+        // objects are sorted in OD
+        // if the current subindex in OD is greater than the subindex which is to search then break loop
+        // in this case user OD has to be search too
+        if (uiSubIndex_p < pSubEntry->m_uiSubIndex)
+        {
+            break;
+        }
+
+        pSubEntry++;
+        nSubIndexCount--;
+    }
+
+    // in this line SubIndex was not fount
+
+Exit:
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdSetStoreLoadObjCallback()
+//
+// Description: function set address to callbackfunction for command Store and Load
+//
+// Parameters:  fpCallback_p
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
+EPLDLLEXPORT tEplKernel PUBLIC EplObdSetStoreLoadObjCallback (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdStoreLoadObjCallback fpCallback_p)
+{
+
+    EPL_MCO_CHECK_INSTANCE_STATE ();
+
+    // set new address of callback function
+    EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) = fpCallback_p;
+
+    return kEplSuccessful;
+
+}
+#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdAccessOdPartIntern()
+//
+// Description: runs through OD and executes a job
+//
+// Parameters:  CurrentOdPart_p
+//              pObdEnty_p
+//              Direction_p     = what is to do (load values from flash or EEPROM, store, ...)
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplObdAccessOdPartIntern (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdPart     CurrentOdPart_p,
+    tEplObdEntryPtr pObdEnty_p,
+    tEplObdDir      Direction_p)
+{
+
+tEplObdSubEntryPtr          pSubIndex;
+unsigned int                nSubIndexCount;
+tEplObdAccess               Access;
+void MEM*                   pDstData;
+void *               pDefault;
+tEplObdSize                 ObjSize;
+tEplKernel                  Ret;
+tEplObdCbStoreParam MEM     CbStore;
+tEplObdVarEntry MEM*        pVarEntry;
+
+    ASSERT (pObdEnty_p != NULL);
+
+    Ret = kEplSuccessful;
+
+    // prepare structure for STORE RESTORE callback function
+    CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
+    CbStore.m_pData          = NULL;
+    CbStore.m_ObjSize        = 0;
+
+    // command of first action depends on direction to access
+    #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
+    if (Direction_p == kEplObdDirLoad)
+    {
+        CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
+
+        // call callback function for previous command
+        Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
+            &CbStore);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        // set command for index and subindex loop
+        CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
+    }
+    else if (Direction_p == kEplObdDirStore)
+    {
+        CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
+
+        // call callback function for previous command
+        Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
+            &CbStore);
+        if (Ret != kEplSuccessful)
+        {
+            goto Exit;
+        }
+
+        // set command for index and subindex loop
+        CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
+    }
+    #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
+
+    // we should not restore the OD values here
+    // the next NMT command "Reset Node" or "Reset Communication" resets the OD data
+    if (Direction_p != kEplObdDirRestore)
+    {
+        // walk through OD part till end is found
+        while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END)
+        {
+            // get address to subindex table and count of subindices
+            pSubIndex     = pObdEnty_p->m_pSubIndex;
+            nSubIndexCount = pObdEnty_p->m_uiCount;
+            ASSERT ((pSubIndex != NULL) && (nSubIndexCount > 0));    // should never be NULL
+
+            // walk through subindex table till all subinices were restored
+            while (nSubIndexCount != 0)
+            {
+                Access = (tEplObdAccess) pSubIndex->m_Access;
+
+                // get pointer to current and default data
+                pDefault = EplObdGetObjectDefaultPtr (pSubIndex);
+                pDstData = EplObdGetObjectCurrentPtr (pSubIndex);
+
+                // NOTE (for kEplObdTypVString):
+                //      The function returnes the max. number of bytes for a
+                //      current string.
+                //      r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit).
+                ObjSize  = EplObdGetObjectSize (pSubIndex);
+
+                // switch direction of OD access
+                switch (Direction_p)
+                {
+                    // --------------------------------------------------------------------------
+                    // VarEntry structures has to be initialized
+                    case kEplObdDirInit:
+
+                        // If VAR-Flag is set, m_pCurrent means not address of data
+                        // but address of tEplObdVarEntry. Address of data has to be get from
+                        // this structure.
+                        if ((Access & kEplObdAccVar) != 0)
+                        {
+                            EplObdGetVarEntry (pSubIndex, &pVarEntry);
+                            EplObdInitVarEntry (pVarEntry, pSubIndex->m_Type, ObjSize);
+/*
+                            if ((Access & kEplObdAccArray) == 0)
+                            {
+                                EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize);
+                            }
+                            else
+                            {
+                                EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
+                                    pSubIndex->m_Type, ObjSize);
+                            }
+*/
+                            // at this time no application variable is defined !!!
+                            // therefore data can not be copied.
+                            break;
+                        }
+                        else if (pSubIndex->m_Type == kEplObdTypVString)
+                        {
+                            // If pointer m_pCurrent is not equal to NULL then the
+                            // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current
+                            // pointer points to struct tEplObdVString located in MEM.
+                            // The element size includes the max. number of
+                            // bytes. The element m_pString includes the pointer
+                            // to string in MEM. The memory location of default string
+                            // must be copied to memory location of current string.
+
+                            pDstData = pSubIndex->m_pCurrent;
+                            if (pDstData != NULL)
+                            {
+                                // 08-dec-2004: code optimization !!!
+                                //              entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString
+                                //              and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+                                //              twice. thats not necessary!
+
+                                // For copying data we have to set the destination pointer to the real RAM string. This
+                                // pointer to RAM string is located in default string info structure. (translated r.d.)
+                                pDstData = (void MEM*) ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString;
+                                ObjSize  = ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size;
+
+
+                                ((tEplObdVString MEM*) pSubIndex->m_pCurrent)->m_pString = pDstData;
+                                ((tEplObdVString MEM*) pSubIndex->m_pCurrent)->m_Size    = ObjSize;
+                            }
+
+                        }
+                        else if(pSubIndex->m_Type == kEplObdTypOString)
+                        {
+                            pDstData = pSubIndex->m_pCurrent;
+                            if (pDstData != NULL)
+                            {
+                                // 08-dec-2004: code optimization !!!
+                                //              entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString
+                                //              and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+                                //              twice. thats not necessary!
+
+                                // For copying data we have to set the destination pointer to the real RAM string. This
+                                // pointer to RAM string is located in default string info structure. (translated r.d.)
+                                pDstData = (void MEM*) ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString;
+                                ObjSize  = ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size;
+
+
+                                ((tEplObdOString MEM*) pSubIndex->m_pCurrent)->m_pString = pDstData;
+                                ((tEplObdOString MEM*) pSubIndex->m_pCurrent)->m_Size    = ObjSize;
+                            }
+
+                        }
+
+
+                        // no break !! because copy of data has to done too.
+
+                    // --------------------------------------------------------------------------
+                    // all objects has to be restored with default values
+                    case kEplObdDirRestore:
+
+                        // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad
+                        //                   is replaced to function ObdCopyObjectData() with a new parameter.
+
+
+                        // restore object data for init phase
+                        EplObdCopyObjectData (pDstData, pDefault, ObjSize, pSubIndex->m_Type);
+                        break;
+
+                    // --------------------------------------------------------------------------
+                    // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file
+                    case kEplObdDirLoad:
+
+                        // restore object data for init phase
+                        EplObdCopyObjectData (pDstData, pDefault, ObjSize, pSubIndex->m_Type);
+
+                        // no break !! because callback function has to be called too.
+
+                    // --------------------------------------------------------------------------
+                    // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file
+                    case kEplObdDirStore:
+
+                        // when attribute kEplObdAccStore is set, then call callback function
+                        #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
+                        if ((Access & kEplObdAccStore) != 0)
+                        {
+                            // fill out data pointer and size of data
+                            CbStore.m_pData    = pDstData;
+                            CbStore.m_ObjSize  = ObjSize;
+
+                            // call callback function for read or write object
+                            Ret = ObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
+                                &CbStore);
+                            if (Ret != kEplSuccessful)
+                            {
+                                goto Exit;
+                            }
+                        }
+                        #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
+                        break;
+
+
+                    // --------------------------------------------------------------------------
+                    // if OD Builder key has to be checked no access to subindex and data should be made
+                    case kEplObdDirOBKCheck:
+
+                        // no break !! because we want to break the second loop too.
+
+
+                    // --------------------------------------------------------------------------
+                    // unknown Direction
+                    default:
+
+                        // so we can break the second loop earler
+                        nSubIndexCount = 1;
+                        break;
+                }
+
+                nSubIndexCount--;
+
+                // next subindex entry
+                if ((Access & kEplObdAccArray) == 0)
+                {
+                    pSubIndex++;
+                    if ((nSubIndexCount > 0)
+                        && ((pSubIndex->m_Access & kEplObdAccArray) != 0))
+                    {
+                        // next subindex points to an array
+                        // reset subindex number
+                        pSubIndex->m_uiSubIndex = 1;
+                    }
+                }
+                else
+                {
+                    if (nSubIndexCount > 0)
+                    {
+                        // next subindex points to an array
+                        // increment subindex number
+                        pSubIndex->m_uiSubIndex++;
+                    }
+                }
+            }
+
+            // next index entry
+            pObdEnty_p++;
+        }
+    }
+
+    // -----------------------------------------------------------------------------------------
+    // command of last action depends on direction to access
+    if (Direction_p == kEplObdDirOBKCheck)
+    {
+
+        goto Exit;
+    }
+    #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
+    else
+    {
+        if (Direction_p == kEplObdDirLoad)
+        {
+            CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
+        }
+        else if (Direction_p == kEplObdDirStore)
+        {
+            CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
+        }
+        else if (Direction_p == kEplObdDirRestore)
+        {
+            CbStore.m_bCommand = (BYTE) kEplObdCommClear;
+        }
+        else
+        {
+            goto Exit;
+        }
+
+        // call callback function for last command
+        Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
+            &CbStore);
+    }
+    #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
+
+//    goto Exit;
+
+Exit:
+
+    return Ret;
+
+}
+
+
+// ----------------------------------------------------------------------------
+// Function:    EplObdCopyObjectData()
+//
+// Description: checks pointers to object data and copy them from source to destination
+//
+// Parameters:  pDstData_p              = destination pointer
+//              pSrcData_p              = source pointer
+//              ObjSize_p               = size of object
+//              ObjType_p               =
+//
+// Returns:     tEplKernel              = error code
+// ----------------------------------------------------------------------------
+
+static void EplObdCopyObjectData (
+            void MEM*           pDstData_p,
+            void *              pSrcData_p,
+            tEplObdSize         ObjSize_p,
+            tEplObdType         ObjType_p)
+{
+
+
+tEplObdSize StrSize = 0;
+
+
+    // it is allowed to set default and current address to NULL (nothing to copy)
+    if (pDstData_p != NULL)
+    {
+
+        if (ObjType_p == kEplObdTypVString)
+        {
+            // The function calculates the really number of characters of string. The
+            // object entry size can be bigger as string size of default string.
+            // The '\0'-termination is included. A string with no characters has a
+            // size of 1.
+            StrSize = EplObdGetStrLen ((void *) pSrcData_p, ObjSize_p, kEplObdTypVString);
+
+            // If the string length is greater than or equal to the entry size in OD then only copy
+            // entry size - 1 and always set the '\0'-termination.
+            if (StrSize >= ObjSize_p)
+            {
+                StrSize = ObjSize_p - 1;
+            }
+        }
+
+        if (pSrcData_p != NULL)
+        {
+            // copy data
+            EPL_MEMCPY (pDstData_p, pSrcData_p, ObjSize_p);
+
+            if (ObjType_p == kEplObdTypVString)
+            {
+                ((char MEM*) pDstData_p)[StrSize] = '\0';
+            }
+        }
+    }
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdIsNumericalIntern()
+//
+// Description: function checks if a entry is numerical or not
+//
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
+//              uiIndex_p           = Index
+//              uiSubIndex_p        = Subindex
+//              pfEntryNumerical_p  = pointer to BOOL for returnvalue
+//                                  -> TRUE if entry a numerical value
+//                                  -> FALSE if entry not a numerical value
+//
+// Return:      tEplKernel = Errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
+                                        BOOL*         pfEntryNumerical_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+
+
+    // get Type
+    if((pObdSubEntry_p->m_Type == kEplObdTypVString)
+        || (pObdSubEntry_p->m_Type == kEplObdTypOString)
+        || (pObdSubEntry_p->m_Type == kEplObdTypDomain))
+    {   // not numerical types
+        *pfEntryNumerical_p = FALSE;
+    }
+    else
+    {   // numerical types
+        *pfEntryNumerical_p = TRUE;
+    }
+
+    return Ret;
+
+}
+
+
+// -------------------------------------------------------------------------
+// function to classify object type (fixed/non fixed)
+// -------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// Function:    EplObdCallStoreCallback()
+//
+// Description: checks address to callback function and calles it when unequal
+//              to NULL
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer)
+//              pCbStoreParam_p        = address to callback parameters
+//
+// Returns:     tEplKernel             = error code
+// ----------------------------------------------------------------------------
+#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
+static tEplKernel EplObdCallStoreCallback (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdCbStoreParam MEM* pCbStoreParam_p)
+{
+
+tEplKernel Ret = kEplSuccessful;
+
+    ASSERT (pCbStoreParam_p != NULL);
+
+    // check if function pointer is NULL - if so, no callback should be called
+    if (EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) != NULL)
+    {
+        Ret = EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) (EPL_MCO_INSTANCE_PARAM_IDX_()
+            pCbStoreParam_p);
+    }
+
+    return Ret;
+
+}
+#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdGetObjectDataPtrIntern()
+//
+// Description: Function gets the data pointer of an object.
+//              It returnes the current data pointer. But if object is an
+//              constant object it returnes the default pointer.
+//
+// Parameters:  pSubindexEntry_p = pointer to subindex entry
+//
+// Return:      void *    = pointer to object data
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+void * EplObdGetObjectDataPtrIntern (tEplObdSubEntryPtr pSubindexEntry_p)
+{
+
+void * pData;
+tEplObdAccess Access;
+
+    ASSERTMSG (pSubindexEntry_p != NULL, "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n");
+
+    // there are are some objects whose data pointer has to get from other structure
+    // get access type for this object
+    Access = pSubindexEntry_p->m_Access;
+
+    // If object has access type = const,
+    // for data only exists default values.
+    if ((Access & kEplObdAccConst) != 0)
+    {
+        // The pointer to defualt value can be received from ObdGetObjectDefaultPtr()
+        pData = ((void *) EplObdGetObjectDefaultPtr (pSubindexEntry_p));
+    }
+    else
+    {
+        // The pointer to current value can be received from ObdGetObjectCurrentPtr()
+        pData = ((void *) EplObdGetObjectCurrentPtr (pSubindexEntry_p));
+    }
+
+    return pData;
+
+}
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+// EOF
+
diff --git a/drivers/staging/epl/EplObd.h b/drivers/staging/epl/EplObd.h
new file mode 100644 (file)
index 0000000..4adf680
--- /dev/null
@@ -0,0 +1,504 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for api function of EplOBD-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObd.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Microsoft VC7
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/02 k.t.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#include "EplInc.h"
+
+#ifndef _EPLOBD_H_
+#define _EPLOBD_H_
+
+
+// ============================================================================
+// defines
+// ============================================================================
+
+#define EPL_OBD_TABLE_INDEX_END     0xFFFF
+
+// for the usage of BOOLEAN in OD
+#define OBD_TRUE    0x01
+#define OBD_FALSE   0x00
+
+// default OD index for Node id
+#define EPL_OBD_NODE_ID_INDEX               0x1F93
+// default subindex for NodeId in OD
+#define EPL_OBD_NODE_ID_SUBINDEX            0x01
+// default subindex for NodeIDByHW_BOOL
+#define EPL_OBD_NODE_ID_HWBOOL_SUBINDEX     0x02
+
+// ============================================================================
+// enums
+// ============================================================================
+
+// directions for access to object dictionary
+typedef enum
+{
+    kEplObdDirInit         = 0x00,    // initialising after power on
+    kEplObdDirStore        = 0x01,    // store all object values to non volatile memory
+    kEplObdDirLoad         = 0x02,    // load all object values from non volatile memory
+    kEplObdDirRestore      = 0x03,    // deletes non volatile memory (restore)
+    kEplObdDirOBKCheck     = 0xFF     // reserved
+
+}tEplObdDir;
+
+// commands for store
+typedef enum
+{
+    kEplObdCommNothing     = 0x00,
+    kEplObdCommOpenWrite   = 0x01,
+    kEplObdCommWriteObj    = 0x02,
+    kEplObdCommCloseWrite  = 0x03,
+    kEplObdCommOpenRead    = 0x04,
+    kEplObdCommReadObj     = 0x05,
+    kEplObdCommCloseRead   = 0x06,
+    kEplObdCommClear       = 0x07,
+    kEplObdCommUnknown     = 0xFF
+}tEplObdCommand;
+
+//-----------------------------------------------------------------------------------------------------------
+// events of object callback function
+typedef enum
+{
+//                                                                                                      m_pArg points to
+//                                                                                                    ---------------------
+    kEplObdEvCheckExist            = 0x06,    // checking if object does exist (reading and writing)    NULL
+    kEplObdEvPreRead               = 0x00,    // before reading an object                               source data buffer in OD
+    kEplObdEvPostRead              = 0x01,    // after reading an object                                destination data buffer from caller
+    kEplObdEvWrStringDomain        = 0x07,    // event for changing string/domain data pointer or size  struct tEplObdVStringDomain in RAM
+    kEplObdEvInitWrite             = 0x04,    // initializes writing an object (checking object size)   size of object in OD (tEplObdSize)
+    kEplObdEvPreWrite              = 0x02,    // before writing an object                               source data buffer from caller
+    kEplObdEvPostWrite             = 0x03,    // after writing an object                                destination data buffer in OD
+//    kEplObdEvAbortSdo              = 0x05     // after an abort of an SDO transfer
+
+} tEplObdEvent;
+
+// part of OD (bit oriented)
+typedef unsigned int tEplObdPart;
+
+#define kEplObdPartNo          0x00    // nothing
+#define kEplObdPartGen         0x01    //  part      (0x1000 - 0x1FFF)
+#define kEplObdPartMan         0x02    // manufacturer part (0x2000 - 0x5FFF)
+#define kEplObdPartDev         0x04    // device part       (0x6000 - 0x9FFF)
+#define kEplObdPartUsr         0x08    // dynamic part e.g. for ICE61131-3
+
+// combinations
+#define kEplObdPartApp         (              kEplObdPartMan | kEplObdPartDev | kEplObdPartUsr)   // manufacturer and device part (0x2000 - 0x9FFF) and user OD
+#define kEplObdPartAll         (kEplObdPartGen | kEplObdPartMan | kEplObdPartDev | kEplObdPartUsr)   // whole OD
+
+//-----------------------------------------------------------------------------------------------------------
+// access types for objects
+// must be a difine because bit-flags
+typedef unsigned int tEplObdAccess;
+
+#define kEplObdAccRead         0x01    // object can be read
+#define kEplObdAccWrite        0x02    // object can be written
+#define kEplObdAccConst        0x04    // object contains a constant value
+#define kEplObdAccPdo          0x08    // object can be mapped in a PDO
+#define kEplObdAccArray        0x10    // object contains an array of numerical values
+#define kEplObdAccRange        0x20    // object contains lower and upper limit
+#define kEplObdAccVar          0x40    // object data is placed in application
+#define kEplObdAccStore        0x80    // object data can be stored to non volatile memory
+
+// combinations (not all combinations are required)
+#define kEplObdAccR            (0            | 0          | 0            | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccW            (0            | 0          | 0            | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccRW           (0            | 0          | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccCR           (0            | 0          | 0            | 0          | kEplObdAccConst | 0            | kEplObdAccRead)
+#define kEplObdAccGR           (0            | 0          | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccGW           (0            | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccGRW          (0            | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccVR           (0            | kEplObdAccVar | 0            | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccVW           (0            | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccVRW          (0            | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccVPR          (0            | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccVPW          (0            | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccVPRW         (0            | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccVGR          (0            | kEplObdAccVar | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccVGW          (0            | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccVGRW         (0            | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccVGPR         (0            | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccVGPW         (0            | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccVGPRW        (0            | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccSR           (kEplObdAccStore | 0          | 0            | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccSW           (kEplObdAccStore | 0          | 0            | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccSRW          (kEplObdAccStore | 0          | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccSCR          (kEplObdAccStore | 0          | 0            | 0          | kEplObdAccConst | 0            | kEplObdAccRead)
+#define kEplObdAccSGR          (kEplObdAccStore | 0          | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccSGW          (kEplObdAccStore | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccSGRW         (kEplObdAccStore | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccSVR          (kEplObdAccStore | kEplObdAccVar | 0            | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccSVW          (kEplObdAccStore | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccSVRW         (kEplObdAccStore | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccSVPR         (kEplObdAccStore | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccSVPW         (kEplObdAccStore | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccSVPRW        (kEplObdAccStore | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccSVGR         (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccSVGW         (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccSVGRW        (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
+#define kEplObdAccSVGPR        (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
+#define kEplObdAccSVGPW        (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
+#define kEplObdAccSVGPRW       (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
+
+
+
+typedef unsigned int tEplObdSize; // For all objects as objects size are used an unsigned int.
+
+
+// -------------------------------------------------------------------------
+// types for data types defined in DS301
+// -------------------------------------------------------------------------
+
+// types of objects in object dictionary
+// DS-301 defines these types as WORD
+typedef enum
+{
+// types which are always supported
+    kEplObdTypBool         = 0x0001,
+
+    kEplObdTypInt8         = 0x0002,
+    kEplObdTypInt16        = 0x0003,
+    kEplObdTypInt32        = 0x0004,
+    kEplObdTypUInt8        = 0x0005,
+    kEplObdTypUInt16       = 0x0006,
+    kEplObdTypUInt32       = 0x0007,
+    kEplObdTypReal32       = 0x0008,
+    kEplObdTypVString      = 0x0009,
+    kEplObdTypOString      = 0x000A,
+    kEplObdTypDomain       = 0x000F,
+
+    kEplObdTypInt24        = 0x0010,
+    kEplObdTypUInt24       = 0x0016,
+
+    kEplObdTypReal64       = 0x0011,
+    kEplObdTypInt40        = 0x0012,
+    kEplObdTypInt48        = 0x0013,
+    kEplObdTypInt56        = 0x0014,
+    kEplObdTypInt64        = 0x0015,
+    kEplObdTypUInt40       = 0x0018,
+    kEplObdTypUInt48       = 0x0019,
+    kEplObdTypUInt56       = 0x001A,
+    kEplObdTypUInt64       = 0x001B,
+    kEplObdTypTimeOfDay    = 0x000C,
+    kEplObdTypTimeDiff     = 0x000D
+
+}tEplObdType;
+// other types are not supported in this version
+
+
+// -------------------------------------------------------------------------
+// types for data types defined in DS301
+// -------------------------------------------------------------------------
+
+typedef unsigned char       tEplObdBoolean;      // 0001
+typedef signed char         tEplObdInteger8;     // 0002
+typedef signed short int    tEplObdInteger16;    // 0003
+typedef signed long         tEplObdInteger32;    // 0004
+typedef unsigned char       tEplObdUnsigned8;    // 0005
+typedef unsigned short int  tEplObdUnsigned16;   // 0006
+typedef unsigned long       tEplObdUnsigned32;   // 0007
+typedef float               tEplObdReal32;       // 0008
+typedef unsigned char       tEplObdDomain;       // 000F
+typedef signed   long       tEplObdInteger24;    // 0010
+typedef unsigned long       tEplObdUnsigned24;   // 0016
+
+typedef signed QWORD        tEplObdInteger40;    // 0012
+typedef signed QWORD        tEplObdInteger48;    // 0013
+typedef signed QWORD        tEplObdInteger56;    // 0014
+typedef signed QWORD        tEplObdInteger64;    // 0015
+
+typedef unsigned QWORD      tEplObdUnsigned40;   // 0018
+typedef unsigned QWORD      tEplObdUnsigned48;   // 0019
+typedef unsigned QWORD      tEplObdUnsigned56;   // 001A
+typedef unsigned QWORD      tEplObdUnsigned64;   // 001B
+
+typedef double              tEplObdReal64;       // 0011
+
+typedef tTimeOfDay          tEplObdTimeOfDay;         // 000C
+typedef tTimeOfDay          tEplObdTimeDifference;    // 000D
+
+
+// -------------------------------------------------------------------------
+// structur for defining a variable
+// -------------------------------------------------------------------------
+// -------------------------------------------------------------------------
+typedef enum
+{
+    kVarValidSize           = 0x01,
+    kVarValidData           = 0x02,
+//    kVarValidCallback       = 0x04,
+//    kVarValidArg            = 0x08,
+
+    kVarValidAll            = 0x03  // currently only size and data are implemented and used
+
+}tEplVarParamValid;
+
+
+typedef tEplKernel (PUBLIC ROM* tEplVarCallback) (CCM_DECL_INSTANCE_HDL_
+    void * pParam_p);
+
+typedef struct
+{
+    tEplVarParamValid   m_ValidFlag;
+    unsigned int        m_uiIndex;
+    unsigned int        m_uiSubindex;
+    tEplObdSize         m_Size;
+    void MEM*           m_pData;
+//    tEplVarCallback     m_fpCallback;
+//    void *       m_pArg;
+
+} tEplVarParam;
+
+typedef struct
+{
+    void MEM*           m_pData;
+    tEplObdSize            m_Size;
+/*
+    #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
+        tEplVarCallback    m_fpCallback;
+        void *   m_pArg;
+    #endif
+*/
+} tEplObdVarEntry;
+
+typedef struct
+{
+   tEplObdSize      m_Size;
+   BYTE *           m_pString;
+
+} tEplObdOString;                          // 000C
+
+typedef struct
+{
+   tEplObdSize      m_Size;
+   char *           m_pString;
+} tEplObdVString;                          // 000D
+
+
+typedef struct
+{
+    tEplObdSize      m_Size;
+    char *    m_pDefString;         // $$$ d.k. it is unused, so we could delete it
+    char *    m_pString;
+
+} tEplObdVStringDef;
+
+typedef struct
+{
+   tEplObdSize      m_Size;
+   BYTE *           m_pDefString;   // $$$ d.k. it is unused, so we could delete it
+   BYTE *           m_pString;
+
+} tEplObdOStringDef;
+
+//r.d. parameter struct for changing object size and/or pointer to data of Strings or Domains
+typedef struct
+{
+   tEplObdSize      m_DownloadSize;     // download size from SDO or APP
+   tEplObdSize      m_ObjSize;          // current object size from OD - should be changed from callback function
+   void *    m_pData;            // current object ptr  from OD - should be changed from callback function
+
+} tEplObdVStringDomain;                          // 000D
+
+
+// ============================================================================
+// types
+// ============================================================================
+// -------------------------------------------------------------------------
+// subindexstruct
+// -------------------------------------------------------------------------
+
+// Change not the order for this struct!!!
+typedef struct
+{
+    unsigned int    m_uiSubIndex;
+    tEplObdType     m_Type;
+    tEplObdAccess   m_Access;
+    void  *  m_pDefault;
+    void  MEM*      m_pCurrent;     // points always to RAM
+
+} tEplObdSubEntry;
+
+// r.d.: has always to be  because new OBD-Macros for arrays
+typedef tEplObdSubEntry * tEplObdSubEntryPtr;
+
+// -------------------------------------------------------------------------
+// callback function for objdictionary modul
+// -------------------------------------------------------------------------
+
+// parameters for callback function
+typedef struct
+{
+    tEplObdEvent    m_ObdEvent;
+    unsigned int    m_uiIndex;
+    unsigned int    m_uiSubIndex;
+    void *   m_pArg;
+    DWORD           m_dwAbortCode;
+
+} tEplObdCbParam;
+
+// define type for callback function: pParam_p points to tEplObdCbParam
+typedef tEplKernel (PUBLIC ROM* tEplObdCallback) (CCM_DECL_INSTANCE_HDL_
+    tEplObdCbParam MEM* pParam_p);
+
+// do not change the order for this struct!!!
+
+typedef struct
+{
+    unsigned int        m_uiIndex;
+    tEplObdSubEntryPtr  m_pSubIndex;
+    unsigned int        m_uiCount;
+    tEplObdCallback     m_fpCallback;   // function is called back if object access
+
+} tEplObdEntry;
+
+
+// allways  pointer
+typedef tEplObdEntry * tEplObdEntryPtr;
+
+
+
+// -------------------------------------------------------------------------
+// structur to initialize OBD module
+// -------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplObdEntryPtr        m_pPart;
+    tEplObdEntryPtr        m_pManufacturerPart;
+    tEplObdEntryPtr        m_pDevicePart;
+
+    #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+
+          tEplObdEntryPtr  m_pUserPart;
+
+    #endif
+
+} tEplObdInitParam;
+
+
+// -------------------------------------------------------------------------
+// structur for parameters of STORE RESTORE command
+// -------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplObdCommand  m_bCommand;
+    tEplObdPart        m_bCurrentOdPart;
+    void MEM*       m_pData;
+    tEplObdSize     m_ObjSize;
+
+} tEplObdCbStoreParam;
+
+
+typedef tEplKernel (PUBLIC ROM* tInitTabEntryCallback) (
+    void MEM* pTabEntry_p,
+    unsigned int uiObjIndex_p);
+
+typedef tEplKernel (PUBLIC ROM* tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_
+    tEplObdCbStoreParam MEM* pCbStoreParam_p);
+
+// -------------------------------------------------------------------------
+// this stucture is used for parameters for function ObdInitModuleTab()
+// -------------------------------------------------------------------------
+typedef struct
+{
+    unsigned int            m_uiLowerObjIndex;  // lower limit of ObjIndex
+    unsigned int            m_uiUpperObjIndex;  // upper limit of ObjIndex
+    tInitTabEntryCallback   m_fpInitTabEntry;   // will be called if ObjIndex was found
+    void MEM*               m_pTabBase;         // base address of table
+    unsigned int            m_uiEntrySize;      // size of table entry      // 25-feb-2005 r.d.: expansion from BYTE to WORD necessary for PDO bit mapping
+    unsigned int            m_uiMaxEntries;     // max. tabel entries
+
+} tEplObdModulTabParam;
+
+//-------------------------------------------------------------------
+//  enum for function EplObdSetNodeId
+//-------------------------------------------------------------------
+typedef enum
+{
+    kEplObdNodeIdUnknown    =   0x00,   // unknown how the node id was set
+    kEplObdNodeIdSoftware   =   0x01,   // node id set by software
+    kEplObdNodeIdHardware   =   0x02    // node id set by hardware
+
+}tEplObdNodeIdType;
+
+// ============================================================================
+// global variables
+// ============================================================================
+
+
+
+// ============================================================================
+// public functions
+// ============================================================================
+
+
+#endif  // #ifndef _EPLOBD_H_
+
+
diff --git a/drivers/staging/epl/EplObdMacro.h b/drivers/staging/epl/EplObdMacro.h
new file mode 100644 (file)
index 0000000..c15c360
--- /dev/null
@@ -0,0 +1,362 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for macros of EplOBD-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObdMacro.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/05 k.t.:   start of the implementation
+                    -> based on CANopen ObdMacro.h
+
+
+
+****************************************************************************/
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#if defined (EPL_OBD_DEFINE_MACRO)
+
+    //-------------------------------------------------------------------------------------------
+    #if defined (EPL_OBD_CREATE_ROM_DATA)
+
+//        #pragma message ("EPL_OBD_CREATE_ROM_DATA")
+
+        #define EPL_OBD_BEGIN()                                                         static  DWORD  dwObd_OBK_g = 0x0000;
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()
+        #define EPL_OBD_BEGIN_PART_DEVICE()
+        #define EPL_OBD_END_PART()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
+        #define EPL_OBD_END_INDEX(ind)
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static  tEplObdUnsigned8    xDef##ind##_0x00_g = (cnt); \
+                                                                                        static  dtyp  xDef##ind##_0x01_g = (def);
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static  tEplObdUnsigned8    xDef##ind##_0x00_g = (cnt); \
+                                                                                        static  dtyp  xDef##ind##_0x01_g = (def);
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static  tEplObdUnsigned8    xDef##ind##_0x00_g = (cnt);
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 static  dtyp  xDef##ind##_##sub##_g        = val;
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     static  dtyp  xDef##ind##_##sub##_g[3]     = {val,low,high};
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 static char  MEM szCur##ind##_##sub##_g[size+1]; \
+                                                                                        static  tEplObdVStringDef  xDef##ind##_##sub##_g = {size, val, szCur##ind##_##sub##_g};
+
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     static  BYTE  MEM bCur##ind##_##sub##_g[size]; \
+                                                                                        static  tEplObdOStringDef  xDef##ind##_##sub##_g = {size, ((BYTE*)""), bCur##ind##_##sub##_g};
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             static  dtyp  xDef##ind##_##sub##_g        = val;
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static  dtyp  xDef##ind##_##sub##_g[3]     = {val,low,high};
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
+
+//-------------------------------------------------------------------------------------------
+    #elif defined (EPL_OBD_CREATE_RAM_DATA)
+
+//        #pragma message ("EPL_OBD_CREATE_RAM_DATA")
+
+        #define EPL_OBD_BEGIN()
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()
+        #define EPL_OBD_BEGIN_PART_DEVICE()
+        #define EPL_OBD_END_PART()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
+        #define EPL_OBD_END_INDEX(ind)
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static dtyp         MEM axCur##ind##_g[cnt];
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 static dtyp         MEM xCur##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     static dtyp         MEM xCur##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 static tEplObdVString  MEM xCur##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     static tEplObdOString  MEM xCur##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)              static dtyp         MEM xCur##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)                           static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)          static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+
+    //-------------------------------------------------------------------------------------------
+    #elif defined (EPL_OBD_CREATE_SUBINDEX_TAB)
+
+//        #pragma message ("EPL_OBD_CREATE_SUBINDEX_TAB")
+
+        #define EPL_OBD_BEGIN()
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()
+        #define EPL_OBD_BEGIN_PART_DEVICE()
+        #define EPL_OBD_END_PART()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)                                   static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[cnt]= {
+        #define EPL_OBD_END_INDEX(ind)                                                  EPL_OBD_END_SUBINDEX()};
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+                                                                                        {0, kEplObdTypUInt8, kEplObdAccCR,          &xDef##ind##_0x00_g,   NULL}, \
+                                                                                        {1, typ,          (acc)|kEplObdAccArray, &xDef##ind##_0x01_g,   &axCur##ind##_g[0]}, \
+                                                                                        EPL_OBD_END_SUBINDEX()};
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+                                                                                        {0, kEplObdTypUInt8, kEplObdAccCR,                     &xDef##ind##_0x00_g,   NULL}, \
+                                                                                        {1, typ,          (acc)|kEplObdAccArray|kEplObdAccVar, &xDef##ind##_0x01_g,   &aVarEntry##ind##_g[0]}, \
+                                                                                        EPL_OBD_END_SUBINDEX()};
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+                                                                                        {0, kEplObdTypUInt8, kEplObdAccCR,                     &xDef##ind##_0x00_g,   NULL}, \
+                                                                                        {1, typ,          (acc)|kEplObdAccArray|kEplObdAccVar, NULL,                  &aVarEntry##ind##_g[0]}, \
+                                                                                        EPL_OBD_END_SUBINDEX()};
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 {sub,typ,            (acc),                        &xDef##ind##_##sub##_g,   &xCur##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     {sub,typ,            (acc)|kEplObdAccRange,           &xDef##ind##_##sub##_g[0],&xCur##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)              {sub,typ,            (acc),                        NULL,   &xCur##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 {sub,kEplObdTypVString,(acc)/*|kEplObdAccVar*/,         &xDef##ind##_##sub##_g,   &xCur##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     {sub,kEplObdTypOString,(acc)/*|kEplObdAccVar*/,         &xDef##ind##_##sub##_g,   &xCur##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)                           {sub,kEplObdTypDomain, (acc)|kEplObdAccVar,             NULL,                     &VarEntry##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             {sub,typ,           (acc)|kEplObdAccVar,             &xDef##ind##_##sub##_g,   &VarEntry##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) {sub,typ,           (acc)|kEplObdAccVar|kEplObdAccRange,&xDef##ind##_##sub##_g[0],&VarEntry##ind##_##sub##_g},
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)          {sub,typ,           (acc)|kEplObdAccVar,             NULL,    &VarEntry##ind##_##sub##_g},
+
+
+    //-------------------------------------------------------------------------------------------
+    #elif defined (EPL_OBD_CREATE_INDEX_TAB)
+
+//        #pragma message ("EPL_OBD_CREATE_INDEX_TAB")
+
+        #define EPL_OBD_BEGIN()
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()                                                   static  tEplObdEntry  aObdTab_g[]      = {
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()                                       static  tEplObdEntry  aObdTabManufacturer_g[] = {
+        #define EPL_OBD_BEGIN_PART_DEVICE()                                             static  tEplObdEntry  aObdTabDevice_g[]       = {
+        #define EPL_OBD_END_PART()                                                      {EPL_OBD_TABLE_INDEX_END,(tEplObdSubEntryPtr)&dwObd_OBK_g,0,NULL}};
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)                                   {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],cnt,(tEplObdCallback)call},
+        #define EPL_OBD_END_INDEX(ind)
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call},
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call},
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call},
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
+
+            //-------------------------------------------------------------------------------------------
+    #elif defined (EPL_OBD_CREATE_INIT_FUNCTION)
+
+//        #pragma message ("EPL_OBD_CREATE_INIT_FUNCTION")
+
+        #define EPL_OBD_BEGIN()
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()                                                   pInitParam->m_pPart      = (tEplObdEntryPtr) &aObdTab_g[0];
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()                                       pInitParam->m_pManufacturerPart = (tEplObdEntryPtr) &aObdTabManufacturer_g[0];
+        #define EPL_OBD_BEGIN_PART_DEVICE()                                             pInitParam->m_pDevicePart       = (tEplObdEntryPtr) &aObdTabDevice_g[0];
+        #define EPL_OBD_END_PART()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
+        #define EPL_OBD_END_INDEX(ind)
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
+
+
+    //-------------------------------------------------------------------------------------------
+    #elif defined (EPL_OBD_CREATE_INIT_SUBINDEX)
+
+//        #pragma message ("EPL_OBD_CREATE_INIT_SUBINDEX")
+
+        #define EPL_OBD_BEGIN()
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()
+        #define EPL_OBD_BEGIN_PART_DEVICE()
+        #define EPL_OBD_END_PART()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)                                   //CCM_SUBINDEX_RAM_ONLY (EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g)));
+        #define EPL_OBD_END_INDEX(ind)
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         //EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g));
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      //EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g));
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   //EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g));
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
+
+    //-------------------------------------------------------------------------------------------
+    #else
+
+//        #pragma message ("ELSE OF DEFINE")
+
+        #define EPL_OBD_BEGIN()
+        #define EPL_OBD_END()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_PART_GENERIC()
+        #define EPL_OBD_BEGIN_PART_MANUFACTURER()
+        #define EPL_OBD_BEGIN_PART_DEVICE()
+        #define EPL_OBD_END_PART()
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
+        #define EPL_OBD_END_INDEX(ind)
+        #define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)
+        #define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)
+
+        //---------------------------------------------------------------------------------------
+        #define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,sizes,val)
+        #define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
+        #define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
+        #define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
+        #define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
+
+    #endif
+
+    //-------------------------------------------------------------------------------------------
+#elif defined (EPL_OBD_UNDEFINE_MACRO)
+
+//    #pragma message ("EPL_OBD_UNDEFINE_MACRO")
+
+    #undef EPL_OBD_BEGIN
+    #undef EPL_OBD_END
+
+    //---------------------------------------------------------------------------------------
+    #undef EPL_OBD_BEGIN_PART_GENERIC
+    #undef EPL_OBD_BEGIN_PART_MANUFACTURER
+    #undef EPL_OBD_BEGIN_PART_DEVICE
+    #undef EPL_OBD_END_PART
+
+    //---------------------------------------------------------------------------------------
+    #undef EPL_OBD_BEGIN_INDEX_RAM
+    #undef EPL_OBD_END_INDEX
+    #undef EPL_OBD_RAM_INDEX_RAM_ARRAY
+    #undef EPL_OBD_RAM_INDEX_RAM_VARARRAY
+    #undef EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT
+
+    //---------------------------------------------------------------------------------------
+    #undef EPL_OBD_SUBINDEX_RAM_VAR
+    #undef EPL_OBD_SUBINDEX_RAM_VAR_RG
+    #undef EPL_OBD_SUBINDEX_RAM_VSTRING
+    #undef EPL_OBD_SUBINDEX_RAM_OSTRING
+    #undef EPL_OBD_SUBINDEX_RAM_VAR_NOINIT
+    #undef EPL_OBD_SUBINDEX_RAM_DOMAIN
+    #undef EPL_OBD_SUBINDEX_RAM_USERDEF
+    #undef EPL_OBD_SUBINDEX_RAM_USERDEF_RG
+    #undef EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT
+
+#else
+
+    #error "nothing defined"
+
+
+#endif
+
+
diff --git a/drivers/staging/epl/EplObdkCal.c b/drivers/staging/epl/EplObdkCal.c
new file mode 100644 (file)
index 0000000..f94a150
--- /dev/null
@@ -0,0 +1,154 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for communication abstraction layer
+                for the Epl-Obd-Kernelspace-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObdkCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "kernel/EplObdkCal.h"
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplObdu.c b/drivers/staging/epl/EplObdu.c
new file mode 100644 (file)
index 0000000..46370cb
--- /dev/null
@@ -0,0 +1,512 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Epl-Obd-Userspace-module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObdu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "user/EplObdu.h"
+#include "user/EplObduCal.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduWriteEntry()
+//
+// Description: Function writes data to an OBD entry. Strings
+//              are stored with added '\0' character.
+//
+// Parameters:  uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry (unsigned int  uiIndex_p,
+                                                unsigned int  uiSubIndex_p,
+                                                void * pSrcData_p,
+                                                tEplObdSize   Size_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalWriteEntry(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p);
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduReadEntry()
+//
+// Description: The function reads an object entry. The application
+//              can always read the data even if attrib kEplObdAccRead
+//              is not set. The attrib is only checked up for SDO transfer.
+//
+// Parameters:  uiIndex_p       = Index oof the OD entry to read
+//              uiSubIndex_p    = Subindex to read
+//              pDstData_p      = pointer to the buffer for data
+//              Offset_p        = offset in data for read access
+//              pSize_p         = IN: Size of the buffer
+//                                OUT: number of readed Bytes
+//
+// Return:      tEplKernel      =   errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry (unsigned int        uiIndex_p,
+                                            unsigned int        uiSubIndex_p,
+                                            void *       pDstData_p,
+                                            tEplObdSize* pSize_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalReadEntry(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdAccessOdPart()
+//
+// Description: restores default values of one part of OD
+//
+// Parameters:  ObdPart_p       = od-part to reset
+//              Direction_p     = directory flag for
+//
+// Return:      tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart (tEplObdPart ObdPart_p,
+                                                    tEplObdDir Direction_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalAccessOdPart(ObdPart_p, Direction_p);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduDefineVar()
+//
+// Description: defines a variable in OD
+//
+// Parameters:  pEplVarParam_p = varentry
+//
+// Return:      tEplKernel  =   errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar (tEplVarParam MEM* pVarParam_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalDefineVar(pVarParam_p);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduGetObjectDataPtr()
+//
+// Description: It returnes the current data pointer. But if object is an
+//              constant object it returnes the default pointer.
+//
+// Parameters:  uiIndex_p    =   Index of the entry
+//              uiSubindex_p =   Subindex of the entry
+//
+// Return:      void *    = pointer to object data
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT void* PUBLIC EplObduGetObjectDataPtr (unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p)
+{
+void*   pData;
+
+    pData =  EplObduCalGetObjectDataPtr(uiIndex_p, uiSubIndex_p);
+
+    return pData;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduRegisterUserOd()
+//
+// Description: function registers the user OD
+//
+// Parameters:  pUserOd_p   =pointer to user ODd
+//
+// Return:     tEplKernel = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd (tEplObdEntryPtr pUserOd_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalRegisterUserOd(pUserOd_p);
+
+    return Ret;
+
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduInitVarEntry()
+//
+// Description: function to initialize VarEntry dependened on object type
+//
+// Parameters:  pVarEntry_p = pointer to var entry structure
+//              bType_p     = object type
+//              ObdSize_p   = size of object data
+//
+// Returns:     none
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT void PUBLIC EplObduInitVarEntry (tEplObdVarEntry MEM* pVarEntry_p,
+                                        BYTE bType_p, tEplObdSize ObdSize_p)
+{
+    EplObduCalInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduGetDataSize()
+//
+// Description: function to initialize VarEntry dependened on object type
+//
+//              gets the data size of an object
+//              for string objects it returnes the string length
+//
+// Parameters:  uiIndex_p   =   Index
+//              uiSubIndex_p=   Subindex
+//
+// Return:      tEplObdSize
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p)
+{
+tEplObdSize Size;
+
+    Size = EplObduCalGetDataSize(uiIndex_p, uiSubIndex_p);
+
+    return Size;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduGetNodeId()
+//
+// Description: function returns nodeid from entry 0x1F93
+//
+//
+// Parameters:
+//
+// Return:      unsigned int = Node Id
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId()
+{
+unsigned int uiNodeId;
+
+    uiNodeId = EplObduCalGetNodeId();
+
+    return uiNodeId;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduSetNodeId()
+//
+// Description: function sets nodeid in entry 0x1F93
+//
+//
+// Parameters:  uiNodeId_p  =   Node Id to set
+//              NodeIdType_p=   Type on which way the Node Id was set
+//
+// Return:      tEplKernel = Errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
+                                         tEplObdNodeIdType NodeIdType_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalSetNodeId(uiNodeId_p, NodeIdType_p);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduGetAccessType()
+//
+// Description: Function returns accesstype of the entry
+//
+// Parameters:  uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pAccessTyp_p    =   pointer to buffer to store accesstyp
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
+                                        unsigned int   uiSubIndex_p,
+                                        tEplObdAccess* pAccessTyp_p)
+{
+tEplObdAccess AccessType;
+
+    AccessType = EplObduCalGetAccessType(uiIndex_p, uiSubIndex_p, pAccessTyp_p);
+
+    return AccessType;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObdReaduEntryToLe()
+//
+// Description: The function reads an object entry from the byteoder
+//              of the system to the little endian byteorder for numeric values.
+//              For other types a normal read will be processed. This is usefull for
+//              the PDO and SDO module. The application
+//              can always read the data even if attrib kEplObdAccRead
+//              is not set. The attrib is only checked up for SDO transfer.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       = Index of the OD entry to read
+//              uiSubIndex_p    = Subindex to read
+//              pDstData_p      = pointer to the buffer for data
+//              Offset_p        = offset in data for read access
+//              pSize_p         = IN: Size of the buffer
+//                                OUT: number of readed Bytes
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe (unsigned int        uiIndex_p,
+                                        unsigned int        uiSubIndex_p,
+                                        void *              pDstData_p,
+                                        tEplObdSize *       pSize_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalReadEntryToLe(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduWriteEntryFromLe()
+//
+// Description: Function writes data to an OBD entry from a source with
+//              little endian byteorder to the od with system specuific
+//              byteorder. Not numeric values will only by copied. Strings
+//              are stored with added '\0' character.
+//
+// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
+//              uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe (unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        void *        pSrcData_p,
+                                        tEplObdSize   Size_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalWriteEntryFromLe(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p);
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduSearchVarEntry()
+//
+// Description: gets variable from OD
+//
+// Parameters:  uiIndex_p       =   index of the var entry to search
+//              uiSubindex_p    =   subindex of var entry to search
+//              ppVarEntry_p    =   pointer to the pointer to the varentry
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                            unsigned int            uiIndex_p,
+                                            unsigned int            uiSubindex_p,
+                                            tEplObdVarEntry MEM**   ppVarEntry_p)
+{
+tEplKernel  Ret;
+
+    Ret = EplObduCalSearchVarEntry(uiIndex_p, uiSubindex_p, ppVarEntry_p);
+
+return Ret;
+}
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplObduCal.c b/drivers/staging/epl/EplObduCal.c
new file mode 100644 (file)
index 0000000..d309c5e
--- /dev/null
@@ -0,0 +1,562 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for communication abstraction layer
+                for the Epl-Obd-Userspace-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObduCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+****************************************************************************/
+#include "EplInc.h"
+#include "user/EplObduCal.h"
+#include "kernel/EplObdk.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) && (EPL_OBD_USE_KERNEL != FALSE)
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalWriteEntry()
+//
+// Description: Function encapsulate access of function EplObdWriteEntry
+//
+// Parameters:  uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry (
+                                                unsigned int  uiIndex_p,
+                                                unsigned int  uiSubIndex_p,
+                                                void * pSrcData_p,
+                                                tEplObdSize   Size_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdWriteEntry(uiIndex_p,uiSubIndex_p,pSrcData_p,Size_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalReadEntry()
+//
+// Description: Function encapsulate access of function EplObdReadEntry
+//
+// Parameters:  uiIndex_p       = Index oof the OD entry to read
+//              uiSubIndex_p    = Subindex to read
+//              pDstData_p      = pointer to the buffer for data
+//              Offset_p        = offset in data for read access
+//              pSize_p         = IN: Size of the buffer
+//                                OUT: number of readed Bytes
+//
+// Return:      tEplKernel      =   errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry (
+                                            unsigned int        uiIndex_p,
+                                            unsigned int        uiSubIndex_p,
+                                            void *       pDstData_p,
+                                            tEplObdSize *pSize_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdReadEntry(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalAccessOdPart()
+//
+// Description: Function encapsulate access of function EplObdAccessOdPart
+//
+// Parameters:  ObdPart_p       = od-part to reset
+//              Direction_p     = directory flag for
+//
+// Return:      tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart (
+                                                    tEplObdPart ObdPart_p,
+                                                    tEplObdDir Direction_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdAccessOdPart(ObdPart_p, Direction_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalDefineVar()
+//
+// Description: Function encapsulate access of function EplObdDefineVar
+//
+// Parameters:  pEplVarParam_p = varentry
+//
+// Return:      tEplKernel  =   errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar (tEplVarParam MEM* pVarParam_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdDefineVar(pVarParam_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalGetObjectDataPtr()
+//
+// Description: Function encapsulate access of function EplObdGetObjectDataPtr
+//
+// Parameters:  uiIndex_p    =   Index of the entry
+//              uiSubindex_p =   Subindex of the entry
+//
+// Return:      void *    = pointer to object data
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT void* PUBLIC EplObduCalGetObjectDataPtr ( unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p)
+{
+void*   pData;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    pData = EplObdGetObjectDataPtr(uiIndex_p, uiSubIndex_p);
+#else
+    pData = NULL;
+#endif
+
+    return pData;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalRegisterUserOd()
+//
+// Description: Function encapsulate access of function EplObdRegisterUserOd
+//
+// Parameters:  pUserOd_p   = pointer to user OD
+//
+// Return:     tEplKernel = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd (tEplObdEntryPtr pUserOd_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdRegisterUserOd(pUserOd_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalInitVarEntry()
+//
+// Description: Function encapsulate access of function EplObdInitVarEntry
+//
+// Parameters:  pVarEntry_p = pointer to var entry structure
+//              bType_p     = object type
+//              ObdSize_p   = size of object data
+//
+// Returns:     none
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry (tEplObdVarEntry MEM* pVarEntry_p,
+                                        BYTE bType_p, tEplObdSize ObdSize_p)
+{
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    EplObdInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
+#endif
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalGetDataSize()
+//
+// Description: Function encapsulate access of function EplObdGetDataSize
+//
+//              gets the data size of an object
+//              for string objects it returnes the string length
+//
+// Parameters:  uiIndex_p   =   Index
+//              uiSubIndex_p=   Subindex
+//
+// Return:      tEplObdSize
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p)
+{
+tEplObdSize Size;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Size = EplObdGetDataSize(uiIndex_p, uiSubIndex_p);
+#else
+    Size = 0;
+#endif
+
+    return Size;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalGetNodeId()
+//
+// Description: Function encapsulate access of function EplObdGetNodeId
+//
+//
+// Parameters:
+//
+// Return:      unsigned int = Node Id
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId()
+{
+unsigned int uiNodeId;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    uiNodeId = EplObdGetNodeId();
+#else
+    uiNodeId = 0;
+#endif
+
+    return uiNodeId;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalSetNodeId()
+//
+// Description: Function encapsulate access of function EplObdSetNodeId
+//
+//
+// Parameters:  uiNodeId_p  =   Node Id to set
+//              NodeIdType_p=   Type on which way the Node Id was set
+//
+// Return:      tEplKernel = Errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
+                                         tEplObdNodeIdType NodeIdType_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdSetNodeId(uiNodeId_p, NodeIdType_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalGetAccessType()
+//
+// Description: Function encapsulate access of function EplObdGetAccessType
+//
+// Parameters:  uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pAccessTyp_p    =   pointer to buffer to store accesstype
+//
+// Return:      tEplKernel      =   errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
+                                        unsigned int   uiSubIndex_p,
+                                        tEplObdAccess* pAccessTyp_p)
+
+{
+tEplObdAccess AccesType;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    AccesType = EplObdGetAccessType(uiIndex_p, uiSubIndex_p, pAccessTyp_p);
+#else
+    AccesType = 0;
+#endif
+
+return AccesType;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalReadEntryToLe()
+//
+// Description: Function encapsulate access of function EplObdReadEntryToLe
+//
+// Parameters:  uiIndex_p       = Index of the OD entry to read
+//              uiSubIndex_p    = Subindex to read
+//              pDstData_p      = pointer to the buffer for data
+//              Offset_p        = offset in data for read access
+//              pSize_p         = IN: Size of the buffer
+//                                OUT: number of readed Bytes
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe (unsigned int        uiIndex_p,
+                                        unsigned int        uiSubIndex_p,
+                                        void *              pDstData_p,
+                                        tEplObdSize *       pSize_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdReadEntryToLe(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalWriteEntryFromLe()
+//
+// Description: Function encapsulate access of function EplObdWriteEntryFromLe
+//
+// Parameters:  uiIndex_p       =   Index of the OD entry
+//              uiSubIndex_p    =   Subindex of the OD Entry
+//              pSrcData_p      =   Pointer to the data to write
+//              Size_p          =   Size of the data in Byte
+//
+// Return:      tEplKernel      =   Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe (unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        void *        pSrcData_p,
+                                        tEplObdSize   Size_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdWriteEntryFromLe(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplObduCalSearchVarEntry()
+//
+// Description: gets variable from OD
+//
+// Parameters:  uiIndex_p       =   index of the var entry to search
+//              uiSubindex_p    =   subindex of var entry to search
+//              ppVarEntry_p    =   pointer to the pointer to the varentry
+//
+// Return:      tEplKernel
+//
+// State:
+//
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                            unsigned int            uiIndex_p,
+                                            unsigned int            uiSubindex_p,
+                                            tEplObdVarEntry MEM**   ppVarEntry_p)
+{
+tEplKernel  Ret;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+    Ret = EplObdSearchVarEntry(uiIndex_p, uiSubindex_p, ppVarEntry_p);
+#else
+    Ret = kEplSuccessful;
+#endif
+    return Ret;
+}
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplObjDef.h b/drivers/staging/epl/EplObjDef.h
new file mode 100644 (file)
index 0000000..5823c14
--- /dev/null
@@ -0,0 +1,220 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  defines objdict dictionary
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObjDef.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/06    k.t.:   take ObjDef.h from CANopen and modify for EPL
+
+****************************************************************************/
+
+#ifndef _EPLOBJDEF_H_
+#define _EPLOBJDEF_H_
+
+
+//---------------------------------------------------------------------------
+// security checks
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// macros to help building OD
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+#if (defined (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB) && (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB != FALSE))
+
+    #define CCM_SUBINDEX_RAM_ONLY(a)    a;
+    #define CCM_SUBINDEX_RAM_ONEOF(a,b) a
+
+#else
+
+    #define CCM_SUBINDEX_RAM_ONLY(a)
+    #define CCM_SUBINDEX_RAM_ONEOF(a,b) b
+
+#endif
+
+
+//---------------------------------------------------------------------------
+// To prevent unused memory in subindex tables we need this macro.
+// But not all compilers support to preset the last struct value followed by a comma.
+// Compilers which does not support a comma after last struct value has to place in a dummy subindex.
+#if ((DEV_SYSTEM & _DEV_COMMA_EXT_) != 0)
+
+    #define EPL_OBD_END_SUBINDEX()
+    #define EPL_OBD_MAX_ARRAY_SUBENTRIES    2
+
+#else
+
+    #define EPL_OBD_END_SUBINDEX()          {0,0,0,NULL,NULL}
+    #define EPL_OBD_MAX_ARRAY_SUBENTRIES    3
+
+#endif
+
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+// globale vars
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+// creation of data in ROM memory
+// -------------------------------------------------------------------------
+#define EPL_OBD_CREATE_ROM_DATA
+    #include "objdict.h"
+#undef EPL_OBD_CREATE_ROM_DATA
+
+
+// -------------------------------------------------------------------------
+// creation of data in RAM memory
+// -------------------------------------------------------------------------
+
+#define EPL_OBD_CREATE_RAM_DATA
+    #include "objdict.h"
+#undef EPL_OBD_CREATE_RAM_DATA
+
+
+// -------------------------------------------------------------------------
+// creation of subindex tables in ROM and RAM
+// -------------------------------------------------------------------------
+
+#define EPL_OBD_CREATE_SUBINDEX_TAB
+    #include "objdict.h"
+#undef EPL_OBD_CREATE_SUBINDEX_TAB
+
+
+// -------------------------------------------------------------------------
+// creation of index tables for generic, manufacturer and device part
+// -------------------------------------------------------------------------
+
+#define EPL_OBD_CREATE_INDEX_TAB
+    #include "objdict.h"
+#undef EPL_OBD_CREATE_INDEX_TAB
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+// ----------------------------------------------------------------------------
+//
+// Function:    EPL_OBD_INIT_RAM_NAME()
+//
+// Description: function to initialize object dictionary
+//
+// Parameters:  pInitParam_p    = pointer to init param struct of Epl
+//
+// Returns:     tEplKernel      = error code
+//
+// State:
+//
+// ----------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EPL_OBD_INIT_RAM_NAME (tEplObdInitParam MEM* pInitParam_p)
+{
+
+tEplObdInitParam MEM* pInitParam = pInitParam_p;
+
+    // check if pointer to parameter structure is valid
+    // if not then only copy subindex tables below
+    if (pInitParam != NULL)
+    {
+        // at first delete all parameters (all pointers will be set zu NULL)
+        EPL_MEMSET (pInitParam, 0, sizeof (tEplObdInitParam));
+
+        #define EPL_OBD_CREATE_INIT_FUNCTION
+        {
+            // inserts code to init pointer to index tables
+            #include "objdict.h"
+        }
+        #undef EPL_OBD_CREATE_INIT_FUNCTION
+
+        #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
+        {
+            // to begin no user OD is defined
+            pInitParam_p->m_pUserPart = NULL;
+        }
+        #endif
+    }
+
+    #define EPL_OBD_CREATE_INIT_SUBINDEX
+    {
+        // inserts code to copy subindex tables
+        #include "objdict.h"
+    }
+    #undef EPL_OBD_CREATE_INIT_SUBINDEX
+
+    return kEplSuccessful;
+
+}
+
+
+#endif // _EPLOBJDEF_H_
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
+
diff --git a/drivers/staging/epl/EplPdo.h b/drivers/staging/epl/EplPdo.h
new file mode 100644 (file)
index 0000000..0273a94
--- /dev/null
@@ -0,0 +1,126 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for PDO module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdo.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_PDO_H_
+#define _EPL_PDO_H_
+
+#include "EplInc.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+// invalid PDO-NodeId
+#define EPL_PDO_INVALID_NODE_ID     0xFF
+// NodeId for PReq RPDO
+#define EPL_PDO_PREQ_NODE_ID        0x00
+// NodeId for PRes TPDO
+#define EPL_PDO_PRES_NODE_ID        0x00
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    void*               m_pVar;
+    WORD                m_wOffset;   // in Bits
+    WORD                m_wSize;     // in Bits
+    BOOL                m_fNumeric;  // numeric value -> use AMI functions
+
+} tEplPdoMapping;
+
+typedef struct
+{
+    unsigned int        m_uiSizeOfStruct;
+    unsigned int        m_uiPdoId;
+    unsigned int        m_uiNodeId;
+    // 0xFF=invalid, RPDO: 0x00=PReq, localNodeId=PRes, remoteNodeId=PRes
+    //               TPDO: 0x00=PRes, MN: CnNodeId=PReq
+
+    BOOL                m_fTxRx;
+    BYTE                m_bMappingVersion;
+    unsigned int        m_uiMaxMappingEntries; // maximum number of mapping entries, i.e. size of m_aPdoMapping
+    tEplPdoMapping      m_aPdoMapping[1];
+
+} tEplPdoParam;
+
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPL_PDO_H_
+
+
diff --git a/drivers/staging/epl/EplPdok.c b/drivers/staging/epl/EplPdok.c
new file mode 100644 (file)
index 0000000..83c2f29
--- /dev/null
@@ -0,0 +1,692 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for kernel PDO module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdok.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "kernel/EplPdok.h"
+#include "kernel/EplPdokCal.h"
+#include "kernel/EplEventk.h"
+#include "kernel/EplObdk.h"
+
+#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
+#include "plccore.h"
+#define PDO_LED 0x08
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) == 0)
+
+    #error 'ERROR: Missing DLLk-Modul!'
+
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
+
+    #error 'ERROR: Missing OBDk-Modul!'
+
+#endif
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPL_PDOK_OBD_IDX_RX_COMM_PARAM  0x1400
+#define EPL_PDOK_OBD_IDX_RX_MAPP_PARAM  0x1600
+#define EPL_PDOK_OBD_IDX_TX_COMM_PARAM  0x1800
+#define EPL_PDOK_OBD_IDX_TX_MAPP_PARAM  0x1A00
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplPdok                                             */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokAddInstance()
+//
+// Description: add and initialize new instance of EPL stack
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokAddInstance(void)
+{
+
+    return kEplSuccessful;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokDelInstance()
+//
+// Description: deletes an instance of EPL stack
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokDelInstance(void)
+{
+
+    return kEplSuccessful;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCbPdoReceived
+//
+// Description: This function is called by DLL if PRes or PReq frame was
+//              received. It posts the frame to the event queue.
+//              It is called in states NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL.
+//              The passed PDO needs not to be valid.
+//
+// Parameters:  pFrameInfo_p            = pointer to frame info structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplEvent       Event;
+
+#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
+    // reset LED
+//    MCF_GPIO_PODR_PCIBG &= ~PDO_LED;  // Level
+#endif
+
+    Event.m_EventSink = kEplEventSinkPdok;
+    Event.m_EventType = kEplEventTypePdoRx;
+    // limit copied data to size of PDO (because from some CNs the frame is larger than necessary)
+    Event.m_uiSize = AmiGetWordFromLe(&pFrameInfo_p->m_pFrame->m_Data.m_Pres.m_le_wSize) + 24; // pFrameInfo_p->m_uiFrameSize;
+    Event.m_pArg = pFrameInfo_p->m_pFrame;
+    Ret = EplEventkPost(&Event);
+
+#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
+    // set LED
+//    MCF_GPIO_PODR_PCIBG |= PDO_LED;  // Level
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCbPdoTransmitted
+//
+// Description: This function is called by DLL if PRes or PReq frame was
+//              sent. It posts the pointer to the frame to the event queue.
+//              It is called in NMT_CS_PRE_OPERATIONAL_2,
+//              NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL.
+//
+// Parameters:  pFrameInfo_p            = pointer to frame info structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplEvent       Event;
+
+#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
+    // reset LED
+    MCF_GPIO_PODR_PCIBG &= ~PDO_LED;  // Level
+#endif
+
+    Event.m_EventSink = kEplEventSinkPdok;
+    Event.m_EventType = kEplEventTypePdoTx;
+    Event.m_uiSize = sizeof (tEplFrameInfo);
+    Event.m_pArg = pFrameInfo_p;
+    Ret = EplEventkPost(&Event);
+
+#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
+    // set LED
+    MCF_GPIO_PODR_PCIBG |= PDO_LED;  // Level
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCbSoa
+//
+// Description: This function is called by DLL if SoA frame was
+//              received resp. sent. It posts this event to the event queue.
+//
+// Parameters:  pFrameInfo_p            = pointer to frame info structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplEvent       Event;
+
+    Event.m_EventSink = kEplEventSinkPdok;
+    Event.m_EventType = kEplEventTypePdoSoa;
+    Event.m_uiSize = 0;
+    Event.m_pArg = NULL;
+    Ret = EplEventkPost(&Event);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokProcess
+//
+// Description: This function processes all received and transmitted PDOs.
+//              This function must not be interrupted by any other task
+//              except ISRs (like the ethernet driver ISR, which may call
+//              EplPdokCbFrameReceived() or EplPdokCbFrameTransmitted()).
+//
+// Parameters:  pEvent_p                = pointer to event structure
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+WORD    wPdoSize;
+WORD    wBitOffset;
+WORD    wBitSize;
+WORD    wVarSize;
+QWORD   qwObjectMapping;
+BYTE    bMappSubindex;
+BYTE    bObdSubindex;
+WORD    wObdMappIndex;
+WORD    wObdCommIndex;
+WORD    wPdoId;
+BYTE    bObdData;
+BYTE    bObjectCount;
+BYTE    bFrameData;
+BOOL    fValid;
+tEplObdSize     ObdSize;
+tEplFrame      *pFrame;
+tEplFrameInfo  *pFrameInfo;
+unsigned int    uiNodeId;
+tEplMsgType     MsgType;
+
+    // 0xFF=invalid, RPDO: 0x00=PReq, localNodeId=PRes, remoteNodeId=PRes
+    //               TPDO: 0x00=PRes, MN: CnNodeId=PReq
+
+    switch (pEvent_p->m_EventType)
+    {
+        case kEplEventTypePdoRx:  // RPDO received
+            pFrame = (tEplFrame *) pEvent_p->m_pArg;
+
+            // check if received RPDO is valid
+            bFrameData = AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1);
+            if ((bFrameData & EPL_FRAME_FLAG1_RD) == 0)
+            {   // RPDO invalid
+                goto Exit;
+            }
+
+            // retrieve EPL message type
+            MsgType = AmiGetByteFromLe(&pFrame->m_le_bMessageType);
+            if (MsgType == kEplMsgTypePreq)
+            {   // RPDO is PReq frame
+                uiNodeId = EPL_PDO_PREQ_NODE_ID;  // 0x00
+            }
+            else
+            {   // RPDO is PRes frame
+                // retrieve node ID
+                uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
+            }
+
+            // search for appropriate valid RPDO in OD
+            wObdMappIndex = EPL_PDOK_OBD_IDX_RX_MAPP_PARAM;
+            for (wObdCommIndex = EPL_PDOK_OBD_IDX_RX_COMM_PARAM;
+                wObdCommIndex < (EPL_PDOK_OBD_IDX_RX_COMM_PARAM + 0x00FF);
+                wObdCommIndex++, wObdMappIndex++)
+            {
+                ObdSize = 1;
+                // read node ID from OD
+                Ret = EplObdReadEntry(wObdCommIndex, 0x01, &bObdData, &ObdSize);
+                if ((Ret == kEplObdIndexNotExist)
+                    || (Ret == kEplObdSubindexNotExist)
+                    || (Ret == kEplObdIllegalPart))
+                {   // PDO does not exist; last PDO reached
+                    Ret = kEplSuccessful;
+                    goto Exit;
+                }
+                else if (Ret != kEplSuccessful)
+                {   // other fatal error occured
+                    goto Exit;
+                }
+                // entry read successfully
+                if (bObdData != uiNodeId)
+                {   // node ID does not equal - wrong PDO, try next PDO in OD
+                    continue;
+                }
+                ObdSize = 1;
+                // read number of mapped objects from OD; this indicates if the PDO is valid
+                Ret = EplObdReadEntry(wObdMappIndex, 0x00, &bObjectCount, &ObdSize);
+                if ((Ret == kEplObdIndexNotExist)
+                    || (Ret == kEplObdSubindexNotExist)
+                    || (Ret == kEplObdIllegalPart))
+                {   // PDO does not exist; last PDO reached
+                    Ret = kEplSuccessful;
+                    goto Exit;
+                }
+                else if (Ret != kEplSuccessful)
+                {   // other fatal error occured
+                    goto Exit;
+                }
+                // entry read successfully
+                if (bObjectCount == 0)
+                {   // PDO in OD not valid, try next PDO in OD
+                    continue;
+                }
+
+                ObdSize = 1;
+                // check PDO mapping version
+                Ret = EplObdReadEntry(wObdCommIndex, 0x02, &bObdData, &ObdSize);
+                if (Ret != kEplSuccessful)
+                {   // other fatal error occured
+                    goto Exit;
+                }
+                // entry read successfully
+                // retrieve PDO version from frame
+                bFrameData = AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bPdoVersion);
+                if ((bObdData & EPL_VERSION_MAIN) != (bFrameData & EPL_VERSION_MAIN))
+                {   // PDO versions do not match
+                    // $$$ raise PDO error
+                    // termiate processing of this RPDO
+                    goto Exit;
+                }
+
+                // valid RPDO found
+
+                // retrieve PDO size
+                wPdoSize = AmiGetWordFromLe(&pFrame->m_Data.m_Pres.m_le_wSize);
+
+                // process mapping
+                for (bMappSubindex = 1; bMappSubindex <= bObjectCount; bMappSubindex++)
+                {
+                    ObdSize = 8;    // QWORD
+                    // read object mapping from OD
+                    Ret = EplObdReadEntry(wObdMappIndex, bMappSubindex, &qwObjectMapping, &ObdSize);
+                    if (Ret != kEplSuccessful)
+                    {   // other fatal error occured
+                        goto Exit;
+                    }
+
+                    // check if object mapping entry is valid, i.e. unequal zero, because "empty" entries are allowed
+                    if (qwObjectMapping == 0)
+                    {   // invalid entry, continue with next entry
+                        continue;
+                    }
+
+                    // decode object mapping
+                    wObdCommIndex = (WORD) (qwObjectMapping & 0x000000000000FFFFLL);
+                    bObdSubindex = (BYTE) ((qwObjectMapping & 0x0000000000FF0000LL) >> 16);
+                    wBitOffset = (WORD) ((qwObjectMapping & 0x0000FFFF00000000LL) >> 32);
+                    wBitSize = (WORD) ((qwObjectMapping & 0xFFFF000000000000LL) >> 48);
+
+                    // check if object exceeds PDO size
+                    if (((wBitOffset + wBitSize) >> 3) > wPdoSize)
+                    {   // wrong object mapping; PDO size is too low
+                        // $$$ raise PDO error
+                        // terminate processing of this RPDO
+                        goto Exit;
+                    }
+
+                    // copy object from RPDO to process/OD variable
+                    ObdSize = wBitSize >> 3;
+                    Ret = EplObdWriteEntryFromLe(wObdCommIndex, bObdSubindex, &pFrame->m_Data.m_Pres.m_le_abPayload[(wBitOffset >> 3)], ObdSize);
+                    if (Ret != kEplSuccessful)
+                    {   // other fatal error occured
+                        goto Exit;
+                    }
+
+                }
+
+                // processing finished successfully
+                goto Exit;
+            }
+            break;
+
+        case kEplEventTypePdoTx:  // TPDO transmitted
+            pFrameInfo = (tEplFrameInfo *) pEvent_p->m_pArg;
+            pFrame = pFrameInfo->m_pFrame;
+
+            // set TPDO invalid, so that only fully processed TPDOs are sent as valid
+            bFrameData = AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1);
+            AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bFlag1, (bFrameData & ~EPL_FRAME_FLAG1_RD));
+
+            // retrieve EPL message type
+            MsgType = AmiGetByteFromLe(&pFrame->m_le_bMessageType);
+            if (MsgType == kEplMsgTypePres)
+            {   // TPDO is PRes frame
+                uiNodeId = EPL_PDO_PRES_NODE_ID;  // 0x00
+            }
+            else
+            {   // TPDO is PReq frame
+                // retrieve node ID
+                uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
+            }
+
+            // search for appropriate valid TPDO in OD
+            wObdMappIndex = EPL_PDOK_OBD_IDX_TX_MAPP_PARAM;
+            wObdCommIndex = EPL_PDOK_OBD_IDX_TX_COMM_PARAM;
+            for (wPdoId = 0; ; wPdoId++, wObdCommIndex++, wObdMappIndex++)
+            {
+                ObdSize = 1;
+                // read node ID from OD
+                Ret = EplObdReadEntry(wObdCommIndex, 0x01, &bObdData, &ObdSize);
+                if ((Ret == kEplObdIndexNotExist)
+                    || (Ret == kEplObdSubindexNotExist)
+                    || (Ret == kEplObdIllegalPart))
+                {   // PDO does not exist; last PDO reached
+                    Ret = kEplSuccessful;
+                    goto Exit;
+                }
+                else if (Ret != kEplSuccessful)
+                {   // other fatal error occured
+                    goto Exit;
+                }
+                // entry read successfully
+                if (bObdData != uiNodeId)
+                {   // node ID does not equal - wrong PDO, try next PDO in OD
+                    continue;
+                }
+                ObdSize = 1;
+                // read number of mapped objects from OD; this indicates if the PDO is valid
+                Ret = EplObdReadEntry(wObdMappIndex, 0x00, &bObjectCount, &ObdSize);
+                if ((Ret == kEplObdIndexNotExist)
+                    || (Ret == kEplObdSubindexNotExist)
+                    || (Ret == kEplObdIllegalPart))
+                {   // PDO does not exist; last PDO reached
+                    Ret = kEplSuccessful;
+                    goto Exit;
+                }
+                else if (Ret != kEplSuccessful)
+                {   // other fatal error occured
+                    goto Exit;
+                }
+                // entry read successfully
+                if (bObjectCount == 0)
+                {   // PDO in OD not valid, try next PDO in OD
+                    continue;
+                }
+
+                // valid TPDO found
+
+                ObdSize = 1;
+                // get PDO mapping version from OD
+                Ret = EplObdReadEntry(wObdCommIndex, 0x02, &bObdData, &ObdSize);
+                if (Ret != kEplSuccessful)
+                {   // other fatal error occured
+                    goto Exit;
+                }
+                // entry read successfully
+                // set PDO version in frame
+                AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bPdoVersion, bObdData);
+
+                // calculate PDO size
+                wPdoSize = 0;
+
+                // process mapping
+                for (bMappSubindex = 1; bMappSubindex <= bObjectCount; bMappSubindex++)
+                {
+                    ObdSize = 8;    // QWORD
+                    // read object mapping from OD
+                    Ret = EplObdReadEntry(wObdMappIndex, bMappSubindex, &qwObjectMapping, &ObdSize);
+                    if (Ret != kEplSuccessful)
+                    {   // other fatal error occured
+                        goto Exit;
+                    }
+
+                    // check if object mapping entry is valid, i.e. unequal zero, because "empty" entries are allowed
+                    if (qwObjectMapping == 0)
+                    {   // invalid entry, continue with next entry
+                        continue;
+                    }
+
+                    // decode object mapping
+                    wObdCommIndex = (WORD) (qwObjectMapping & 0x000000000000FFFFLL);
+                    bObdSubindex = (BYTE) ((qwObjectMapping & 0x0000000000FF0000LL) >> 16);
+                    wBitOffset = (WORD) ((qwObjectMapping & 0x0000FFFF00000000LL) >> 32);
+                    wBitSize = (WORD) ((qwObjectMapping & 0xFFFF000000000000LL) >> 48);
+
+                    // calculate max PDO size
+                    ObdSize = wBitSize >> 3;
+                    wVarSize = (wBitOffset >> 3) + (WORD) ObdSize;
+                    if ((unsigned int)(wVarSize + 24) > pFrameInfo->m_uiFrameSize)
+                    {   // TPDO is too short
+                        // $$$ raise PDO error, set Ret
+                        goto Exit;
+                    }
+                    if (wVarSize > wPdoSize)
+                    {   // memorize new PDO size
+                        wPdoSize = wVarSize;
+                    }
+
+                    // copy object from process/OD variable to TPDO
+                    Ret = EplObdReadEntryToLe(wObdCommIndex, bObdSubindex, &pFrame->m_Data.m_Pres.m_le_abPayload[(wBitOffset >> 3)], &ObdSize);
+                    if (Ret != kEplSuccessful)
+                    {   // other fatal error occured
+                        goto Exit;
+                    }
+
+                }
+
+                // set PDO size in frame
+                AmiSetWordToLe(&pFrame->m_Data.m_Pres.m_le_wSize, wPdoSize);
+
+                Ret = EplPdokCalAreTpdosValid(&fValid);
+                if (fValid != FALSE)
+                {
+                    // set TPDO valid
+                    bFrameData = AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1);
+                    AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bFlag1, (bFrameData | EPL_FRAME_FLAG1_RD));
+                }
+
+                // processing finished successfully
+
+                goto Exit;
+            }
+            break;
+
+        case kEplEventTypePdoSoa: // SoA received
+
+            // invalidate TPDOs
+            Ret = EplPdokCalSetTpdosValid(FALSE);
+            break;
+
+        default:
+        {
+            ASSERTMSG(FALSE, "EplPdokProcess(): unhandled event type!\n");
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplPdokCal.c b/drivers/staging/epl/EplPdokCal.c
new file mode 100644 (file)
index 0000000..0dd9954
--- /dev/null
@@ -0,0 +1,274 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for kernel PDO Communication Abstraction Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdokCal.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/27 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "kernel/EplPdokCal.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplPdokCal                                          */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    BOOL            m_fTpdosValid;
+
+} tEplPdokCalInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplPdokCalInstance  EplPdokCalInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCalAddInstance()
+//
+// Description: add and initialize new instance of EPL stack
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCalAddInstance(void)
+{
+
+    EPL_MEMSET(&EplPdokCalInstance_g, 0, sizeof(EplPdokCalInstance_g));
+
+    return kEplSuccessful;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCalDelInstance()
+//
+// Description: deletes an instance of EPL stack
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCalDelInstance(void)
+{
+
+    return kEplSuccessful;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCalSetTpdosValid()
+//
+// Description: This function sets the validity flag for TPDOs to the
+//              specified value.
+//
+// Parameters:  fValid_p                = validity flag
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCalSetTpdosValid(BOOL fValid_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    EplPdokCalInstance_g.m_fTpdosValid = fValid_p;
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdokCalAreTpdosValid()
+//
+// Description: This function returns the validity flag for TPDOs.
+//
+// Parameters:  pfValid_p               = OUT: validity flag
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCalAreTpdosValid(BOOL * pfValid_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+
+    *pfValid_p = EplPdokCalInstance_g.m_fTpdosValid;
+
+    return Ret;
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+#endif
+
+// EOF
+
diff --git a/drivers/staging/epl/EplPdou.c b/drivers/staging/epl/EplPdou.c
new file mode 100644 (file)
index 0000000..289d25e
--- /dev/null
@@ -0,0 +1,608 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for user PDO module
+                Currently, this module just implements a OD callback function
+                to check if the PDO configuration is valid.
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdou.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+****************************************************************************/
+
+#include "EplInc.h"
+//#include "user/EplPdouCal.h"
+#include "user/EplObdu.h"
+#include "user/EplPdou.h"
+#include "EplSdoAc.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
+#error "EPL PDOu module needs EPL module OBDU or OBDK!"
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPL_PDOU_OBD_IDX_RX_COMM_PARAM  0x1400
+#define EPL_PDOU_OBD_IDX_RX_MAPP_PARAM  0x1600
+#define EPL_PDOU_OBD_IDX_TX_COMM_PARAM  0x1800
+#define EPL_PDOU_OBD_IDX_TX_MAPP_PARAM  0x1A00
+#define EPL_PDOU_OBD_IDX_MAPP_PARAM     0x0200
+#define EPL_PDOU_OBD_IDX_MASK           0xFF00
+#define EPL_PDOU_PDO_ID_MASK            0x00FF
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  EplPdou                                             */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM* pParam_p, unsigned int uiIndex_p);
+
+static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+                                    unsigned int* puiIndex_p,
+                                    unsigned int* puiSubIndex_p,
+                                    unsigned int* puiBitOffset_p,
+                                    unsigned int* puiBitSize_p);
+
+static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+                                       tEplObdAccess AccessType_p,
+                                       DWORD* pdwAbortCode_p,
+                                       unsigned int* puiPdoSize_p);
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdouAddInstance()
+//
+// Description: add and initialize new instance of EPL stack
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdouAddInstance(void)
+{
+
+    return kEplSuccessful;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdouDelInstance()
+//
+// Description: deletes an instance of EPL stack
+//
+// Parameters:  none
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdouDelInstance(void)
+{
+
+    return kEplSuccessful;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdouCbObdAccess
+//
+// Description: callback function for OD accesses
+//
+// Parameters:  pParam_p                = OBD parameter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM* pParam_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+unsigned int        uiPdoId;
+unsigned int        uiIndexType;
+tEplObdSize         ObdSize;
+BYTE                bObjectCount;
+QWORD               qwObjectMapping;
+tEplObdAccess       AccessType;
+BYTE                bMappSubindex;
+unsigned int        uiCurPdoSize;
+WORD                wMaxPdoSize;
+unsigned int        uiSubIndex;
+
+    // fetch PDO ID
+    uiPdoId = pParam_p->m_uiIndex & EPL_PDOU_PDO_ID_MASK;
+
+    // fetch object index type
+    uiIndexType = pParam_p->m_uiIndex & EPL_PDOU_OBD_IDX_MASK;
+
+    if (pParam_p->m_ObdEvent != kEplObdEvPreWrite)
+    {   // read accesses, post write events etc. are OK
+        pParam_p->m_dwAbortCode = 0;
+        goto Exit;
+    }
+
+    // check index type
+    switch (uiIndexType)
+    {
+        case EPL_PDOU_OBD_IDX_RX_COMM_PARAM:
+            // RPDO communication parameter accessed
+        case EPL_PDOU_OBD_IDX_TX_COMM_PARAM:
+        {   // TPDO communication parameter accessed
+            Ret = EplPdouCheckPdoValidity(pParam_p,
+                    (EPL_PDOU_OBD_IDX_MAPP_PARAM | pParam_p->m_uiIndex));
+            if (Ret != kEplSuccessful)
+            {   // PDO is valid or does not exist
+                goto Exit;
+            }
+
+            goto Exit;
+        }
+
+        case EPL_PDOU_OBD_IDX_RX_MAPP_PARAM:
+        {   // RPDO mapping parameter accessed
+
+            AccessType = kEplObdAccWrite;
+            break;
+        }
+
+        case EPL_PDOU_OBD_IDX_TX_MAPP_PARAM:
+        {   // TPDO mapping parameter accessed
+
+            AccessType = kEplObdAccRead;
+            break;
+        }
+
+        default:
+        {   // this callback function is only for
+            // PDO mapping and communication parameters
+            pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
+            goto Exit;
+        }
+    }
+
+    // RPDO and TPDO mapping parameter accessed
+
+    if (pParam_p->m_uiSubIndex == 0)
+    {   // object mapping count accessed
+
+        // PDO is enabled or disabled
+        bObjectCount = *((BYTE*) pParam_p->m_pArg);
+
+        if (bObjectCount == 0)
+        {   // PDO shall be disabled
+
+            // that is always possible
+            goto Exit;
+        }
+
+        // PDO shall be enabled
+        // it should have been disabled for this operation
+        Ret = EplPdouCheckPdoValidity(pParam_p, pParam_p->m_uiIndex);
+        if (Ret != kEplSuccessful)
+        {   // PDO is valid or does not exist
+            goto Exit;
+        }
+
+        if (AccessType == kEplObdAccWrite)
+        {
+            uiSubIndex = 0x04;  // PReqActPayloadLimit_U16
+        }
+        else
+        {
+            uiSubIndex = 0x05;  // PResActPayloadLimit_U16
+        }
+
+        // fetch maximum PDO size from Object 1F98h: NMT_CycleTiming_REC
+        ObdSize = sizeof (wMaxPdoSize);
+        Ret = EplObduReadEntry(0x1F98, uiSubIndex, &wMaxPdoSize, &ObdSize);
+        if (Ret != kEplSuccessful)
+        {   // other fatal error occured
+            pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
+            goto Exit;
+        }
+
+        // check all objectmappings
+        for (bMappSubindex = 1; bMappSubindex <= bObjectCount; bMappSubindex++)
+        {
+            // read object mapping from OD
+            ObdSize = sizeof (qwObjectMapping); // QWORD
+            Ret = EplObduReadEntry(pParam_p->m_uiIndex,
+                                bMappSubindex, &qwObjectMapping, &ObdSize);
+            if (Ret != kEplSuccessful)
+            {   // other fatal error occured
+                pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
+                goto Exit;
+            }
+
+            // check object mapping
+            Ret = EplPdouCheckObjectMapping(qwObjectMapping,
+                                   AccessType,
+                                   &pParam_p->m_dwAbortCode,
+                                   &uiCurPdoSize);
+            if (Ret != kEplSuccessful)
+            {   // illegal object mapping
+                goto Exit;
+            }
+
+            if (uiCurPdoSize > wMaxPdoSize)
+            {   // mapping exceeds object size
+                pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
+                Ret = kEplPdoVarNotFound;
+            }
+
+
+        }
+
+    }
+    else
+    {   // ObjectMapping
+        Ret = EplPdouCheckPdoValidity(pParam_p, pParam_p->m_uiIndex);
+        if (Ret != kEplSuccessful)
+        {   // PDO is valid or does not exist
+            goto Exit;
+        }
+
+        // check existence of object and validity of object length
+
+        qwObjectMapping = *((QWORD*) pParam_p->m_pArg);
+
+        Ret = EplPdouCheckObjectMapping(qwObjectMapping,
+                               AccessType,
+                               &pParam_p->m_dwAbortCode,
+                               &uiCurPdoSize);
+
+    }
+
+Exit:
+    return Ret;
+}
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdouCheckPdoValidity
+//
+// Description: check if PDO is valid
+//
+// Parameters:  pParam_p                = OBD parameter
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM* pParam_p, unsigned int uiIndex_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplObdSize         ObdSize;
+BYTE                bObjectCount;
+
+    ObdSize = 1;
+    // read number of mapped objects from OD; this indicates if the PDO is valid
+    Ret = EplObduReadEntry(uiIndex_p, 0x00, &bObjectCount, &ObdSize);
+    if (Ret != kEplSuccessful)
+    {   // other fatal error occured
+        pParam_p->m_dwAbortCode = EPL_SDOAC_GEN_INTERNAL_INCOMPATIBILITY;
+        goto Exit;
+    }
+    // entry read successfully
+    if (bObjectCount != 0)
+    {   // PDO in OD is still valid
+        pParam_p->m_dwAbortCode = EPL_SDOAC_GEN_PARAM_INCOMPATIBILITY;
+        Ret = kEplPdoNotExist;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdouDecodeObjectMapping
+//
+// Description: decodes the given object mapping entry into index, subindex,
+//              bit offset and bit size.
+//
+// Parameters:  qwObjectMapping_p       = object mapping entry
+//              puiIndex_p              = [OUT] pointer to object index
+//              puiSubIndex_p           = [OUT] pointer to subindex
+//              puiBitOffset_p          = [OUT] pointer to bit offset
+//              puiBitSize_p            = [OUT] pointer to bit size
+//
+// Returns:     (void)
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+                                    unsigned int* puiIndex_p,
+                                    unsigned int* puiSubIndex_p,
+                                    unsigned int* puiBitOffset_p,
+                                    unsigned int* puiBitSize_p)
+{
+    *puiIndex_p = (unsigned int)
+                    (qwObjectMapping_p & 0x000000000000FFFFLL);
+
+    *puiSubIndex_p = (unsigned int)
+                    ((qwObjectMapping_p & 0x0000000000FF0000LL) >> 16);
+
+    *puiBitOffset_p = (unsigned int)
+                    ((qwObjectMapping_p & 0x0000FFFF00000000LL) >> 32);
+
+    *puiBitSize_p = (unsigned int)
+                    ((qwObjectMapping_p & 0xFFFF000000000000LL) >> 48);
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplPdouCheckObjectMapping
+//
+// Description: checks the given object mapping entry.
+//
+// Parameters:  qwObjectMapping_p       = object mapping entry
+//              AccessType_p            = access type to mapped object:
+//                                        write = RPDO and read = TPDO
+//              puiPdoSize_p            = [OUT] pointer to covered PDO size
+//                                        (offset + size) in byte;
+//                                        0 if mapping failed
+//              pdwAbortCode_p          = [OUT] pointer to SDO abort code;
+//                                        0 if mapping is possible
+//
+// Returns:     tEplKernel              = error code
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+                                       tEplObdAccess AccessType_p,
+                                       DWORD* pdwAbortCode_p,
+                                       unsigned int* puiPdoSize_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplObdSize         ObdSize;
+unsigned int        uiIndex;
+unsigned int        uiSubIndex;
+unsigned int        uiBitOffset;
+unsigned int        uiBitSize;
+tEplObdAccess       AccessType;
+BOOL                fNumerical;
+
+    if (qwObjectMapping_p == 0)
+    {   // discard zero value
+        *puiPdoSize_p = 0;
+        goto Exit;
+    }
+
+    // decode object mapping
+    EplPdouDecodeObjectMapping(qwObjectMapping_p,
+                               &uiIndex,
+                               &uiSubIndex,
+                               &uiBitOffset,
+                               &uiBitSize);
+
+    if ((uiBitOffset & 0x7) != 0x0)
+    {   // bit mapping is not supported
+        *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
+        Ret = kEplPdoGranularityMismatch;
+        goto Exit;
+    }
+
+    if ((uiBitSize & 0x7) != 0x0)
+    {   // bit mapping is not supported
+        *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
+        Ret = kEplPdoGranularityMismatch;
+        goto Exit;
+    }
+
+    // check access type
+    Ret = EplObduGetAccessType(uiIndex, uiSubIndex, &AccessType);
+    if (Ret != kEplSuccessful)
+    {   // entry doesn't exist
+        *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_EXIST;
+        goto Exit;
+    }
+
+    if ((AccessType & kEplObdAccPdo) == 0)
+    {   // object is not mappable
+        *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_MAPPABLE;
+        Ret = kEplPdoVarNotFound;
+        goto Exit;
+    }
+
+    if ((AccessType & AccessType_p) == 0)
+    {   // object is not writeable (RPDO) or readable (TPDO) respectively
+        *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_MAPPABLE;
+        Ret = kEplPdoVarNotFound;
+        goto Exit;
+    }
+
+    ObdSize = EplObduGetDataSize(uiIndex, uiSubIndex);
+    if (ObdSize < (uiBitSize >> 3))
+    {   // object does not exist or has smaller size
+        *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
+        Ret = kEplPdoVarNotFound;
+    }
+
+    Ret = EplObduIsNumerical(uiIndex, uiSubIndex, &fNumerical);
+    if (Ret != kEplSuccessful)
+    {   // entry doesn't exist
+        *pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_EXIST;
+        goto Exit;
+    }
+
+    if ((fNumerical != FALSE)
+        && ((uiBitSize >> 3) != ObdSize))
+    {
+        // object is numerical,
+        // therefor size has to fit, but it does not.
+        *pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
+        Ret = kEplPdoVarNotFound;
+        goto Exit;
+    }
+
+    // calucaled needed PDO size
+    *puiPdoSize_p = (uiBitOffset >> 3) + (uiBitSize >> 3);
+
+Exit:
+    return Ret;
+}
+
+
+#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplSdo.h b/drivers/staging/epl/EplSdo.h
new file mode 100644 (file)
index 0000000..c41b32c
--- /dev/null
@@ -0,0 +1,271 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for api function of the sdo module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdo.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+ 2006/06/26 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "EplFrame.h"
+#include "EplSdoAc.h"
+
+#ifndef _EPLSDO_H_
+#define _EPLSDO_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+// global defines
+#ifndef EPL_SDO_MAX_PAYLOAD
+#define EPL_SDO_MAX_PAYLOAD     256
+#endif
+
+// handle between Protocol Abstraction Layer and asynchronous SDO Sequence Layer
+#define EPL_SDO_UDP_HANDLE      0x8000
+#define EPL_SDO_ASND_HANDLE     0x4000
+#define EPL_SDO_ASY_HANDLE_MASK 0xC000
+#define EPL_SDO_ASY_INVALID_HDL 0x3FFF
+
+// handle between  SDO Sequence Layer and sdo command layer
+#define EPL_SDO_ASY_HANDLE      0x8000
+#define EPL_SDO_PDO_HANDLE      0x4000
+#define EPL_SDO_SEQ_HANDLE_MASK 0xC000
+#define EPL_SDO_SEQ_INVALID_HDL 0x3FFF
+
+#define EPL_ASND_HEADER_SIZE        4
+//#define EPL_SEQ_HEADER_SIZE         4
+#define EPL_ETHERNET_HEADER_SIZE    14
+
+#define EPL_SEQ_NUM_MASK            0xFC
+
+// size for send buffer and history
+#define EPL_MAX_SDO_FRAME_SIZE      EPL_C_IP_MIN_MTU
+// size for receive frame
+// -> needed because SND-Kit sends up to 1518 Byte
+//    without Sdo-Command: Maximum Segment Size
+#define EPL_MAX_SDO_REC_FRAME_SIZE  EPL_C_IP_MAX_MTU
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+// handle between Protocol Abstraction Layer and asynchronuus SDO Sequence Layer
+typedef unsigned int tEplSdoConHdl;
+
+// callback function pointer for Protocol Abstraction Layer to call
+// asynchronuus SDO Sequence Layer
+typedef tEplKernel (PUBLIC* tEplSequLayerReceiveCb ) (
+    tEplSdoConHdl       ConHdl_p,
+    tEplAsySdoSeq*      pSdoSeqData_p,
+    unsigned int        uiDataSize_p);
+
+// handle between asynchronuus SDO Sequence Layer and SDO Command layer
+typedef unsigned int tEplSdoSeqConHdl;
+
+// callback function pointer for asynchronuus SDO Sequence Layer to call
+// SDO Command layer for received data
+typedef tEplKernel (PUBLIC* tEplSdoComReceiveCb) (
+    tEplSdoSeqConHdl    SdoSeqConHdl_p,
+    tEplAsySdoCom*      pAsySdoCom_p,
+    unsigned int        uiDataSize_p);
+
+// status of connection
+typedef enum
+{
+    kAsySdoConStateConnected    = 0x00,
+    kAsySdoConStateInitError    = 0x01,
+    kAsySdoConStateConClosed    = 0x02,
+    kAsySdoConStateAckReceived  = 0x03,
+    kAsySdoConStateFrameSended  = 0x04,
+    kAsySdoConStateTimeout      = 0x05
+
+}tEplAsySdoConState;
+
+// callback function pointer for asynchronuus SDO Sequence Layer to call
+// SDO Command layer for connection status
+typedef tEplKernel (PUBLIC* tEplSdoComConCb) (
+    tEplSdoSeqConHdl    SdoSeqConHdl_p,
+    tEplAsySdoConState  AsySdoConState_p);
+
+// handle between  SDO Command layer and application
+typedef unsigned int tEplSdoComConHdl;
+
+// status of connection
+typedef enum
+{
+    kEplSdoComTransferNotActive         =   0x00,
+    kEplSdoComTransferRunning           =   0x01,
+    kEplSdoComTransferTxAborted         =   0x02,
+    kEplSdoComTransferRxAborted         =   0x03,
+    kEplSdoComTransferFinished          =   0x04,
+    kEplSdoComTransferLowerLayerAbort   =   0x05
+
+} tEplSdoComConState;
+
+// SDO Services and Command-Ids from DS 1.0.0 p.152
+typedef enum
+{
+    kEplSdoServiceNIL               = 0x00,
+    kEplSdoServiceWriteByIndex      = 0x01,
+    kEplSdoServiceReadByIndex       = 0x02
+
+    //--------------------------------
+    // the following services are optional and
+    // not supported now
+/*
+    kEplSdoServiceWriteAllByIndex   = 0x03,
+    kEplSdoServiceReadAllByIndex    = 0x04,
+    kEplSdoServiceWriteByName       = 0x05,
+    kEplSdoServiceReadByName        = 0x06,
+
+    kEplSdoServiceFileWrite         = 0x20,
+    kEplSdoServiceFileRead          = 0x21,
+
+    kEplSdoServiceWriteMultiByIndex = 0x31,
+    kEplSdoServiceReadMultiByIndex  = 0x32,
+
+    kEplSdoServiceMaxSegSize        = 0x70
+
+    // 0x80 - 0xFF manufacturer specific
+
+ */
+} tEplSdoServiceType;
+
+// describes if read or write access
+typedef enum
+{
+    kEplSdoAccessTypeRead   = 0x00,
+    kEplSdoAccessTypeWrite  = 0x01
+
+} tEplSdoAccessType;
+
+typedef enum
+{
+    kEplSdoTypeAuto  =   0x00,
+    kEplSdoTypeUdp   =   0x01,
+    kEplSdoTypeAsnd  =   0x02,
+    kEplSdoTypePdo   =   0x03
+
+}tEplSdoType;
+
+typedef enum
+{
+    kEplSdoTransAuto             =   0x00,
+    kEplSdoTransExpedited        =   0x01,
+    kEplSdoTransSegmented        =   0x02
+
+
+} tEplSdoTransType;
+
+
+// structure to inform application about finish of SDO transfer
+typedef struct
+{
+    tEplSdoComConHdl    m_SdoComConHdl;
+    tEplSdoComConState  m_SdoComConState;
+    DWORD               m_dwAbortCode;
+    tEplSdoAccessType   m_SdoAccessType;
+    unsigned int        m_uiNodeId;         // NodeId of the target
+    unsigned int        m_uiTargetIndex;    // index which was accessed
+    unsigned int        m_uiTargetSubIndex; // subindex which was accessed
+    unsigned int        m_uiTransferredByte; // number of bytes transferred
+    void*               m_pUserArg;         // user definable argument pointer
+
+} tEplSdoComFinished;
+
+
+// callback function pointer to inform application about connection
+typedef tEplKernel (PUBLIC* tEplSdoFinishedCb) (
+    tEplSdoComFinished* pSdoComFinished_p);
+
+
+// structure to init SDO transfer to Read or Write by Index
+typedef struct
+{
+    tEplSdoComConHdl    m_SdoComConHdl;
+    unsigned int        m_uiIndex;
+    unsigned int        m_uiSubindex;
+    void*               m_pData;
+    unsigned int        m_uiDataSize;
+    unsigned int        m_uiTimeout;    // not used in this version
+    tEplSdoAccessType   m_SdoAccessType;
+    tEplSdoFinishedCb   m_pfnSdoFinishedCb;
+    void*               m_pUserArg;         // user definable argument pointer
+
+} tEplSdoComTransParamByIndex;
+
+
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPLSDO_H_
+
+
diff --git a/drivers/staging/epl/EplSdoAc.h b/drivers/staging/epl/EplSdoAc.h
new file mode 100644 (file)
index 0000000..97de988
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  definitions for SDO Abort codes
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoAc.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    ...
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/30 k.t.: first implementation
+
+****************************************************************************/
+
+#ifndef _EPLSDOAC_H_
+#define _EPLSDOAC_H_
+
+
+// =========================================================================
+// SDO abort codes
+// =========================================================================
+
+#define    EPL_SDOAC_TIME_OUT                            0x05040000L
+#define    EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER           0x05040001L
+#define    EPL_SDOAC_INVALID_BLOCK_SIZE                  0x05040002L
+#define    EPL_SDOAC_INVALID_SEQUENCE_NUMBER             0x05040003L
+#define    EPL_SDOAC_OUT_OF_MEMORY                       0x05040005L
+#define    EPL_SDOAC_UNSUPPORTED_ACCESS                  0x06010000L
+#define    EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ              0x06010001L
+#define    EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ              0x06010002L
+#define    EPL_SDOAC_OBJECT_NOT_EXIST                    0x06020000L
+#define    EPL_SDOAC_OBJECT_NOT_MAPPABLE                 0x06040041L
+#define    EPL_SDOAC_PDO_LENGTH_EXCEEDED                 0x06040042L
+#define    EPL_SDOAC_GEN_PARAM_INCOMPATIBILITY           0x06040043L
+#define    EPL_SDOAC_INVALID_HEARTBEAT_DEC               0x06040044L
+#define    EPL_SDOAC_GEN_INTERNAL_INCOMPATIBILITY        0x06040047L
+#define    EPL_SDOAC_ACCESS_FAILED_DUE_HW_ERROR          0x06060000L
+#define    EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH          0x06070010L
+#define    EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH           0x06070012L
+#define    EPL_SDOAC_DATA_TYPE_LENGTH_TOO_LOW            0x06070013L
+#define    EPL_SDOAC_SUB_INDEX_NOT_EXIST                 0x06090011L
+#define    EPL_SDOAC_VALUE_RANGE_EXCEEDED                0x06090030L
+#define    EPL_SDOAC_VALUE_RANGE_TOO_HIGH                0x06090031L
+#define    EPL_SDOAC_VALUE_RANGE_TOO_LOW                 0x06090032L
+#define    EPL_SDOAC_MAX_VALUE_LESS_MIN_VALUE            0x06090036L
+#define    EPL_SDOAC_GENERAL_ERROR                       0x08000000L
+#define    EPL_SDOAC_DATA_NOT_TRANSF_OR_STORED           0x08000020L
+#define    EPL_SDOAC_DATA_NOT_TRANSF_DUE_LOCAL_CONTROL   0x08000021L
+#define    EPL_SDOAC_DATA_NOT_TRANSF_DUE_DEVICE_STATE    0x08000022L
+#define    EPL_SDOAC_OBJECT_DICTIONARY_NOT_EXIST         0x08000023L
+#define    EPL_SDOAC_CONFIG_DATA_EMPTY                   0x08000024L
+
+
+#endif // _EPLSDOAC_H_
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
diff --git a/drivers/staging/epl/EplSdoAsndu.c b/drivers/staging/epl/EplSdoAsndu.c
new file mode 100644 (file)
index 0000000..54b1a17
--- /dev/null
@@ -0,0 +1,509 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for SDO/Asnd-Protocolabstractionlayer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoAsndu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.7 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/07 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplSdoAsndu.h"
+#include "user/EplDlluCal.h"
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef EPL_SDO_MAX_CONNECTION_ASND
+#define EPL_SDO_MAX_CONNECTION_ASND 5
+#endif
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+// instance table
+typedef struct
+{
+    unsigned int            m_auiSdoAsndConnection[EPL_SDO_MAX_CONNECTION_ASND];
+    tEplSequLayerReceiveCb  m_fpSdoAsySeqCb;
+
+
+} tEplSdoAsndInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static tEplSdoAsndInstance  SdoAsndInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <EPL SDO-Asnd Protocolabstraction layer>            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: EPL SDO-Asnd Protocolabstraction layer
+//
+//
+/***************************************************************************/
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduInit
+//
+// Description: init first instance of the module
+//
+//
+//
+// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
+//                                  callback-function
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+{
+tEplKernel  Ret;
+
+
+    Ret = EplSdoAsnduAddInstance(fpReceiveCb_p);
+
+return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduAddInstance
+//
+// Description: init additional instance of the module
+//
+//
+//
+// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
+//                                  callback-function
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // init control structure
+    EPL_MEMSET(&SdoAsndInstance_g, 0x00, sizeof(SdoAsndInstance_g));
+
+    // save pointer to callback-function
+    if (fpReceiveCb_p != NULL)
+    {
+        SdoAsndInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
+    }
+    else
+    {
+        Ret = kEplSdoUdpMissCb;
+    }
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
+                                   EplSdoAsnduCb,
+                                   kEplDllAsndFilterLocal);
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduDelInstance
+//
+// Description: del instance of the module
+//              del socket and del Listen-Thread
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    // deregister callback function from DLL
+    Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
+                                   NULL,
+                                   kEplDllAsndFilterNone);
+#endif
+
+return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduInitCon
+//
+// Description: init a new connect
+//
+//
+//
+// Parameters:  pSdoConHandle_p = pointer for the new connection handle
+//              uiTargetNodeId_p = NodeId of the target node
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl*  pSdoConHandle_p,
+                               unsigned int    uiTargetNodeId_p)
+{
+tEplKernel      Ret;
+unsigned int    uiCount;
+unsigned int    uiFreeCon;
+unsigned int*   puiConnection;
+
+    Ret = kEplSuccessful;
+
+    if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
+        || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST))
+    {
+        Ret = kEplSdoAsndInvalidNodeId;
+        goto Exit;
+    }
+
+    // get free entry in control structure
+    uiCount = 0;
+    uiFreeCon = EPL_SDO_MAX_CONNECTION_ASND;
+    puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
+    while(uiCount < EPL_SDO_MAX_CONNECTION_ASND)
+    {
+        if (*puiConnection == uiTargetNodeId_p)
+        {   // existing connection to target node found
+            // save handle for higher layer
+            *pSdoConHandle_p = (uiCount | EPL_SDO_ASND_HANDLE );
+
+            goto Exit;
+        }
+        else if (*puiConnection == 0)
+        {   // free entry-> save target nodeId
+            uiFreeCon = uiCount;
+        }
+        uiCount++;
+        puiConnection++;
+    }
+
+    if (uiFreeCon == EPL_SDO_MAX_CONNECTION_ASND)
+    {
+        // no free connection
+        Ret = kEplSdoAsndNoFreeHandle;
+    }
+    else
+    {
+        puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeCon];
+        *puiConnection = uiTargetNodeId_p;
+        // save handle for higher layer
+        *pSdoConHandle_p = (uiFreeCon | EPL_SDO_ASND_HANDLE );
+
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduSendData
+//
+// Description: send data using exisiting connection
+//
+//
+//
+// Parameters:  SdoConHandle_p  = connection handle
+//              pSrcData_p      = pointer to data
+//              dwDataSize_p    = number of databyte
+//                                  -> without asnd-header!!!
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl       SdoConHandle_p,
+                                    tEplFrame *          pSrcData_p,
+                                    DWORD                dwDataSize_p)
+{
+tEplKernel      Ret;
+unsigned int    uiArray;
+tEplFrameInfo   FrameInfo;
+
+    Ret = kEplSuccessful;
+
+    uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
+
+    if(uiArray > EPL_SDO_MAX_CONNECTION_ASND)
+    {
+        Ret = kEplSdoAsndInvalidHandle;
+        goto Exit;
+    }
+
+    // fillout Asnd header
+    // own node id not needed -> filled by DLL
+
+    // set message type
+    AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE)kEplMsgTypeAsnd); // ASnd == 0x06
+    // target node id
+    AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, (BYTE) SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray]);
+    // set source-nodeid (filled by DLL 0)
+    AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
+
+    // calc size
+    dwDataSize_p += EPL_ASND_HEADER_SIZE;
+
+    // send function of DLL
+    FrameInfo.m_uiFrameSize = dwDataSize_p;
+    FrameInfo.m_pFrame = pSrcData_p;
+    EPL_MEMSET(&FrameInfo.m_NetTime , 0x00, sizeof(tEplNetTime));
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+    Ret = EplDlluCalAsyncSend(&FrameInfo,kEplDllAsyncReqPrioGeneric);
+#endif
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduDelCon
+//
+// Description: delete connection from intern structure
+//
+//
+//
+// Parameters:  SdoConHandle_p  = connection handle
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
+{
+tEplKernel  Ret;
+unsigned int    uiArray;
+
+    Ret = kEplSuccessful;
+
+
+    uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
+    // check parameter
+    if(uiArray > EPL_SDO_MAX_CONNECTION_ASND)
+    {
+        Ret = kEplSdoAsndInvalidHandle;
+        goto Exit;
+    }
+
+    // set target nodeId to 0
+    SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray] = 0;
+
+Exit:
+    return Ret;
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsnduCb
+//
+// Description: callback function for SDO ASnd frames
+//
+//
+//
+// Parameters:      pFrameInfo_p = Frame with SDO payload
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiCount;
+unsigned int*   puiConnection;
+unsigned int    uiNodeId;
+unsigned int    uiFreeEntry = 0xFFFF;
+tEplSdoConHdl   SdoConHdl;
+tEplFrame*      pFrame;
+
+    pFrame = pFrameInfo_p->m_pFrame;
+
+    uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
+
+    // search corresponding entry in control structure
+    uiCount = 0;
+    puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
+    while (uiCount < EPL_SDO_MAX_CONNECTION_ASND)
+    {
+        if (uiNodeId == *puiConnection)
+        {
+            break;
+        }
+        else if ((*puiConnection == 0)
+            && (uiFreeEntry == 0xFFFF))
+        {   // free entry
+            uiFreeEntry = uiCount;
+        }
+        uiCount++;
+        puiConnection++;
+    }
+
+    if (uiCount == EPL_SDO_MAX_CONNECTION_ASND)
+    {
+        if (uiFreeEntry != 0xFFFF)
+        {
+            puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeEntry];
+            *puiConnection = uiNodeId;
+            uiCount = uiFreeEntry;
+        }
+        else
+        {
+            EPL_DBGLVL_SDO_TRACE0("EplSdoAsnduCb(): no free handle\n");
+            goto Exit;
+        }
+    }
+//    if (uiNodeId == *puiConnection)
+    {   // entry found or created
+        SdoConHdl = (uiCount | EPL_SDO_ASND_HANDLE );
+
+        SdoAsndInstance_g.m_fpSdoAsySeqCb(SdoConHdl, &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame, (pFrameInfo_p->m_uiFrameSize - 18));
+    }
+
+Exit:
+    return Ret;
+
+}
+
+
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+// EOF
+
diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c
new file mode 100644 (file)
index 0000000..8a4e1e2
--- /dev/null
@@ -0,0 +1,2401 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for asychronous SDO Sequence Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoAsySequ.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.10 $  $Date: 2008/11/13 17:13:09 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplSdoAsySequ.h"
+
+
+#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) == 0) &&\
+     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) == 0)   )
+
+    #error 'ERROR: At least UDP or Asnd module needed!'
+
+#endif
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define EPL_SDO_HISTORY_SIZE        5
+
+#ifndef EPL_MAX_SDO_SEQ_CON
+#define EPL_MAX_SDO_SEQ_CON         10
+#endif
+
+#define EPL_SEQ_DEFAULT_TIMEOUT     5000    // in [ms] => 5 sec
+
+#define EPL_SEQ_RETRY_COUNT         5       // => max. Timeout 30 sec
+
+#define EPL_SEQ_NUM_THRESHOLD       100     // threshold which distinguishes between old and new sequence numbers
+
+// define frame with size of Asnd-Header-, SDO Sequenze Header size, SDO Command header
+// and Ethernet-Header size
+#define EPL_SEQ_FRAME_SIZE          24
+// size of the header of the asynchronus SDO Sequence layer
+#define EPL_SEQ_HEADER_SIZE         4
+
+// buffersize for one frame in history
+#define EPL_SEQ_HISTROY_FRAME_SIZE  EPL_MAX_SDO_FRAME_SIZE
+
+// mask to get scon and rcon
+#define EPL_ASY_SDO_CON_MASK        0x03
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+// events for processfunction
+typedef enum
+{
+    kAsySdoSeqEventNoEvent  =   0x00,   // no Event
+    kAsySdoSeqEventInitCon  =   0x01,   // init connection
+    kAsySdoSeqEventFrameRec =   0x02,   // frame received
+    kAsySdoSeqEventFrameSend=   0x03,   // frame to send
+    kAsySdoSeqEventTimeout  =   0x04,   // Timeout for connection
+    kAsySdoSeqEventCloseCon =   0x05    // higher layer close connection
+
+}tEplAsySdoSeqEvent;
+
+// structure for History-Buffer
+typedef struct
+{
+    BYTE                m_bFreeEntries;
+    BYTE                m_bWrite; // index of the next free buffer entry
+    BYTE                m_bAck;   // index of the next message which should become acknowledged
+    BYTE                m_bRead;  // index between m_bAck and m_bWrite to the next message for retransmission
+    BYTE                m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE][EPL_SEQ_HISTROY_FRAME_SIZE];
+    unsigned int        m_auiFrameSize[EPL_SDO_HISTORY_SIZE];
+
+}tEplAsySdoConHistory;
+
+// state of the statemaschine
+typedef enum
+{
+    kEplAsySdoStateIdle         = 0x00,
+    kEplAsySdoStateInit1        = 0x01,
+    kEplAsySdoStateInit2        = 0x02,
+    kEplAsySdoStateInit3        = 0x03,
+    kEplAsySdoStateConnected    = 0x04,
+    kEplAsySdoStateWaitAck      = 0x05
+
+}tEplAsySdoState;
+
+// connection control structure
+typedef struct
+{
+    tEplSdoConHdl           m_ConHandle;
+    tEplAsySdoState         m_SdoState;
+    BYTE                    m_bRecSeqNum;   // name from view of the communication partner
+    BYTE                    m_bSendSeqNum;  // name from view of the communication partner
+    tEplAsySdoConHistory    m_SdoConHistory;
+    tEplTimerHdl            m_EplTimerHdl;
+    unsigned int            m_uiRetryCount; // retry counter
+    unsigned int            m_uiUseCount;   // one sequence layer connection may be used by
+                                            // multiple command layer connections
+
+}tEplAsySdoSeqCon;
+
+// instance structure
+typedef struct
+{
+    tEplAsySdoSeqCon    m_AsySdoConnection[EPL_MAX_SDO_SEQ_CON];
+    tEplSdoComReceiveCb m_fpSdoComReceiveCb;
+    tEplSdoComConCb     m_fpSdoComConCb;
+
+#if defined(WIN32) || defined(_WIN32)
+    LPCRITICAL_SECTION  m_pCriticalSection;
+    CRITICAL_SECTION    m_CriticalSection;
+
+    LPCRITICAL_SECTION  m_pCriticalSectionReceive;
+    CRITICAL_SECTION    m_CriticalSectionReceive;
+#endif
+
+}tEplAsySdoSequInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static tEplAsySdoSequInstance   AsySdoSequInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel EplSdoAsySeqProcess(unsigned int  uiHandle_p,
+                                         unsigned int       uiDataSize_p,
+                                         tEplFrame*         pData_p,
+                                         tEplAsySdoSeq*     pRecFrame_p,
+                                         tEplAsySdoSeqEvent Event_p);
+
+static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                         unsigned int       uiDataSize_p,
+                                         tEplFrame*         pData_p,
+                                         BOOL               fFrameInHistory);
+
+static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                         unsigned int       uiDataSize_p,
+                                         tEplFrame*         pEplFrame_p);
+
+tEplKernel PUBLIC EplSdoAsyReceiveCb (tEplSdoConHdl       ConHdl_p,
+                                        tEplAsySdoSeq*      pSdoSeqData_p,
+                                        unsigned int        uiDataSize_p);
+
+static tEplKernel EplSdoAsyInitHistory(void);
+
+static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                        tEplFrame*      pFrame_p,
+                                        unsigned int    uiSize_p);
+
+static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                        BYTE   bRecSeqNumber_p);
+
+static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                           tEplFrame**      ppFrame_p,
+                                           unsigned int*    puiSize_p,
+                                           BOOL             fInitRead);
+
+static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p);
+
+static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon* pAsySdoSeqCon_p,
+                                        unsigned long    ulTimeout);
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <EPL asychronus SDO Sequence layer>                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: this module contains the asynchronus SDO Sequence Layer for
+//              the EPL SDO service
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqInit
+//
+// Description: init first instance
+//
+//
+//
+// Parameters:  fpSdoComCb_p    = callback function to inform Command layer
+//                                about new frames
+//              fpSdoComConCb_p = callback function to inform command layer
+//                                about connection state
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+                                   tEplSdoComConCb fpSdoComConCb_p)
+{
+tEplKernel  Ret;
+
+
+    Ret = EplSdoAsySeqAddInstance(fpSdoComCb_p, fpSdoComConCb_p);
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqAddInstance
+//
+// Description: init following instances
+//
+//
+//
+// Parameters:  fpSdoComCb_p    = callback function to inform Command layer
+//                                about new frames
+//              fpSdoComConCb_p = callback function to inform command layer
+//                                about connection state
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqAddInstance (tEplSdoComReceiveCb fpSdoComCb_p,
+                                   tEplSdoComConCb fpSdoComConCb_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // check functionpointer
+    if(fpSdoComCb_p == NULL)
+    {
+        Ret = kEplSdoSeqMissCb;
+        goto Exit;
+    }
+    else
+    {
+        AsySdoSequInstance_g.m_fpSdoComReceiveCb = fpSdoComCb_p;
+    }
+
+    // check functionpointer
+    if(fpSdoComConCb_p == NULL)
+    {
+        Ret = kEplSdoSeqMissCb;
+        goto Exit;
+    }
+    else
+    {
+        AsySdoSequInstance_g.m_fpSdoComConCb = fpSdoComConCb_p;
+    }
+
+    // set controllstructure to 0
+    EPL_MEMSET(&AsySdoSequInstance_g.m_AsySdoConnection[0], 0x00, sizeof(AsySdoSequInstance_g.m_AsySdoConnection));
+
+    // init History
+    Ret = EplSdoAsyInitHistory();
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#if defined(WIN32) || defined(_WIN32)
+    // create critical section for process function
+    AsySdoSequInstance_g.m_pCriticalSection = &AsySdoSequInstance_g.m_CriticalSection;
+    InitializeCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
+
+    // init critical section for receive cb function
+    AsySdoSequInstance_g.m_pCriticalSectionReceive = &AsySdoSequInstance_g.m_CriticalSectionReceive;
+    InitializeCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
+#endif
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+    // init lower layer
+    Ret = EplSdoUdpuAddInstance(EplSdoAsyReceiveCb);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+    // init lower layer
+    Ret = EplSdoAsnduAddInstance(EplSdoAsyReceiveCb);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqDelInstance
+//
+// Description: delete instances
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqDelInstance()
+{
+tEplKernel  Ret;
+unsigned int        uiCount;
+tEplAsySdoSeqCon*   pAsySdoSeqCon;
+
+    Ret = kEplSuccessful;
+
+    // delete timer of open connections
+    uiCount = 0;
+    pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0];
+    while(uiCount < EPL_MAX_SDO_SEQ_CON)
+    {
+        if (pAsySdoSeqCon->m_ConHandle != 0)
+        {
+            EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+        }
+        uiCount++;
+        pAsySdoSeqCon++;
+    }
+
+
+#if defined(WIN32) || defined(_WIN32)
+    // delete critical section for process function
+    DeleteCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
+#endif
+
+    // set instance-table to 0
+    EPL_MEMSET(&AsySdoSequInstance_g, 0x00, sizeof(AsySdoSequInstance_g));
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+    // delete lower layer
+    Ret = EplSdoUdpuDelInstance();
+#endif
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+    // delete lower layer
+    Ret = EplSdoAsnduDelInstance();
+#endif
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqInitCon
+//
+// Description: start initialization of a sequence layer connection.
+//              It tries to reuse an existing connection to the same node.
+//
+//
+// Parameters:  pSdoSeqConHdl_p = pointer to the variable for the connection handle
+//              uiNodeId_p      = Node Id of the target
+//              SdoType          = Type of the SDO connection
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl* pSdoSeqConHdl_p,
+                                unsigned int uiNodeId_p,
+                                tEplSdoType   SdoType)
+{
+tEplKernel          Ret;
+unsigned int        uiCount;
+unsigned int        uiFreeCon;
+tEplSdoConHdl       ConHandle;
+tEplAsySdoSeqCon*   pAsySdoSeqCon;
+    Ret = kEplSuccessful;
+
+    // check SdoType
+    // call init function of the protcol abstraction layer
+    // which tries to find an existing connection to the same node
+    switch (SdoType)
+    {
+        // SDO over UDP
+        case kEplSdoTypeUdp:
+        {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+            Ret = EplSdoUdpuInitCon(&ConHandle,
+                                    uiNodeId_p);
+            if(Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+#else
+            Ret = kEplSdoSeqUnsupportedProt;
+#endif
+            break;
+        }
+
+        // SDO over Asnd
+        case kEplSdoTypeAsnd:
+        {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+            Ret = EplSdoAsnduInitCon(&ConHandle,
+                                    uiNodeId_p);
+            if(Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+#else
+            Ret = kEplSdoSeqUnsupportedProt;
+#endif
+            break;
+        }
+
+        // unsupported protocols
+        // -> auto should be replaced by command layer
+        case kEplSdoTypeAuto:
+        case kEplSdoTypePdo:
+        default:
+        {
+            Ret = kEplSdoSeqUnsupportedProt;
+            goto Exit;
+        }
+
+    }// end of switch(SdoType)
+
+
+    // find existing connection to the same node or find empty entry for connection
+    uiCount = 0;
+    uiFreeCon = EPL_MAX_SDO_SEQ_CON;
+    pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0];
+
+    while (uiCount < EPL_MAX_SDO_SEQ_CON)
+    {
+        if (pAsySdoSeqCon->m_ConHandle == ConHandle)
+        {   // existing connection found
+            break;
+        }
+        if (pAsySdoSeqCon->m_ConHandle == 0)
+        {
+            uiFreeCon = uiCount;
+        }
+        uiCount++;
+        pAsySdoSeqCon++;
+    }
+
+    if (uiCount == EPL_MAX_SDO_SEQ_CON)
+    {
+        if (uiFreeCon == EPL_MAX_SDO_SEQ_CON)
+        {   // no free entry found
+            switch (SdoType)
+            {
+                // SDO over UDP
+                case kEplSdoTypeUdp:
+                {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+                    Ret = EplSdoUdpuDelCon(ConHandle);
+                    if(Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+#endif
+                    break;
+                }
+
+                // SDO over Asnd
+                case kEplSdoTypeAsnd:
+                {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+                    Ret = EplSdoAsnduDelCon(ConHandle);
+                    if(Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+#endif
+                    break;
+                }
+
+                // unsupported protocols
+                // -> auto should be replaced by command layer
+                case kEplSdoTypeAuto:
+                case kEplSdoTypePdo:
+                default:
+                {
+                    Ret = kEplSdoSeqUnsupportedProt;
+                    goto Exit;
+                }
+
+            }// end of switch(SdoType)
+
+            Ret = kEplSdoSeqNoFreeHandle;
+            goto Exit;
+        }
+        else
+        {   // free entry found
+            pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiFreeCon];
+            pAsySdoSeqCon->m_ConHandle = ConHandle;
+            uiCount = uiFreeCon;
+        }
+    }
+
+    // set handle
+    *pSdoSeqConHdl_p = (uiCount | EPL_SDO_ASY_HANDLE);
+
+    // increment use counter
+    pAsySdoSeqCon->m_uiUseCount++;
+
+    // call intern process function
+    Ret = EplSdoAsySeqProcess(uiCount,
+                                0,
+                                NULL,
+                                NULL,
+                                kAsySdoSeqEventInitCon);
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqSendData
+//
+// Description: send sata unsing a established connection
+//
+//
+//
+// Parameters:  pSdoSeqConHdl_p = connection handle
+//              uiDataSize_p    = Size of Frame to send
+//                                  -> wihtout SDO sequence layer header, Asnd header
+//                                     and ethernetnet
+//                                  ==> SDO Sequence layer payload
+//              SdoType          = Type of the SDO connection
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+                                 unsigned int    uiDataSize_p,
+                                 tEplFrame*      pabData_p )
+{
+tEplKernel      Ret;
+unsigned int    uiHandle;
+
+
+
+    uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK);
+
+    // check if connection ready
+    if(AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].m_SdoState == kEplAsySdoStateIdle )
+    {
+        // no connection with this handle
+        Ret = kEplSdoSeqInvalidHdl;
+        goto Exit;
+    }
+    else if(AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].m_SdoState != kEplAsySdoStateConnected)
+    {
+        Ret = kEplSdoSeqConnectionBusy;
+        goto Exit;
+    }
+
+    Ret = EplSdoAsySeqProcess(uiHandle,
+                                uiDataSize_p,
+                                pabData_p,
+                                NULL,
+                                kAsySdoSeqEventFrameSend);
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqProcessEvent
+//
+// Description: function processes extern events
+//              -> later needed for timeout controll with timer-module
+//
+//
+//
+// Parameters:  pEvent_p = pointer to event
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent* pEvent_p)
+{
+tEplKernel          Ret;
+tEplTimerEventArg*  pTimerEventArg;
+tEplAsySdoSeqCon*   pAsySdoSeqCon;
+tEplTimerHdl        EplTimerHdl;
+unsigned int        uiCount;
+
+    Ret = kEplSuccessful;
+    // check parameter
+    if(pEvent_p == NULL)
+    {
+        Ret = kEplSdoSeqInvalidEvent;
+        goto Exit;
+    }
+
+    if(pEvent_p->m_EventType != kEplEventTypeTimer)
+    {
+        Ret = kEplSdoSeqInvalidEvent;
+        goto Exit;
+    }
+
+    // get timerhdl
+    pTimerEventArg = (tEplTimerEventArg*)pEvent_p->m_pArg;
+    EplTimerHdl = pTimerEventArg->m_TimerHdl;
+
+    // get pointer to intern control structure of connection
+    if(pTimerEventArg->m_ulArg == 0)
+    {
+        goto Exit;
+    }
+    pAsySdoSeqCon = (tEplAsySdoSeqCon*)pTimerEventArg->m_ulArg;
+
+    // check if time is current
+    if(EplTimerHdl != pAsySdoSeqCon->m_EplTimerHdl)
+    {
+        // delete timer
+        EplTimeruDeleteTimer(&EplTimerHdl);
+        goto Exit;
+    }
+
+    // delete timer
+    EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+
+    // get indexnumber of control structure
+    uiCount = 0;
+    while((&AsySdoSequInstance_g.m_AsySdoConnection[uiCount]) != pAsySdoSeqCon)
+    {
+        uiCount++;
+        if(uiCount > EPL_MAX_SDO_SEQ_CON)
+        {
+            goto Exit;
+        }
+    }
+
+
+    // process event and call processfunction if needed
+    Ret = EplSdoAsySeqProcess(uiCount,
+                                0,
+                                NULL,
+                                NULL,
+                                kAsySdoSeqEventTimeout);
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqDelCon
+//
+// Description: del and close one connection
+//
+//
+//
+// Parameters:  SdoSeqConHdl_p = handle of connection
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiHandle;
+tEplAsySdoSeqCon*   pAsySdoSeqCon;
+
+    uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK);
+
+    // check if handle invalid
+    if(uiHandle >= EPL_MAX_SDO_SEQ_CON)
+    {
+        Ret = kEplSdoSeqInvalidHdl;
+        goto Exit;
+    }
+
+    // get pointer to connection
+    pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle];
+
+    // decrement use counter
+    pAsySdoSeqCon->m_uiUseCount--;
+
+    if (pAsySdoSeqCon->m_uiUseCount == 0)
+    {
+        // process close in processfunction
+        Ret = EplSdoAsySeqProcess(uiHandle,
+                                    0,
+                                    NULL,
+                                    NULL,
+                                    kAsySdoSeqEventCloseCon);
+
+        //check protocol
+        if((pAsySdoSeqCon->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_UDP_HANDLE)
+        {
+        #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+            // call close function of lower layer
+            EplSdoUdpuDelCon(pAsySdoSeqCon->m_ConHandle);
+        #endif// end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+        }
+        else
+        {
+        #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+            // call close function of lower layer
+            EplSdoAsnduDelCon(pAsySdoSeqCon->m_ConHandle);
+        #endif// end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+        }
+
+        // delete timer
+        EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+
+        // clean controllstructure
+        EPL_MEMSET(pAsySdoSeqCon, 0x00, sizeof(tEplAsySdoSeqCon));
+        pAsySdoSeqCon->m_SdoConHistory.m_bFreeEntries = EPL_SDO_HISTORY_SIZE;
+    }
+
+Exit:
+    return Ret;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplEplSdoAsySeqProcess
+//
+// Description: intern function to process the asynchronus SDO Sequence Layer
+//              state maschine
+//
+//
+//
+// Parameters:  uiHandle_p      = index of the control structure of the connection
+//              uiDataSize_p    = size of data frame to process (can be 0)
+//                                  -> without size of sequence header and Asnd header!!!
+//
+//              pData_p         = pointer to frame to send (can be NULL)
+//              pRecFrame_p     = pointer to received frame (can be NULL)
+//              Event_p         = Event to process
+//
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsySeqProcess(unsigned int  uiHandle_p,
+                                         unsigned int       uiDataSize_p,
+                                         tEplFrame*         pData_p,
+                                         tEplAsySdoSeq*     pRecFrame_p,
+                                         tEplAsySdoSeqEvent Event_p)
+
+{
+tEplKernel          Ret;
+unsigned int        uiFrameSize;
+tEplFrame*          pEplFrame;
+tEplAsySdoSeqCon*   pAsySdoSeqCon;
+tEplSdoSeqConHdl    SdoSeqConHdl;
+unsigned int        uiFreeEntries;
+
+#if defined(WIN32) || defined(_WIN32)
+    // enter  critical section for process function
+    EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
+#endif
+
+    Ret = kEplSuccessful;
+
+    // get handle for hinger layer
+    SdoSeqConHdl = uiHandle_p | EPL_SDO_ASY_HANDLE;
+
+    // check if handle invalid
+    if((SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL)
+    {
+        Ret = kEplSdoSeqInvalidHdl;
+        goto Exit;
+    }
+
+    // get pointer to connection
+    pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle_p];
+
+    // check size
+    if((pData_p == NULL)&& (pRecFrame_p == NULL) && (uiDataSize_p != 0))
+    {
+        Ret = kEplSdoSeqInvalidFrame;
+        goto Exit;
+    }
+
+    // check state
+    switch(pAsySdoSeqCon->m_SdoState)
+    {
+        // idle state
+        case kEplAsySdoStateIdle:
+        {
+            // check event
+            switch(Event_p)
+            {
+                // new connection
+                // -> send init frame and change to
+                // kEplAsySdoStateInit1
+                case kAsySdoSeqEventInitCon:
+                {
+                    // set sending scon to 1
+                    pAsySdoSeqCon->m_bRecSeqNum = 0x01;
+                    // set set send rcon to 0
+                    pAsySdoSeqCon->m_bSendSeqNum = 0x00;
+                    Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                    if(Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+
+                    // change state
+                    pAsySdoSeqCon->m_SdoState = kEplAsySdoStateInit1;
+
+                    // set timer
+                    Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+
+                    break;
+                }
+
+                // init con from extern
+                // check rcon and scon
+                // -> send answer
+                case kAsySdoSeqEventFrameRec:
+                {
+/*
+                    PRINTF3("%s scon=%u rcon=%u\n",
+                            __FUNCTION__,
+                            pRecFrame_p->m_le_bSendSeqNumCon,
+                            pRecFrame_p->m_le_bRecSeqNumCon);
+*/
+                    // check if scon == 1 and rcon == 0
+                    if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x00)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01))
+                    {
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                        // create answer and send answer
+                        // set rcon to 1 (in send direction own scon)
+                        pAsySdoSeqCon->m_bRecSeqNum++;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        // change state to kEplAsySdoStateInit2
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateInit2;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+                    }
+                    else
+                    {   // error -> close
+                        // delete timer
+                        EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                        if (((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)
+                            || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00))
+                        {   // d.k. only answer with close message if the message sent was not a close message
+                            // save sequence numbers
+                            pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                            pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                            // set rcon and scon to 0
+                            pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                            pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                            // send frame
+                            EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                        }
+
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateInitError);
+                    }
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            }// end of switch(Event_p)
+            break;
+        }
+
+        // init connection step 1
+        // wait for frame with scon = 1
+        // and rcon = 1
+        case kEplAsySdoStateInit1:
+        {
+//            PRINTF0("EplSdoAsySequ: StateInit1\n");
+
+            // check event
+            switch(Event_p)
+            {
+                // frame received
+                case kAsySdoSeqEventFrameRec:
+                {
+                    // check scon == 1 and rcon == 1
+                    if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01))
+                    {   // create answer own scon = 2
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+
+                        pAsySdoSeqCon->m_bRecSeqNum++;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        // change state to kEplAsySdoStateInit3
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateInit3;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+
+                    }
+                    // check if scon == 1 and rcon == 0, i.e. other side wants me to be server
+                    else if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x00)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01))
+                    {
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                        // create answer and send answer
+                        // set rcon to 1 (in send direction own scon)
+                        pAsySdoSeqCon->m_bRecSeqNum++;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        // change state to kEplAsySdoStateInit2
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateInit2;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+                    }
+                    else
+                    {   // error -> Close
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                        // delete timer
+                        EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                        if (((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)
+                            || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00))
+                        {   // d.k. only answer with close message if the message sent was not a close message
+                            // save sequence numbers
+                            pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                            pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+
+                            // set rcon and scon to 0
+                            pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                            pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                            // send frame
+                            EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                        }
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateInitError);
+                    }
+                    break;
+                }
+
+                // timeout
+                case kAsySdoSeqEventTimeout:
+                {   // error -> Close
+                    pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+
+                    // set rcon and scon to 0
+                    pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                    pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                    // send frame
+                    EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                0,
+                                                NULL,
+                                                FALSE);
+                    // call Command Layer Cb
+                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                        kAsySdoConStateInitError);
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            }// end of switch(Event_p)
+            break;
+        }
+
+        // init connection step 2
+        case kEplAsySdoStateInit2:
+        {
+//            PRINTF0("EplSdoAsySequ: StateInit2\n");
+
+            // check event
+            switch(Event_p)
+            {
+                // frame received
+                case kAsySdoSeqEventFrameRec:
+                {
+                    // check scon == 2 and rcon == 1
+                    if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02))
+                    {   // create answer own rcon = 2
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+
+                        pAsySdoSeqCon->m_bRecSeqNum++;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        // change state to kEplAsySdoStateConnected
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateConnected;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                        kAsySdoConStateConnected);
+
+                    }
+                    // check scon == 1 and rcon == 1, i.e. other side wants me to initiate the connection
+                    else if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01))
+                    {
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                        // create answer and send answer
+                        // set rcon to 1 (in send direction own scon)
+                        pAsySdoSeqCon->m_bRecSeqNum++;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+                        // change state to kEplAsySdoStateInit3
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateInit3;
+
+                    }
+                    else
+                    {   // error -> Close
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                        // delete timer
+                        EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                        if (((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)
+                            || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00))
+                        {   // d.k. only answer with close message if the message sent was not a close message
+                            // save sequence numbers
+                            pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                            pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                            // set rcon and scon to 0
+                            pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                            pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                            // send frame
+                            EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                        }
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateInitError);
+                    }
+                    break;
+                }
+
+                // timeout
+                case kAsySdoSeqEventTimeout:
+                {   // error -> Close
+                    pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                    // set rcon and scon to 0
+                    pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                    pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                    // send frame
+                    EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                0,
+                                                NULL,
+                                                FALSE);
+
+                    // call Command Layer Cb
+                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateInitError);
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            }// end of switch(Event_p)
+            break;
+        }
+
+        // init connection step 3
+        case kEplAsySdoStateInit3:
+        {
+            // check event
+            switch(Event_p)
+            {
+                // frame received
+                case kAsySdoSeqEventFrameRec:
+                {
+                    // check scon == 2 and rcon == 2
+                    if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02))
+                    {
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                        // change state to kEplAsySdoStateConnected
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateConnected;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                        kAsySdoConStateConnected);
+
+                    }
+                    // check scon == 2 and rcon == 1
+                    else if(((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)
+                        &&((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02))
+                    {   // create answer own rcon = 2
+                        // save sequence numbers
+                        pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                        pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+
+                        pAsySdoSeqCon->m_bRecSeqNum++;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        // change state to kEplAsySdoStateConnected
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateConnected;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                        kAsySdoConStateConnected);
+
+                    }
+                    else
+                    {   // error -> Close
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                        // delete timer
+                        EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                        if (((pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)
+                            || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00))
+                        {   // d.k. only answer with close message if the message sent was not a close message
+                            // save sequence numbers
+                            pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                            pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+                            // set rcon and scon to 0
+                            pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                            pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                            // send frame
+                            EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                        }
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateInitError);
+                    }
+                    break;
+                }
+
+                // timeout
+                case kAsySdoSeqEventTimeout:
+                {   // error -> Close
+                    pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                    // set rcon and scon to 0
+                    pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                    pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                    // send frame
+                    EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                0,
+                                                NULL,
+                                                FALSE);
+
+                    // call Command Layer Cb
+                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                        kAsySdoConStateInitError);
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            }// end of switch(Event_p)
+            break;
+        }
+
+        // connection established
+        case kEplAsySdoStateConnected:
+        {
+            // check event
+            switch(Event_p)
+            {
+
+                // frame to send
+                case kAsySdoSeqEventFrameSend:
+                {
+                    // set timer
+                    Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                            EPL_SEQ_DEFAULT_TIMEOUT);
+                    // check if data frame or ack
+                    if(pData_p == NULL)
+                    {   // send ack
+                        // inc scon
+                        //pAsySdoSeqCon->m_bRecSeqNum += 4;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                    }
+                    else
+                    {   // send dataframe
+                        // increment send sequence number
+                        pAsySdoSeqCon->m_bRecSeqNum += 4;
+                        Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 uiDataSize_p,
+                                                 pData_p,
+                                                 TRUE);
+                        if(Ret == kEplSdoSeqRequestAckNeeded)
+                        { // request ack
+                            // change state to wait ack
+                            pAsySdoSeqCon->m_SdoState = kEplAsySdoStateWaitAck;
+                            // set Ret to kEplSuccessful, because no error
+                            // for higher layer
+                            Ret = kEplSuccessful;
+
+                        }
+                        else if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        else
+                        {
+                            // call Command Layer Cb
+                            AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateFrameSended);
+                        }
+                    }
+                    break;
+                }// end of case kAsySdoSeqEventFrameSend
+
+                // frame received
+                case kAsySdoSeqEventFrameRec:
+                {
+                BYTE bSendSeqNumCon = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+
+                    // set timer
+                    Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                            EPL_SEQ_DEFAULT_TIMEOUT);
+                    // check scon
+                    switch (bSendSeqNumCon & EPL_ASY_SDO_CON_MASK)
+                    {
+                        // close from other node
+                        case 0:
+                        case 1:
+                        {
+                            // return to idle
+                            pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                            // delete timer
+                            EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                            // call Command Layer Cb
+                            AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                    kAsySdoConStateConClosed);
+
+                            break;
+                        }
+
+                        // Request Ack or Error Ack
+                        // possible contain data
+                        case 3:
+                        // normal frame
+                        case 2:
+                        {
+                            if ((AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon) & EPL_ASY_SDO_CON_MASK) == 3)
+                            {
+//                                PRINTF0("EplSdoAsySequ: error response received\n");
+
+                                // error response (retransmission request)
+                                // resend frames from history
+
+                                // read frame from history
+                                Ret = EplSdoAsyReadFromHistory(pAsySdoSeqCon,
+                                                                &pEplFrame,
+                                                                &uiFrameSize,
+                                                                TRUE);
+                                if (Ret != kEplSuccessful)
+                                {
+                                    goto Exit;
+                                }
+
+                                while ((pEplFrame != NULL)
+                                       && (uiFrameSize != 0))
+                                {
+                                    // send frame
+                                    Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon,
+                                                        uiFrameSize,
+                                                        pEplFrame);
+                                    if(Ret != kEplSuccessful)
+                                    {
+                                        goto Exit;
+                                    }
+
+                                    // read next frame from history
+                                    Ret = EplSdoAsyReadFromHistory(pAsySdoSeqCon,
+                                                                    &pEplFrame,
+                                                                    &uiFrameSize,
+                                                                    FALSE);
+                                    if(Ret != kEplSuccessful)
+                                    {
+                                        goto Exit;
+                                    }
+                                } // end of while((pabFrame != NULL)
+                            }   // end of if (error response)
+
+                            if (((pAsySdoSeqCon->m_bSendSeqNum + 4) & EPL_SEQ_NUM_MASK) == (bSendSeqNumCon & EPL_SEQ_NUM_MASK))
+                            {   // next frame of sequence received
+                                // save send sequence number (without ack request)
+                                pAsySdoSeqCon->m_bSendSeqNum = bSendSeqNumCon & ~0x01;
+
+                                // check if ack or data-frame
+                                //ignore ack -> already processed
+                                if(uiDataSize_p > EPL_SEQ_HEADER_SIZE)
+                                {
+                                    AsySdoSequInstance_g.m_fpSdoComReceiveCb(
+                                                        SdoSeqConHdl,
+                                                        ((tEplAsySdoCom*) &pRecFrame_p->m_le_abSdoSeqPayload),
+                                                        (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
+                                    // call Command Layer Cb
+                                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                                kAsySdoConStateFrameSended);
+
+
+                                }
+                                else
+                                {
+                                    // call Command Layer Cb
+                                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                        kAsySdoConStateAckReceived);
+                                }
+                            }
+                            else if (((bSendSeqNumCon - pAsySdoSeqCon->m_bSendSeqNum - 4) & EPL_SEQ_NUM_MASK) < EPL_SEQ_NUM_THRESHOLD)
+                            {   // frame of sequence was lost,
+                                // because difference of received and old value
+                                // is less then halve of the values range.
+
+                                // send error frame with own rcon = 3
+                                pAsySdoSeqCon->m_bSendSeqNum |= 0x03;
+                                Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                                // restore send sequence number
+                                pAsySdoSeqCon->m_bSendSeqNum = (pAsySdoSeqCon->m_bSendSeqNum & EPL_SEQ_NUM_MASK) | 0x02;
+                                if(Ret != kEplSuccessful)
+                                {
+                                    goto Exit;
+                                }
+
+                                // break here, because a requested acknowledge
+                                // was sent implicitly above
+                                break;
+                            }
+                            // else, ignore repeated frame
+
+                            if ((bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 3)
+                            {   // ack request received
+
+                                // create ack with own scon = 2
+                                Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                                if(Ret != kEplSuccessful)
+                                {
+                                    goto Exit;
+                                }
+                            }
+
+                            break;
+                        }
+
+                    } // switch(pAsySdoSeqCon->m_bSendSeqNum & EPL_ASY_SDO_CON_MASK)
+                    break;
+                } // end of case kAsySdoSeqEventFrameRec:
+
+
+                //close event from higher layer
+                case kAsySdoSeqEventCloseCon:
+                {
+                    pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                    // set rcon and scon to 0
+                    pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                    pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                    // send frame
+                    EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                 0,
+                                                 NULL,
+                                                 FALSE);
+
+                    // delete timer
+                    EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                    // call Command Layer Cb is not necessary, because the event came from there
+//                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+//                                                            kAsySdoConStateInitError);
+                    break;
+                }
+
+                // timeout
+                case kAsySdoSeqEventTimeout:
+                {
+
+                    uiFreeEntries = EplSdoAsyGetFreeEntriesFromHistory(pAsySdoSeqCon);
+                    if ((uiFreeEntries < EPL_SDO_HISTORY_SIZE)
+                        && (pAsySdoSeqCon->m_uiRetryCount < EPL_SEQ_RETRY_COUNT))
+                    {   // unacknowlegded frames in history
+                        // and retry counter not exceeded
+
+                        // resend data with acknowledge request
+
+                        // increment retry counter
+                        pAsySdoSeqCon->m_uiRetryCount++;
+
+                        // set timer
+                        Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                                EPL_SEQ_DEFAULT_TIMEOUT);
+
+                        // read first frame from history
+                        Ret = EplSdoAsyReadFromHistory(pAsySdoSeqCon,
+                                                        &pEplFrame,
+                                                        &uiFrameSize,
+                                                        TRUE);
+                        if (Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+
+                        if ((pEplFrame != NULL)
+                               && (uiFrameSize != 0))
+                        {
+
+                            // set ack request in scon
+                            AmiSetByteToLe( &pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_bSendSeqNumCon,
+                                    AmiGetByteFromLe( &pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_bSendSeqNumCon) | 0x03);
+
+                            // send frame
+                            Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon,
+                                                uiFrameSize,
+                                                pEplFrame);
+                            if(Ret != kEplSuccessful)
+                            {
+                                goto Exit;
+                            }
+
+                        }
+                    }
+                    else
+                    {
+                        // timeout, because of no traffic -> Close
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                        // set rcon and scon to 0
+                        pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                        pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                        // send frame
+                        EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                    0,
+                                                    NULL,
+                                                    FALSE);
+
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                                kAsySdoConStateTimeout);
+                    }
+
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            }// end of switch(Event_p)
+            break;
+        }
+
+        // wait for Acknowledge (history buffer full)
+        case kEplAsySdoStateWaitAck:
+        {
+            PRINTF0("EplSdoAsySequ: StateWaitAck\n");
+
+            // set timer
+            Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
+                                        EPL_SEQ_DEFAULT_TIMEOUT);
+
+            //TODO: retry of acknowledge
+            if(Event_p == kAsySdoSeqEventFrameRec)
+            {
+                // check rcon
+                switch(pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK)
+                {
+                    // close-frome other node
+                    case 0:
+                    {
+                        // return to idle
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                        // delete timer
+                        EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                kAsySdoConStateConClosed);
+
+                        break;
+                    }
+
+                    // normal frame
+                    case 2:
+                    {
+                        // should be ack
+                        // -> change to state kEplAsySdoStateConnected
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateConnected;
+                        // call Command Layer Cb
+                        AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                                kAsySdoConStateAckReceived);
+                        // send data to higher layer if needed
+                        if(uiDataSize_p > EPL_SEQ_HEADER_SIZE)
+                        {
+                            AsySdoSequInstance_g.m_fpSdoComReceiveCb(
+                                                SdoSeqConHdl,
+                                                ((tEplAsySdoCom*) &pRecFrame_p->m_le_abSdoSeqPayload),
+                                                (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
+                        }
+                        break;
+                    }
+
+                    // Request Ack or Error Ack
+                    case 3:
+                    {
+                        // -> change to state kEplAsySdoStateConnected
+                        pAsySdoSeqCon->m_SdoState = kEplAsySdoStateConnected;
+
+                        if(pRecFrame_p->m_le_bRecSeqNumCon == pAsySdoSeqCon->m_bRecSeqNum )
+                        {   // ack request
+                            // -> send ack
+                            // save sequence numbers
+                            pAsySdoSeqCon->m_bRecSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bRecSeqNumCon);
+                            pAsySdoSeqCon->m_bSendSeqNum = AmiGetByteFromLe(&pRecFrame_p->m_le_bSendSeqNumCon);
+
+                            // create answer own rcon = 2
+                            pAsySdoSeqCon->m_bRecSeqNum--;
+
+                            // check if ack or data-frame
+                            if(uiDataSize_p > EPL_SEQ_HEADER_SIZE)
+                            {
+                                AsySdoSequInstance_g.m_fpSdoComReceiveCb(
+                                                    SdoSeqConHdl,
+                                                    ((tEplAsySdoCom*) &pRecFrame_p->m_le_abSdoSeqPayload),
+                                                    (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
+                                // call Command Layer Cb
+                                AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                            kAsySdoConStateFrameSended);
+
+
+                            }
+                            else
+                            {
+                                Ret = EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                                        0,
+                                                        NULL,
+                                                        FALSE);
+                                if(Ret != kEplSuccessful)
+                                {
+                                    goto Exit;
+                                }
+                            }
+
+                        }
+                        else
+                        {
+                            // error ack
+                            // resend frames from history
+
+                            // read frame from history
+                            Ret = EplSdoAsyReadFromHistory(pAsySdoSeqCon,
+                                                            &pEplFrame,
+                                                            &uiFrameSize,
+                                                            TRUE);
+                            while ((pEplFrame != NULL)
+                                    && (uiFrameSize != 0))
+                            {
+                                // send frame
+                                Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon,
+                                                    uiFrameSize,
+                                                    pEplFrame);
+                                if(Ret != kEplSuccessful)
+                                {
+                                    goto Exit;
+                                }
+                                // read next frame
+
+                                // read frame from history
+                                Ret = EplSdoAsyReadFromHistory(pAsySdoSeqCon,
+                                                                &pEplFrame,
+                                                                &uiFrameSize,
+                                                                FALSE);
+                            } // end of while((pabFrame != NULL)
+                        }
+                        break;
+                    }
+                }// end of switch(pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK)
+
+            }
+            else if(Event_p == kAsySdoSeqEventTimeout)
+            {   // error -> Close
+                pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
+                // set rcon and scon to 0
+                pAsySdoSeqCon->m_bSendSeqNum &= EPL_SEQ_NUM_MASK;
+                pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
+                // send frame
+                EplSdoAsySeqSendIntern(pAsySdoSeqCon,
+                                            0,
+                                            NULL,
+                                            FALSE);
+
+                // call Command Layer Cb
+                AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
+                                                        kAsySdoConStateTimeout);
+            }
+
+            break;
+        }
+
+        // unknown state
+        default:
+        {
+            EPL_DBGLVL_SDO_TRACE0("Error: Unknown State in EplSdoAsySeqProcess\n");
+
+        }
+    }// end of switch(pAsySdoSeqCon->m_SdoState)
+
+
+
+Exit:
+
+#if defined(WIN32) || defined(_WIN32)
+    // leave critical section for process function
+    LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
+#endif
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqSendIntern
+//
+// Description: intern function to create and send a frame
+//              -> if uiDataSize_p == 0 create a frame with infos from
+//                 pAsySdoSeqCon_p
+//
+//
+//
+// Parameters:  pAsySdoSeqCon_p = pointer to control structure of the connection
+//              uiDataSize_p    = size of data frame to process (can be 0)
+//                                  -> without size of sequence header and Asnd header!!!
+//              pData_p         = pointer to frame to process (can be NULL)
+//              fFrameInHistory = if TRUE frame is saved to history else not
+//
+//
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                         unsigned int       uiDataSize_p,
+                                         tEplFrame*         pData_p,
+                                         BOOL               fFrameInHistory_p)
+{
+tEplKernel      Ret;
+BYTE            abFrame[EPL_SEQ_FRAME_SIZE];
+tEplFrame*      pEplFrame;
+unsigned int    uiFreeEntries;
+
+    if(pData_p == NULL)
+    {   // set pointer to own frame
+        EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
+        pEplFrame = (tEplFrame*)&abFrame[0];
+    }
+    else
+    {   // set pointer to frame from calling function
+        pEplFrame = pData_p;
+    }
+
+    if(fFrameInHistory_p != FALSE)
+    {
+        // check if only one free entry in history buffer
+        uiFreeEntries = EplSdoAsyGetFreeEntriesFromHistory(pAsySdoSeqCon_p);
+        if(uiFreeEntries == 1)
+        {   // request an acknowledge in dataframe
+            // own scon = 3
+            pAsySdoSeqCon_p->m_bRecSeqNum |= 0x03;
+        }
+    }
+
+    // fillin header informations
+    // set service id sdo
+    AmiSetByteToLe( &pEplFrame->m_Data.m_Asnd.m_le_bServiceId, 0x05);
+    AmiSetByteToLe( &pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abReserved,0x00);
+    // set receive sequence number and rcon
+    AmiSetByteToLe( &pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_bRecSeqNumCon, pAsySdoSeqCon_p->m_bSendSeqNum);
+    // set send sequence number and scon
+    AmiSetByteToLe( &pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_bSendSeqNumCon, pAsySdoSeqCon_p->m_bRecSeqNum);
+
+    // add size
+    uiDataSize_p += EPL_SEQ_HEADER_SIZE;
+
+
+    // forward frame to appropriate lower layer
+    Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon_p,
+                                     uiDataSize_p,
+                                     pEplFrame);    // pointer to frame
+
+    // check if all allright
+    if ((Ret == kEplSuccessful)
+        && (fFrameInHistory_p != FALSE))
+    {
+        // set own scon to 2 if needed
+        if((pAsySdoSeqCon_p->m_bRecSeqNum & 0x03) == 0x03)
+        {
+            pAsySdoSeqCon_p->m_bRecSeqNum--;
+        }
+
+        // save frame to history
+        Ret = EplSdoAsyAddFrameToHistory(pAsySdoSeqCon_p,
+                                            pEplFrame,
+                                            uiDataSize_p);
+        if (Ret == kEplSdoSeqNoFreeHistory)
+        {   // request Ack needed
+            Ret = kEplSdoSeqRequestAckNeeded;
+        }
+
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoAsySeqSendLowerLayer
+//
+// Description: intern function to send a previously created frame to lower layer
+//
+// Parameters:  pAsySdoSeqCon_p = pointer to control structure of the connection
+//              uiDataSize_p    = size of data frame to process (can be 0)
+//                                  -> without size of Asnd header!!!
+//              pData_p         = pointer to frame to process (can be NULL)
+//
+// Returns:     tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                         unsigned int       uiDataSize_p,
+                                         tEplFrame*         pEplFrame_p)
+{
+tEplKernel      Ret;
+
+    // call send-function
+    // check handle for UDP or Asnd
+    if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_UDP_HANDLE)
+    {   // send over UDP
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+        Ret = EplSdoUdpuSendData(pAsySdoSeqCon_p->m_ConHandle,
+                                    pEplFrame_p,      // pointer to frame
+                                    uiDataSize_p);
+#else
+        Ret = kEplSdoSeqUnsupportedProt;
+#endif
+
+    }
+    else if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_ASND_HANDLE)
+    {   // ASND
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+        Ret = EplSdoAsnduSendData(pAsySdoSeqCon_p->m_ConHandle,
+                                    pEplFrame_p,      // pointer to frame
+                                    uiDataSize_p);
+#else
+        Ret = kEplSdoSeqUnsupportedProt;
+#endif
+    }
+    else
+    {   // error
+        Ret =  kEplSdoSeqInvalidHdl;
+    }
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsyReceiveCb
+//
+// Description:     callback-function for received frames from lower layer
+//
+//
+//
+// Parameters:      ConHdl_p        = handle of the connection
+//                  pSdoSeqData_p   = pointer to frame
+//                  uiDataSize_p    = size of frame
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsyReceiveCb (
+                tEplSdoConHdl       ConHdl_p,
+                tEplAsySdoSeq*      pSdoSeqData_p,
+                unsigned int        uiDataSize_p)
+{
+tEplKernel          Ret;
+unsigned int        uiCount = 0;
+unsigned int        uiFreeEntry = EPL_MAX_SDO_SEQ_CON;
+tEplAsySdoSeqCon*   pAsySdoSeqCon;
+
+#if defined(WIN32) || defined(_WIN32)
+    // enter  critical section
+    EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
+#endif
+
+    EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p,((BYTE*)pSdoSeqData_p)[0]);
+
+    // search controll structure for this connection
+    pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount];
+    while (uiCount < EPL_MAX_SDO_SEQ_CON)
+    {
+        if (pAsySdoSeqCon->m_ConHandle == ConHdl_p)
+        {
+            break;
+        }
+        else if ((pAsySdoSeqCon->m_ConHandle == 0)
+            && (uiFreeEntry == EPL_MAX_SDO_SEQ_CON))
+        {
+            // free entry
+            uiFreeEntry = uiCount;
+        }
+        uiCount++;
+        pAsySdoSeqCon++;
+    }
+
+    if (uiCount == EPL_MAX_SDO_SEQ_CON)
+    {   // new connection
+        if (uiFreeEntry == EPL_MAX_SDO_SEQ_CON)
+        {
+            Ret = kEplSdoSeqNoFreeHandle;
+            goto Exit;
+        }
+        else
+        {
+            pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiFreeEntry];
+            // save handle from lower layer
+            pAsySdoSeqCon->m_ConHandle = ConHdl_p;
+            // increment use counter
+            pAsySdoSeqCon->m_uiUseCount++;
+            uiCount = uiFreeEntry ;
+        }
+    }
+
+    // call history ack function
+    Ret = EplSdoAsyAckFrameToHistory(pAsySdoSeqCon,
+        (AmiGetByteFromLe(&pSdoSeqData_p->m_le_bRecSeqNumCon)& EPL_SEQ_NUM_MASK));
+    if (Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#if defined(WIN32) || defined(_WIN32)
+    // leave critical section
+    LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
+#endif
+
+    // call process function with pointer of frame and event kAsySdoSeqEventFrameRec
+    Ret = EplSdoAsySeqProcess(uiCount,
+                                uiDataSize_p,
+                                NULL,
+                                pSdoSeqData_p,
+                                kAsySdoSeqEventFrameRec);
+
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsyInitHistory
+//
+// Description:     inti function for history buffer
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsyInitHistory(void)
+{
+tEplKernel      Ret;
+unsigned int    uiCount;
+
+    Ret = kEplSuccessful;
+    // init m_bFreeEntries in history-buffer
+    for(uiCount = 0; uiCount < EPL_MAX_SDO_SEQ_CON; uiCount++)
+    {
+        AsySdoSequInstance_g.m_AsySdoConnection[uiCount].m_SdoConHistory.m_bFreeEntries = EPL_SDO_HISTORY_SIZE;
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsyAddFrameToHistory
+//
+// Description:     function to add a frame to the history buffer
+//
+//
+//
+// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
+//                  pFrame_p        = pointer to frame
+//                  uiSize_p        = size of the frame
+//                                     -> without size of the ethernet header
+//                                        and the asnd header
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                        tEplFrame*      pFrame_p,
+                                        unsigned int    uiSize_p)
+{
+tEplKernel              Ret;
+tEplAsySdoConHistory*   pHistory;
+
+    Ret = kEplSuccessful;
+
+    // add frame to history buffer
+
+    // check size
+    // $$$ d.k. EPL_SEQ_HISTORY_FRAME_SIZE includes the header size, but uiSize_p does not!!!
+    if(uiSize_p > EPL_SEQ_HISTROY_FRAME_SIZE)
+    {
+        Ret = kEplSdoSeqFrameSizeError;
+        goto Exit;
+    }
+
+    // save pointer to history
+    pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
+
+
+    // check if a free entry is available
+    if(pHistory->m_bFreeEntries > 0)
+    {   // write message in free entry
+        EPL_MEMCPY(&((tEplFrame*)pHistory->m_aabHistoryFrame[pHistory->m_bWrite])->m_le_bMessageType,
+                &pFrame_p->m_le_bMessageType,
+                uiSize_p + EPL_ASND_HEADER_SIZE);
+        // store size
+        pHistory->m_auiFrameSize[pHistory->m_bWrite] = uiSize_p;
+
+        // decremend number of free bufferentries
+        pHistory->m_bFreeEntries--;
+
+        // increment writeindex
+        pHistory->m_bWrite++;
+
+        // check if write-index run over array-boarder
+        if(pHistory->m_bWrite == EPL_SDO_HISTORY_SIZE)
+        {
+            pHistory->m_bWrite = 0;
+        }
+
+    }
+    else
+    {   // no free entry
+        Ret = kEplSdoSeqNoFreeHistory;
+    }
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsyAckFrameToHistory
+//
+// Description:     function to delete acknowledged frames fron history buffer
+//
+//
+//
+// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
+//                  bRecSeqNumber_p = receive sequence number of the received frame
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                        BYTE   bRecSeqNumber_p)
+{
+tEplKernel              Ret;
+tEplAsySdoConHistory*   pHistory;
+BYTE                    bAckIndex;
+BYTE                    bCurrentSeqNum;
+
+    Ret = kEplSuccessful;
+
+    // get pointer to history buffer
+    pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
+
+    // release all acknowledged frames from history buffer
+
+    // check if there are entries in history
+    if (pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE)
+    {
+        bAckIndex = pHistory->m_bAck;
+        do
+        {
+            bCurrentSeqNum = (((tEplFrame*)pHistory->m_aabHistoryFrame[bAckIndex])->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_bSendSeqNumCon & EPL_SEQ_NUM_MASK);
+            if (((bRecSeqNumber_p - bCurrentSeqNum) & EPL_SEQ_NUM_MASK)
+                    < EPL_SEQ_NUM_THRESHOLD)
+            {
+                pHistory->m_auiFrameSize[bAckIndex] = 0;
+                bAckIndex++;
+                pHistory->m_bFreeEntries++;
+                if (bAckIndex == EPL_SDO_HISTORY_SIZE)
+                {   // read index run over array-boarder
+                    bAckIndex = 0;
+                }
+            }
+            else
+            {   // nothing to do anymore,
+                // because any further frame in history has larger sequence
+                // number than the acknowledge
+                goto Exit;
+            }
+        }
+        while ((((bRecSeqNumber_p - 1 - bCurrentSeqNum) & EPL_SEQ_NUM_MASK)
+                    < EPL_SEQ_NUM_THRESHOLD)
+               && (pHistory->m_bWrite != bAckIndex));
+
+        // store local read-index to global var
+        pHistory->m_bAck = bAckIndex;
+    }
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsyReadFromHistory
+//
+// Description:     function to one frame from history
+//
+//
+//
+// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
+//                  ppFrame_p       = pointer to pointer to the buffer of the stored frame
+//                  puiSize_p       = OUT: size of the frame
+//                  fInitRead       = bool which indicate a start of retransmission
+//                                      -> return last not acknowledged message if TRUE
+//
+//
+// Returns:         tEplKernel = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p,
+                                           tEplFrame**      ppFrame_p,
+                                           unsigned int*    puiSize_p,
+                                           BOOL             fInitRead_p)
+{
+tEplKernel              Ret;
+tEplAsySdoConHistory*   pHistory;
+
+    Ret = kEplSuccessful;
+
+    // read one message from History
+
+    // get pointer to history buffer
+    pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
+
+    // check if init
+    if (fInitRead_p != FALSE)
+    {   // initialize read index to the index which shall be acknowledged next
+        pHistory->m_bRead = pHistory->m_bAck;
+    }
+
+    // check if entries are available for reading
+    if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE)
+        && (pHistory->m_bWrite != pHistory->m_bRead))
+    {
+//        PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (WORD)pHistory->m_bRead, (WORD)pHistory->m_bWrite, (WORD)pHistory->m_bAck);
+//        PRINTF2(", free entries = %u, next frame size = %u\n", (WORD)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
+
+        // return pointer to stored frame
+        *ppFrame_p = (tEplFrame*)pHistory->m_aabHistoryFrame[pHistory->m_bRead];
+
+        // save size
+        *puiSize_p = pHistory->m_auiFrameSize[pHistory->m_bRead];
+
+        pHistory->m_bRead++;
+        if(pHistory->m_bRead == EPL_SDO_HISTORY_SIZE)
+        {
+            pHistory->m_bRead = 0;
+        }
+
+    }
+    else
+    {
+//        PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (WORD)pHistory->m_bRead, (WORD)pHistory->m_bAck, (WORD)pHistory->m_bFreeEntries);
+
+        // no more frames to send
+        // return null pointer
+        *ppFrame_p = NULL;
+
+        *puiSize_p = 0;
+    }
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsyGetFreeEntriesFromHistory
+//
+// Description:     function returns the number of free histroy entries
+//
+//
+//
+// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
+//
+//
+// Returns:         unsigned int    = number of free entries
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon*  pAsySdoSeqCon_p)
+{
+unsigned int uiFreeEntries;
+
+    uiFreeEntries = (unsigned int)pAsySdoSeqCon_p->m_SdoConHistory.m_bFreeEntries;
+
+    return uiFreeEntries;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoAsySeqSetTimer
+//
+// Description:     function sets or modify timer in timermosule
+//
+//
+//
+// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
+//                  ulTimeout       = timeout in ms
+//
+//
+// Returns:         unsigned int    = number of free entries
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon* pAsySdoSeqCon_p,
+                                        unsigned long    ulTimeout)
+{
+tEplKernel      Ret;
+tEplTimerArg    TimerArg;
+
+    TimerArg.m_EventSink = kEplEventSinkSdoAsySeq;
+    TimerArg.m_ulArg = (unsigned long)pAsySdoSeqCon_p;
+
+    if(pAsySdoSeqCon_p->m_EplTimerHdl == 0)
+    {   // create new timer
+        Ret = EplTimeruSetTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl,
+                                    ulTimeout,
+                                    TimerArg);
+    }
+    else
+    {   // modify exisiting timer
+        Ret = EplTimeruModifyTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl,
+                                    ulTimeout,
+                                    TimerArg);
+
+    }
+
+
+    return Ret;
+}
+
+// EOF
+
diff --git a/drivers/staging/epl/EplSdoComu.c b/drivers/staging/epl/EplSdoComu.c
new file mode 100644 (file)
index 0000000..ce5af66
--- /dev/null
@@ -0,0 +1,3029 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for SDO Command Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoComu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.14 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplSdoComu.h"
+
+#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\
+     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0)   )
+
+    #error 'ERROR: At least SDO Server or SDO Client should be activate!'
+
+#endif
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+    #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
+
+    #error 'ERROR: SDO Server needs OBDu module!'
+
+    #endif
+
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef EPL_MAX_SDO_COM_CON
+#define EPL_MAX_SDO_COM_CON         5
+#endif
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+// intern events
+typedef enum
+{
+    kEplSdoComConEventSendFirst     = 0x00, // first frame to send
+    kEplSdoComConEventRec           = 0x01, // frame received
+    kEplSdoComConEventConEstablished= 0x02, // connection established
+    kEplSdoComConEventConClosed     = 0x03, // connection closed
+    kEplSdoComConEventAckReceived   = 0x04, // acknowledge received by lower layer
+                                        // -> continue sending
+    kEplSdoComConEventFrameSended   = 0x05, // lower has send a frame
+    kEplSdoComConEventInitError     = 0x06, // error duringinitialisiation
+                                            // of the connection
+    kEplSdoComConEventTimeout       = 0x07 // timeout in lower layer
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+
+    ,
+
+    kEplSdoComConEventInitCon       = 0x08, // init connection (only client)
+    kEplSdoComConEventAbort         = 0x09 // abort sdo transfer (only client)
+#endif
+
+
+}tEplSdoComConEvent;
+
+typedef enum
+{
+    kEplSdoComSendTypeReq      = 0x00,  // send a request
+    kEplSdoComSendTypeAckRes   = 0x01,  // send a resonse without data
+    kEplSdoComSendTypeRes      = 0x02,  // send response with data
+    kEplSdoComSendTypeAbort    = 0x03   // send abort
+
+}tEplSdoComSendType;
+
+// state of the state maschine
+typedef enum
+{
+    // General State
+    kEplSdoComStateIdle             = 0x00, // idle state
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+    // Server States
+    kEplSdoComStateServerSegmTrans  = 0x01, // send following frames
+#endif
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+    // Client States
+    kEplSdoComStateClientWaitInit   = 0x10, // wait for init connection
+                                            // on lower layer
+    kEplSdoComStateClientConnected  = 0x11, // connection established
+    kEplSdoComStateClientSegmTrans  = 0x12  // send following frames
+#endif
+
+
+
+} tEplSdoComState;
+
+
+// control structure for transaction
+typedef struct
+{
+    tEplSdoSeqConHdl    m_SdoSeqConHdl;     // if != 0 -> entry used
+    tEplSdoComState     m_SdoComState;
+    BYTE                m_bTransactionId;
+    unsigned int        m_uiNodeId;         // NodeId of the target
+                                            // -> needed to reinit connection
+                                            //    after timeout
+    tEplSdoTransType    m_SdoTransType;     // Auto, Expedited, Segmented
+    tEplSdoServiceType  m_SdoServiceType;   // WriteByIndex, ReadByIndex
+    tEplSdoType         m_SdoProtType;      // protocol layer: Auto, Udp, Asnd, Pdo
+    BYTE*               m_pData;            // pointer to data
+    unsigned int        m_uiTransSize;      // number of bytes
+                                            // to transfer
+    unsigned int        m_uiTransferredByte;// number of bytes
+                                            // already transferred
+    tEplSdoFinishedCb   m_pfnTransferFinished;// callback function of the
+                                            // application
+                                            // -> called in the end of
+                                            //    the SDO transfer
+    void*               m_pUserArg;         // user definable argument pointer
+
+    DWORD               m_dwLastAbortCode;  // save the last abort code
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+    // only for client
+    unsigned int        m_uiTargetIndex;    // index to access
+    unsigned int        m_uiTargetSubIndex; // subiondex to access
+
+    // for future use
+    unsigned int        m_uiTimeout;        // timeout for this connection
+
+#endif
+
+} tEplSdoComCon;
+
+// instance table
+typedef struct
+{
+    tEplSdoComCon       m_SdoComCon[EPL_MAX_SDO_COM_CON];
+
+#if defined(WIN32) || defined(_WIN32)
+    LPCRITICAL_SECTION  m_pCriticalSection;
+    CRITICAL_SECTION    m_CriticalSection;
+#endif
+
+}tEplSdoComInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+static tEplSdoComInstance SdoComInstance_g;
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComReceiveCb (tEplSdoSeqConHdl    SdoSeqConHdl_p,
+                                    tEplAsySdoCom*      pAsySdoCom_p,
+                                    unsigned int        uiDataSize_p);
+
+
+tEplKernel PUBLIC EplSdoComConCb (tEplSdoSeqConHdl    SdoSeqConHdl_p,
+                                    tEplAsySdoConState  AsySdoConState_p);
+
+static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl    SdoSeqConHdl_p,
+                                         tEplSdoComConEvent SdoComConEvent_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p);
+
+static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl   SdoComCon_p,
+                                         tEplSdoComConEvent SdoComConEvent_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p);
+
+static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl   SdoComCon_p,
+                                            tEplSdoComCon*     pSdoComCon_p,
+                                            tEplSdoComConState SdoComConState_p);
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon*     pSdoComCon_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p);
+
+static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon*     pSdoComCon_p,
+                                           unsigned int       uiIndex_p,
+                                           unsigned int       uiSubIndex_p,
+                                           tEplSdoComSendType SendType_p);
+
+static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon*     pSdoComCon_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p);
+#endif
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+
+static tEplKernel EplSdoComClientSend(tEplSdoComCon* pSdoComCon_p);
+
+static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl   SdoComCon_p,
+                                              tEplAsySdoCom*     pAsySdoCom_p);
+
+static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon* pSdoComCon_p,
+                                           DWORD          dwAbortCode_p);
+#endif
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <SDO Command Layer>                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: SDO Command layer Modul
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComInit
+//
+// Description: Init first instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComInit(void)
+{
+tEplKernel  Ret;
+
+
+    Ret = EplSdoComAddInstance();
+
+return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComAddInstance
+//
+// Description: Init additional instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComAddInstance(void)
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // init controll structure
+    EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g));
+
+    // init instance of lower layer
+    Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb);
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+#if defined(WIN32) || defined(_WIN32)
+    // create critical section for process function
+    SdoComInstance_g.m_pCriticalSection = &SdoComInstance_g.m_CriticalSection;
+    InitializeCriticalSection(SdoComInstance_g.m_pCriticalSection);
+#endif
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComDelInstance
+//
+// Description: delete instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComDelInstance(void)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+
+#if defined(WIN32) || defined(_WIN32)
+    // delete critical section for process function
+    DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection);
+#endif
+
+    Ret = EplSdoAsySeqDelInstance();
+    if(Ret != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+
+Exit:
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComDefineCon
+//
+// Description: function defines a SDO connection to another node
+//              -> init lower layer and returns a handle for the connection.
+//              Two client connections to the same node via the same protocol
+//              are not allowed. If this function detects such a situation
+//              it will return kEplSdoComHandleExists and the handle of
+//              the existing connection in pSdoComConHdl_p.
+//              Using of existing server connections is possible.
+//
+// Parameters:  pSdoComConHdl_p     = pointer to the buffer of the handle
+//              uiTargetNodeId_p    = NodeId of the targetnode
+//              ProtType_p          = type of protocol to use for connection
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl*  pSdoComConHdl_p,
+                                      unsigned int      uiTargetNodeId_p,
+                                      tEplSdoType       ProtType_p)
+{
+tEplKernel      Ret;
+unsigned int    uiCount;
+unsigned int    uiFreeHdl;
+tEplSdoComCon*  pSdoComCon;
+
+    // check Parameter
+    ASSERT(pSdoComConHdl_p != NULL);
+
+    // check NodeId
+    if((uiTargetNodeId_p == EPL_C_ADR_INVALID)
+        ||(uiTargetNodeId_p >= EPL_C_ADR_BROADCAST))
+    {
+        Ret = kEplInvalidNodeId;
+
+    }
+
+    // search free control structure
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
+    uiCount = 0;
+    uiFreeHdl = EPL_MAX_SDO_COM_CON;
+    while (uiCount < EPL_MAX_SDO_COM_CON)
+    {
+        if (pSdoComCon->m_SdoSeqConHdl == 0)
+        {   // free entry
+            uiFreeHdl = uiCount;
+        }
+        else if ((pSdoComCon->m_uiNodeId == uiTargetNodeId_p)
+            && (pSdoComCon->m_SdoProtType == ProtType_p))
+        {   // existing client connection with same node ID and same protocol type
+            *pSdoComConHdl_p = uiCount;
+            Ret = kEplSdoComHandleExists;
+            goto Exit;
+        }
+        uiCount++;
+        pSdoComCon++;
+    }
+
+    if (uiFreeHdl == EPL_MAX_SDO_COM_CON)
+    {
+        Ret = kEplSdoComNoFreeHandle;
+        goto Exit;
+    }
+
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl];
+    // save handle for application
+    *pSdoComConHdl_p = uiFreeHdl;
+    // save parameters
+    pSdoComCon->m_SdoProtType = ProtType_p;
+    pSdoComCon->m_uiNodeId = uiTargetNodeId_p;
+
+    // set Transaction Id
+    pSdoComCon->m_bTransactionId = 0;
+
+    // check protocol
+    switch(ProtType_p)
+    {
+        // udp
+        case kEplSdoTypeUdp:
+        {
+            // call connection int function of lower layer
+            Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
+                          pSdoComCon->m_uiNodeId,
+                          kEplSdoTypeUdp);
+            if(Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+            break;
+        }
+
+        // Asend
+        case kEplSdoTypeAsnd:
+        {
+            // call connection int function of lower layer
+            Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
+                          pSdoComCon->m_uiNodeId,
+                          kEplSdoTypeAsnd);
+            if(Ret != kEplSuccessful)
+            {
+                goto Exit;
+            }
+            break;
+        }
+
+        // Pdo -> not supported
+        case kEplSdoTypePdo:
+        default:
+        {
+            Ret = kEplSdoComUnsupportedProt;
+            goto Exit;
+        }
+    }// end of switch(m_ProtType_p)
+
+    // call process function
+    Ret = EplSdoComProcessIntern(uiFreeHdl,
+                                    kEplSdoComConEventInitCon,
+                                    NULL);
+
+Exit:
+    return Ret;
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComInitTransferByIndex
+//
+// Description: function init SDO Transfer for a defined connection
+//
+//
+//
+// Parameters:  SdoComTransParam_p    = Structure with parameters for connection
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex* pSdoComTransParam_p)
+{
+tEplKernel      Ret;
+tEplSdoComCon*  pSdoComCon;
+
+    // check parameter
+    if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF)
+        || (pSdoComTransParam_p->m_uiIndex == 0)
+        || (pSdoComTransParam_p->m_uiIndex > 0xFFFF)
+        || (pSdoComTransParam_p->m_pData == NULL)
+        || (pSdoComTransParam_p->m_uiDataSize == 0))
+    {
+        Ret = kEplSdoComInvalidParam;
+        goto Exit;
+    }
+
+    if(pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    // get pointer to control structure of connection
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl];
+
+    // check if handle ok
+    if(pSdoComCon->m_SdoSeqConHdl == 0)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    // check if command layer is idle
+    if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0)
+    {   // handle is not idle
+        Ret = kEplSdoComHandleBusy;
+        goto Exit;
+    }
+
+    // save parameter
+    // callback function for end of transfer
+    pSdoComCon->m_pfnTransferFinished = pSdoComTransParam_p->m_pfnSdoFinishedCb;
+    pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg;
+
+    // set type of SDO command
+    if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead)
+    {
+        pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex;
+    }
+    else
+    {
+        pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex;
+
+    }
+    // save pointer to data
+    pSdoComCon->m_pData = pSdoComTransParam_p->m_pData;
+    // maximal bytes to transfer
+    pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize;
+    // bytes already transfered
+    pSdoComCon->m_uiTransferredByte = 0;
+
+    // reset parts of control structure
+    pSdoComCon->m_dwLastAbortCode = 0;
+    pSdoComCon->m_SdoTransType = kEplSdoTransAuto;
+    // save timeout
+    //pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout;
+
+    // save index and subindex
+    pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex;
+    pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex;
+
+    // call process function
+    Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl,
+                                    kEplSdoComConEventSendFirst,    // event to start transfer
+                                    NULL);
+
+Exit:
+    return Ret;
+
+}
+#endif
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComUndefineCon
+//
+// Description: function undefine a SDO connection
+//
+//
+//
+// Parameters:  SdoComConHdl_p    = handle for the connection
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl  SdoComConHdl_p)
+{
+tEplKernel          Ret;
+tEplSdoComCon*      pSdoComCon;
+
+    Ret = kEplSuccessful;
+
+    if(SdoComConHdl_p >= EPL_MAX_SDO_COM_CON)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    // get pointer to control structure
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
+
+    // $$$ d.k. abort a running transfer before closing the sequence layer
+
+    if(((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK)  != EPL_SDO_SEQ_INVALID_HDL)
+        && (pSdoComCon->m_SdoSeqConHdl != 0))
+    {
+        // close connection in lower layer
+        switch(pSdoComCon->m_SdoProtType)
+        {
+            case kEplSdoTypeAsnd:
+            case kEplSdoTypeUdp:
+            {
+                Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                break;
+            }
+
+            case kEplSdoTypePdo:
+            case kEplSdoTypeAuto:
+            default:
+            {
+                Ret = kEplSdoComUnsupportedProt;
+                goto Exit;
+            }
+
+        }// end of switch(pSdoComCon->m_SdoProtType)
+    }
+
+
+    // clean controll structure
+    EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
+Exit:
+    return Ret;
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComGetState
+//
+// Description: function returns the state fo the connection
+//
+//
+//
+// Parameters:  SdoComConHdl_p    = handle for the connection
+//              pSdoComFinished_p = pointer to structur for sdo state
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl    SdoComConHdl_p,
+                                    tEplSdoComFinished* pSdoComFinished_p)
+{
+tEplKernel          Ret;
+tEplSdoComCon*      pSdoComCon;
+
+    Ret = kEplSuccessful;
+
+    if(SdoComConHdl_p >= EPL_MAX_SDO_COM_CON)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    // get pointer to control structure
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
+
+    // check if handle ok
+    if(pSdoComCon->m_SdoSeqConHdl == 0)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg;
+    pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId;
+    pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex;
+    pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex;
+    pSdoComFinished_p->m_uiTransferredByte = pSdoComCon->m_uiTransferredByte;
+    pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode;
+    pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p;
+    if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex)
+    {
+        pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite;
+    }
+    else
+    {
+        pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead;
+    }
+
+    if(pSdoComCon->m_dwLastAbortCode != 0)
+    {   // sdo abort
+        pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferRxAborted;
+
+        // delete abort code
+        pSdoComCon->m_dwLastAbortCode = 0;
+
+    }
+    else if((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK)== EPL_SDO_SEQ_INVALID_HDL)
+    {   // check state
+        pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferLowerLayerAbort;
+    }
+    else if(pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit)
+    {
+        // finished
+        pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferNotActive;
+    }
+    else if(pSdoComCon->m_uiTransSize == 0)
+    {   // finished
+        pSdoComFinished_p->m_SdoComConState = kEplSdoComTransferFinished;
+    }
+
+Exit:
+    return Ret;
+
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComSdoAbort
+//
+// Description: function abort a sdo transfer
+//
+//
+//
+// Parameters:  SdoComConHdl_p    = handle for the connection
+//              dwAbortCode_p     = abort code
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+                                    DWORD            dwAbortCode_p)
+{
+tEplKernel  Ret;
+tEplSdoComCon*      pSdoComCon;
+
+
+    if(SdoComConHdl_p >= EPL_MAX_SDO_COM_CON)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    // get pointer to control structure of connection
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
+
+    // check if handle ok
+    if(pSdoComCon->m_SdoSeqConHdl == 0)
+    {
+        Ret = kEplSdoComInvalidHandle;
+        goto Exit;
+    }
+
+    // save pointer to abort code
+    pSdoComCon->m_pData = (BYTE*)&dwAbortCode_p;
+
+    Ret = EplSdoComProcessIntern(SdoComConHdl_p,
+                                kEplSdoComConEventAbort,
+                                (tEplAsySdoCom*)NULL);
+
+Exit:
+    return Ret;
+}
+#endif
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComReceiveCb
+//
+// Description:     callback function for SDO Sequence Layer
+//                  -> indicates new data
+//
+//
+//
+// Parameters:      SdoSeqConHdl_p = Handle for connection
+//                  pAsySdoCom_p   = pointer to data
+//                  uiDataSize_p   = size of data ($$$ not used yet, but it should)
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComReceiveCb (tEplSdoSeqConHdl    SdoSeqConHdl_p,
+                                    tEplAsySdoCom*      pAsySdoCom_p,
+                                    unsigned int        uiDataSize_p)
+{
+tEplKernel       Ret;
+
+
+    // search connection internally
+    Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
+                                   kEplSdoComConEventRec,
+                                   pAsySdoCom_p);
+
+    EPL_DBGLVL_SDO_TRACE3("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n", SdoSeqConHdl_p, (WORD)pAsySdoCom_p->m_le_abCommandData[0], uiDataSize_p);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComConCb
+//
+// Description:     callback function called by SDO Sequence Layer to inform
+//                  command layer about state change of connection
+//
+//
+//
+// Parameters:      SdoSeqConHdl_p      = Handle of the connection
+//                  AsySdoConState_p    = Event of the connection
+//
+//
+// Returns:         tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComConCb (tEplSdoSeqConHdl    SdoSeqConHdl_p,
+                                    tEplAsySdoConState  AsySdoConState_p)
+{
+tEplKernel          Ret;
+tEplSdoComConEvent  SdoComConEvent = kEplSdoComConEventSendFirst;
+
+    Ret = kEplSuccessful;
+
+    // check state
+    switch(AsySdoConState_p)
+    {
+        case kAsySdoConStateConnected:
+        {
+            EPL_DBGLVL_SDO_TRACE0("Connection established\n");
+            SdoComConEvent = kEplSdoComConEventConEstablished;
+            // start transmission if needed
+            break;
+        }
+
+        case kAsySdoConStateInitError:
+        {
+            EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n");
+            SdoComConEvent = kEplSdoComConEventInitError;
+            // inform app about error and close sequence layer handle
+            break;
+        }
+
+        case kAsySdoConStateConClosed:
+        {
+            EPL_DBGLVL_SDO_TRACE0("Connection closed\n");
+            SdoComConEvent = kEplSdoComConEventConClosed;
+            // close sequence layer handle
+            break;
+        }
+
+        case kAsySdoConStateAckReceived:
+        {
+            EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n");
+            SdoComConEvent = kEplSdoComConEventAckReceived;
+            // continue transmission
+            break;
+        }
+
+        case kAsySdoConStateFrameSended:
+        {
+            EPL_DBGLVL_SDO_TRACE0("One Frame sent\n");
+            SdoComConEvent = kEplSdoComConEventFrameSended;
+            // to continue transmission
+            break;
+
+        }
+
+        case kAsySdoConStateTimeout:
+        {
+            EPL_DBGLVL_SDO_TRACE0("Timeout\n");
+            SdoComConEvent = kEplSdoComConEventTimeout;
+            // close sequence layer handle
+            break;
+
+        }
+    }// end of switch(AsySdoConState_p)
+
+    Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
+                                   SdoComConEvent,
+                                   (tEplAsySdoCom*)NULL);
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComSearchConIntern
+//
+// Description:     search a Sdo Sequence Layer connection handle in the
+//                  control structure of the Command Layer
+//
+// Parameters:      SdoSeqConHdl_p     = Handle to search
+//                  SdoComConEvent_p = event to process
+//                  pAsySdoCom_p     = pointer to received frame
+//
+// Returns:         tEplKernel
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl    SdoSeqConHdl_p,
+                                         tEplSdoComConEvent SdoComConEvent_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p)
+{
+tEplKernel          Ret;
+tEplSdoComCon*      pSdoComCon;
+tEplSdoComConHdl    HdlCount;
+tEplSdoComConHdl    HdlFree;
+
+    Ret = kEplSdoComNotResponsible;
+
+    // get pointer to first element of the array
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
+    HdlCount = 0;
+    HdlFree = 0xFFFF;
+    while (HdlCount < EPL_MAX_SDO_COM_CON)
+    {
+        if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p)
+        {   // matching command layer handle found
+            Ret = EplSdoComProcessIntern(HdlCount,
+                                    SdoComConEvent_p,
+                                    pAsySdoCom_p);
+        }
+        else if ((pSdoComCon->m_SdoSeqConHdl == 0)
+            &&(HdlFree == 0xFFFF))
+        {
+            HdlFree = HdlCount;
+        }
+
+        pSdoComCon++;
+        HdlCount++;
+    }
+
+    if (Ret == kEplSdoComNotResponsible)
+    {   // no responsible command layer handle found
+        if (HdlFree == 0xFFFF)
+        {   // no free handle
+            // delete connection immediately
+            // 2008/04/14 m.u./d.k. This connection actually does not exist.
+            //                      pSdoComCon is invalid.
+            // Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+            Ret = kEplSdoComNoFreeHandle;
+        }
+        else
+        {   // create new handle
+            HdlCount = HdlFree;
+            pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount];
+            pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p;
+            Ret = EplSdoComProcessIntern(HdlCount,
+                                    SdoComConEvent_p,
+                                    pAsySdoCom_p);
+        }
+    }
+
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComProcessIntern
+//
+// Description:     search a Sdo Sequence Layer connection handle in the
+//                  control structer of the Command Layer
+//
+//
+//
+// Parameters:      SdoComCon_p     = index of control structure of connection
+//                  SdoComConEvent_p = event to process
+//                  pAsySdoCom_p     = pointer to received frame
+//
+// Returns:         tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl   SdoComCon_p,
+                                         tEplSdoComConEvent SdoComConEvent_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p)
+{
+tEplKernel          Ret;
+tEplSdoComCon*      pSdoComCon;
+BYTE                bFlag;
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+DWORD               dwAbortCode;
+unsigned int        uiSize;
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+    // enter  critical section for process function
+    EnterCriticalSection(SdoComInstance_g.m_pCriticalSection);
+    EPL_DBGLVL_SDO_TRACE0("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n");
+#endif
+
+    Ret = kEplSuccessful;
+
+    // get pointer to control structure
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
+
+    // process state maschine
+    switch(pSdoComCon->m_SdoComState)
+    {
+        // idle state
+        case kEplSdoComStateIdle:
+        {
+            // check events
+            switch(SdoComConEvent_p)
+            {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+                // init con for client
+                case kEplSdoComConEventInitCon:
+                {
+
+                    // call of the init function already
+                    // processed in EplSdoComDefineCon()
+                    // only change state to kEplSdoComStateClientWaitInit
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
+                    break;
+                }
+#endif
+
+
+                // int con for server
+                case kEplSdoComConEventRec:
+                {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+                    // check if init of an transfer and no SDO abort
+                    if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0)
+                    {   // SDO request
+                        if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0)
+                        {   // no SDO abort
+                            // save tansaction id
+                            pSdoComCon->m_bTransactionId = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
+                            // check command
+                            switch(pAsySdoCom_p->m_le_bCommandId)
+                            {
+                                case kEplSdoServiceNIL:
+                                {   // simply acknowlegde NIL command on sequence layer
+
+                                    Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
+                                                                            0,
+                                                                            (tEplFrame*)NULL);
+
+                                    break;
+                                }
+
+                                case kEplSdoServiceReadByIndex:
+                                {   // read by index
+
+                                    // search entry an start transfer
+                                    EplSdoComServerInitReadByIndex(pSdoComCon,
+                                                                    pAsySdoCom_p);
+                                    // check next state
+                                    if(pSdoComCon->m_uiTransSize == 0)
+                                    {   // ready -> stay idle
+                                        pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
+                                        // reset abort code
+                                        pSdoComCon->m_dwLastAbortCode = 0;
+                                    }
+                                    else
+                                    {   // segmented transfer
+                                        pSdoComCon->m_SdoComState = kEplSdoComStateServerSegmTrans;
+                                    }
+
+                                    break;
+                                }
+
+                                case kEplSdoServiceWriteByIndex:
+                                {
+
+                                    // search entry an start write
+                                    EplSdoComServerInitWriteByIndex(pSdoComCon,
+                                                                    pAsySdoCom_p);
+                                    // check next state
+                                    if(pSdoComCon->m_uiTransSize == 0)
+                                    {   // already -> stay idle
+                                        pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
+                                        // reset abort code
+                                        pSdoComCon->m_dwLastAbortCode = 0;
+                                    }
+                                    else
+                                    {   // segmented transfer
+                                        pSdoComCon->m_SdoComState = kEplSdoComStateServerSegmTrans;
+                                    }
+
+                                    break;
+                                }
+
+                                default:
+                                {
+                                    //  unsupported command
+                                    //       -> abort senden
+                                    dwAbortCode = EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER;
+                                    // send abort
+                                    pSdoComCon->m_pData = (BYTE*)&dwAbortCode;
+                                    Ret = EplSdoComServerSendFrameIntern(pSdoComCon,
+                                                                0,
+                                                                0,
+                                                                kEplSdoComSendTypeAbort);
+
+                                }
+
+
+                            }// end of switch(pAsySdoCom_p->m_le_bCommandId)
+                        }
+                    }
+                    else
+                    {   // this command layer handle is not responsible
+                        // (wrong direction or wrong transaction ID)
+                        Ret = kEplSdoComNotResponsible;
+                        goto Exit;
+                    }
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+
+                    break;
+                }
+
+                // connection closed
+                case kEplSdoComConEventInitError:
+                case kEplSdoComConEventTimeout:
+                case kEplSdoComConEventConClosed:
+                {
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    // clean control structure
+                    EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+            }// end of switch(SdoComConEvent_p)
+            break;
+        }
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+        //-------------------------------------------------------------------------
+        // SDO Server part
+        // segmented transfer
+        case kEplSdoComStateServerSegmTrans:
+        {
+            // check events
+            switch(SdoComConEvent_p)
+            {
+                // send next frame
+                case kEplSdoComConEventAckReceived:
+                case kEplSdoComConEventFrameSended:
+                {
+                    // check if it is a read
+                    if(pSdoComCon->m_SdoServiceType == kEplSdoServiceReadByIndex)
+                    {
+                        // send next frame
+                        EplSdoComServerSendFrameIntern(pSdoComCon,
+                                                            0,
+                                                            0,
+                                                            kEplSdoComSendTypeRes);
+                        // if all send -> back to idle
+                        if(pSdoComCon->m_uiTransSize == 0)
+                        {   // back to idle
+                            pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
+                            // reset abort code
+                            pSdoComCon->m_dwLastAbortCode = 0;
+                        }
+
+                    }
+                    break;
+                }
+
+                // process next frame
+                case kEplSdoComConEventRec:
+                {
+                    // check if the frame is a SDO response and has the right transaction ID
+                    bFlag = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
+                    if (((bFlag & 0x80) != 0) && (AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId) == pSdoComCon->m_bTransactionId))
+                    {
+                        // check if it is a abort
+                        if((bFlag & 0x40) != 0)
+                        {   // SDO abort
+                            // clear control structure
+                            pSdoComCon->m_uiTransSize = 0;
+                            pSdoComCon->m_uiTransferredByte = 0;
+                            // change state
+                            pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
+                            // reset abort code
+                            pSdoComCon->m_dwLastAbortCode = 0;
+                            // d.k.: do not execute anything further on this command
+                            break;
+                        }
+
+                        // check if it is a write
+                        if(pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex)
+                        {
+                            // write data to OD
+                            uiSize = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+                            if(pSdoComCon->m_dwLastAbortCode == 0)
+                            {
+                                EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0],uiSize);
+                            }
+                            // update counter
+                            pSdoComCon->m_uiTransferredByte += uiSize;
+                            pSdoComCon->m_uiTransSize -= uiSize;
+
+                            // update pointer
+                            if(pSdoComCon->m_dwLastAbortCode == 0)
+                            {
+                                (/*(BYTE*)*/pSdoComCon->m_pData) += uiSize;
+                            }
+
+                            // check end of transfer
+                            if((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30)
+                            {   // transfer ready
+                                pSdoComCon->m_uiTransSize = 0;
+
+                                if(pSdoComCon->m_dwLastAbortCode == 0)
+                                {
+                                    // send response
+                                    // send next frame
+                                    EplSdoComServerSendFrameIntern(pSdoComCon,
+                                                                        0,
+                                                                        0,
+                                                                        kEplSdoComSendTypeRes);
+                                    // if all send -> back to idle
+                                    if(pSdoComCon->m_uiTransSize == 0)
+                                    {   // back to idle
+                                        pSdoComCon->m_SdoComState = kEplSdoComStateIdle;
+                                        // reset abort code
+                                        pSdoComCon->m_dwLastAbortCode = 0;
+                                    }
+                                }
+                                else
+                                {   // send dabort code
+                                    // send abort
+                                    pSdoComCon->m_pData = (BYTE*)&pSdoComCon->m_dwLastAbortCode;
+                                    Ret = EplSdoComServerSendFrameIntern(pSdoComCon,
+                                                                0,
+                                                                0,
+                                                                kEplSdoComSendTypeAbort);
+
+                                    // reset abort code
+                                    pSdoComCon->m_dwLastAbortCode = 0;
+
+                                }
+                            }
+                            else
+                            {
+                                // send acknowledge without any Command layer data
+                                Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
+                                                                        0,
+                                                                        (tEplFrame*)NULL);
+                            }
+                        }
+                    }
+                    else
+                    {   // this command layer handle is not responsible
+                        // (wrong direction or wrong transaction ID)
+                        Ret = kEplSdoComNotResponsible;
+                        goto Exit;
+                    }
+                    break;
+                }
+
+                // connection closed
+                case kEplSdoComConEventInitError:
+                case kEplSdoComConEventTimeout:
+                case kEplSdoComConEventConClosed:
+                {
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    // clean control structure
+                    EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+            }// end of switch(SdoComConEvent_p)
+
+            break;
+        }
+#endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+        //-------------------------------------------------------------------------
+        // SDO Client part
+        // wait for finish of establishing connection
+        case kEplSdoComStateClientWaitInit:
+        {
+
+            // if connection handle is invalid reinit connection
+            // d.k.: this will be done only on new events (i.e. InitTransfer)
+            if((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL)
+            {
+                // check kind of connection to reinit
+                // check protocol
+                switch(pSdoComCon->m_SdoProtType)
+                {
+                    // udp
+                    case kEplSdoTypeUdp:
+                    {
+                        // call connection int function of lower layer
+                        Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
+                                    pSdoComCon->m_uiNodeId,
+                                    kEplSdoTypeUdp);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        break;
+                    }
+
+                    // Asend -> not supported
+                    case kEplSdoTypeAsnd:
+                    {
+                        // call connection int function of lower layer
+                        Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
+                                    pSdoComCon->m_uiNodeId,
+                                    kEplSdoTypeAsnd);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+                        break;
+                    }
+
+                    // Pdo -> not supported
+                    case kEplSdoTypePdo:
+                    default:
+                    {
+                        Ret = kEplSdoComUnsupportedProt;
+                        goto Exit;
+                    }
+                }// end of switch(m_ProtType_p)
+                // d.k.: reset transaction ID, because new sequence layer connection was initialized
+                // $$$ d.k. is this really necessary?
+                //pSdoComCon->m_bTransactionId = 0;
+            }
+
+            // check events
+            switch(SdoComConEvent_p)
+            {
+                // connection established
+                case kEplSdoComConEventConEstablished:
+                {
+                    //send first frame if needed
+                    if((pSdoComCon->m_uiTransSize > 0)
+                        &&(pSdoComCon->m_uiTargetIndex != 0))
+                    {   // start SDO transfer
+                        Ret = EplSdoComClientSend(pSdoComCon);
+                        if(Ret != kEplSuccessful)
+                        {
+                            goto Exit;
+                        }
+
+                        // check if segemted transfer
+                        if(pSdoComCon->m_SdoTransType == kEplSdoTransSegmented)
+                        {
+                            pSdoComCon->m_SdoComState = kEplSdoComStateClientSegmTrans;
+                            goto Exit;
+                        }
+                    }
+                    // goto state kEplSdoComStateClientConnected
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
+                    goto Exit;
+                }
+
+                case kEplSdoComConEventSendFirst:
+                {
+                    // infos for transfer already saved by function EplSdoComInitTransferByIndex
+                    break;
+                }
+
+                case kEplSdoComConEventConClosed:
+                case kEplSdoComConEventInitError:
+                case kEplSdoComConEventTimeout:
+                {
+                    // close sequence layer handle
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
+                    // call callback function
+                    if (SdoComConEvent_p == kEplSdoComConEventTimeout)
+                    {
+                        pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_TIME_OUT;
+                    }
+                    else
+                    {
+                        pSdoComCon->m_dwLastAbortCode = 0;
+                    }
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
+                    // d.k.: do not clean control structure
+                    break;
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            } // end of  switch(SdoComConEvent_p)
+            break;
+        }
+
+        // connected
+        case kEplSdoComStateClientConnected:
+        {
+            // check events
+            switch(SdoComConEvent_p)
+            {
+                // send a frame
+                case kEplSdoComConEventSendFirst:
+                case kEplSdoComConEventAckReceived:
+                case kEplSdoComConEventFrameSended:
+                {
+                    Ret = EplSdoComClientSend(pSdoComCon);
+                    if(Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+
+                    // check if read transfer finished
+                    if((pSdoComCon->m_uiTransSize == 0)
+                        && (pSdoComCon->m_uiTransferredByte != 0)
+                        && (pSdoComCon->m_SdoServiceType == kEplSdoServiceReadByIndex))
+                    {
+                        // inc transaction id
+                        pSdoComCon->m_bTransactionId++;
+                        // call callback of application
+                        pSdoComCon->m_dwLastAbortCode = 0;
+                        Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
+
+                        goto Exit;
+                    }
+
+                    // check if segemted transfer
+                    if(pSdoComCon->m_SdoTransType == kEplSdoTransSegmented)
+                    {
+                        pSdoComCon->m_SdoComState = kEplSdoComStateClientSegmTrans;
+                        goto Exit;
+                    }
+                    break;
+                }
+
+                // frame received
+                case kEplSdoComConEventRec:
+                {
+                    // check if the frame is a SDO response and has the right transaction ID
+                    bFlag = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
+                    if (((bFlag & 0x80) != 0) && (AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId) == pSdoComCon->m_bTransactionId))
+                    {
+                        // check if abort or not
+                        if((bFlag & 0x40) != 0)
+                        {
+                            // send acknowledge without any Command layer data
+                            Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
+                                                                    0,
+                                                                    (tEplFrame*)NULL);
+                            // inc transaction id
+                            pSdoComCon->m_bTransactionId++;
+                            // save abort code
+                            pSdoComCon->m_dwLastAbortCode = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
+                            // call callback of application
+                            Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferRxAborted);
+
+                            goto Exit;
+                        }
+                        else
+                        {   // normal frame received
+                            // check frame
+                            Ret = EplSdoComClientProcessFrame(SdoComCon_p, pAsySdoCom_p);
+
+                            // check if transfer ready
+                            if(pSdoComCon->m_uiTransSize == 0)
+                            {
+                                // send acknowledge without any Command layer data
+                                Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
+                                                                        0,
+                                                                        (tEplFrame*)NULL);
+                                // inc transaction id
+                                pSdoComCon->m_bTransactionId++;
+                                // call callback of application
+                                pSdoComCon->m_dwLastAbortCode = 0;
+                                Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
+
+                                goto Exit;
+                            }
+
+                        }
+                    }
+                    else
+                    {   // this command layer handle is not responsible
+                        // (wrong direction or wrong transaction ID)
+                        Ret = kEplSdoComNotResponsible;
+                        goto Exit;
+                    }
+                    break;
+                }
+
+                // connection closed event go back to kEplSdoComStateClientWaitInit
+                case kEplSdoComConEventConClosed:
+                {   // connection closed by communication partner
+                    // close sequence layer handle
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    // set handle to invalid and enter kEplSdoComStateClientWaitInit
+                    pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
+                    // change state
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
+
+                    // call callback of application
+                    pSdoComCon->m_dwLastAbortCode = 0;
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
+
+                    goto Exit;
+
+                    break;
+                }
+
+                // abort to send from higher layer
+                case kEplSdoComConEventAbort:
+                {
+                    EplSdoComClientSendAbort(pSdoComCon,*((DWORD*)pSdoComCon->m_pData));
+
+                    // inc transaction id
+                    pSdoComCon->m_bTransactionId++;
+                    // call callback of application
+                    pSdoComCon->m_dwLastAbortCode = *((DWORD*)pSdoComCon->m_pData);
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
+
+                    break;
+                }
+
+                case kEplSdoComConEventInitError:
+                case kEplSdoComConEventTimeout:
+                {
+                    // close sequence layer handle
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
+                    // change state
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
+                    // call callback of application
+                    pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_TIME_OUT;
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
+
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            } // end of switch(SdoComConEvent_p)
+
+            break;
+        }
+
+        // process segmented transfer
+        case kEplSdoComStateClientSegmTrans:
+        {
+            // check events
+            switch(SdoComConEvent_p)
+            {
+                // sned a frame
+                case kEplSdoComConEventSendFirst:
+                case kEplSdoComConEventAckReceived:
+                case kEplSdoComConEventFrameSended:
+                {
+                    Ret = EplSdoComClientSend(pSdoComCon);
+                    if(Ret != kEplSuccessful)
+                    {
+                        goto Exit;
+                    }
+
+                    // check if read transfer finished
+                    if((pSdoComCon->m_uiTransSize == 0)
+                        && (pSdoComCon->m_SdoServiceType == kEplSdoServiceReadByIndex))
+                    {
+                        // inc transaction id
+                        pSdoComCon->m_bTransactionId++;
+                        // change state
+                        pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
+                        // call callback of application
+                        pSdoComCon->m_dwLastAbortCode = 0;
+                        Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
+
+                        goto Exit;
+                    }
+
+                    break;
+                }
+
+                // frame received
+                case kEplSdoComConEventRec:
+                {
+                    // check if the frame is a response
+                    bFlag = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
+                    if (((bFlag & 0x80) != 0) && (AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId) == pSdoComCon->m_bTransactionId))
+                    {
+                        // check if abort or not
+                        if((bFlag & 0x40) != 0)
+                        {
+                            // send acknowledge without any Command layer data
+                            Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
+                                                                    0,
+                                                                    (tEplFrame*)NULL);
+                            // inc transaction id
+                            pSdoComCon->m_bTransactionId++;
+                            // change state
+                            pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
+                            // save abort code
+                            pSdoComCon->m_dwLastAbortCode = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
+                            // call callback of application
+                            Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferRxAborted);
+
+                            goto Exit;
+                        }
+                        else
+                        {   // normal frame received
+                            // check frame
+                            Ret = EplSdoComClientProcessFrame(SdoComCon_p, pAsySdoCom_p);
+
+                            // check if transfer ready
+                            if(pSdoComCon->m_uiTransSize == 0)
+                            {
+                                // send acknowledge without any Command layer data
+                                Ret = EplSdoAsySeqSendData(pSdoComCon->m_SdoSeqConHdl,
+                                                                        0,
+                                                                        (tEplFrame*)NULL);
+                                // inc transaction id
+                                pSdoComCon->m_bTransactionId++;
+                                // change state
+                                pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
+                                // call callback of application
+                                pSdoComCon->m_dwLastAbortCode = 0;
+                                Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
+
+                            }
+
+                        }
+                    }
+                    break;
+                }
+
+                // connection closed event go back to kEplSdoComStateClientWaitInit
+                case kEplSdoComConEventConClosed:
+                {   // connection closed by communication partner
+                    // close sequence layer handle
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    // set handle to invalid and enter kEplSdoComStateClientWaitInit
+                    pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
+                    // change state
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
+                    // inc transaction id
+                    pSdoComCon->m_bTransactionId++;
+                    // call callback of application
+                    pSdoComCon->m_dwLastAbortCode = 0;
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferFinished);
+
+                    break;
+                }
+
+                // abort to send from higher layer
+                case kEplSdoComConEventAbort:
+                {
+                    EplSdoComClientSendAbort(pSdoComCon,*((DWORD*)pSdoComCon->m_pData));
+
+                    // inc transaction id
+                    pSdoComCon->m_bTransactionId++;
+                    // change state
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientConnected;
+                    // call callback of application
+                    pSdoComCon->m_dwLastAbortCode = *((DWORD*)pSdoComCon->m_pData);
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
+
+                    break;
+                }
+
+                case kEplSdoComConEventInitError:
+                case kEplSdoComConEventTimeout:
+                {
+                    // close sequence layer handle
+                    Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
+                    pSdoComCon->m_SdoSeqConHdl |= EPL_SDO_SEQ_INVALID_HDL;
+                    // change state
+                    pSdoComCon->m_SdoComState = kEplSdoComStateClientWaitInit;
+                    // call callback of application
+                    pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_TIME_OUT;
+                    Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferLowerLayerAbort);
+
+                }
+
+                default:
+                    // d.k. do nothing
+                    break;
+
+            } // end of switch(SdoComConEvent_p)
+
+            break;
+        }
+#endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+
+    }// end of switch(pSdoComCon->m_SdoComState)
+
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+Exit:
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+    // leave critical section for process function
+    EPL_DBGLVL_SDO_TRACE0("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n");
+    LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection);
+
+#endif
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComServerInitReadByIndex
+//
+// Description:    function start the processing of an read by index command
+//
+//
+//
+// Parameters:      pSdoComCon_p     = pointer to control structure of connection
+//                  pAsySdoCom_p     = pointer to received frame
+//
+// Returns:         tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon*     pSdoComCon_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p)
+{
+tEplKernel      Ret;
+unsigned int    uiIndex;
+unsigned int    uiSubindex;
+tEplObdSize     EntrySize;
+tEplObdAccess   AccessType;
+DWORD           dwAbortCode;
+
+    dwAbortCode = 0;
+
+    // a init of a read could not be a segmented transfer
+    // -> no variable part of header
+
+    // get index and subindex
+    uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
+    uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
+
+    // check accesstype of entry
+    // existens of entry
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+    Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
+/*#else
+    Ret = kEplObdSubindexNotExist;
+    AccessType = 0;
+#endif*/
+    if(Ret == kEplObdSubindexNotExist)
+    {   // subentry doesn't exist
+        dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
+        // send abort
+        pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);
+        goto Exit;
+    }
+    else if(Ret != kEplSuccessful)
+    {   // entry doesn't exist
+        dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
+        // send abort
+        pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);
+        goto Exit;
+    }
+
+    // compare accesstype must be read or const
+    if(((AccessType & kEplObdAccRead) == 0)
+        && ((AccessType & kEplObdAccConst) == 0))
+    {
+
+        if((AccessType & kEplObdAccWrite) != 0)
+        {
+            // entry read a write only object
+            dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ;
+        }
+        else
+        {
+            dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
+        }
+        // send abort
+        pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);
+        goto Exit;
+    }
+
+    // save service
+    pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex;
+
+    // get size of object to see iof segmented or expedited transfer
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+    EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
+/*#else
+    EntrySize = 0;
+#endif*/
+    if(EntrySize > EPL_SDO_MAX_PAYLOAD)
+    {   // segmented transfer
+        pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
+        // get pointer to object-entry data
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+        pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex, uiSubindex);
+//#endif
+    }
+    else
+    {   // expedited transfer
+        pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
+    }
+
+    pSdoComCon_p->m_uiTransSize = EntrySize;
+    pSdoComCon_p->m_uiTransferredByte = 0;
+
+    Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeRes);
+    if(Ret != kEplSuccessful)
+    {
+        // error -> abort
+        dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
+        // send abort
+        pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+#endif
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComServerSendFrameIntern();
+//
+// Description:    function creats and send a frame for server
+//
+//
+//
+// Parameters:      pSdoComCon_p     = pointer to control structure of connection
+//                  uiIndex_p        = index to send if expedited transfer else 0
+//                  uiSubIndex_p     = subindex to send if expedited transfer else 0
+//                  SendType_p       = to of frame to send
+//
+// Returns:         tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon*     pSdoComCon_p,
+                                           unsigned int       uiIndex_p,
+                                           unsigned int       uiSubIndex_p,
+                                           tEplSdoComSendType SendType_p)
+{
+tEplKernel      Ret;
+BYTE            abFrame[EPL_MAX_SDO_FRAME_SIZE];
+tEplFrame*      pFrame;
+tEplAsySdoCom*  pCommandFrame;
+unsigned int    uiSizeOfFrame;
+BYTE            bFlag;
+
+    Ret = kEplSuccessful;
+
+    pFrame = (tEplFrame*)&abFrame[0];
+
+    EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
+
+    // build generic part of frame
+    // get pointer to command layerpart of frame
+    pCommandFrame = &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abSdoSeqPayload;
+    AmiSetByteToLe(&pCommandFrame->m_le_bCommandId, pSdoComCon_p->m_SdoServiceType);
+    AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId, pSdoComCon_p->m_bTransactionId);
+
+    // set size to header size
+    uiSizeOfFrame = 8;
+
+    // check SendType
+    switch(SendType_p)
+    {
+        // requestframe to send
+        case kEplSdoComSendTypeReq:
+        {
+            // nothing to do for server
+            //-> error
+            Ret = kEplSdoComInvalidSendType;
+            break;
+        }
+
+        // response without data to send
+        case kEplSdoComSendTypeAckRes:
+        {
+            // set response flag
+            AmiSetByteToLe(&pCommandFrame->m_le_bFlags,  0x80);
+
+            // send frame
+            Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                            uiSizeOfFrame,
+                                            pFrame);
+
+            break;
+        }
+
+        // responsframe to send
+        case kEplSdoComSendTypeRes:
+        {
+            // set response flag
+            bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
+            bFlag |= 0x80;
+            AmiSetByteToLe(&pCommandFrame->m_le_bFlags,  bFlag);
+
+            // check type of resonse
+            if(pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited)
+            {   // Expedited transfer
+                // copy data in frame
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+                Ret = EplObduReadEntryToLe(uiIndex_p,
+                                        uiSubIndex_p,
+                                        &pCommandFrame->m_le_abCommandData[0],
+                                        (tEplObdSize*)&pSdoComCon_p->m_uiTransSize);
+                if(Ret != kEplSuccessful)
+                {
+                    goto Exit;
+                }
+//#endif
+
+                // set size of frame
+                AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, (WORD) pSdoComCon_p->m_uiTransSize);
+
+                // correct byte-counter
+                uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
+                pSdoComCon_p->m_uiTransferredByte += pSdoComCon_p->m_uiTransSize;
+                pSdoComCon_p->m_uiTransSize = 0;
+
+
+                // send frame
+                uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
+                Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                            uiSizeOfFrame,
+                                            pFrame);
+            }
+            else if(pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented)
+            {   // segmented transfer
+                // distinguish between init, segment and complete
+                if(pSdoComCon_p->m_uiTransferredByte == 0)
+                {   // init
+                    // set init flag
+                    bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
+                    bFlag |= 0x10;
+                    AmiSetByteToLe(&pCommandFrame->m_le_bFlags,  bFlag);
+                    // init variable header
+                    AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],pSdoComCon_p->m_uiTransSize);
+                    // copy data in frame
+                    EPL_MEMCPY(&pCommandFrame->m_le_abCommandData[4],pSdoComCon_p->m_pData, (EPL_SDO_MAX_PAYLOAD-4));
+
+                    // correct byte-counter
+                    pSdoComCon_p->m_uiTransSize -= (EPL_SDO_MAX_PAYLOAD-4);
+                    pSdoComCon_p->m_uiTransferredByte += (EPL_SDO_MAX_PAYLOAD-4);
+                    // move data pointer
+                    pSdoComCon_p->m_pData +=(EPL_SDO_MAX_PAYLOAD-4);
+
+                    // set segment size
+                    AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,(EPL_SDO_MAX_PAYLOAD-4));
+
+                    // send frame
+                    uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
+                    Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                                uiSizeOfFrame,
+                                                pFrame);
+
+                }
+                else if((pSdoComCon_p->m_uiTransferredByte > 0)
+                    &&(pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD))
+                {   // segment
+                    // set segment flag
+                    bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
+                    bFlag |= 0x20;
+                    AmiSetByteToLe(&pCommandFrame->m_le_bFlags,  bFlag);
+
+                    // copy data in frame
+                    EPL_MEMCPY(&pCommandFrame->m_le_abCommandData[0],pSdoComCon_p->m_pData, EPL_SDO_MAX_PAYLOAD);
+
+                    // correct byte-counter
+                    pSdoComCon_p->m_uiTransSize -= EPL_SDO_MAX_PAYLOAD;
+                    pSdoComCon_p->m_uiTransferredByte += EPL_SDO_MAX_PAYLOAD;
+                    // move data pointer
+                    pSdoComCon_p->m_pData +=EPL_SDO_MAX_PAYLOAD;
+
+                    // set segment size
+                    AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,EPL_SDO_MAX_PAYLOAD);
+
+                    // send frame
+                    uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
+                    Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                                uiSizeOfFrame,
+                                                pFrame);
+                }
+                else
+                {
+                    if((pSdoComCon_p->m_uiTransSize == 0)
+                        && (pSdoComCon_p->m_SdoServiceType != kEplSdoServiceWriteByIndex))
+                    {
+                        goto Exit;
+                    }
+                    // complete
+                    // set segment complete flag
+                    bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
+                    bFlag |= 0x30;
+                    AmiSetByteToLe(&pCommandFrame->m_le_bFlags,  bFlag);
+
+                    // copy data in frame
+                    EPL_MEMCPY(&pCommandFrame->m_le_abCommandData[0],pSdoComCon_p->m_pData, pSdoComCon_p->m_uiTransSize);
+
+                    // correct byte-counter
+                    pSdoComCon_p->m_uiTransferredByte += pSdoComCon_p->m_uiTransSize;
+
+
+                    // move data pointer
+                    pSdoComCon_p->m_pData +=pSdoComCon_p->m_uiTransSize;
+
+                    // set segment size
+                    AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, (WORD) pSdoComCon_p->m_uiTransSize);
+
+                    // send frame
+                    uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
+                    pSdoComCon_p->m_uiTransSize = 0;
+                    Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                                uiSizeOfFrame,
+                                                pFrame);
+                }
+
+            }
+            break;
+        }
+        // abort to send
+        case kEplSdoComSendTypeAbort:
+        {
+            // set response and abort flag
+            bFlag = AmiGetByteFromLe( &pCommandFrame->m_le_bFlags);
+            bFlag |= 0xC0;
+            AmiSetByteToLe(&pCommandFrame->m_le_bFlags,  bFlag);
+
+            // copy abortcode to frame
+            AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], *((DWORD*)pSdoComCon_p->m_pData));
+
+            // set size of segment
+            AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
+
+            // update counter
+            pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+            pSdoComCon_p->m_uiTransSize = 0;
+
+            // calc framesize
+            uiSizeOfFrame += sizeof(DWORD);
+            Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                                uiSizeOfFrame,
+                                                pFrame);
+            break;
+        }
+    } // end of switch(SendType_p)
+
+Exit:
+    return Ret;
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComServerInitWriteByIndex
+//
+// Description:    function start the processing of an write by index command
+//
+//
+//
+// Parameters:      pSdoComCon_p     = pointer to control structure of connection
+//                  pAsySdoCom_p     = pointer to received frame
+//
+// Returns:         tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
+static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon*     pSdoComCon_p,
+                                         tEplAsySdoCom*     pAsySdoCom_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+unsigned int    uiIndex;
+unsigned int    uiSubindex;
+unsigned int    uiBytesToTransfer;
+tEplObdSize     EntrySize;
+tEplObdAccess   AccessType;
+DWORD           dwAbortCode;
+BYTE*           pbSrcData;
+
+    dwAbortCode = 0;
+
+    // a init of a write
+    // -> variable part of header possible
+
+    // check if expedited or segmented transfer
+    if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10)
+    {   // initiate segmented transfer
+        pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
+        // get index and subindex
+        uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]);
+        uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]);
+        // get source-pointer for copy
+        pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8];
+        // save size
+        pSdoComCon_p->m_uiTransSize = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
+
+    }
+    else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00)
+    {   // expedited transfer
+        pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
+        // get index and subindex
+        uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
+        uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
+        // get source-pointer for copy
+        pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4];
+        // save size
+        pSdoComCon_p->m_uiTransSize = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+        // subtract header
+        pSdoComCon_p->m_uiTransSize -= 4;
+
+    }
+    else
+    {
+        // just ignore any other transfer type
+        goto Exit;
+    }
+
+    // check accesstype of entry
+    // existens of entry
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+    Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
+/*#else
+    Ret = kEplObdSubindexNotExist;
+    AccessType = 0;
+#endif*/
+    if (Ret == kEplObdSubindexNotExist)
+    {   // subentry doesn't exist
+        pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
+        // send abort
+        // d.k. This is wrong: k.t. not needed send abort on end of write
+        /*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);*/
+        goto Abort;
+    }
+    else if(Ret != kEplSuccessful)
+    {   // entry doesn't exist
+        pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
+        // send abort
+        // d.k. This is wrong: k.t. not needed send abort on end of write
+        /*
+        pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);*/
+        goto Abort;
+    }
+
+    // compare accesstype must be read
+    if((AccessType & kEplObdAccWrite) == 0)
+    {
+
+        if((AccessType & kEplObdAccRead) != 0)
+        {
+            // entry write a read only object
+            pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ;
+        }
+        else
+        {
+            pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
+        }
+        // send abort
+        // d.k. This is wrong: k.t. not needed send abort on end of write
+        /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);*/
+        goto Abort;
+    }
+
+    // save service
+    pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex;
+
+    pSdoComCon_p->m_uiTransferredByte = 0;
+
+    // write data to OD
+    if(pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited)
+    {   // expedited transfer
+        // size checking is done by EplObduWriteEntryFromLe()
+
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+        Ret = EplObduWriteEntryFromLe(uiIndex,
+                                    uiSubindex,
+                                    pbSrcData,
+                                    pSdoComCon_p->m_uiTransSize);
+        switch (Ret)
+        {
+            case kEplSuccessful:
+            {
+                break;
+            }
+
+            case kEplObdAccessViolation:
+            {
+                pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
+                // send abort
+                goto Abort;
+            }
+
+            case kEplObdValueLengthError:
+            {
+                pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH;
+                // send abort
+                goto Abort;
+            }
+
+            case kEplObdValueTooHigh:
+            {
+                pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_VALUE_RANGE_TOO_HIGH;
+                // send abort
+                goto Abort;
+            }
+
+            case kEplObdValueTooLow:
+            {
+                pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_VALUE_RANGE_TOO_LOW;
+                // send abort
+                goto Abort;
+            }
+
+            default:
+            {
+                pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
+                // send abort
+                goto Abort;
+            }
+        }
+//#endif
+        // send command acknowledge
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                        0,
+                                        0,
+                                        kEplSdoComSendTypeAckRes);
+
+        pSdoComCon_p->m_uiTransSize = 0;
+        goto Exit;
+    }
+    else
+    {
+        // get size of the object to check if it fits
+        // because we directly write to the destination memory
+        // d.k. no one calls the user OD callback function
+
+    //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+        EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
+    /*#else
+        EntrySize = 0;
+    #endif*/
+        if(EntrySize < pSdoComCon_p->m_uiTransSize)
+        {   // parameter too big
+            pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
+            // send abort
+            // d.k. This is wrong: k.t. not needed send abort on end of write
+            /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+            Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                        uiIndex,
+                                        uiSubindex,
+                                        kEplSdoComSendTypeAbort);*/
+            goto Abort;
+        }
+
+        uiBytesToTransfer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+        // eleminate header (Command header (8) + variable part (4) + Command header (4))
+        uiBytesToTransfer -= 16;
+        // get pointer to object entry
+//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+        pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex,
+                                                        uiSubindex);
+//#endif
+        if(pSdoComCon_p->m_pData == NULL)
+        {
+            pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
+            // send abort
+            // d.k. This is wrong: k.t. not needed send abort on end of write
+/*            pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
+            Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                        uiIndex,
+                                        uiSubindex,
+                                        kEplSdoComSendTypeAbort);*/
+            goto Abort;
+        }
+
+        // copy data
+        EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer);
+
+        // update internal counter
+        pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer;
+        pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
+
+        // update target pointer
+        (/*(BYTE*)*/pSdoComCon_p->m_pData) += uiBytesToTransfer;
+
+        // send acknowledge without any Command layer data
+        Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                                0,
+                                                (tEplFrame*)NULL);
+        goto Exit;
+    }
+
+Abort:
+    if(pSdoComCon_p->m_dwLastAbortCode != 0)
+    {
+        // send abort
+        pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
+        Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
+                                    uiIndex,
+                                    uiSubindex,
+                                    kEplSdoComSendTypeAbort);
+
+        // reset abort code
+        pSdoComCon_p->m_dwLastAbortCode = 0;
+        pSdoComCon_p->m_uiTransSize = 0;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+#endif
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComClientSend
+//
+// Description:    function starts an sdo transfer an send all further frames
+//
+//
+//
+// Parameters:      pSdoComCon_p     = pointer to control structure of connection
+//
+// Returns:         tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+static tEplKernel EplSdoComClientSend(tEplSdoComCon* pSdoComCon_p)
+{
+tEplKernel      Ret;
+BYTE            abFrame[EPL_MAX_SDO_FRAME_SIZE];
+tEplFrame*      pFrame;
+tEplAsySdoCom*  pCommandFrame;
+unsigned int    uiSizeOfFrame;
+BYTE            bFlags;
+BYTE*           pbPayload;
+
+    Ret = kEplSuccessful;
+
+    pFrame = (tEplFrame*)&abFrame[0];
+
+    EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
+
+    // build generic part of frame
+    // get pointer to command layerpart of frame
+    pCommandFrame = &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abSdoSeqPayload;
+    AmiSetByteToLe( &pCommandFrame->m_le_bCommandId, pSdoComCon_p->m_SdoServiceType);
+    AmiSetByteToLe( &pCommandFrame->m_le_bTransactionId, pSdoComCon_p->m_bTransactionId);
+
+    // set size constant part of header
+    uiSizeOfFrame = 8;
+
+    // check if first frame to send -> command header needed
+    if (pSdoComCon_p->m_uiTransSize > 0)
+    {
+        if (pSdoComCon_p->m_uiTransferredByte == 0)
+        {   // start SDO transfer
+            // check if segmented or expedited transfer
+            // only for write commands
+            switch(pSdoComCon_p->m_SdoServiceType)
+            {
+                case kEplSdoServiceReadByIndex:
+                {   // first frame of read access always expedited
+                    pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
+                    pbPayload = &pCommandFrame->m_le_abCommandData[0];
+                    // fill rest of header
+                    AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, 4);
+
+                    // create command header
+                    AmiSetWordToLe(pbPayload, (WORD)pSdoComCon_p->m_uiTargetIndex);
+                    pbPayload += 2;
+                    AmiSetByteToLe(pbPayload, (BYTE)pSdoComCon_p->m_uiTargetSubIndex);
+                    // calc size
+                    uiSizeOfFrame += 4;
+
+                    // set pSdoComCon_p->m_uiTransferredByte to one
+                    pSdoComCon_p->m_uiTransferredByte = 1;
+                    break;
+                }
+
+                case kEplSdoServiceWriteByIndex:
+                {
+                    if(pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD )
+                    {   // segmented transfer
+                        // -> variable part of header needed
+                        // save that transfer is segmented
+                        pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
+                        // fill variable part of header
+                        AmiSetDwordToLe( &pCommandFrame->m_le_abCommandData[0], pSdoComCon_p->m_uiTransSize);
+                        // set pointer to real payload
+                        pbPayload = &pCommandFrame->m_le_abCommandData[4];
+                        // fill rest of header
+                        AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, EPL_SDO_MAX_PAYLOAD);
+                        bFlags = 0x10;
+                        AmiSetByteToLe( &pCommandFrame->m_le_bFlags, bFlags);
+                        // create command header
+                        AmiSetWordToLe(pbPayload, (WORD) pSdoComCon_p->m_uiTargetIndex);
+                        pbPayload += 2;
+                        AmiSetByteToLe(pbPayload, (BYTE)pSdoComCon_p->m_uiTargetSubIndex);
+                        // on byte for reserved
+                        pbPayload += 2;
+                        // calc size
+                        uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
+
+                        // copy payload
+                        EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData,  (EPL_SDO_MAX_PAYLOAD - 8));
+                        pSdoComCon_p->m_pData += (EPL_SDO_MAX_PAYLOAD - 8);
+                        // correct intern counter
+                        pSdoComCon_p->m_uiTransSize -= (EPL_SDO_MAX_PAYLOAD - 8);
+                        pSdoComCon_p->m_uiTransferredByte = (EPL_SDO_MAX_PAYLOAD - 8);
+
+                    }
+                    else
+                    {   // expedited trandsfer
+                        // save that transfer is expedited
+                        pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
+                        pbPayload = &pCommandFrame->m_le_abCommandData[0];
+
+                        // create command header
+                        AmiSetWordToLe(pbPayload, (WORD) pSdoComCon_p->m_uiTargetIndex);
+                        pbPayload += 2;
+                        AmiSetByteToLe(pbPayload, (BYTE)pSdoComCon_p->m_uiTargetSubIndex);
+                        // + 2 -> one byte for subindex and one byte reserved
+                        pbPayload += 2;
+                        // copy data
+                        EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData,  pSdoComCon_p->m_uiTransSize);
+                        // calc size
+                        uiSizeOfFrame += (4 + pSdoComCon_p->m_uiTransSize);
+                        // fill rest of header
+                        AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, (WORD) (4 + pSdoComCon_p->m_uiTransSize));
+
+                        pSdoComCon_p->m_uiTransferredByte = pSdoComCon_p->m_uiTransSize;
+                        pSdoComCon_p->m_uiTransSize = 0;
+                    }
+                    break;
+                }
+
+                case kEplSdoServiceNIL:
+                default:
+                    // invalid service requested
+                    Ret = kEplSdoComInvalidServiceType;
+                    goto Exit;
+            } // end of switch(pSdoComCon_p->m_SdoServiceType)
+        }
+        else // (pSdoComCon_p->m_uiTransferredByte > 0)
+        {   // continue SDO transfer
+            switch(pSdoComCon_p->m_SdoServiceType)
+            {
+                // for expedited read is nothing to do
+                // -> server sends data
+
+                case kEplSdoServiceWriteByIndex:
+                {   // send next frame
+                    if(pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented)
+                    {
+                        if(pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)
+                        {   // next segment
+                            pbPayload = &pCommandFrame->m_le_abCommandData[0];
+                            // fill rest of header
+                            AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, EPL_SDO_MAX_PAYLOAD);
+                            bFlags = 0x20;
+                            AmiSetByteToLe( &pCommandFrame->m_le_bFlags, bFlags);
+                            // copy data
+                            EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData,  EPL_SDO_MAX_PAYLOAD);
+                            pSdoComCon_p->m_pData += EPL_SDO_MAX_PAYLOAD;
+                            // correct intern counter
+                            pSdoComCon_p->m_uiTransSize -= EPL_SDO_MAX_PAYLOAD;
+                            pSdoComCon_p->m_uiTransferredByte = EPL_SDO_MAX_PAYLOAD;
+                            // calc size
+                            uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
+
+
+                        }
+                        else
+                        {   // end of transfer
+                            pbPayload = &pCommandFrame->m_le_abCommandData[0];
+                            // fill rest of header
+                            AmiSetWordToLe( &pCommandFrame->m_le_wSegmentSize, (WORD) pSdoComCon_p->m_uiTransSize);
+                            bFlags = 0x30;
+                            AmiSetByteToLe( &pCommandFrame->m_le_bFlags, bFlags);
+                            // copy data
+                            EPL_MEMCPY( pbPayload,pSdoComCon_p->m_pData,  pSdoComCon_p->m_uiTransSize);
+                            pSdoComCon_p->m_pData += pSdoComCon_p->m_uiTransSize;
+                            // calc size
+                            uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
+                            // correct intern counter
+                            pSdoComCon_p->m_uiTransSize = 0;
+                            pSdoComCon_p->m_uiTransferredByte = pSdoComCon_p->m_uiTransSize;
+
+                        }
+                    }
+                    else
+                    {
+                        goto Exit;
+                    }
+                    break;
+                }
+                default:
+                {
+                    goto Exit;
+                }
+            } // end of switch(pSdoComCon_p->m_SdoServiceType)
+        }
+    }
+    else
+    {
+        goto Exit;
+    }
+
+
+    // call send function of lower layer
+    switch(pSdoComCon_p->m_SdoProtType)
+    {
+        case kEplSdoTypeAsnd:
+        case kEplSdoTypeUdp:
+        {
+            Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                        uiSizeOfFrame,
+                                        pFrame);
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplSdoComUnsupportedProt;
+        }
+    } // end of switch(pSdoComCon_p->m_SdoProtType)
+
+
+Exit:
+    return Ret;
+
+}
+#endif
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoComClientProcessFrame
+//
+// Description:    function process a received frame
+//
+//
+//
+// Parameters:      SdoComCon_p      = connection handle
+//                  pAsySdoCom_p     = pointer to frame to process
+//
+// Returns:         tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl   SdoComCon_p,
+                                              tEplAsySdoCom*     pAsySdoCom_p)
+{
+tEplKernel          Ret;
+BYTE                bBuffer;
+unsigned int        uiBuffer;
+unsigned int        uiDataSize;
+unsigned long       ulBuffer;
+tEplSdoComCon*      pSdoComCon;
+
+
+    Ret = kEplSuccessful;
+
+    // get pointer to control structure
+    pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
+
+    // check if transaction Id fit
+    bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
+    if(pSdoComCon->m_bTransactionId != bBuffer)
+    {
+        // incorrect transaction id
+
+        // if running transfer
+        if((pSdoComCon->m_uiTransferredByte != 0)
+            && (pSdoComCon->m_uiTransSize !=0))
+        {
+            pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
+            // -> send abort
+            EplSdoComClientSendAbort(pSdoComCon, pSdoComCon->m_dwLastAbortCode);
+            // call callback of application
+            Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
+        }
+
+    }
+    else
+    {   // check if correct command
+        bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId);
+        if(pSdoComCon->m_SdoServiceType != bBuffer)
+        {
+            // incorrect command
+            // if running transfer
+            if((pSdoComCon->m_uiTransferredByte != 0)
+                && (pSdoComCon->m_uiTransSize !=0))
+            {
+                pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
+                // -> send abort
+                EplSdoComClientSendAbort(pSdoComCon, pSdoComCon->m_dwLastAbortCode);
+                // call callback of application
+                Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferTxAborted);
+            }
+
+        }
+        else
+        {   // switch on command
+            switch(pSdoComCon->m_SdoServiceType)
+            {
+                case kEplSdoServiceWriteByIndex:
+                {   // check if confirmation from server
+                    // nothing more to do
+                    break;
+                }
+
+                case kEplSdoServiceReadByIndex:
+                {   // check if it is an segmented or an expedited transfer
+                    bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bFlags);
+                    // mask uninteressting bits
+                    bBuffer &= 0x30;
+                    switch(bBuffer)
+                    {
+                        // expedited transfer
+                        case 0x00:
+                        {
+                            // check size of buffer
+                            uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+                            if(uiBuffer > pSdoComCon->m_uiTransSize)
+                            {   // buffer provided by the application is to small
+                                // copy only a part
+                                uiDataSize = pSdoComCon->m_uiTransSize;
+                            }
+                            else
+                            {   // buffer fits
+                                uiDataSize = uiBuffer;
+                            }
+
+                            // copy data
+                            EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0], uiDataSize);
+
+                            // correct counter
+                            pSdoComCon->m_uiTransSize = 0;
+                            pSdoComCon->m_uiTransferredByte = uiDataSize;
+                            break;
+                        }
+
+                        // start of a segmented transfer
+                        case 0x10:
+                        {   // get total size of transfer
+                            ulBuffer = AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
+                            if(ulBuffer <= pSdoComCon->m_uiTransSize)
+                            {   // buffer fit
+                                pSdoComCon->m_uiTransSize = (unsigned int)ulBuffer;
+                            }
+                            else
+                            {   // buffer to small
+                                // send abort
+                                pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
+                                // -> send abort
+                                EplSdoComClientSendAbort(pSdoComCon, pSdoComCon->m_dwLastAbortCode);
+                                // call callback of application
+                                Ret = EplSdoComTransferFinished(SdoComCon_p, pSdoComCon, kEplSdoComTransferRxAborted);
+                                goto Exit;
+                            }
+
+                            // get segment size
+                            // check size of buffer
+                            uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+                            // subtract size of vaiable header from datasize
+                            uiBuffer -= 4;
+                            // copy data
+                            EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[4], uiBuffer);
+
+                            // correct counter an pointer
+                            pSdoComCon->m_pData += uiBuffer;
+                            pSdoComCon->m_uiTransferredByte += uiBuffer;
+                            pSdoComCon->m_uiTransSize -= uiBuffer;
+
+                            break;
+                        }
+
+                        // segment
+                        case 0x20:
+                        {
+                            // get segment size
+                            // check size of buffer
+                            uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+                            // check if data to copy fit to buffer
+                            if(uiBuffer >= pSdoComCon->m_uiTransSize)
+                            {   // to much data
+                                uiBuffer =  (pSdoComCon->m_uiTransSize - 1);
+                            }
+                            // copy data
+                            EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0], uiBuffer);
+
+                            // correct counter an pointer
+                            pSdoComCon->m_pData += uiBuffer;
+                            pSdoComCon->m_uiTransferredByte += uiBuffer;
+                            pSdoComCon->m_uiTransSize -= uiBuffer;
+                            break;
+                        }
+
+                        // last segment
+                        case 0x30:
+                        {
+                            // get segment size
+                            // check size of buffer
+                            uiBuffer = AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
+                            // check if data to copy fit to buffer
+                            if(uiBuffer > pSdoComCon->m_uiTransSize)
+                            {   // to much data
+                                uiBuffer =  (pSdoComCon->m_uiTransSize - 1);
+                            }
+                            // copy data
+                            EPL_MEMCPY(pSdoComCon->m_pData, &pAsySdoCom_p->m_le_abCommandData[0], uiBuffer);
+
+                            // correct counter an pointer
+                            pSdoComCon->m_pData += uiBuffer;
+                            pSdoComCon->m_uiTransferredByte += uiBuffer;
+                            pSdoComCon->m_uiTransSize  = 0;
+
+                            break;
+                        }
+                    }// end of switch(bBuffer & 0x30)
+
+                    break;
+                }
+
+                case kEplSdoServiceNIL:
+                default:
+                    // invalid service requested
+                    // $$$ d.k. What should we do?
+                    break;
+            }// end of switch(pSdoComCon->m_SdoServiceType)
+        }
+    }
+
+Exit:
+    return Ret;
+}
+#endif
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComClientSendAbort
+//
+// Description: function send a abort message
+//
+//
+//
+// Parameters:  pSdoComCon_p     = pointer to control structure of connection
+//              dwAbortCode_p    = Sdo abort code
+//
+// Returns:     tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon* pSdoComCon_p,
+                                           DWORD          dwAbortCode_p)
+{
+tEplKernel      Ret;
+BYTE            abFrame[EPL_MAX_SDO_FRAME_SIZE];
+tEplFrame*      pFrame;
+tEplAsySdoCom*  pCommandFrame;
+unsigned int    uiSizeOfFrame;
+
+    Ret = kEplSuccessful;
+
+    pFrame = (tEplFrame*)&abFrame[0];
+
+    EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
+
+    // build generic part of frame
+    // get pointer to command layerpart of frame
+    pCommandFrame = &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.m_le_abSdoSeqPayload;
+    AmiSetByteToLe( &pCommandFrame->m_le_bCommandId, pSdoComCon_p->m_SdoServiceType);
+    AmiSetByteToLe( &pCommandFrame->m_le_bTransactionId, pSdoComCon_p->m_bTransactionId);
+
+    uiSizeOfFrame = 8;
+
+    // set response and abort flag
+    pCommandFrame->m_le_bFlags |= 0x40;
+
+    // copy abortcode to frame
+    AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
+
+    // set size of segment
+    AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
+
+    // update counter
+    pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+    pSdoComCon_p->m_uiTransSize = 0;
+
+    // calc framesize
+    uiSizeOfFrame += sizeof(DWORD);
+
+    // save abort code
+    pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
+
+    // call send function of lower layer
+    switch(pSdoComCon_p->m_SdoProtType)
+    {
+        case kEplSdoTypeAsnd:
+        case kEplSdoTypeUdp:
+        {
+            Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
+                                        uiSizeOfFrame,
+                                        pFrame);
+            break;
+        }
+
+        default:
+        {
+            Ret = kEplSdoComUnsupportedProt;
+        }
+    } // end of switch(pSdoComCon_p->m_SdoProtType)
+
+
+    return Ret;
+}
+#endif
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoComTransferFinished
+//
+// Description: calls callback function of application if available
+//              and clears entry in control structure
+//
+// Parameters:  pSdoComCon_p     = pointer to control structure of connection
+//              SdoComConState_p = state of SDO transfer
+//
+// Returns:     tEplKernel  =  errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl   SdoComCon_p,
+                                            tEplSdoComCon*     pSdoComCon_p,
+                                            tEplSdoComConState SdoComConState_p)
+{
+tEplKernel      Ret;
+
+    Ret = kEplSuccessful;
+
+    if(pSdoComCon_p->m_pfnTransferFinished != NULL)
+    {
+    tEplSdoFinishedCb   pfnTransferFinished;
+    tEplSdoComFinished  SdoComFinished;
+
+        SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg;
+        SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId;
+        SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex;
+        SdoComFinished.m_uiTargetSubIndex = pSdoComCon_p->m_uiTargetSubIndex;
+        SdoComFinished.m_uiTransferredByte = pSdoComCon_p->m_uiTransferredByte;
+        SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode;
+        SdoComFinished.m_SdoComConHdl = SdoComCon_p;
+        SdoComFinished.m_SdoComConState = SdoComConState_p;
+        if (pSdoComCon_p->m_SdoServiceType == kEplSdoServiceWriteByIndex)
+        {
+            SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite;
+        }
+        else
+        {
+            SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead;
+        }
+
+        // reset transfer state so this handle is not busy anymore
+        pSdoComCon_p->m_uiTransferredByte = 0;
+        pSdoComCon_p->m_uiTransSize = 0;
+
+        pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished;
+        // delete function pointer to inform application only once for each transfer
+        pSdoComCon_p->m_pfnTransferFinished = NULL;
+
+        // call application's callback function
+        pfnTransferFinished(&SdoComFinished);
+
+    }
+
+    return Ret;
+}
+
+// EOF
+
diff --git a/drivers/staging/epl/EplSdoUdpu.c b/drivers/staging/epl/EplSdoUdpu.c
new file mode 100644 (file)
index 0000000..b761cf3
--- /dev/null
@@ -0,0 +1,821 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for SDO/UDP-Protocolabstractionlayer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoUdpu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 k.t.:   start of the implementation
+
+****************************************************************************/
+
+
+#include "user/EplSdoUdpu.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+
+#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+#include "SocketLinuxKernel.h"
+#include <linux/completion.h>
+#include <linux/sched.h>
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef EPL_SDO_MAX_CONNECTION_UDP
+#define EPL_SDO_MAX_CONNECTION_UDP  5
+#endif
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    unsigned long   m_ulIpAddr;     // in network byte order
+    unsigned int    m_uiPort;       // in network byte order
+
+} tEplSdoUdpCon;
+
+// instance table
+typedef struct
+{
+    tEplSdoUdpCon           m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP];
+    tEplSequLayerReceiveCb  m_fpSdoAsySeqCb;
+    SOCKET                  m_UdpSocket;
+
+#if (TARGET_SYSTEM == _WIN32_)
+    HANDLE                  m_ThreadHandle;
+    LPCRITICAL_SECTION      m_pCriticalSection;
+    CRITICAL_SECTION        m_CriticalSection;
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+    struct completion       m_CompletionUdpThread;
+    int                     m_ThreadHandle;
+    int                     m_iTerminateThread;
+#endif
+
+} tEplSdoUdpInstance;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static tEplSdoUdpInstance  SdoUdpInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+#if (TARGET_SYSTEM == _WIN32_)
+static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter);
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+static int EplSdoUdpThread(void * pArg_p);
+#endif
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <EPL-SDO-UDP-Layer>                                 */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: Protocolabstraction layer for UDP
+//
+//
+/***************************************************************************/
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuInit
+//
+// Description: init first instance of the module
+//
+//
+//
+// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
+//                                  callback-function
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+{
+tEplKernel  Ret;
+
+
+    Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuAddInstance
+//
+// Description: init additional instance of the module
+//              Ã®nit socket and start Listen-Thread
+//
+//
+//
+// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
+//                                  callback-function
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+{
+tEplKernel          Ret;
+
+#if (TARGET_SYSTEM == _WIN32_)
+int                 iError;
+WSADATA             Wsa;
+
+#endif
+
+    // set instance variables to 0
+    EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
+
+    Ret = kEplSuccessful;
+
+    // save pointer to callback-function
+    if (fpReceiveCb_p != NULL)
+    {
+        SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
+    }
+    else
+    {
+        Ret = kEplSdoUdpMissCb;
+        goto Exit;
+    }
+
+#if (TARGET_SYSTEM == _WIN32_)
+    // start winsock2 for win32
+    // windows specific start of socket
+    iError = WSAStartup(MAKEWORD(2,0),&Wsa);
+    if (iError != 0)
+    {
+        Ret = kEplSdoUdpNoSocket;
+        goto Exit;
+    }
+
+    // create critical section for acccess of instnace variables
+    SdoUdpInstance_g.m_pCriticalSection = &SdoUdpInstance_g.m_CriticalSection;
+    InitializeCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+    init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
+    SdoUdpInstance_g.m_iTerminateThread = 0;
+#endif
+
+    SdoUdpInstance_g.m_ThreadHandle = 0;
+    SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
+
+    Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuDelInstance
+//
+// Description: del instance of the module
+//              del socket and del Listen-Thread
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuDelInstance()
+{
+tEplKernel      Ret;
+
+#if (TARGET_SYSTEM == _WIN32_)
+BOOL                fTermError;
+#endif
+
+    Ret = kEplSuccessful;
+
+    if (SdoUdpInstance_g.m_ThreadHandle != 0)
+    {   // listen thread was started
+        // close thread
+#if (TARGET_SYSTEM == _WIN32_)
+        fTermError = TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
+        if(fTermError == FALSE)
+        {
+            Ret = kEplSdoUdpThreadError;
+            goto Exit;
+        }
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+        SdoUdpInstance_g.m_iTerminateThread = 1;
+        /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
+        send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
+        wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
+#endif
+
+        SdoUdpInstance_g.m_ThreadHandle = 0;
+    }
+
+    if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET)
+    {
+        // close socket
+        closesocket(SdoUdpInstance_g.m_UdpSocket);
+        SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
+    }
+
+#if (TARGET_SYSTEM == _WIN32_)
+    // delete critical section
+    DeleteCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+
+#if (TARGET_SYSTEM == _WIN32_)
+    // for win 32
+    WSACleanup();
+#endif
+
+#if (TARGET_SYSTEM == _WIN32_)
+Exit:
+#endif
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuConfig
+//
+// Description: reconfigurate socket with new IP-Address
+//              -> needed for NMT ResetConfiguration
+//
+// Parameters:  ulIpAddr_p      = IpAddress in platform byte order
+//              uiPort_p        = port number in platform byte order
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
+{
+tEplKernel          Ret;
+struct sockaddr_in  Addr;
+int                 iError;
+
+#if (TARGET_SYSTEM == _WIN32_)
+BOOL                fTermError;
+unsigned long       ulThreadId;
+#endif
+
+    Ret = kEplSuccessful;
+
+    if (uiPort_p == 0)
+    {   // set UDP port to default port number
+        uiPort_p = EPL_C_SDO_EPL_PORT;
+    }
+    else if (uiPort_p > 65535)
+    {
+        Ret = kEplSdoUdpSocketError;
+        goto Exit;
+    }
+
+    if (SdoUdpInstance_g.m_ThreadHandle != 0)
+    {   // listen thread was started
+
+        // close old thread
+#if (TARGET_SYSTEM == _WIN32_)
+        fTermError = TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
+        if(fTermError == FALSE)
+        {
+            Ret = kEplSdoUdpThreadError;
+            goto Exit;
+        }
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+        SdoUdpInstance_g.m_iTerminateThread = 1;
+        /* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
+        send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
+        wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
+        SdoUdpInstance_g.m_iTerminateThread = 0;
+#endif
+
+        SdoUdpInstance_g.m_ThreadHandle = 0;
+    }
+
+    if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET)
+    {
+        // close socket
+        iError = closesocket(SdoUdpInstance_g.m_UdpSocket);
+        SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
+        if(iError != 0)
+        {
+            Ret = kEplSdoUdpSocketError;
+            goto Exit;
+        }
+    }
+
+    // create Socket
+    SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET)
+    {
+        Ret = kEplSdoUdpNoSocket;
+        EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n");
+        goto Exit;
+    }
+
+    // bind socket
+    Addr.sin_family = AF_INET;
+    Addr.sin_port = htons((unsigned short) uiPort_p);
+    Addr.sin_addr.s_addr = htonl(ulIpAddr_p);
+    iError = bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr*)&Addr, sizeof (Addr));
+    if (iError < 0)
+    {
+        //iError = WSAGetLastError();
+        EPL_DBGLVL_SDO_TRACE1("EplSdoUdpuConfig: bind() finished with %i\n", iError);
+        Ret = kEplSdoUdpNoSocket;
+        goto Exit;
+    }
+
+    // create Listen-Thread
+#if (TARGET_SYSTEM == _WIN32_)
+    // for win32
+
+    // create thread
+    SdoUdpInstance_g.m_ThreadHandle = CreateThread(NULL,
+                                                    0,
+                                                    EplSdoUdpThread,
+                                                    &SdoUdpInstance_g,
+                                                    0,
+                                                    &ulThreadId);
+    if(SdoUdpInstance_g.m_ThreadHandle == NULL)
+    {
+        Ret = kEplSdoUdpThreadError;
+        goto Exit;
+    }
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+
+    SdoUdpInstance_g.m_ThreadHandle = kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
+    if(SdoUdpInstance_g.m_ThreadHandle == 0)
+    {
+        Ret = kEplSdoUdpThreadError;
+        goto Exit;
+    }
+#endif
+
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuInitCon
+//
+// Description: init a new connect
+//
+//
+//
+// Parameters:  pSdoConHandle_p = pointer for the new connection handle
+//              uiTargetNodeId_p = NodeId of the target node
+//
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl*  pSdoConHandle_p,
+                                    unsigned int    uiTargetNodeId_p)
+{
+tEplKernel          Ret;
+unsigned int        uiCount;
+unsigned int        uiFreeCon;
+tEplSdoUdpCon*      pSdoUdpCon;
+
+    Ret = kEplSuccessful;
+
+    // get free entry in control structure
+    uiCount = 0;
+    uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP;
+    pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0];
+    while (uiCount < EPL_SDO_MAX_CONNECTION_UDP)
+    {
+        if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p))
+        {   // existing connection to target node found
+            // set handle
+            *pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE);
+
+            goto Exit;
+        }
+        else if ((pSdoUdpCon->m_ulIpAddr == 0)
+                && (pSdoUdpCon->m_uiPort == 0))
+        {
+            uiFreeCon = uiCount;
+        }
+        uiCount++;
+        pSdoUdpCon++;
+    }
+
+    if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP)
+    {
+        // error no free handle
+        Ret = kEplSdoUdpNoFreeHandle;
+    }
+    else
+    {
+        pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon];
+        // save infos for connection
+        pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT);
+        pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p);   // 192.168.100.uiTargetNodeId_p
+
+        // set handle
+        *pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
+
+    }
+
+Exit:
+    return Ret;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuSendData
+//
+// Description: send data using exisiting connection
+//
+//
+//
+// Parameters:  SdoConHandle_p  = connection handle
+//              pSrcData_p      = pointer to data
+//              dwDataSize_p    = number of databyte
+//                                  -> without asend-header!!!
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl       SdoConHandle_p,
+                                    tEplFrame *          pSrcData_p,
+                                    DWORD                dwDataSize_p)
+{
+tEplKernel          Ret;
+int                 iError;
+unsigned int        uiArray;
+struct sockaddr_in  Addr;
+
+    Ret = kEplSuccessful;
+
+    uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
+    if(uiArray >= EPL_SDO_MAX_CONNECTION_UDP)
+    {
+        Ret = kEplSdoUdpInvalidHdl;
+        goto Exit;
+    }
+    //set message type
+    AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06); // SDO
+    // target node id (for Udp = 0)
+    AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00);
+    // set source-nodeid (for Udp = 0)
+    AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
+
+    // calc size
+    dwDataSize_p += EPL_ASND_HEADER_SIZE;
+
+    // call sendto
+    Addr.sin_family = AF_INET;
+#if (TARGET_SYSTEM == _WIN32_)
+        // enter  critical section for process function
+    EnterCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+
+    Addr.sin_port = (unsigned short) SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort;
+    Addr.sin_addr.s_addr = SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
+
+#if (TARGET_SYSTEM == _WIN32_)
+    // leave critical section for process function
+    LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+
+    iError = sendto (SdoUdpInstance_g.m_UdpSocket,       // sockethandle
+                (const char*) &pSrcData_p->m_le_bMessageType,        // data to send
+                dwDataSize_p,                          // number of bytes to send
+                0,                                     // flags
+                (struct sockaddr*)&Addr,                      // target
+                sizeof(struct sockaddr_in));                  // sizeof targetadress
+    if(iError < 0)
+    {
+        EPL_DBGLVL_SDO_TRACE1("EplSdoUdpuSendData: sendto() finished with %i\n", iError);
+        Ret = kEplSdoUdpSendError;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoUdpuDelCon
+//
+// Description: delete connection from intern structure
+//
+//
+//
+// Parameters:  SdoConHandle_p  = connection handle
+//
+// Returns:     tEplKernel  = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
+{
+tEplKernel      Ret;
+unsigned int    uiArray;
+
+
+    uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
+
+    if(uiArray >= EPL_SDO_MAX_CONNECTION_UDP)
+    {
+        Ret = kEplSdoUdpInvalidHdl;
+        goto Exit;
+    }
+    else
+    {
+        Ret = kEplSuccessful;
+    }
+
+
+    // delete connection
+    SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
+    SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
+
+Exit:
+    return Ret;
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:        EplSdoUdpThread
+//
+// Description:     thread check socket for new data
+//
+//
+//
+// Parameters:      lpParameter = pointer to parameter type tEplSdoUdpThreadPara
+//
+//
+// Returns:         DWORD   =   errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+#if (TARGET_SYSTEM == _WIN32_)
+static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter)
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+static int EplSdoUdpThread(void * pArg_p)
+#endif
+{
+
+tEplSdoUdpInstance* pInstance;
+struct sockaddr_in  RemoteAddr;
+int                 iError;
+int                 iCount;
+int                 iFreeEntry;
+BYTE                abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
+unsigned int        uiSize;
+tEplSdoConHdl       SdoConHdl;
+
+#if (TARGET_SYSTEM == _WIN32_)
+    pInstance = (tEplSdoUdpInstance*)lpParameter;
+
+    for (;;)
+
+#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+    pInstance = (tEplSdoUdpInstance*)pArg_p;
+    daemonize("EplSdoUdpThread");
+    allow_signal( SIGTERM );
+
+    for (;pInstance->m_iTerminateThread == 0;)
+#endif
+
+    {
+        // wait for data
+        uiSize = sizeof(struct sockaddr);
+        iError = recvfrom(pInstance->m_UdpSocket,   // Socket
+                        (char *)&abBuffer[0],               // buffer for data
+                        sizeof(abBuffer),           // size of the buffer
+                        0,                          // flags
+                        (struct sockaddr*)&RemoteAddr,
+                        (int*)&uiSize);
+#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+        if (iError == -ERESTARTSYS)
+        {
+            break;
+        }
+#endif
+        if (iError > 0)
+        {
+            // get handle for higher layer
+            iCount = 0;
+            iFreeEntry = 0xFFFF;
+#if (TARGET_SYSTEM == _WIN32_)
+        // enter  critical section for process function
+    EnterCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+            while (iCount < EPL_SDO_MAX_CONNECTION_UDP)
+            {
+                // check if this connection is already known
+                if((pInstance->m_aSdoAbsUdpConnection[iCount].m_ulIpAddr == RemoteAddr.sin_addr.s_addr)
+                    && (pInstance->m_aSdoAbsUdpConnection[iCount].m_uiPort == RemoteAddr.sin_port))
+                {
+                    break;
+                }
+
+                if((pInstance->m_aSdoAbsUdpConnection[iCount].m_ulIpAddr == 0)
+                    && (pInstance->m_aSdoAbsUdpConnection[iCount].m_uiPort == 0)
+                    && (iFreeEntry == 0xFFFF))
+
+                {
+                    iFreeEntry  = iCount;
+                }
+
+                iCount++;
+            }
+
+            if (iCount == EPL_SDO_MAX_CONNECTION_UDP)
+            {
+                // connection unknown
+                // see if there is a free handle
+                if (iFreeEntry != 0xFFFF)
+                {
+                    // save adress infos
+                    pInstance->m_aSdoAbsUdpConnection[iFreeEntry].m_ulIpAddr =
+                        RemoteAddr.sin_addr.s_addr;
+                    pInstance->m_aSdoAbsUdpConnection[iFreeEntry].m_uiPort =
+                        RemoteAddr.sin_port;
+#if (TARGET_SYSTEM == _WIN32_)
+    // leave critical section for process function
+    LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+                    // call callback
+                    SdoConHdl = iFreeEntry;
+                    SdoConHdl |= EPL_SDO_UDP_HANDLE;
+                    // offset 4 -> start of SDO Sequence header
+                    pInstance->m_fpSdoAsySeqCb(SdoConHdl, (tEplAsySdoSeq*)&abBuffer[4], (iError - 4));
+                }
+                else
+                {
+                    EPL_DBGLVL_SDO_TRACE0("Error in EplSdoUdpThread() no free handle\n");
+#if (TARGET_SYSTEM == _WIN32_)
+    // leave critical section for process function
+    LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+                }
+
+            }
+            else
+            {
+                // known connection
+                // call callback with correct handle
+                SdoConHdl = iCount;
+                SdoConHdl |= EPL_SDO_UDP_HANDLE;
+#if (TARGET_SYSTEM == _WIN32_)
+    // leave critical section for process function
+    LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
+#endif
+                // offset 4 -> start of SDO Sequence header
+                pInstance->m_fpSdoAsySeqCb(SdoConHdl, (tEplAsySdoSeq*)&abBuffer[4], (iError - 4));
+            }
+        } // end of  if(iError!=SOCKET_ERROR)
+    }// end of for(;;)
+
+#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+    complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
+#endif
+
+    return 0;
+}
+
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+
+// EOF
+
diff --git a/drivers/staging/epl/EplStatusu.c b/drivers/staging/epl/EplStatusu.c
new file mode 100644 (file)
index 0000000..2c81636
--- /dev/null
@@ -0,0 +1,387 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Statusu-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplStatusu.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/11/15 d.k.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplStatusu.h"
+#include "user/EplDlluCal.h"
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <xxxxx>                                             */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description:
+//
+//
+/***************************************************************************/
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   D E F I N I T I O N S                          //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplStatusuCbResponse m_apfnCbResponse[254];
+
+} tEplStatusuInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplStatusuInstance   EplStatusuInstance_g;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo * pFrameInfo_p);
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplStatusuInit
+//
+// Description: init first instance of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplStatusuInit()
+{
+tEplKernel Ret;
+
+    Ret = EplStatusuAddInstance();
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplStatusuAddInstance
+//
+// Description: init other instances of the module
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplStatusuAddInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplStatusuInstance_g, 0, sizeof (EplStatusuInstance_g));
+
+    // register StatusResponse callback function
+    Ret = EplDlluCalRegAsndService(kEplDllAsndStatusResponse, EplStatusuCbStatusResponse, kEplDllAsndFilterAny);
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplStatusuDelInstance
+//
+// Description: delete instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplStatusuDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // deregister StatusResponse callback function
+    Ret = EplDlluCalRegAsndService(kEplDllAsndStatusResponse, NULL, kEplDllAsndFilterNone);
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplStatusuReset
+//
+// Description: resets this instance
+//
+// Parameters:
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+EPLDLLEXPORT tEplKernel PUBLIC EplStatusuReset()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // reset instance structure
+    EPL_MEMSET(&EplStatusuInstance_g, 0, sizeof (EplStatusuInstance_g));
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplStatusuRequestStatusResponse
+//
+// Description: returns the StatusResponse for the specified node.
+//
+// Parameters:  uiNodeId_p                  = IN: node ID
+//              pfnCbResponse_p             = IN: function pointer to callback function
+//                                            which will be called if StatusResponse is received
+//
+// Return:      tEplKernel                  = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplStatusuRequestStatusResponse(
+                                  unsigned int        uiNodeId_p,
+                                  tEplStatusuCbResponse pfnCbResponse_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // decrement node ID, because array is zero based
+    uiNodeId_p--;
+    if (uiNodeId_p < tabentries (EplStatusuInstance_g.m_apfnCbResponse))
+    {
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+        if (EplStatusuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL)
+        {   // request already issued (maybe by someone else)
+            Ret = kEplInvalidOperation;
+        }
+        else
+        {
+            EplStatusuInstance_g.m_apfnCbResponse[uiNodeId_p] = pfnCbResponse_p;
+            Ret = EplDlluCalIssueRequest(kEplDllReqServiceStatus, (uiNodeId_p + 1), 0xFF);
+        }
+#else
+        Ret = kEplInvalidOperation;
+#endif
+    }
+    else
+    {   // invalid node ID specified
+        Ret = kEplInvalidNodeId;
+    }
+
+    return Ret;
+
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplStatusuCbStatusResponse
+//
+// Description: callback funktion for StatusResponse
+//
+//
+//
+// Parameters:  pFrameInfo_p            = Frame with the StatusResponse
+//
+//
+// Returns:     tEplKernel              = error code
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+unsigned int    uiNodeId;
+unsigned int    uiIndex;
+tEplStatusuCbResponse    pfnCbResponse;
+
+    uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);
+
+    uiIndex = uiNodeId - 1;
+
+    if (uiIndex < tabentries (EplStatusuInstance_g.m_apfnCbResponse))
+    {
+        // memorize pointer to callback function
+        pfnCbResponse = EplStatusuInstance_g.m_apfnCbResponse[uiIndex];
+        if (pfnCbResponse == NULL)
+        {   // response was not requested
+            goto Exit;
+        }
+        // reset callback function pointer so that caller may issue next request
+        EplStatusuInstance_g.m_apfnCbResponse[uiIndex] = NULL;
+
+        if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_STATUSRES)
+        {   // StatusResponse not received or it has invalid size
+            Ret = pfnCbResponse(uiNodeId, NULL);
+        }
+        else
+        {   // StatusResponse received
+            Ret = pfnCbResponse(uiNodeId, &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_StatusResponse);
+        }
+    }
+
+Exit:
+    return Ret;
+}
+
+// EOF
+
diff --git a/drivers/staging/epl/EplTarget.h b/drivers/staging/epl/EplTarget.h
new file mode 100644 (file)
index 0000000..0d1fe8a
--- /dev/null
@@ -0,0 +1,240 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for target api function
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTarget.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2005/12/05 -as:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPLTARGET_H_
+#define _EPLTARGET_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+// =========================================================================
+// macros for memory access (depends on target system)
+// =========================================================================
+
+// NOTE:
+// The following macros are used to combine standard library definitions. Some
+// applications needs to use one common library function (e.g. memcpy()). So
+// you can set (or change) it here.
+
+#if (TARGET_SYSTEM == _WIN32_)
+
+    #define _WIN32_WINDOWS 0x0401
+    #define _WIN32_WINNT   0x0400
+
+    #include <stdlib.h>
+    #include <stdio.h>
+
+    //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
+    #include <string.h>
+
+    #define EPL_MEMCPY(dst,src,siz)     memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
+    #define EPL_MEMSET(dst,val,siz)     memset((void*)(dst),(int)(val),(size_t)(siz));
+
+    // f.j.: die Funktionen für <MemAlloc> und <MemFree> sind in WinMem.c definiert
+    //definition der Prototypen
+    void FAR*  MemAlloc (DWORD dwMemSize_p);
+    void       MemFree (void FAR* pMem_p);
+
+    #define EPL_MALLOC(siz)             malloc((size_t)(siz))
+    #define EPL_FREE(ptr)               free((void *)ptr)
+
+    #ifndef PRINTF0
+        void trace (const char* fmt, ...);
+        #define PRINTF                      TRACE
+        #define PRINTF0(arg)                TRACE0(arg)
+        #define PRINTF1(arg,p1)             TRACE1(arg,p1)
+        #define PRINTF2(arg,p1,p2)          TRACE2(arg,p1,p2)
+        #define PRINTF3(arg,p1,p2,p3)       TRACE3(arg,p1,p2,p3)
+        #define PRINTF4(arg,p1,p2,p3,p4)    TRACE4(arg,p1,p2,p3,p4)
+        //#define PRINTF                      printf
+        //#define PRINTF0(arg)                PRINTF(arg)
+        //#define PRINTF1(arg,p1)             PRINTF(arg,p1)
+        //#define PRINTF2(arg,p1,p2)          PRINTF(arg,p1,p2)
+        //#define PRINTF3(arg,p1,p2,p3)       PRINTF(arg,p1,p2,p3)
+        //#define PRINTF4(arg,p1,p2,p3,p4)    PRINTF(arg,p1,p2,p3,p4)
+    #endif
+
+    #ifdef ASSERTMSG
+        #undef ASSERTMSG
+    #endif
+
+    #define ASSERTMSG(expr,string)  if (!(expr)) { \
+                                        MessageBox (NULL, string, "Assertion failed", MB_OK | MB_ICONERROR); \
+                                        exit (-1);}
+
+
+
+#elif (TARGET_SYSTEM == _NO_OS_)
+
+    #include <stdlib.h>
+    #include <stdio.h>
+
+    //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
+//    #include <string.h>
+
+    #define EPL_MEMCPY(dst,src,siz)     memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
+    #define EPL_MEMSET(dst,val,siz)     memset((void*)(dst),(int)(val),(size_t)(siz));
+
+    #define EPL_MALLOC(siz)             malloc((size_t)(siz))
+    #define EPL_FREE(ptr)               free((void *)ptr)
+
+    #ifndef PRINTF0
+        #define PRINTF                      TRACE
+        #define PRINTF0(arg)                TRACE0(arg)
+        #define PRINTF1(arg,p1)             TRACE1(arg,p1)
+        #define PRINTF2(arg,p1,p2)          TRACE2(arg,p1,p2)
+        #define PRINTF3(arg,p1,p2,p3)       TRACE3(arg,p1,p2,p3)
+        #define PRINTF4(arg,p1,p2,p3,p4)    TRACE4(arg,p1,p2,p3,p4)
+        //#define PRINTF                      printf
+        //#define PRINTF0(arg)                PRINTF(arg)
+        //#define PRINTF1(arg,p1)             PRINTF(arg,p1)
+        //#define PRINTF2(arg,p1,p2)          PRINTF(arg,p1,p2)
+        //#define PRINTF3(arg,p1,p2,p3)       PRINTF(arg,p1,p2,p3)
+        //#define PRINTF4(arg,p1,p2,p3,p4)    PRINTF(arg,p1,p2,p3,p4)
+    #endif
+
+
+#elif (TARGET_SYSTEM == _LINUX_)
+
+    #ifndef __KERNEL__
+        #include <stdlib.h>
+        #include <stdio.h>
+    #else
+//        #include <linux/config.h>
+        #include <linux/module.h>
+        #include <linux/kernel.h>
+        #include <linux/init.h>
+        #include <linux/errno.h>
+        #include <linux/major.h>
+        #include <linux/version.h>
+    #endif
+
+    //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
+//    #include <string.h>
+
+    #define EPL_MEMCPY(dst,src,siz)     memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
+    #define EPL_MEMSET(dst,val,siz)     memset((void*)(dst),(int)(val),(size_t)(siz));
+
+    #ifndef __KERNEL__
+        #define EPL_MALLOC(siz)             malloc((size_t)(siz))
+        #define EPL_FREE(ptr)               free((void *)ptr)
+    #else
+        #define EPL_MALLOC(siz)             kmalloc((size_t)(siz), GFP_KERNEL)
+        #define EPL_FREE(ptr)               kfree((void *)ptr)
+    #endif
+
+    #ifndef PRINTF0
+        #define PRINTF                      TRACE
+        #define PRINTF0(arg)                TRACE0(arg)
+        #define PRINTF1(arg,p1)             TRACE1(arg,p1)
+        #define PRINTF2(arg,p1,p2)          TRACE2(arg,p1,p2)
+        #define PRINTF3(arg,p1,p2,p3)       TRACE3(arg,p1,p2,p3)
+        #define PRINTF4(arg,p1,p2,p3,p4)    TRACE4(arg,p1,p2,p3,p4)
+        //#define PRINTF                      printf
+        //#define PRINTF0(arg)                PRINTF(arg)
+        //#define PRINTF1(arg,p1)             PRINTF(arg,p1)
+        //#define PRINTF2(arg,p1,p2)          PRINTF(arg,p1,p2)
+        //#define PRINTF3(arg,p1,p2,p3)       PRINTF(arg,p1,p2,p3)
+        //#define PRINTF4(arg,p1,p2,p3,p4)    PRINTF(arg,p1,p2,p3,p4)
+    #endif
+
+
+#endif
+
+#define EPL_TGT_INTMASK_ETH     0x0001  // ethernet interrupt
+#define EPL_TGT_INTMASK_DMA     0x0002  // DMA interrupt
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+// currently no Timer functions are needed by EPL stack
+// so they are not implemented yet
+//void  PUBLIC TgtTimerInit(void);
+//DWORD PUBLIC TgtGetTickCount(void);
+//void PUBLIC TgtGetNetTime(tEplNetTime * pNetTime_p);
+
+// functions for ethernet driver
+tEplKernel PUBLIC TgtInitEthIsr(void);
+void PUBLIC TgtFreeEthIsr(void);
+void  PUBLIC  TgtEnableGlobalInterrupt(BYTE fEnable_p);
+void PUBLIC TgtEnableEthInterrupt0(BYTE fEnable_p, unsigned int uiInterruptMask_p);
+void PUBLIC TgtEnableEthInterrupt1(BYTE fEnable_p, unsigned int uiInterruptMask_p);
+
+#endif  // #ifndef _EPLTARGET_H_
+
+
diff --git a/drivers/staging/epl/EplTimer.h b/drivers/staging/epl/EplTimer.h
new file mode 100644 (file)
index 0000000..6dbb53b
--- /dev/null
@@ -0,0 +1,125 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Epl Timer-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimer.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/06 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "EplEvent.h"
+
+#ifndef _EPLTIMER_H_
+#define _EPLTIMER_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+// type for timer handle
+typedef unsigned long tEplTimerHdl;
+
+typedef struct
+{
+    tEplEventSink   m_EventSink;
+    unsigned long   m_ulArg;    // d.k.: converted to unsigned long because
+                                // it is never accessed as a pointer by the
+                                // timer module and the data the
+                                // pointer points to is not saved in any way.
+                                // It is just a value. The user is responsible
+                                // to store the data statically and convert
+                                // the pointer between address spaces.
+
+} tEplTimerArg;
+
+typedef struct
+{
+    tEplTimerHdl    m_TimerHdl;
+    unsigned long   m_ulArg;    // d.k.: converted to unsigned long because
+                                // it is never accessed as a pointer by the
+                                // timer module and the data the
+                                // pointer points to is not saved in any way.
+                                // It is just a value.
+
+} tEplTimerEventArg;
+
+typedef tEplKernel (PUBLIC * tEplTimerkCallback) (
+    tEplTimerEventArg* pEventArg_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPLTIMER_H_
+
+
diff --git a/drivers/staging/epl/EplTimeruLinuxKernel.c b/drivers/staging/epl/EplTimeruLinuxKernel.c
new file mode 100644 (file)
index 0000000..41dfb61
--- /dev/null
@@ -0,0 +1,472 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for EPL User Timermodule for Linux kernel module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimeruLinuxKernel.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/09/12 d.k.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplTimeru.h"
+#include <linux/timer.h>
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+typedef struct
+{
+    struct timer_list   m_Timer;
+    tEplTimerArg        TimerArgument;
+
+} tEplTimeruData;
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <Epl Userspace-Timermodule for Linux Kernel>              */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: Epl Userspace-Timermodule for Linux Kernel
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruInit
+//
+// Description: function inits first instance
+//
+// Parameters:  void
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruInit()
+{
+tEplKernel  Ret;
+
+    Ret = EplTimeruAddInstance();
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruAddInstance
+//
+// Description: function inits additional instance
+//
+// Parameters:  void
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruAddInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruDelInstance
+//
+// Description: function deletes instance
+//              -> under Linux nothing to do
+//              -> no instance table needed
+//
+// Parameters:  void
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruSetTimerMs
+//
+// Description: function creates a timer and returns the corresponding handle
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//              ulTime_p    = time for timer in ms
+//              Argument_p  = argument for timer
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long   ulTime_p,
+                                        tEplTimerArg    Argument_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplTimeruData*     pData;
+
+    // check pointer to handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    pData = (tEplTimeruData*) EPL_MALLOC(sizeof (tEplTimeruData));
+    if (pData == NULL)
+    {
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    init_timer(&pData->m_Timer);
+    pData->m_Timer.function = EplTimeruCbMs;
+    pData->m_Timer.data = (unsigned long) pData;
+    pData->m_Timer.expires = jiffies + ulTime_p * HZ / 1000;
+
+    EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
+
+    add_timer(&pData->m_Timer);
+
+    *pTimerHdl_p = (tEplTimerHdl) pData;
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruModifyTimerMs
+//
+// Description: function changes a timer and returns the corresponding handle
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//              ulTime_p    = time for timer in ms
+//              Argument_p  = argument for timer
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long     ulTime_p,
+                                        tEplTimerArg      Argument_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplTimeruData*     pData;
+
+    // check pointer to handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    // check handle itself, i.e. was the handle initialized before
+    if (*pTimerHdl_p == 0)
+    {
+        Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p);
+        goto Exit;
+    }
+    pData = (tEplTimeruData*) *pTimerHdl_p;
+    if ((tEplTimeruData*)pData->m_Timer.data != pData)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));
+
+    // copy the TimerArg after the timer is restarted,
+    // so that a timer occured immediately before mod_timer
+    // won't use the new TimerArg and
+    // therefore the old timer cannot be distinguished from the new one.
+    // But if the new timer is too fast, it may get lost.
+    EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
+
+    // check if timer is really running
+    if (timer_pending(&pData->m_Timer) == 0)
+    {   // timer is not running
+        // retry starting it
+        add_timer(&pData->m_Timer);
+    }
+
+    // set handle to pointer of tEplTimeruData
+//    *pTimerHdl_p = (tEplTimerHdl) pData;
+
+Exit:
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruDeleteTimer
+//
+// Description: function deletes a timer
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//
+// Returns:     tEplKernel  = errorcode
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl*     pTimerHdl_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplTimeruData*     pData;
+
+    // check pointer to handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    // check handle itself, i.e. was the handle initialized before
+    if (*pTimerHdl_p == 0)
+    {
+        Ret = kEplSuccessful;
+        goto Exit;
+    }
+    pData = (tEplTimeruData*) *pTimerHdl_p;
+    if ((tEplTimeruData*)pData->m_Timer.data != pData)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+/*    if (del_timer(&pData->m_Timer) == 1)
+    {
+        kfree(pData);
+    }
+*/
+    // try to delete the timer
+    del_timer(&pData->m_Timer);
+    // free memory in any case
+    kfree(pData);
+
+    // uninitialize handle
+    *pTimerHdl_p = 0;
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruIsTimerActive
+//
+// Description: checks if the timer referenced by the handle is currently
+//              active.
+//
+// Parameters:  TimerHdl_p  = handle of the timer to check
+//
+// Returns:     BOOL        = TRUE, if active;
+//                            FALSE, otherwise
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
+{
+BOOL        fActive = FALSE;
+tEplTimeruData*     pData;
+
+    // check handle itself, i.e. was the handle initialized before
+    if (TimerHdl_p == 0)
+    {   // timer was not created yet, so it is not active
+        goto Exit;
+    }
+    pData = (tEplTimeruData*) TimerHdl_p;
+    if ((tEplTimeruData*)pData->m_Timer.data != pData)
+    {   // invalid timer
+        goto Exit;
+    }
+
+    // check if timer is running
+    if (timer_pending(&pData->m_Timer) == 0)
+    {   // timer is not running
+        goto Exit;
+    }
+
+    fActive = TRUE;
+
+Exit:
+    return fActive;
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruCbMs
+//
+// Description: function to process timer
+//
+//
+//
+// Parameters:  lpParameter = pointer to structur of type tEplTimeruData
+//
+//
+// Returns:     (none)
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
+{
+tEplKernel          Ret = kEplSuccessful;
+tEplTimeruData*     pData;
+tEplEvent           EplEvent;
+tEplTimerEventArg   TimerEventArg;
+
+    pData = (tEplTimeruData*) ulParameter_p;
+
+    // call event function
+    TimerEventArg.m_TimerHdl = (tEplTimerHdl)pData;
+    TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg;
+
+    EplEvent.m_EventSink = pData->TimerArgument.m_EventSink;
+    EplEvent.m_EventType = kEplEventTypeTimer;
+    EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
+    EplEvent.m_pArg = &TimerEventArg;
+    EplEvent.m_uiSize = sizeof(TimerEventArg);
+
+    Ret = EplEventuPost(&EplEvent);
+
+    // d.k. do not free memory, user has to call EplTimeruDeleteTimer()
+    //kfree(pData);
+
+}
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplTimeruNull.c b/drivers/staging/epl/EplTimeruNull.c
new file mode 100644 (file)
index 0000000..ce9af38
--- /dev/null
@@ -0,0 +1,323 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Epl Userspace-Timermodule NULL-Implementation
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimeruNull.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/06 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplTimeru.h"
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <Epl Userspace-Timermodule NULL-Implementation>     */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: Epl Userspace-Timermodule NULL-Implementation
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruInit
+//
+// Description: function init first instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruInit()
+{
+tEplKernel  Ret;
+
+    Ret = EplTimeruAddInstance();
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruAddInstance
+//
+// Description: function init additional instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruAddInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruDelInstance
+//
+// Description: function delte instance
+//              -> under Win32 nothing to do
+//              -> no instnace table needed
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruSetTimerMs
+//
+// Description: function create a timer and return a handle to the pointer
+//
+//
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//              ulTime_p    = time for timer in ms
+//              Argument_p  = argument for timer
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long   ulTime_p,
+                                        tEplTimerArg    Argument_p)
+{
+tEplKernel          Ret;
+
+
+    Ret = kEplSuccessful;
+
+    // check handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+
+ //---------------------------------------------------------------------------
+//
+// Function:    EplTimeruModifyTimerMs
+//
+// Description: function change a timer and return a handle to the pointer
+//
+//
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//              ulTime_p    = time for timer in ms
+//              Argument_p  = argument for timer
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long     ulTime_p,
+                                        tEplTimerArg      Argument_p)
+{
+tEplKernel          Ret;
+
+    Ret = kEplSuccessful;
+
+    // check parameter
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+
+Exit:
+    return Ret;
+}
+
+ //---------------------------------------------------------------------------
+//
+// Function:    EplTimeruDeleteTimer
+//
+// Description: function delte a timer
+//
+//
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl*     pTimerHdl_p)
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    // check parameter
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    // set handle invalide
+    *pTimerHdl_p = 0;
+
+
+Exit:
+    return Ret;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplTimeruWin32.c b/drivers/staging/epl/EplTimeruWin32.c
new file mode 100644 (file)
index 0000000..b5d845c
--- /dev/null
@@ -0,0 +1,551 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  source file for Epl Userspace-Timermodule for Win32
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimeruWin32.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/06 k.t.:   start of the implementation
+
+****************************************************************************/
+
+#include "user/EplTimeru.h"
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+typedef struct
+{
+    tEplTimerArg    TimerArgument;
+    HANDLE          DelteHandle;
+    unsigned long   ulTimeout;
+
+}tEplTimeruThread;
+
+typedef struct
+{
+    LPCRITICAL_SECTION  m_pCriticalSection;
+    CRITICAL_SECTION    m_CriticalSection;
+}tEplTimeruInstance;
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+static tEplTimeruInstance EplTimeruInstance_g;
+static tEplTimeruThread   ThreadData_l;
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          C L A S S  <Epl Userspace-Timermodule for Win32>               */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+//
+// Description: Epl Userspace-Timermodule for Win32
+//
+//
+/***************************************************************************/
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruInit
+//
+// Description: function init first instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruInit()
+{
+tEplKernel  Ret;
+
+    Ret = EplTimeruAddInstance();
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruAddInstance
+//
+// Description: function init additional instance
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruAddInstance()
+{
+tEplKernel Ret;
+
+    Ret = kEplSuccessful;
+
+
+    // create critical section
+    EplTimeruInstance_g.m_pCriticalSection = &EplTimeruInstance_g.m_CriticalSection;
+    InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
+
+
+
+return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruDelInstance
+//
+// Description: function delte instance
+//              -> under Win32 nothing to do
+//              -> no instnace table needed
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruDelInstance()
+{
+tEplKernel  Ret;
+
+    Ret = kEplSuccessful;
+
+    return Ret;
+}
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimeruSetTimerMs
+//
+// Description: function create a timer and return a handle to the pointer
+//
+//
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//              ulTime_p    = time for timer in ms
+//              Argument_p  = argument for timer
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long   ulTime_p,
+                                        tEplTimerArg    Argument_p)
+{
+tEplKernel          Ret;
+HANDLE              DeleteHandle;
+HANDLE              ThreadHandle;
+DWORD               ThreadId;
+
+
+    Ret = kEplSuccessful;
+
+    // check handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    // enter  critical section
+    EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
+
+    // first create event to delete timer
+    DeleteHandle = CreateEvent(NULL,FALSE,FALSE, NULL);
+    if(DeleteHandle == NULL)
+    {
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+    // set handle for caller
+    *pTimerHdl_p = (tEplTimerHdl)DeleteHandle;
+
+
+
+
+    // fill data for thread
+    ThreadData_l.DelteHandle = DeleteHandle;
+    EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, sizeof(tEplTimerArg));
+    ThreadData_l.ulTimeout = ulTime_p;
+
+    // create thread to create waitable timer and wait for timer
+    ThreadHandle = CreateThread(NULL,
+                                0,
+                                EplSdoTimeruThreadms,
+                                &ThreadData_l,
+                                0,
+                                &ThreadId);
+    if(ThreadHandle == NULL)
+    {
+        // leave critical section
+        LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
+
+        // delte handle
+        CloseHandle(DeleteHandle);
+
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+
+ //---------------------------------------------------------------------------
+//
+// Function:    EplTimeruModifyTimerMs
+//
+// Description: function change a timer and return a handle to the pointer
+//
+//
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//              ulTime_p    = time for timer in ms
+//              Argument_p  = argument for timer
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long     ulTime_p,
+                                        tEplTimerArg      Argument_p)
+{
+tEplKernel          Ret;
+HANDLE              DeleteHandle;
+HANDLE              ThreadHandle;
+DWORD               ThreadId;
+
+    Ret = kEplSuccessful;
+
+    // check parameter
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    DeleteHandle = (HANDLE)(*pTimerHdl_p);
+
+    // set event to end timer task for this timer
+    SetEvent(DeleteHandle);
+
+    // create new timer
+    // first create event to delete timer
+    DeleteHandle = CreateEvent(NULL,FALSE,FALSE, NULL);
+    if(DeleteHandle == NULL)
+    {
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+    // set handle for caller
+    *pTimerHdl_p = (tEplTimerHdl)DeleteHandle;
+
+    // enter  critical section
+    EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
+
+    // fill data for thread
+    ThreadData_l.DelteHandle = DeleteHandle;
+    EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p, sizeof(tEplTimerArg));
+    ThreadData_l.ulTimeout = ulTime_p;
+
+    // create thread to create waitable timer and wait for timer
+    ThreadHandle = CreateThread(NULL,
+                                0,
+                                EplSdoTimeruThreadms,
+                                &ThreadData_l,
+                                0,
+                                &ThreadId);
+    if(ThreadHandle == NULL)
+    {
+        // leave critical section
+        LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
+
+        // delte handle
+
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+ //---------------------------------------------------------------------------
+//
+// Function:    EplTimeruDeleteTimer
+//
+// Description: function delte a timer
+//
+//
+//
+// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
+//
+//
+// Returns:     tEplKernel  = errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl*     pTimerHdl_p)
+{
+tEplKernel  Ret;
+HANDLE      DeleteHandle;
+
+    Ret = kEplSuccessful;
+
+    // check parameter
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    DeleteHandle = (HANDLE)(*pTimerHdl_p);
+
+    // set event to end timer task for this timer
+    SetEvent(DeleteHandle);
+
+    // set handle invalide
+    *pTimerHdl_p = 0;
+
+
+Exit:
+    return Ret;
+
+}
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplSdoTimeruThreadms
+//
+// Description: function to process timer as thread
+//
+//
+//
+// Parameters:  lpParameter = pointer to structur of type tEplTimeruThread
+//
+//
+// Returns:     DWORD = Errorcode
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
+{
+tEplKernel          Ret;
+tEplTimeruThread*   pThreadData;
+HANDLE              aHandles[2];
+BOOL                fReturn;
+LARGE_INTEGER       TimeoutTime;
+unsigned long       ulEvent;
+tEplEvent           EplEvent;
+tEplTimeruThread    ThreadData;
+tEplTimerEventArg   TimerEventArg;
+
+    Ret = kEplSuccessful;
+
+    // get pointer to data
+    pThreadData = (tEplTimeruThread*)lpParameter;
+    // copy thread data
+    EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
+    pThreadData = &ThreadData;
+
+    // leave critical section
+    LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
+
+    // create waitable timer
+    aHandles[1] = CreateWaitableTimer(NULL,FALSE,NULL);
+    if(aHandles[1] == NULL)
+    {
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+    // set timer
+    // set timeout interval -> needed to be negativ
+    // -> because relative timeout
+    // -> multiply by 10000 for 100 ns timebase of function
+    TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
+    fReturn = SetWaitableTimer(aHandles[1],
+                               &TimeoutTime,
+                               0,
+                               NULL,
+                               NULL,
+                               FALSE);
+    if(fReturn == 0)
+    {
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+    // save delte event handle in handle array
+    aHandles[0] = pThreadData->DelteHandle;
+
+    // wait for one of the events
+    ulEvent = WaitForMultipleObjects( 2,
+                            &aHandles[0],
+                            FALSE,
+                            INFINITE);
+    if(ulEvent == WAIT_OBJECT_0)
+    {   // delte event
+
+        // close handels
+        CloseHandle(aHandles[1]);
+        // terminate thread
+        goto Exit;
+    }
+    else if(ulEvent == (WAIT_OBJECT_0 + 1))
+    {   // timer event
+        // call event function
+        TimerEventArg.m_TimerHdl = (tEplTimerHdl)pThreadData->DelteHandle;
+        TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
+
+        EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
+        EplEvent.m_EventType = kEplEventTypeTimer;
+        EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
+        EplEvent.m_pArg = &TimerEventArg;
+        EplEvent.m_uiSize = sizeof(TimerEventArg);
+
+        Ret = EplEventuPost(&EplEvent);
+
+        // close handels
+        CloseHandle(aHandles[1]);
+        // terminate thread
+        goto Exit;
+
+    }
+    else
+    {   // error
+        ulEvent = GetLastError();
+        TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",ulEvent);
+         // terminate thread
+        goto Exit;
+    }
+
+Exit:
+    return Ret;
+}
+
+
+// EOF
+
diff --git a/drivers/staging/epl/EplVersion.h b/drivers/staging/epl/EplVersion.h
new file mode 100644 (file)
index 0000000..4f47761
--- /dev/null
@@ -0,0 +1,100 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  This file defines the EPL version for the stack, as string
+                and for object 0x1018 within object dictionary.
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplVersion.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    all
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+****************************************************************************/
+
+#ifndef _EPL_VERSION_H_
+#define _EPL_VERSION_H_
+
+
+// NOTE:
+// All version macros should contain the same version number. But do not use
+// defines instead of the numbers. Because the macro EPL_STRING_VERSION() can not
+// convert a define to a string.
+//
+// Format: maj.min.build
+//         maj            = major version
+//             min        = minor version (will be set to 0 if major version will be incremented)
+//                 build  = current build (will be set to 0 if minor version will be incremented)
+//
+#define DEFINED_STACK_VERSION       EPL_STACK_VERSION   (1, 3, 0)
+#define DEFINED_OBJ1018_VERSION     EPL_OBJ1018_VERSION (1, 3, 0)
+#define DEFINED_STRING_VERSION      EPL_STRING_VERSION  (1, 3, 0)
+
+
+// -----------------------------------------------------------------------------
+#define EPL_PRODUCT_NAME            "EPL V2"
+#define EPL_PRODUCT_VERSION         DEFINED_STRING_VERSION
+#define EPL_PRODUCT_MANUFACTURER    "SYS TEC electronic GmbH"
+
+    #define EPL_PRODUCT_KEY         "SO-1083"
+    #define EPL_PRODUCT_DESCRIPTION "openPOWERLINK Protocol Stack Source"
+
+#endif // _EPL_VERSION_H_
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
diff --git a/drivers/staging/epl/Kconfig b/drivers/staging/epl/Kconfig
new file mode 100644 (file)
index 0000000..9f939d5
--- /dev/null
@@ -0,0 +1,6 @@
+config EPL
+       tristate "openPOWERLINK protocol stack"
+       depends on NET && HIGH_RES_TIMERS && X86
+       default N
+       ---help---
+         Enable support for the openPOWERLINK network protocol stack.
diff --git a/drivers/staging/epl/Makefile b/drivers/staging/epl/Makefile
new file mode 100644 (file)
index 0000000..a2c8241
--- /dev/null
@@ -0,0 +1,41 @@
+obj-$(CONFIG_EPL)      += epl.o
+
+epl-objs :=    \
+       EplApiGeneric.o         \
+       EplApiLinuxKernel.o     \
+       EplApiProcessImage.o    \
+       EplDllk.o               \
+       EplDllkCal.o            \
+       EplDlluCal.o            \
+       EplErrorHandlerk.o      \
+       EplEventk.o             \
+       EplEventu.o             \
+       EplIdentu.o             \
+       EplNmtCnu.o             \
+       EplNmtk.o               \
+       EplNmtkCal.o            \
+       EplNmtMnu.o             \
+       EplNmtu.o               \
+       EplNmtuCal.o            \
+       EplObd.o                \
+       EplObdkCal.o            \
+       EplObdu.o               \
+       EplObduCal.o            \
+       EplPdok.o               \
+       EplPdokCal.o            \
+       EplPdou.o               \
+       EplSdoAsndu.o           \
+       EplSdoAsySequ.o         \
+       EplSdoComu.o            \
+       EplSdoUdpu.o            \
+       EplStatusu.o            \
+       EplTimeruLinuxKernel.o  \
+       amix86.o                \
+       SharedBuff.o            \
+       ShbIpc-LinuxKernel.o    \
+       TimerHighReskX86.o      \
+       VirtualEthernetLinux.o  \
+       SocketLinuxKernel.o     \
+       proc_fs.o               \
+       demo_main.o             \
+       Edrv8139.o              \
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
new file mode 100644 (file)
index 0000000..1833d71
--- /dev/null
@@ -0,0 +1,2041 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      Project independend shared buffer (linear + circular)
+
+  Description:  Implementation of platform independend part for the
+                shared buffer
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+  2006/06/27 -rs:   V 1.00 (initial version)
+
+****************************************************************************/
+
+#if defined(WIN32) || defined(_WIN32)
+
+    #ifdef UNDER_RTSS
+        // RTX header
+        #include <windows.h>
+        #include <process.h>
+        #include <rtapi.h>
+
+    #elif __BORLANDC__
+        // borland C header
+        #include <windows.h>
+        #include <process.h>
+
+    #elif WINCE
+        #include <windows.h>
+
+    #else
+        // MSVC needs to include windows.h at first
+        // the following defines ar necessary for function prototypes for waitable timers
+        #define _WIN32_WINDOWS 0x0401
+        #define _WIN32_WINNT   0x0400
+        #include <windows.h>
+        #include <process.h>
+    #endif
+
+#endif
+
+#include "global.h"
+#include "SharedBuff.h"
+#include "ShbIpc.h"
+
+// d.k. Linux kernel modules needs other header files for memcpy()
+#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
+    #include <linux/string.h>
+#else
+    #include <stdio.h>
+    #include <stdlib.h>
+    #include <string.h>
+#endif
+
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Configuration
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Constant definitions
+//---------------------------------------------------------------------------
+
+#define SBC_MAGIC_ID    0x53424323              // magic ID ("SBC#")
+#define SBL_MAGIC_ID    0x53424C23              // magic ID ("SBL#")
+
+
+
+//---------------------------------------------------------------------------
+//  Local types
+//---------------------------------------------------------------------------
+
+// structure to administrate circular shared buffer head
+typedef struct
+{
+    unsigned long          m_ShbCirMagicID;     // magic ID ("SBC#")
+    unsigned long          m_ulBufferTotalSize; // over-all size of complete buffer
+    unsigned long          m_ulBufferDataSize;  // size of complete data area
+    unsigned long          m_ulWrIndex;         // current write index (set bevore write)
+    unsigned long          m_ulRdIndex;         // current read index (set after read)
+    unsigned long          m_ulNumOfWriteJobs;  // number of currently (parallel running) write operations
+    unsigned long          m_ulDataInUse;       // currently used buffer size (incl. uncompleted write operations)
+    unsigned long          m_ulDataApended;     // buffer size of complete new written but not yet readable data (in case of m_ulNumOfWriteJobs>1)
+    unsigned long          m_ulBlocksApended;   // number of complete new written but not yet readable data blocks (in case of m_ulNumOfWriteJobs>1)
+    unsigned long          m_ulDataReadable;    // buffer size with readable (complete written) data
+    unsigned long          m_ulBlocksReadable;  // number of readable (complete written) data blocks
+    tShbCirSigHndlrNewData m_pfnSigHndlrNewData;// application handler to signal new data
+    unsigned int           m_fBufferLocked;     // TRUE if buffer is locked (because of pending reset request)
+    tShbCirSigHndlrReset   m_pfnSigHndlrReset;  // application handler to signal buffer reset is done
+    unsigned char          m_Data;              // start of data area (the real data size is unknown at this time)
+
+} tShbCirBuff;
+
+
+// structure to administrate linear shared buffer head
+typedef struct
+{
+    unsigned int          m_ShbLinMagicID;      // magic ID ("SBL#")
+    unsigned long         m_ulBufferTotalSize;  // over-all size of complete buffer
+    unsigned long         m_ulBufferDataSize;   // size of complete data area
+    unsigned char         m_Data;               // start of data area (the real data size is unknown at this time)
+
+} tShbLinBuff;
+
+
+// type to save size of a single data block inside the circular shared buffer
+typedef struct
+{
+    unsigned int    m_uiFullBlockSize  :    28; // a single block must not exceed a length of 256MByte :-)
+    unsigned int    m_uiAlignFillBytes :     4;
+
+} tShbCirBlockSize;
+
+#define SBC_BLOCK_ALIGNMENT                  4  // alignment must *not* be lower than sizeof(tShbCirBlockSize)!
+#define SBC_MAX_BLOCK_SIZE         ((1<<28)-1)  // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
+
+#define SBL_BLOCK_ALIGNMENT                  4
+#define SBL_MAX_BLOCK_SIZE         ((1<<28)-1)  // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
+
+
+
+//---------------------------------------------------------------------------
+//  Global variables
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Local variables
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Prototypes of internal functions
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+//  Get pointer to Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbCirBuff*  ShbCirGetBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbCirBuff*  pShbCirBuff;
+
+
+    pShbCirBuff = (tShbCirBuff*) ShbIpcGetShMemPtr (pShbInstance_p);
+    ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID);
+
+    return (pShbCirBuff);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get pointer to Linear Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbLinBuff*  ShbLinGetBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbLinBuff*  pShbLinBuff;
+
+
+    pShbLinBuff = (tShbLinBuff*) ShbIpcGetShMemPtr (pShbInstance_p);
+    ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID);
+
+    return (pShbLinBuff);
+
+}
+
+
+
+// not inlined internal functions
+int           ShbCirSignalHandlerNewData (tShbInstance pShbInstance_p);
+void          ShbCirSignalHandlerReset   (tShbInstance pShbInstance_p, unsigned int fTimeOut_p);
+
+#endif
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+#if !defined(INLINE_ENABLED)
+// not inlined external functions
+
+//---------------------------------------------------------------------------
+//  Initialize Shared Buffer Module
+//---------------------------------------------------------------------------
+
+tShbError  ShbInit (void)
+{
+
+tShbError  ShbError;
+
+
+    ShbError = ShbIpcInit();
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Deinitialize Shared Buffer Module
+//---------------------------------------------------------------------------
+
+tShbError  ShbExit (void)
+{
+
+tShbError  ShbError;
+
+
+    ShbError = ShbIpcExit();
+
+    return (ShbError);
+
+}
+
+
+
+
+
+//-------------------------------------------------------------------------//
+//                                                                         //
+//          C i r c u l a r   S h a r e d   B u f f e r                    //
+//                                                                         //
+//-------------------------------------------------------------------------//
+
+//---------------------------------------------------------------------------
+//  Allocate Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbCirAllocBuffer (
+    unsigned long ulBufferSize_p,
+    const char* pszBufferID_p,
+    tShbInstance* ppShbInstance_p,
+    unsigned int* pfShbNewCreated_p)
+{
+
+tShbInstance   pShbInstance;
+tShbCirBuff*   pShbCirBuff;
+unsigned int   fShbNewCreated;
+unsigned long  ulBufferDataSize;
+unsigned long  ulBufferTotalSize;
+tShbError      ShbError;
+
+
+    // check arguments
+    if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    // calculate length of memory to allocate
+    ulBufferDataSize  = (ulBufferSize_p + (SBC_BLOCK_ALIGNMENT-1)) & ~(SBC_BLOCK_ALIGNMENT-1);
+    ulBufferTotalSize = ulBufferDataSize + sizeof(tShbCirBuff);
+
+    // allocate a new or open an existing shared buffer
+    ShbError = ShbIpcAllocBuffer (ulBufferTotalSize, pszBufferID_p,
+                                  &pShbInstance, &fShbNewCreated);
+    if (ShbError != kShbOk)
+    {
+        goto Exit;
+    }
+
+    if (pShbInstance == NULL)
+    {
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+
+
+    // get pointer to shared buffer
+    pShbCirBuff = (tShbCirBuff*) ShbIpcGetShMemPtr (pShbInstance);
+
+    // if the shared buffer was new created, than this process has
+    // to initialize it, otherwise the buffer is already in use
+    // and *must not* be reseted
+    if ( fShbNewCreated )
+    {
+        #ifndef NDEBUG
+        {
+            memset (pShbCirBuff, 0xCC, ulBufferTotalSize);
+        }
+        #endif
+
+
+        pShbCirBuff->m_ShbCirMagicID      = SBC_MAGIC_ID;
+        pShbCirBuff->m_ulBufferTotalSize  = ulBufferTotalSize;
+        pShbCirBuff->m_ulBufferDataSize   = ulBufferDataSize;
+        pShbCirBuff->m_ulWrIndex          = 0;
+        pShbCirBuff->m_ulRdIndex          = 0;
+        pShbCirBuff->m_ulNumOfWriteJobs   = 0;
+        pShbCirBuff->m_ulDataInUse        = 0;
+        pShbCirBuff->m_ulDataApended      = 0;
+        pShbCirBuff->m_ulBlocksApended    = 0;
+        pShbCirBuff->m_ulDataReadable     = 0;
+        pShbCirBuff->m_ulBlocksReadable   = 0;
+        pShbCirBuff->m_pfnSigHndlrNewData = NULL;
+        pShbCirBuff->m_fBufferLocked      = FALSE;
+        pShbCirBuff->m_pfnSigHndlrReset   = NULL;
+    }
+    else
+    {
+        if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+        {
+            ShbError = kShbInvalidBufferType;
+            goto Exit;
+        }
+    }
+
+
+Exit:
+
+    *ppShbInstance_p   = pShbInstance;
+    *pfShbNewCreated_p = fShbNewCreated;
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Release Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbCirReleaseBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbError  ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+
+    ShbError = ShbIpcReleaseBuffer (pShbInstance_p);
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+#endif  // !defined(INLINE_ENABLED)
+
+#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Reset Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirResetBuffer (
+    tShbInstance pShbInstance_p,
+    unsigned long ulTimeOut_p,
+    tShbCirSigHndlrReset pfnSignalHandlerReset_p)
+{
+
+tShbCirBuff*   pShbCirBuff;
+unsigned long  ulNumOfWriteJobs = 0;  // d.k. GCC complains about uninitialized variable otherwise
+tShbError      ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    ShbError    = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // start reset job by setting request request in buffer header
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        if ( !pShbCirBuff->m_fBufferLocked )
+        {
+            ulNumOfWriteJobs = pShbCirBuff->m_ulNumOfWriteJobs;
+
+            pShbCirBuff->m_fBufferLocked    = TRUE;
+            pShbCirBuff->m_pfnSigHndlrReset = pfnSignalHandlerReset_p;
+        }
+        else
+        {
+            ShbError = kShbAlreadyReseting;
+        }
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+    if (ShbError != kShbOk)
+    {
+        goto Exit;
+    }
+
+
+    // if there is currently no running write operation then reset buffer
+    // immediately, otherwise wait until the last write job is ready by
+    // starting a signal process
+    if (ulNumOfWriteJobs == 0)
+    {
+        // there is currently no running write operation
+        // -> reset buffer immediately
+        ShbCirSignalHandlerReset (pShbInstance_p, FALSE);
+        ShbError = kShbOk;
+    }
+    else
+    {
+        // there is currently at least one running write operation
+        // -> starting signal process to wait until the last write job is ready
+        ShbError = ShbIpcStartSignalingJobReady (pShbInstance_p, ulTimeOut_p, ShbCirSignalHandlerReset);
+    }
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Write data block to Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirWriteDataBlock (
+    tShbInstance pShbInstance_p,
+    const void* pSrcDataBlock_p,
+    unsigned long ulDataBlockSize_p)
+{
+
+tShbCirBuff*      pShbCirBuff;
+tShbCirBlockSize  ShbCirBlockSize;
+unsigned int      uiFullBlockSize;
+unsigned int      uiAlignFillBytes;
+unsigned char*    pShbCirDataPtr;
+unsigned char*    pScrDataPtr;
+unsigned long     ulDataSize;
+unsigned long     ulChunkSize;
+unsigned long     ulWrIndex = 0;  // d.k. GCC complains about uninitialized variable otherwise
+unsigned int      fSignalNewData;
+unsigned int      fSignalReset;
+tShbError         ShbError;
+tShbError         ShbError2;
+int               fRes;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+    if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0))
+    {
+        // nothing to do here
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+    if (ulDataBlockSize_p > SBC_MAX_BLOCK_SIZE)
+    {
+        ShbError = kShbExceedDataSizeLimit;
+        goto Exit;
+    }
+
+
+    pShbCirBuff    = ShbCirGetBuffer (pShbInstance_p);
+    pScrDataPtr    = (unsigned char*)pSrcDataBlock_p;
+    fSignalNewData = FALSE;
+    fSignalReset   = FALSE;
+    ShbError       = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // calculate data block size in circular buffer
+    ulDataSize       = (ulDataBlockSize_p + (SBC_BLOCK_ALIGNMENT-1)) & ~(SBC_BLOCK_ALIGNMENT-1);
+    uiFullBlockSize  = ulDataSize + sizeof(tShbCirBlockSize);   // data size + header
+    uiAlignFillBytes = ulDataSize - ulDataBlockSize_p;
+
+    ShbCirBlockSize.m_uiFullBlockSize  = uiFullBlockSize;
+    ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
+
+
+    // reserve the needed memory for the write operation to do now
+    // and make necessary adjustments in the circular buffer header
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        // check if there is sufficient memory available to store
+        // the new data
+        fRes = uiFullBlockSize <= (pShbCirBuff->m_ulBufferDataSize - pShbCirBuff->m_ulDataInUse);
+        if ( fRes )
+        {
+            // set write pointer for the write operation to do now
+            // to the current write pointer of the circular buffer
+            ulWrIndex = pShbCirBuff->m_ulWrIndex;
+
+            // reserve the needed memory for the write operation to do now
+            pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
+
+            // set new write pointer behind the reserved memory
+            // for the write operation to do now
+            pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
+            pShbCirBuff->m_ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+            // increment number of currently (parallel running)
+            // write operations
+            pShbCirBuff->m_ulNumOfWriteJobs++;
+        }
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    if ( !fRes )
+    {
+        ShbError = kShbBufferFull;
+        goto Exit;
+    }
+
+
+    // copy the data to the circular buffer
+    // (the copy process itself will be done outside of any
+    // critical/locked section)
+    pShbCirDataPtr = &pShbCirBuff->m_Data;          // ptr to start of data area
+
+    // write real size of current block (incl. alignment fill bytes)
+    *(tShbCirBlockSize*)(pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
+    ulWrIndex += sizeof(tShbCirBlockSize);
+    ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+     if (ulWrIndex + ulDataBlockSize_p <= pShbCirBuff->m_ulBufferDataSize)
+    {
+        // linear write operation
+        memcpy (pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulDataBlockSize_p);
+    }
+    else
+    {
+        // wrap-around write operation
+        ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
+        memcpy (pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulChunkSize);
+        memcpy (pShbCirDataPtr, pScrDataPtr + ulChunkSize, ulDataBlockSize_p - ulChunkSize);
+    }
+
+
+    // adjust header information for circular buffer with properties
+    // of the wiritten data block
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        pShbCirBuff->m_ulDataApended   += uiFullBlockSize;
+        pShbCirBuff->m_ulBlocksApended ++;
+
+        // decrement number of currently (parallel running) write operations
+        if ( !--pShbCirBuff->m_ulNumOfWriteJobs )
+        {
+            // if there is no other write process running then
+            // set new size of readable (complete written) data and
+            // adjust number of readable blocks
+            pShbCirBuff->m_ulDataReadable   += pShbCirBuff->m_ulDataApended;
+            pShbCirBuff->m_ulBlocksReadable += pShbCirBuff->m_ulBlocksApended;
+
+            pShbCirBuff->m_ulDataApended   = 0;
+            pShbCirBuff->m_ulBlocksApended = 0;
+
+            fSignalNewData = TRUE;
+            fSignalReset   = pShbCirBuff->m_fBufferLocked;
+        }
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    // signal new data event to a potentially reading application
+    if ( fSignalNewData )
+    {
+        ShbError2 = ShbIpcSignalNewData (pShbInstance_p);
+        if (ShbError == kShbOk)
+        {
+            ShbError = ShbError2;
+        }
+    }
+
+    // signal that the last write job has been finished to allow
+    // a waiting application to reset the buffer now
+    if ( fSignalReset )
+    {
+        ShbError2 = ShbIpcSignalJobReady (pShbInstance_p);
+        if (ShbError == kShbOk)
+        {
+            ShbError = ShbError2;
+        }
+    }
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Allocate block within the Circular Shared Buffer for chunk writing
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirAllocDataBlock (
+    tShbInstance pShbInstance_p,
+    tShbCirChunk* pShbCirChunk_p,
+    unsigned long ulDataBufferSize_p)
+{
+
+tShbCirBuff*      pShbCirBuff;
+tShbCirBlockSize  ShbCirBlockSize;
+unsigned int      uiFullBlockSize;
+unsigned int      uiAlignFillBytes;
+unsigned char*    pShbCirDataPtr;
+unsigned long     ulDataSize;
+unsigned long     ulWrIndex = 0;  // d.k. GCC complains about uninitialized variable otherwise
+tShbError         ShbError;
+int               fRes;
+
+
+    // check arguments
+    if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL))
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+    if (ulDataBufferSize_p == 0)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+    if (ulDataBufferSize_p > SBC_MAX_BLOCK_SIZE)
+    {
+        ShbError = kShbExceedDataSizeLimit;
+        goto Exit;
+    }
+
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    ShbError    = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // calculate data block size in circular buffer
+    ulDataSize       = (ulDataBufferSize_p + (SBC_BLOCK_ALIGNMENT-1)) & ~(SBC_BLOCK_ALIGNMENT-1);
+    uiFullBlockSize  = ulDataSize + sizeof(tShbCirBlockSize);   // data size + header
+    uiAlignFillBytes = ulDataSize - ulDataBufferSize_p;
+
+    ShbCirBlockSize.m_uiFullBlockSize  = uiFullBlockSize;
+    ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
+
+
+    // reserve the needed memory for the write operation to do now
+    // and make necessary adjustments in the circular buffer header
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        // check if there is sufficient memory available to store
+        // the new data
+        fRes = (uiFullBlockSize <= (pShbCirBuff->m_ulBufferDataSize - pShbCirBuff->m_ulDataInUse));
+        if ( fRes )
+        {
+            // set write pointer for the write operation to do now
+            // to the current write pointer of the circular buffer
+            ulWrIndex = pShbCirBuff->m_ulWrIndex;
+
+            // reserve the needed memory for the write operation to do now
+            pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
+
+            // set new write pointer behind the reserved memory
+            // for the write operation to do now
+            pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
+            pShbCirBuff->m_ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+            // increment number of currently (parallel running)
+            // write operations
+            pShbCirBuff->m_ulNumOfWriteJobs++;
+        }
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    if ( !fRes )
+    {
+        ShbError = kShbBufferFull;
+        goto Exit;
+    }
+
+
+    // setup header information for allocated buffer
+    pShbCirDataPtr = &pShbCirBuff->m_Data;          // ptr to start of data area
+
+    // write real size of current block (incl. alignment fill bytes)
+    *(tShbCirBlockSize*)(pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
+    ulWrIndex += sizeof(tShbCirBlockSize);
+    ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+    // setup chunk descriptor
+    pShbCirChunk_p->m_uiFullBlockSize  = uiFullBlockSize;
+    pShbCirChunk_p->m_ulAvailableSize  = ulDataBufferSize_p;
+    pShbCirChunk_p->m_ulWrIndex        = ulWrIndex;
+    pShbCirChunk_p->m_fBufferCompleted = FALSE;
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Write data chunk into an allocated buffer of the Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirWriteDataChunk (
+    tShbInstance pShbInstance_p,
+    tShbCirChunk* pShbCirChunk_p,
+    const void* pSrcDataChunk_p,
+    unsigned long ulDataChunkSize_p,
+    unsigned int* pfBufferCompleted_p)
+{
+
+tShbCirBuff*    pShbCirBuff;
+unsigned char*  pShbCirDataPtr;
+unsigned char*  pScrDataPtr;
+unsigned long   ulSubChunkSize;
+unsigned long   ulWrIndex;
+unsigned int    fBufferCompleted;
+unsigned int    fSignalNewData;
+unsigned int    fSignalReset;
+tShbError       ShbError;
+tShbError       ShbError2;
+
+
+    // check arguments
+    if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL) || (pfBufferCompleted_p == NULL))
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+    if ((pSrcDataChunk_p == NULL) || (ulDataChunkSize_p == 0))
+    {
+        // nothing to do here
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+    if ( pShbCirChunk_p->m_fBufferCompleted )
+    {
+        ShbError = kShbBufferAlreadyCompleted;
+        goto Exit;
+    }
+
+    if (ulDataChunkSize_p > pShbCirChunk_p->m_ulAvailableSize)
+    {
+        ShbError = kShbExceedDataSizeLimit;
+        goto Exit;
+    }
+
+
+    pShbCirBuff    = ShbCirGetBuffer (pShbInstance_p);
+    pScrDataPtr    = (unsigned char*)pSrcDataChunk_p;
+    fSignalNewData = FALSE;
+    fSignalReset   = FALSE;
+    ShbError       = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    ulWrIndex = pShbCirChunk_p->m_ulWrIndex;
+
+
+    // copy the data to the circular buffer
+    // (the copy process itself will be done outside of any
+    // critical/locked section)
+    pShbCirDataPtr = &pShbCirBuff->m_Data;          // ptr to start of data area
+
+
+    if (ulWrIndex + ulDataChunkSize_p <= pShbCirBuff->m_ulBufferDataSize)
+    {
+        // linear write operation
+        memcpy (pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulDataChunkSize_p);
+    }
+    else
+    {
+        // wrap-around write operation
+        ulSubChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
+        memcpy (pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulSubChunkSize);
+        memcpy (pShbCirDataPtr, pScrDataPtr + ulSubChunkSize, ulDataChunkSize_p - ulSubChunkSize);
+    }
+
+
+    // adjust chunk descriptor
+    ulWrIndex += ulDataChunkSize_p;
+    ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+    pShbCirChunk_p->m_ulAvailableSize -= ulDataChunkSize_p;
+    pShbCirChunk_p->m_ulWrIndex        = ulWrIndex;
+
+    fBufferCompleted = (pShbCirChunk_p->m_ulAvailableSize == 0);
+    pShbCirChunk_p->m_fBufferCompleted = fBufferCompleted;
+
+
+    // if the complete allocated buffer is filled with data then
+    // adjust header information for circular buffer with properties
+    // of the wiritten data block
+    if ( fBufferCompleted )
+    {
+        ShbIpcEnterAtomicSection (pShbInstance_p);
+        {
+            pShbCirBuff->m_ulDataApended   += pShbCirChunk_p->m_uiFullBlockSize;
+            pShbCirBuff->m_ulBlocksApended ++;
+
+            // decrement number of currently (parallel running) write operations
+            if ( !--pShbCirBuff->m_ulNumOfWriteJobs )
+            {
+                // if there is no other write process running then
+                // set new size of readable (complete written) data and
+                // adjust number of readable blocks
+                pShbCirBuff->m_ulDataReadable   += pShbCirBuff->m_ulDataApended;
+                pShbCirBuff->m_ulBlocksReadable += pShbCirBuff->m_ulBlocksApended;
+
+                pShbCirBuff->m_ulDataApended   = 0;
+                pShbCirBuff->m_ulBlocksApended = 0;
+
+                fSignalNewData = TRUE;
+                fSignalReset   = pShbCirBuff->m_fBufferLocked;
+            }
+        }
+        ShbIpcLeaveAtomicSection (pShbInstance_p);
+    }
+
+
+    // signal new data event to a potentially reading application
+    if ( fSignalNewData )
+    {
+        ShbError2 = ShbIpcSignalNewData (pShbInstance_p);
+        if (ShbError == kShbOk)
+        {
+            ShbError = ShbError2;
+        }
+    }
+
+    // signal that the last write job has been finished to allow
+    // a waiting application to reset the buffer now
+    if ( fSignalReset )
+    {
+        ShbError2 = ShbIpcSignalJobReady (pShbInstance_p);
+        if (ShbError == kShbOk)
+        {
+            ShbError = ShbError2;
+        }
+    }
+
+
+    *pfBufferCompleted_p = fBufferCompleted;
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Read data block from Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirReadDataBlock (
+    tShbInstance pShbInstance_p,
+    void* pDstDataBlock_p,
+    unsigned long ulRdBuffSize_p,
+    unsigned long* pulDataBlockSize_p)
+{
+
+tShbCirBuff*      pShbCirBuff;
+tShbCirBlockSize  ShbCirBlockSize;
+unsigned long     ulDataReadable;
+unsigned char*    pShbCirDataPtr;
+unsigned char*    pDstDataPtr;
+unsigned long     ulDataSize = 0;  // d.k. GCC complains about uninitialized variable otherwise
+unsigned long     ulChunkSize;
+unsigned long     ulRdIndex;
+tShbError         ShbError;
+
+
+    // check arguments
+    if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+    if ((pDstDataBlock_p == NULL) || (ulRdBuffSize_p == 0))
+    {
+        // nothing to do here
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+
+    ShbError    = kShbOk;
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    pDstDataPtr = (unsigned char*)pDstDataBlock_p;
+    ulDataSize  = 0;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // get total number of readable bytes for the whole circular buffer
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        ulDataReadable = pShbCirBuff->m_ulDataReadable;
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    // if there are readable data available, then there must be at least
+    // one complete readable data block
+    if (ulDataReadable > 0)
+    {
+        // get pointer to start of data area and current read index
+        pShbCirDataPtr = &pShbCirBuff->m_Data;      // ptr to start of data area
+        ulRdIndex      =  pShbCirBuff->m_ulRdIndex;
+
+        // get real size of current block (incl. alignment fill bytes)
+        ShbCirBlockSize = *(tShbCirBlockSize*)(pShbCirDataPtr + ulRdIndex);
+        ulRdIndex += sizeof(tShbCirBlockSize);
+        ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+        // get size of user data inside the current block
+        ulDataSize  = ShbCirBlockSize.m_uiFullBlockSize - ShbCirBlockSize.m_uiAlignFillBytes;
+        ulDataSize -= sizeof(tShbCirBlockSize);
+    }
+
+
+    // ulDataSize = MIN(ulDataSize, ulRdBuffSize_p);
+    if (ulDataSize > ulRdBuffSize_p)
+    {
+        ulDataSize = ulRdBuffSize_p;
+        ShbError = kShbDataTruncated;
+    }
+
+    if (ulDataSize == 0)
+    {
+        // nothing to do here
+        ShbError = kShbNoReadableData;
+        goto Exit;
+    }
+
+
+    // copy the data from the circular buffer
+    // (the copy process itself will be done outside of any
+    // critical/locked section)
+    if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize)
+    {
+        // linear read operation
+        memcpy (pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulDataSize);
+    }
+    else
+    {
+        // wrap-around read operation
+        ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
+        memcpy (pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulChunkSize);
+        memcpy (pDstDataPtr + ulChunkSize, pShbCirDataPtr, ulDataSize - ulChunkSize);
+    }
+
+
+    #ifndef NDEBUG
+    {
+        tShbCirBlockSize  ClrShbCirBlockSize;
+
+        if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize)
+        {
+            // linear buffer
+            memset (pShbCirDataPtr + ulRdIndex, 0xDD, ulDataSize);
+        }
+        else
+        {
+            // wrap-around read operation
+            ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
+            memset (pShbCirDataPtr + ulRdIndex, 0xDD, ulChunkSize);
+            memset (pShbCirDataPtr, 0xDD, ulDataSize - ulChunkSize);
+        }
+
+        ClrShbCirBlockSize.m_uiFullBlockSize  = /*(unsigned int)*/ -1;     // -1 = xFFFFFFF
+        ClrShbCirBlockSize.m_uiAlignFillBytes = /*(unsigned int)*/ -1;     // -1 = Fxxxxxxx
+        *(tShbCirBlockSize*)(pShbCirDataPtr + pShbCirBuff->m_ulRdIndex) = ClrShbCirBlockSize;
+    }
+    #endif  // #ifndef NDEBUG
+
+
+    // set new size of readable data, data in use, new read index
+    // and adjust number of readable blocks
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        pShbCirBuff->m_ulDataInUse      -= ShbCirBlockSize.m_uiFullBlockSize;
+        pShbCirBuff->m_ulDataReadable   -= ShbCirBlockSize.m_uiFullBlockSize;
+        pShbCirBuff->m_ulBlocksReadable --;
+
+        //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+        if ((pShbCirBuff->m_ulDataInUse == 0) && (pShbCirBuff->m_ulDataReadable == 0))
+        {
+            ASSERT(pShbCirBuff->m_ulBlocksReadable == 0);
+
+            pShbCirBuff->m_ulWrIndex = 0;
+            pShbCirBuff->m_ulRdIndex = 0;
+        }
+        else
+        //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+        {
+            pShbCirBuff->m_ulRdIndex += ShbCirBlockSize.m_uiFullBlockSize;
+            pShbCirBuff->m_ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
+        }
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+Exit:
+
+    *pulDataBlockSize_p = ulDataSize;
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get data size of next readable block from Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirGetReadDataSize (
+    tShbInstance pShbInstance_p,
+    unsigned long* pulDataBlockSize_p)
+{
+
+tShbCirBuff*      pShbCirBuff;
+unsigned long     ulDataReadable;
+unsigned char*    pShbCirDataPtr;
+tShbCirBlockSize  ShbCirBlockSize;
+unsigned long     ulDataSize;
+tShbError         ShbError;
+
+
+    // check arguments
+    if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    ulDataSize  = 0;
+    ShbError    = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // get total number of readable bytes for the whole circular buffer
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        ulDataReadable = pShbCirBuff->m_ulDataReadable;
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    // if there are readable data available, then there must be at least
+    // one complete readable data block
+    if (ulDataReadable > 0)
+    {
+        pShbCirDataPtr = &pShbCirBuff->m_Data + pShbCirBuff->m_ulRdIndex;
+
+        // get real size of current block (incl. alignment fill bytes)
+        ShbCirBlockSize = *(tShbCirBlockSize*)pShbCirDataPtr;
+
+        // get size of user data inside the current block
+        ulDataSize  = ShbCirBlockSize.m_uiFullBlockSize - ShbCirBlockSize.m_uiAlignFillBytes;
+        ulDataSize -= sizeof(tShbCirBlockSize);
+    }
+
+
+Exit:
+
+    *pulDataBlockSize_p = ulDataSize;
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get number of readable blocks from Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirGetReadBlockCount (
+    tShbInstance pShbInstance_p,
+    unsigned long* pulDataBlockCount_p)
+{
+
+tShbCirBuff*   pShbCirBuff;
+unsigned long  ulBlockCount;
+tShbError      ShbError;
+
+
+    // check arguments
+    if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL))
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+
+    pShbCirBuff  = ShbCirGetBuffer (pShbInstance_p);
+    ulBlockCount = 0;
+    ShbError     = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        ulBlockCount = pShbCirBuff->m_ulBlocksReadable;
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    *pulDataBlockCount_p = ulBlockCount;
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Set application handler to signal new data for Circular Shared Buffer
+//  d.k.: new parameter priority as enum
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbCirSetSignalHandlerNewData (
+    tShbInstance pShbInstance_p,
+    tShbCirSigHndlrNewData pfnSignalHandlerNewData_p,
+    tShbPriority ShbPriority_p)
+{
+
+tShbCirBuff*  pShbCirBuff;
+tShbError     ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    ShbError    = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    if (pfnSignalHandlerNewData_p != NULL)
+    {
+        // set a new signal handler
+        if (pShbCirBuff->m_pfnSigHndlrNewData != NULL)
+        {
+            ShbError = kShbAlreadySignaling;
+            goto Exit;
+        }
+
+        pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
+        ShbError = ShbIpcStartSignalingNewData (pShbInstance_p, ShbCirSignalHandlerNewData, ShbPriority_p);
+    }
+    else
+    {
+        // remove existing signal handler
+        ShbError = ShbIpcStopSignalingNewData (pShbInstance_p);
+        if (pShbCirBuff->m_pfnSigHndlrNewData != NULL)
+        {
+            pShbCirBuff->m_pfnSigHndlrNewData (pShbInstance_p, 0);
+        }
+        pShbCirBuff->m_pfnSigHndlrNewData = NULL;
+    }
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+#endif
+
+#if !defined(INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  DEBUG: Trace Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+#ifndef NDEBUG
+tShbError  ShbCirTraceBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbCirBuff*      pShbCirBuff;
+char              szMagigID[sizeof(SBC_MAGIC_ID)+1];
+tShbCirBlockSize  ShbCirBlockSize;
+unsigned long     ulDataReadable;
+unsigned char*    pShbCirDataPtr;
+unsigned long     ulBlockIndex;
+unsigned int      nBlockCount;
+unsigned long     ulDataSize;
+unsigned long     ulChunkSize;
+unsigned long     ulRdIndex;
+tShbError         ShbError;
+
+
+    TRACE0("\n\n##### Circular Shared Buffer #####\n");
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", (unsigned long)pShbInstance_p);
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    ShbError    = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    *(unsigned long*) &szMagigID[0] = pShbCirBuff->m_ShbCirMagicID;
+    szMagigID[sizeof(SBC_MAGIC_ID)] = '\0';
+
+
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        TRACE1("\nBuffer Address:   0x%08lX\n",    (unsigned long)pShbCirBuff);
+
+        TRACE0("\nHeader Info:");
+        TRACE2("\nMagigID:          '%s' (%08lX)", szMagigID, pShbCirBuff->m_ShbCirMagicID);
+        TRACE1("\nBufferTotalSize:  %4lu [Bytes]", pShbCirBuff->m_ulBufferTotalSize);
+        TRACE1("\nBufferDataSize:   %4lu [Bytes]", pShbCirBuff->m_ulBufferDataSize);
+        TRACE1("\nWrIndex:          %4lu",         pShbCirBuff->m_ulWrIndex);
+        TRACE1("\nRdIndex:          %4lu",         pShbCirBuff->m_ulRdIndex);
+        TRACE1("\nNumOfWriteJobs:   %4lu",         pShbCirBuff->m_ulNumOfWriteJobs);
+        TRACE1("\nDataInUse:        %4lu [Bytes]", pShbCirBuff->m_ulDataInUse);
+        TRACE1("\nDataApended:      %4lu [Bytes]", pShbCirBuff->m_ulDataApended);
+        TRACE1("\nBlocksApended:    %4lu",         pShbCirBuff->m_ulBlocksApended);
+        TRACE1("\nDataReadable:     %4lu [Bytes]", pShbCirBuff->m_ulDataReadable);
+        TRACE1("\nBlocksReadable:   %4lu",         pShbCirBuff->m_ulBlocksReadable);
+        TRACE1("\nSigHndlrNewData:  %08lX",        (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData);
+        TRACE1("\nBufferLocked:     %d",           pShbCirBuff->m_fBufferLocked);
+        TRACE1("\nSigHndlrReset:    %08lX",        (unsigned long)pShbCirBuff->m_pfnSigHndlrReset);
+
+        ShbTraceDump (&pShbCirBuff->m_Data, pShbCirBuff->m_ulBufferDataSize,
+                      0x00000000L, "\nData Area:");
+
+
+        ulDataReadable = pShbCirBuff->m_ulDataReadable;
+        nBlockCount  = 1;
+        ulBlockIndex = pShbCirBuff->m_ulRdIndex;
+
+        while (ulDataReadable > 0)
+        {
+            TRACE1("\n\n--- Block #%u ---", nBlockCount);
+
+            // get pointer to start of data area and current read index
+            pShbCirDataPtr = &pShbCirBuff->m_Data;      // ptr to start of data area
+            ulRdIndex      = ulBlockIndex;
+
+            // get real size of current block (incl. alignment fill bytes)
+            ShbCirBlockSize = *(tShbCirBlockSize*)(pShbCirDataPtr + ulRdIndex);
+            ulRdIndex += sizeof(tShbCirBlockSize);
+            ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+            // get size of user data inside the current block
+            ulDataSize  = ShbCirBlockSize.m_uiFullBlockSize - ShbCirBlockSize.m_uiAlignFillBytes;
+            ulDataSize -= sizeof(tShbCirBlockSize);
+
+            TRACE1("\nFull Data Size:       %4u [Bytes] (incl. header and alignment fill bytes)", ShbCirBlockSize.m_uiFullBlockSize);
+            TRACE1("\nUser Data Size:       %4lu [Bytes]", ulDataSize);
+            TRACE1("\nAlignment Fill Bytes: %4u [Bytes]", ShbCirBlockSize.m_uiAlignFillBytes);
+
+
+            if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize)
+            {
+                // linear data buffer
+                ShbTraceDump (pShbCirDataPtr + ulRdIndex, ulDataSize, 0x00000000L, NULL);
+            }
+            else
+            {
+                // wrap-around data buffer
+                ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
+                ShbTraceDump (pShbCirDataPtr + ulRdIndex, ulChunkSize, 0x00000000L, NULL);
+                ShbTraceDump (pShbCirDataPtr, ulDataSize - ulChunkSize, ulChunkSize, NULL);
+            }
+
+            nBlockCount++;
+
+            ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize;
+            ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize;
+
+            ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize;
+        }
+
+        ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount-1);
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+
+Exit:
+
+    return (ShbError);
+
+}
+#endif
+
+
+
+
+
+//-------------------------------------------------------------------------//
+//                                                                         //
+//          L i n e a r   S h a r e d   B u f f e r                        //
+//                                                                         //
+//-------------------------------------------------------------------------//
+
+//---------------------------------------------------------------------------
+//  Allocate Linear Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbLinAllocBuffer (
+    unsigned long ulBufferSize_p,
+    const char* pszBufferID_p,
+    tShbInstance* ppShbInstance_p,
+    unsigned int* pfShbNewCreated_p)
+{
+
+tShbInstance   pShbInstance;
+tShbLinBuff*   pShbLinBuff;
+unsigned int   fShbNewCreated;
+unsigned long  ulBufferDataSize;
+unsigned long  ulBufferTotalSize;
+tShbError      ShbError;
+
+
+    // check arguments
+    if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    // calculate length of memory to allocate
+    ulBufferDataSize  = (ulBufferSize_p + (SBL_BLOCK_ALIGNMENT-1)) & ~(SBL_BLOCK_ALIGNMENT-1);
+    ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff);
+
+    // allocate a new or open an existing shared buffer
+    ShbError = ShbIpcAllocBuffer (ulBufferTotalSize, pszBufferID_p,
+                                  &pShbInstance, &fShbNewCreated);
+    if (ShbError != kShbOk)
+    {
+        goto Exit;
+    }
+
+    if (pShbInstance == NULL)
+    {
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+
+
+    // get pointer to shared buffer
+    pShbLinBuff = (tShbLinBuff*) ShbIpcGetShMemPtr (pShbInstance);
+
+    // if the shared buffer was new created, than this process has
+    // to initialize it, otherwise the buffer is already in use
+    // and *must not* be reseted
+    if ( fShbNewCreated )
+    {
+        #ifndef NDEBUG
+        {
+            memset (pShbLinBuff, 0xCC, ulBufferTotalSize);
+        }
+        #endif
+
+
+        pShbLinBuff->m_ShbLinMagicID     = SBL_MAGIC_ID;
+        pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize;
+        pShbLinBuff->m_ulBufferDataSize  = ulBufferDataSize;
+    }
+    else
+    {
+        if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID)
+        {
+            ShbError = kShbInvalidBufferType;
+            goto Exit;
+        }
+    }
+
+
+Exit:
+
+    *ppShbInstance_p   = pShbInstance;
+    *pfShbNewCreated_p = fShbNewCreated;
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Release Linear Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbLinReleaseBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbError  ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+
+    ShbError = ShbIpcReleaseBuffer (pShbInstance_p);
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+#endif  // !defined(INLINE_ENABLED)
+
+#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Write data block to Linear Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbLinWriteDataBlock (
+    tShbInstance pShbInstance_p,
+    unsigned long ulDstBufferOffs_p,
+    const void* pSrcDataBlock_p,
+    unsigned long ulDataBlockSize_p)
+{
+
+tShbLinBuff*    pShbLinBuff;
+unsigned char*  pShbLinDataPtr;
+unsigned char*  pScrDataPtr;
+unsigned long   ulBufferDataSize;
+tShbError       ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+    if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0))
+    {
+        // nothing to do here
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+    if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE)
+    {
+        ShbError = kShbExceedDataSizeLimit;
+        goto Exit;
+    }
+
+
+    pShbLinBuff = ShbLinGetBuffer (pShbInstance_p);
+    pScrDataPtr = (unsigned char*)pSrcDataBlock_p;
+    ShbError    = kShbOk;
+
+    if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // check if offeset and size for the write operation matches with
+    // the size of the shared buffer
+    ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize;
+    if ( (ulDstBufferOffs_p > ulBufferDataSize) ||
+         (ulDataBlockSize_p > ulBufferDataSize) ||
+         ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize) )
+    {
+        ShbError = kShbDataOutsideBufferArea;
+        goto Exit;
+    }
+
+
+    // copy the data to the linear buffer
+    // (the copy process will be done inside of any critical/locked section)
+    pShbLinDataPtr  = &pShbLinBuff->m_Data;         // ptr to start of data area
+    pShbLinDataPtr += ulDstBufferOffs_p;
+
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        memcpy (pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p);
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Read data block from Linear Shared Buffer
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbLinReadDataBlock (
+    tShbInstance pShbInstance_p,
+    void* pDstDataBlock_p,
+    unsigned long ulSrcBufferOffs_p,
+    unsigned long ulDataBlockSize_p)
+{
+
+tShbLinBuff*    pShbLinBuff;
+unsigned char*  pShbLinDataPtr;
+unsigned char*  pDstDataPtr;
+unsigned long   ulBufferDataSize;
+tShbError       ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+    if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0))
+    {
+        // nothing to do here
+        ShbError = kShbOk;
+        goto Exit;
+    }
+
+    if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE)
+    {
+        ShbError = kShbExceedDataSizeLimit;
+        goto Exit;
+    }
+
+
+    pShbLinBuff = ShbLinGetBuffer (pShbInstance_p);
+    pDstDataPtr = (unsigned char*)pDstDataBlock_p;
+    ShbError    = kShbOk;
+
+    if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    // check if offeset and size for the read operation matches with
+    // the size of the shared buffer
+    ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize;
+    if ( (ulSrcBufferOffs_p > ulBufferDataSize) ||
+         (ulDataBlockSize_p > ulBufferDataSize) ||
+         ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize) )
+    {
+        ShbError = kShbDataOutsideBufferArea;
+        goto Exit;
+    }
+
+
+    // copy the data to the linear buffer
+    // (the copy process will be done inside of any critical/locked section)
+    pShbLinDataPtr  = &pShbLinBuff->m_Data;         // ptr to start of data area
+    pShbLinDataPtr += ulSrcBufferOffs_p;
+
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        memcpy (pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p);
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+#endif
+
+
+#if !defined(INLINE_ENABLED)
+
+
+//---------------------------------------------------------------------------
+//  DEBUG: Trace Linear Shared Buffer
+//---------------------------------------------------------------------------
+
+#ifndef NDEBUG
+tShbError  ShbLinTraceBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbLinBuff*  pShbLinBuff;
+char          szMagigID[sizeof(SBL_MAGIC_ID)+1];
+tShbError     ShbError;
+
+
+    TRACE0("\n\n##### Linear Shared Buffer #####\n");
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", (unsigned long)pShbInstance_p);
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+
+
+    pShbLinBuff = ShbLinGetBuffer (pShbInstance_p);
+    ShbError    = kShbOk;
+
+    if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID)
+    {
+        ShbError = kShbInvalidBufferType;
+        goto Exit;
+    }
+
+
+    *(unsigned int*) &szMagigID[0] = pShbLinBuff->m_ShbLinMagicID;
+    szMagigID[sizeof(SBL_MAGIC_ID)] = '\0';
+
+
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        TRACE1("\nBuffer Address:   0x%08lX\n",    (unsigned long)pShbLinBuff);
+
+        TRACE0("\nHeader Info:");
+        TRACE2("\nMagigID:          '%s' (%08X)", szMagigID, pShbLinBuff->m_ShbLinMagicID);
+        TRACE1("\nBufferTotalSize:  %4lu [Bytes]", pShbLinBuff->m_ulBufferTotalSize);
+        TRACE1("\nBufferDataSize:   %4lu [Bytes]", pShbLinBuff->m_ulBufferDataSize);
+
+        ShbTraceDump (&pShbLinBuff->m_Data, pShbLinBuff->m_ulBufferDataSize,
+                      0x00000000L, "\nData Area:");
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+
+Exit:
+
+    return (ShbError);
+
+}
+#endif
+
+
+
+
+
+//---------------------------------------------------------------------------
+//  Dump buffer contents
+//---------------------------------------------------------------------------
+
+#ifndef NDEBUG
+tShbError  ShbTraceDump (
+    const unsigned char* pabStartAddr_p,
+    unsigned long ulDataSize_p,
+    unsigned long ulAddrOffset_p,
+    const char* pszInfoText_p)
+{
+
+const unsigned char*  pabBuffData;
+unsigned long         ulBuffSize;
+unsigned char         bData;
+int                   nRow;
+int                   nCol;
+
+
+    // get pointer to buffer and length of buffer
+    pabBuffData = pabStartAddr_p;
+    ulBuffSize  = ulDataSize_p;
+
+
+    if (pszInfoText_p != NULL)
+    {
+        TRACE0(pszInfoText_p);
+    }
+
+    // dump buffer contents
+    for (nRow=0; ; nRow++)
+    {
+        TRACE1("\n%08lX:   ", (unsigned long)(nRow*0x10) + ulAddrOffset_p);
+
+        for (nCol=0; nCol<16; nCol++)
+        {
+            if ((unsigned long)nCol < ulBuffSize)
+            {
+                TRACE1("%02X ", (unsigned int)*(pabBuffData+nCol));
+            }
+            else
+            {
+                TRACE0("   ");
+            }
+        }
+
+        TRACE0(" ");
+
+        for (nCol=0; nCol<16; nCol++)
+        {
+            bData = *pabBuffData++;
+            if ((unsigned long)nCol < ulBuffSize)
+            {
+                if ((bData >= 0x20) && (bData < 0x7F))
+                {
+                    TRACE1("%c", bData);
+                }
+                else
+                {
+                    TRACE0(".");
+                }
+            }
+            else
+            {
+                TRACE0(" ");
+            }
+        }
+
+        if (ulBuffSize > 16)
+        {
+            ulBuffSize -= 16;
+        }
+        else
+        {
+            break;
+        }
+    }
+
+
+    return (kShbOk);
+
+}
+#endif  // #ifndef NDEBUG
+
+
+
+
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//  Handler to signal new data event for Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+int  ShbCirSignalHandlerNewData (
+    tShbInstance pShbInstance_p)
+{
+
+tShbCirBuff*   pShbCirBuff;
+unsigned long  ulDataSize;
+unsigned long  ulBlockCount;
+tShbError      ShbError;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        return FALSE;
+    }
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    ShbError    = kShbOk;
+
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        return FALSE;
+    }
+
+
+    // call application handler
+    if (pShbCirBuff->m_pfnSigHndlrNewData != NULL)
+    {
+/*        do
+        {*/
+            ShbError = ShbCirGetReadDataSize (pShbInstance_p, &ulDataSize);
+            if ((ulDataSize > 0) && (ShbError == kShbOk))
+            {
+                pShbCirBuff->m_pfnSigHndlrNewData (pShbInstance_p, ulDataSize);
+            }
+
+            ShbError = ShbCirGetReadBlockCount (pShbInstance_p, &ulBlockCount);
+/*        }
+        while ((ulBlockCount > 0) && (ShbError == kShbOk));*/
+    }
+
+    // Return TRUE if there are pending blocks.
+    // In that case ShbIpc tries to call this function again immediately if there
+    // is no other filled shared buffer with higher priority.
+    return ((ulBlockCount > 0) && (ShbError == kShbOk));
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Handler to reset Circular Shared Buffer
+//---------------------------------------------------------------------------
+
+void  ShbCirSignalHandlerReset (
+    tShbInstance pShbInstance_p,
+    unsigned int fTimeOut_p)
+{
+
+tShbCirBuff*  pShbCirBuff;
+
+
+    // check arguments
+    if (pShbInstance_p == NULL)
+    {
+        return;
+    }
+
+    pShbCirBuff = ShbCirGetBuffer (pShbInstance_p);
+    if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID)
+    {
+        return;
+    }
+
+
+    // reset buffer header
+    if ( !fTimeOut_p )
+    {
+        ShbIpcEnterAtomicSection (pShbInstance_p);
+        {
+            pShbCirBuff->m_ulWrIndex        = 0;
+            pShbCirBuff->m_ulRdIndex        = 0;
+            pShbCirBuff->m_ulNumOfWriteJobs = 0;
+            pShbCirBuff->m_ulDataInUse      = 0;
+            pShbCirBuff->m_ulDataApended    = 0;
+            pShbCirBuff->m_ulBlocksApended  = 0;
+            pShbCirBuff->m_ulDataReadable   = 0;
+            pShbCirBuff->m_ulBlocksReadable = 0;
+        }
+        ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+        #ifndef NDEBUG
+        {
+            memset (&pShbCirBuff->m_Data, 0xCC, pShbCirBuff->m_ulBufferDataSize);
+        }
+        #endif
+    }
+
+
+    // call application handler
+    if (pShbCirBuff->m_pfnSigHndlrReset != NULL)
+    {
+        pShbCirBuff->m_pfnSigHndlrReset (pShbInstance_p, fTimeOut_p);
+    }
+
+
+    // unlock buffer
+    ShbIpcEnterAtomicSection (pShbInstance_p);
+    {
+        pShbCirBuff->m_fBufferLocked    = FALSE;
+        pShbCirBuff->m_pfnSigHndlrReset = NULL;
+    }
+    ShbIpcLeaveAtomicSection (pShbInstance_p);
+
+
+    return;
+
+}
+
+#endif
+
+
+// EOF
+
diff --git a/drivers/staging/epl/SharedBuff.h b/drivers/staging/epl/SharedBuff.h
new file mode 100644 (file)
index 0000000..9b5d286
--- /dev/null
@@ -0,0 +1,183 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      Project independend shared buffer (linear + circular)
+
+  Description:  Declaration of platform independend part for the
+                shared buffer
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+  2006/06/27 -rs:   V 1.00 (initial version)
+
+****************************************************************************/
+
+#ifndef _SHAREDBUFF_H_
+#define _SHAREDBUFF_H_
+
+
+
+//---------------------------------------------------------------------------
+//  Type definitions
+//---------------------------------------------------------------------------
+
+typedef enum
+{
+    kShbOk                      =  0,
+    kShbNoReadableData          =  1,
+    kShbDataTruncated           =  2,
+    kShbBufferFull              =  3,
+    kShbDataOutsideBufferArea   =  4,
+    kShbBufferAlreadyCompleted  =  5,
+    kShbMemUsedByOtherProcs     =  6,
+    kShbOpenMismatch            =  7,
+    kShbInvalidBufferType       =  8,
+    kShbInvalidArg              =  9,
+    kShbBufferInvalid           = 10,
+    kShbOutOfMem                = 11,
+    kShbAlreadyReseting         = 12,
+    kShbAlreadySignaling        = 13,
+    kShbExceedDataSizeLimit     = 14,
+
+} tShbError;
+
+
+// 2006/08/24 d.k.: Priority for threads (new data, job signaling)
+typedef enum
+{
+    kShbPriorityLow             =  0,
+    kShbPriorityNormal          =  1,
+    kshbPriorityHigh            =  2
+
+} tShbPriority;
+
+
+typedef struct
+{
+    unsigned int   m_uiFullBlockSize;       // real size of allocated block (incl. alignment fill bytes)
+    unsigned long  m_ulAvailableSize;       // still available size for data
+    unsigned long  m_ulWrIndex;             // current write index
+    unsigned int   m_fBufferCompleted;      // TRUE if allocated block is complete filled with data
+
+} tShbCirChunk;
+
+
+typedef void*  tShbInstance;
+
+
+typedef void  (*tShbCirSigHndlrNewData)  (tShbInstance pShbInstance_p, unsigned long ulDataBlockSize_p);
+typedef void  (*tShbCirSigHndlrReset)    (tShbInstance pShbInstance_p, unsigned int fTimeOut_p);
+
+
+
+//---------------------------------------------------------------------------
+//  Prototypes
+//---------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*#if defined(INLINE_FUNCTION_DEF)
+    #undef  INLINE_FUNCTION
+    #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+    #define INLINE_ENABLED      TRUE
+    #define SHAREDBUFF_INLINED
+    #include "SharedBuff.c"
+#endif
+*/
+
+tShbError  ShbInit (void);
+tShbError  ShbExit (void);
+
+// Circular Shared Buffer
+tShbError  ShbCirAllocBuffer             (unsigned long ulBufferSize_p, const char* pszBufferID_p, tShbInstance* ppShbInstance_p, unsigned int* pfShbNewCreated_p);
+tShbError  ShbCirReleaseBuffer           (tShbInstance pShbInstance_p);
+
+#if !defined(INLINE_ENABLED)
+
+tShbError  ShbCirResetBuffer             (tShbInstance pShbInstance_p, unsigned long ulTimeOut_p, tShbCirSigHndlrReset pfnSignalHandlerReset_p);
+tShbError  ShbCirWriteDataBlock          (tShbInstance pShbInstance_p, const void* pSrcDataBlock_p, unsigned long ulDataBlockSize_p);
+tShbError  ShbCirAllocDataBlock          (tShbInstance pShbInstance_p, tShbCirChunk* pShbCirChunk_p, unsigned long ulDataBufferSize_p);
+tShbError  ShbCirWriteDataChunk          (tShbInstance pShbInstance_p, tShbCirChunk* pShbCirChunk_p, const void* pSrcDataChunk_p, unsigned long ulDataChunkSize_p, unsigned int* pfBufferCompleted_p);
+tShbError  ShbCirReadDataBlock           (tShbInstance pShbInstance_p, void* pDstDataBlock_p, unsigned long ulRdBuffSize_p, unsigned long* pulDataBlockSize_p);
+tShbError  ShbCirGetReadDataSize         (tShbInstance pShbInstance_p, unsigned long* pulDataBlockSize_p);
+tShbError  ShbCirGetReadBlockCount       (tShbInstance pShbInstance_p, unsigned long* pulDataBlockCount_p);
+tShbError  ShbCirSetSignalHandlerNewData (tShbInstance pShbInstance_p, tShbCirSigHndlrNewData pfnShbSignalHandlerNewData_p, tShbPriority ShbPriority_p);
+
+#endif
+
+// Linear Shared Buffer
+tShbError  ShbLinAllocBuffer             (unsigned long ulBufferSize_p, const char* pszBufferID_p, tShbInstance* ppShbInstance_p, unsigned int* pfShbNewCreated_p);
+tShbError  ShbLinReleaseBuffer           (tShbInstance pShbInstance_p);
+
+#if !defined(INLINE_ENABLED)
+
+tShbError  ShbLinWriteDataBlock          (tShbInstance pShbInstance_p, unsigned long ulDstBufferOffs_p, const void* pSrcDataBlock_p, unsigned long ulDataBlockSize_p);
+tShbError  ShbLinReadDataBlock           (tShbInstance pShbInstance_p, void* pDstDataBlock_p, unsigned long ulSrcBufferOffs_p, unsigned long ulDataBlockSize_p);
+
+#endif
+
+#ifndef NDEBUG
+    tShbError  ShbCirTraceBuffer         (tShbInstance pShbInstance_p);
+    tShbError  ShbLinTraceBuffer         (tShbInstance pShbInstance_p);
+    tShbError  ShbTraceDump              (const unsigned char* pabStartAddr_p, unsigned long ulDataSize_p, unsigned long ulAddrOffset_p, const char* pszInfoText_p);
+#else
+    #define ShbCirTraceBuffer(p0)
+    #define ShbLinTraceBuffer(p0)
+    #define ShbTraceDump(p0, p1, p2, p3)
+#endif
+
+#undef  INLINE_ENABLED              // disable actual inlining of functions
+#undef  INLINE_FUNCTION
+#define INLINE_FUNCTION             // define INLINE_FUNCTION to nothing
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // #ifndef _SHAREDBUFF_H_
+
diff --git a/drivers/staging/epl/ShbIpc-LinuxKernel.c b/drivers/staging/epl/ShbIpc-LinuxKernel.c
new file mode 100644 (file)
index 0000000..50a2f2d
--- /dev/null
@@ -0,0 +1,1031 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      Project independend shared buffer (linear + circular)
+
+  Description:  Implementation of platform specific part for the
+                shared buffer
+                (Implementation for Linux KernelSpace)
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+  2006/06/28 -rs:   V 1.00 (initial version)
+
+****************************************************************************/
+
+
+#include "global.h"
+#include "SharedBuff.h"
+#include "ShbIpc.h"
+#include "ShbLinuxKernel.h"
+#include "Debug.h"
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+//#include <linux/vmalloc.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/completion.h>
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Configuration
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Constant definitions
+//---------------------------------------------------------------------------
+
+#define MAX_LEN_BUFFER_ID       256
+
+#define TIMEOUT_ENTER_ATOMIC    1000        // (ms) for debgging: INFINITE
+#define TIMEOUT_TERM_THREAD     1000
+#define INFINITE                3600
+
+#define SBI_MAGIC_ID            0x5342492B  // magic ID ("SBI+")
+#define SBH_MAGIC_ID            0x5342482A  // magic ID ("SBH*")
+
+#define INVALID_ID              -1
+
+#define TABLE_SIZE              10
+
+
+//---------------------------------------------------------------------------
+//  Local types
+//---------------------------------------------------------------------------
+
+// This structure is the common header for the shared memory region used
+// by all processes attached this shared memory. It includes common
+// information to administrate/manage the shared buffer from a couple of
+// separated processes (e.g. the refernce counter). This structure is
+// located at the start of the shared memory region itself and exists
+// consequently only one times per shared memory instance.
+typedef struct
+{
+
+    unsigned long       m_ulShMemSize;
+    unsigned long       m_ulRefCount;
+    int                 m_iBufferId;
+//    int                 m_iUserSpaceMem;           //0 for userspace mem   !=0 kernelspace mem
+    spinlock_t          m_SpinlockBuffAccess;
+    BOOL                m_fNewData;
+    BOOL                m_fJobReady;
+    wait_queue_head_t   m_WaitQueueNewData;
+    wait_queue_head_t   m_WaitQueueJobReady;
+
+    #ifndef NDEBUG
+        unsigned long   m_ulOwnerProcID;
+    #endif
+
+} tShbMemHeader;
+
+
+
+// This structure is the "external entry point" from a separate process
+// to get access to a shared buffer. This structure includes all platform
+// resp. target specific information to administrate/manage the shared
+// buffer from a separate process. Every process attached to the shared
+// buffer has its own runtime instance of this structure with its individual
+// runtime data (e.g. the scope of an event handle is limitted to the
+// owner process only). The structure member <m_pShbMemHeader> points
+// to the (process specific) start address of the shared memory region
+// itself.
+typedef struct
+{
+    unsigned long       m_SbiMagicID;           // magic ID ("SBI+")
+//    void*               m_pSharedMem;
+    int                 m_tThreadNewDataId;
+    long                m_lThreadNewDataNice;   // nice value of the new data thread
+    int                 m_tThreadJobReadyId;
+    unsigned long       m_ulFlagsBuffAccess;    // d.k. moved from tShbMemHeader, because each
+                                                // process needs to store the interrupt flags separately
+    tSigHndlrNewData    m_pfnSigHndlrNewData;
+    unsigned long       m_ulTimeOutJobReady;
+    tSigHndlrJobReady   m_pfnSigHndlrJobReady;
+    tShbMemHeader*      m_pShbMemHeader;
+    int                 m_iThreadTermFlag;
+    struct completion   m_CompletionNewData;
+/*
+    struct semaphore    *m_pSemBuffAccess;
+    struct semaphore    *m_pSemNewData;
+    struct semaphore    *m_pSemStopSignalingNewData;
+    struct semaphore    *m_pSemJobReady;
+*/
+    #ifndef NDEBUG
+        unsigned long   m_ulThreadIDNewData;
+        unsigned long   m_ulThreadIDJobReady;
+    #endif
+} tShbMemInst;
+
+
+//---------------------------------------------------------------------------
+//  Prototypes of internal functions
+//---------------------------------------------------------------------------
+
+//tShbMemInst*            ShbIpcGetShbMemInst         (tShbInstance pShbInstance_p);
+//tShbMemHeader*          ShbIpcGetShbMemHeader       (tShbMemInst* pShbMemInst_p);
+
+//---------------------------------------------------------------------------
+//  Get pointer to process local information structure
+//---------------------------------------------------------------------------
+
+static inline tShbMemInst*  ShbIpcGetShbMemInst (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+
+
+    pShbMemInst = (tShbMemInst*)pShbInstance_p;
+
+
+    return (pShbMemInst);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get pointer to shared memory header
+//---------------------------------------------------------------------------
+
+static inline tShbMemHeader*  ShbIpcGetShbMemHeader (
+    tShbMemInst* pShbMemInst_p)
+{
+
+tShbMemHeader*  pShbMemHeader;
+
+
+    pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
+
+    return (pShbMemHeader);
+
+}
+
+//  Get pointer to process local information structure
+//#define ShbIpcGetShbMemInst(pShbInstance_p) ((tShbMemInst*)pShbInstance_p)
+
+//  Get pointer to shared memory header
+//#define ShbIpcGetShbMemHeader(pShbMemInst_p) (pShbMemInst_p->m_pShbMemHeader)
+
+// not inlined internal functions
+int                     ShbIpcThreadSignalNewData   (void* pvThreadParam_p);
+int                     ShbIpcThreadSignalJobReady  (void* pvThreadParam_p);
+#endif
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+struct sShbMemTable *psMemTableElementFirst_g;
+
+static void*            ShbIpcAllocPrivateMem       (unsigned long ulMemSize_p);
+static int              ShbIpcFindListElement       (int iBufferId, struct sShbMemTable **ppsReturnMemTableElement);
+static void             ShbIpcAppendListElement     (struct sShbMemTable *sNewMemTableElement);
+static void             ShbIpcDeleteListElement     (int iBufferId);
+static void             ShbIpcCrc32GenTable         (unsigned long aulCrcTable[256]);
+static unsigned long    ShbIpcCrc32GetCrc           (const char *pcString, unsigned long aulCrcTable[256]);
+
+#endif
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+// not inlined external functions
+
+//---------------------------------------------------------------------------
+//  Initialize IPC for Shared Buffer Module
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcInit (void)
+{
+    psMemTableElementFirst_g = NULL;
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Deinitialize IPC for Shared Buffer Module
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcExit (void)
+{
+
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Allocate Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcAllocBuffer (
+    unsigned long ulBufferSize_p,
+    const char* pszBufferID_p,
+    tShbInstance* ppShbInstance_p,
+    unsigned int* pfShbNewCreated_p)
+{
+tShbError               ShbError;
+int                     iBufferId=0;
+unsigned long           ulCrc32=0;
+unsigned int            uiFirstProcess=0;
+unsigned long           ulShMemSize;
+tShbMemHeader*          pShbMemHeader;
+tShbMemInst*            pShbMemInst=NULL;
+tShbInstance            pShbInstance;
+unsigned int            fShMemNewCreated=FALSE;
+void                    *pSharedMem=NULL;
+unsigned long           aulCrcTable[256];
+struct sShbMemTable     *psMemTableElement;
+
+
+    DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer \n");
+    ulShMemSize      = ulBufferSize_p + sizeof(tShbMemHeader);
+
+    //create Buffer ID
+    ShbIpcCrc32GenTable(aulCrcTable);
+    ulCrc32=ShbIpcCrc32GetCrc(pszBufferID_p,aulCrcTable);
+    iBufferId=ulCrc32;
+    DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n",ulBufferSize_p,sizeof(tShbMemHeader));
+    DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n",iBufferId,ulShMemSize);
+    //---------------------------------------------------------------
+    // (1) open an existing or create a new shared memory
+    //---------------------------------------------------------------
+    //test if buffer already exists
+    if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0)
+    {
+        //Buffer already exists
+        fShMemNewCreated=FALSE;
+        pSharedMem = psMemTableElement->m_pBuffer;
+        DEBUG_LVL_29_TRACE1("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n",pSharedMem);
+        uiFirstProcess=1;
+    }
+    else
+    {
+        //create new Buffer
+        fShMemNewCreated = TRUE;
+        uiFirstProcess=0;
+        pSharedMem = kmalloc(ulShMemSize,GFP_KERNEL);
+        DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n",pSharedMem,iBufferId);
+        if (pSharedMem == NULL)
+        {
+            //unable to create mem
+            ShbError = kShbOutOfMem;
+            goto Exit;
+        }
+        DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer create semas\n");
+        // append Element to Mem Table
+        psMemTableElement = kmalloc(sizeof(struct sShbMemTable),GFP_KERNEL);
+        psMemTableElement->m_iBufferId = iBufferId;
+        psMemTableElement->m_pBuffer = pSharedMem;
+        psMemTableElement->m_psNextMemTableElement = NULL;
+        ShbIpcAppendListElement (psMemTableElement);
+    }
+
+    DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer update header\n");
+    //update header
+    pShbMemHeader = (tShbMemHeader*)pSharedMem;
+    DEBUG_LVL_29_TRACE1("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n",pShbMemHeader->m_ulShMemSize);
+    // allocate a memory block from process specific mempool to save
+    // process local information to administrate/manage the shared buffer
+    DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer alloc private mem\n");
+    pShbMemInst = (tShbMemInst*) ShbIpcAllocPrivateMem (sizeof(tShbMemInst));
+    if (pShbMemInst == NULL)
+    {
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+
+    // reset complete header to default values
+    //pShbMemInst->m_SbiMagicID                             = SBI_MAGIC_ID;
+//    pShbMemInst->m_pSharedMem                               = pSharedMem;
+    pShbMemInst->m_tThreadNewDataId                         = INVALID_ID;
+    pShbMemInst->m_tThreadJobReadyId                        = INVALID_ID;
+    pShbMemInst->m_pfnSigHndlrNewData                       = NULL;
+    pShbMemInst->m_ulTimeOutJobReady                        = 0;
+    pShbMemInst->m_pfnSigHndlrJobReady                      = NULL;
+    pShbMemInst->m_pShbMemHeader                            = pShbMemHeader;
+    pShbMemInst->m_iThreadTermFlag                          = 0;
+
+    // initialize completion etc.
+    init_completion(&pShbMemInst->m_CompletionNewData);
+
+    ShbError         = kShbOk;
+    if ( fShMemNewCreated )
+    {
+        // this process was the first who wanted to use the shared memory,
+        // so a new shared memory was created
+        // -> setup new header information inside the shared memory region
+        //    itself
+        pShbMemHeader->m_ulShMemSize = ulShMemSize;
+        pShbMemHeader->m_ulRefCount  = 1;
+        pShbMemHeader->m_iBufferId=iBufferId;
+        // initialize spinlock
+        spin_lock_init(&pShbMemHeader->m_SpinlockBuffAccess);
+        // initialize wait queues
+        init_waitqueue_head(&pShbMemHeader->m_WaitQueueNewData);
+        init_waitqueue_head(&pShbMemHeader->m_WaitQueueJobReady);
+    }
+    else
+    {
+        // any other process has created the shared memory and this
+        // process only has to attach to it
+        // -> check and update existing header information inside the
+        //    shared memory region itself
+        if (pShbMemHeader->m_ulShMemSize != ulShMemSize)
+        {
+            ShbError = kShbOpenMismatch;
+            goto Exit;
+        }
+        pShbMemHeader->m_ulRefCount++;
+    }
+
+    Exit:
+    pShbInstance = (tShbInstance*)pShbMemInst;
+    *pfShbNewCreated_p = fShMemNewCreated;
+    *ppShbInstance_p   = pShbInstance;
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Release Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcReleaseBuffer (tShbInstance pShbInstance_p)
+{
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbError       ShbError;
+tShbError       ShbError2;
+
+    DEBUG_LVL_26_TRACE1("ShbIpcReleaseBuffer(%p)\n", pShbInstance_p);
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbOk);
+    }
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+
+    // stop threads in any case, because they are bound to that specific instance
+    ShbError2 = ShbIpcStopSignalingNewData (pShbInstance_p);
+    // d.k.: Whats up with JobReady thread?
+    //       Just wake it up, but without setting the semaphore variable
+    wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
+
+    if ( !--pShbMemHeader->m_ulRefCount )
+    {
+        ShbError = kShbOk;
+        // delete mem table element
+        ShbIpcDeleteListElement(pShbMemHeader->m_iBufferId);
+        // delete shared mem
+        kfree(pShbMemInst->m_pShbMemHeader);
+    }
+    else
+    {
+        ShbError = kShbMemUsedByOtherProcs;
+    }
+    //delete privat mem
+    kfree(pShbMemInst);
+    return (ShbError);
+}
+
+
+#endif  // !defined(SHBIPC_INLINE_ENABLED)
+
+#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
+
+
+//---------------------------------------------------------------------------
+//  Enter atomic section for Shared Buffer access
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcEnterAtomicSection (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbError       ShbError = kShbOk;
+
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+    DEBUG_LVL_29_TRACE0("enter atomic\n");
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+
+    // lock interrupts
+    spin_lock_irqsave(&pShbMemHeader->m_SpinlockBuffAccess, pShbMemInst->m_ulFlagsBuffAccess);
+
+Exit:
+    return ShbError;
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Leave atomic section for Shared Buffer access
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcLeaveAtomicSection (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbError       ShbError = kShbOk;
+
+    if (pShbInstance_p == NULL)
+    {
+        ShbError = kShbInvalidArg;
+        goto Exit;
+    }
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+    // unlock interrupts
+    spin_unlock_irqrestore(&pShbMemHeader->m_SpinlockBuffAccess, pShbMemInst->m_ulFlagsBuffAccess);
+
+Exit:
+    DEBUG_LVL_29_TRACE0("Leave Atomic \n");
+    return ShbError;
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Start signaling of new data (called from reading process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcStartSignalingNewData (
+    tShbInstance pShbInstance_p,
+    tSigHndlrNewData pfnSignalHandlerNewData_p,
+    tShbPriority ShbPriority_p)
+{
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbError       ShbError;
+
+    DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n");
+    if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+    ShbError = kShbOk;
+
+    if ((pShbMemInst->m_tThreadNewDataId != INVALID_ID)
+        || (pShbMemInst->m_pfnSigHndlrNewData != NULL))
+    {
+        ShbError = kShbAlreadySignaling;
+        goto Exit;
+    }
+    DEBUG_LVL_26_TRACE2("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n", pShbInstance_p, pfnSignalHandlerNewData_p);
+    pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
+    pShbMemHeader->m_fNewData = FALSE;
+    pShbMemInst->m_iThreadTermFlag = 0;
+
+    switch (ShbPriority_p)
+    {
+        case kShbPriorityLow:
+            pShbMemInst->m_lThreadNewDataNice = -2;
+            break;
+
+        case kShbPriorityNormal:
+            pShbMemInst->m_lThreadNewDataNice = -9;
+            break;
+
+        case kshbPriorityHigh:
+            pShbMemInst->m_lThreadNewDataNice = -20;
+            break;
+
+    }
+
+    //create thread for signalling new data
+    pShbMemInst->m_tThreadNewDataId = kernel_thread(ShbIpcThreadSignalNewData,pShbInstance_p,CLONE_KERNEL);
+
+Exit:
+    return ShbError;
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Stop signaling of new data (called from reading process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcStopSignalingNewData (
+    tShbInstance pShbInstance_p)
+{
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbError       ShbError;
+
+    DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n");
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+    ShbError = kShbOk;
+    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+
+    DEBUG_LVL_26_TRACE2("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n", pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData);
+    if (pShbMemInst->m_pfnSigHndlrNewData != NULL)
+    {   // signal handler was set before
+        int iErr;
+        //set termination flag in mem header
+        pShbMemInst->m_iThreadTermFlag = 1;
+
+        // check if thread is still running at all by sending the null-signal to this thread
+        /* iErr = kill_proc(pShbMemInst->m_tThreadNewDataId, 0, 1); */
+        iErr = send_sig(0, pShbMemInst->m_tThreadNewDataId, 1);
+        if (iErr == 0)
+        {
+            // wake up thread, because it is still running
+            wake_up_interruptible(&pShbMemHeader->m_WaitQueueNewData);
+
+            //wait for termination of thread
+            wait_for_completion(&pShbMemInst->m_CompletionNewData);
+        }
+
+        pShbMemInst->m_pfnSigHndlrNewData = NULL;
+        pShbMemInst->m_tThreadNewDataId = INVALID_ID;
+    }
+
+    return ShbError;
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Signal new data (called from writing process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcSignalNewData (
+    tShbInstance pShbInstance_p)
+{
+tShbMemHeader*  pShbMemHeader;
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+    pShbMemHeader = ShbIpcGetShbMemHeader (ShbIpcGetShbMemInst (pShbInstance_p));
+    //set semaphore
+    pShbMemHeader->m_fNewData = TRUE;
+    DEBUG_LVL_29_TRACE0("ShbIpcSignalNewData set Sem -> New Data\n");
+
+    wake_up_interruptible(&pShbMemHeader->m_WaitQueueNewData);
+    return (kShbOk);
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Start signaling for job ready (called from waiting process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcStartSignalingJobReady (
+    tShbInstance pShbInstance_p,
+    unsigned long ulTimeOut_p,
+    tSigHndlrJobReady pfnSignalHandlerJobReady_p)
+{
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbError       ShbError;
+
+    if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+
+    ShbError = kShbOk;
+    if ((pShbMemInst->m_tThreadJobReadyId != INVALID_ID)||(pShbMemInst->m_pfnSigHndlrJobReady!= NULL))
+    {
+        ShbError = kShbAlreadySignaling;
+        goto Exit;
+    }
+    pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
+    pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
+    pShbMemHeader->m_fJobReady = FALSE;
+    //create thread for signalling new data
+    pShbMemInst->m_tThreadJobReadyId=kernel_thread(ShbIpcThreadSignalJobReady,pShbInstance_p,CLONE_KERNEL);
+    Exit:
+    return ShbError;
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Signal job ready (called from executing process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcSignalJobReady (
+    tShbInstance pShbInstance_p)
+{
+tShbMemHeader*  pShbMemHeader;
+
+
+    DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady\n");
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+    pShbMemHeader = ShbIpcGetShbMemHeader (ShbIpcGetShbMemInst (pShbInstance_p));
+    //set semaphore
+    pShbMemHeader->m_fJobReady = TRUE;
+    DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady set Sem -> Job Ready \n");
+
+    wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
+    return (kShbOk);
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get pointer to common used share memory area
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void*  ShbIpcGetShMemPtr (tShbInstance pShbInstance_p)
+{
+
+tShbMemHeader*  pShbMemHeader;
+void*  pShbShMemPtr;
+
+
+    pShbMemHeader = ShbIpcGetShbMemHeader (ShbIpcGetShbMemInst (pShbInstance_p));
+    if (pShbMemHeader != NULL)
+    {
+        pShbShMemPtr = (BYTE*)pShbMemHeader + sizeof(tShbMemHeader);
+    }
+    else
+    {
+        pShbShMemPtr = NULL;
+    }
+
+    return (pShbShMemPtr);
+
+}
+
+#endif
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Get pointer to process local information structure
+//---------------------------------------------------------------------------
+
+/*tShbMemInst*  ShbIpcGetShbMemInst (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+
+
+    pShbMemInst = (tShbMemInst*)pShbInstance_p;
+
+
+    return (pShbMemInst);
+
+}
+*/
+
+
+//---------------------------------------------------------------------------
+//  Get pointer to shared memory header
+//---------------------------------------------------------------------------
+
+/*tShbMemHeader*  ShbIpcGetShbMemHeader (
+    tShbMemInst* pShbMemInst_p)
+{
+
+tShbMemHeader*  pShbMemHeader;
+
+
+    pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
+
+    return (pShbMemHeader);
+
+}
+*/
+
+
+//---------------------------------------------------------------------------
+//  Allocate a memory block from process specific mempool
+//---------------------------------------------------------------------------
+
+static void*  ShbIpcAllocPrivateMem (unsigned long ulMemSize_p)
+{
+tShbError       ShbError;
+void*           pMem;
+
+    DEBUG_LVL_29_TRACE0("ShbIpcAllocPrivateMem \n");
+    //get private mem
+    pMem = kmalloc(ulMemSize_p, GFP_KERNEL);
+    if (pMem == NULL)
+    {
+        //unable to create mem
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+Exit:
+    return (pMem);
+
+}
+
+
+//---------------------------------------------------------------------------
+//  Thread for new data signaling
+//---------------------------------------------------------------------------
+
+int ShbIpcThreadSignalNewData (void *pvThreadParam_p)
+{
+tShbInstance    pShbInstance;
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+int             iRetVal=-1;
+int             fCallAgain;
+
+    daemonize("ShbND%p", pvThreadParam_p);
+    allow_signal(SIGTERM);
+    pShbInstance = (tShbMemInst*)pvThreadParam_p;
+    pShbMemInst  = ShbIpcGetShbMemInst (pShbInstance);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+
+    DEBUG_LVL_26_TRACE1("ShbIpcThreadSignalNewData(%p)\n",pvThreadParam_p);
+
+    set_user_nice(current, pShbMemInst->m_lThreadNewDataNice);
+
+//            DEBUG_LVL_29_TRACE1("ShbIpcThreadSignalNewData wait for New Data Sem %p\n",pShbMemInst->m_pSemNewData);
+    do
+    {
+        iRetVal = wait_event_interruptible(pShbMemHeader->m_WaitQueueNewData,
+            (pShbMemInst->m_iThreadTermFlag != 0) || (pShbMemHeader->m_fNewData != FALSE));
+
+        if (iRetVal != 0)
+        {   // signal pending
+            break;
+        }
+
+        if (pShbMemHeader->m_fNewData != FALSE)
+        {
+            pShbMemHeader->m_fNewData = FALSE;
+            do
+            {
+                fCallAgain = pShbMemInst->m_pfnSigHndlrNewData(pShbInstance);
+                // call scheduler, which will execute any task with higher priority
+                schedule();
+            } while (fCallAgain != FALSE);
+        }
+    } while (pShbMemInst->m_iThreadTermFlag==0);
+    DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalNewData terminated \n");
+    //set thread completed
+    complete_and_exit(&pShbMemInst->m_CompletionNewData, 0);
+    return 0;
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Thread for new data Job Ready signaling
+//---------------------------------------------------------------------------
+
+int ShbIpcThreadSignalJobReady (void *pvThreadParam_p)
+{
+tShbInstance    pShbInstance;
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+long            lTimeOut;
+int             iRetVal=-1;
+
+    daemonize("ShbJR%p", pvThreadParam_p);
+    allow_signal(SIGTERM);
+    pShbInstance = (tShbMemInst*)pvThreadParam_p;
+    pShbMemInst  = ShbIpcGetShbMemInst (pShbInstance);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
+
+    DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalJobReady wait for job ready Sem\n");
+    if (pShbMemInst->m_ulTimeOutJobReady != 0)
+    {
+        lTimeOut = (long) pShbMemInst->m_ulTimeOutJobReady;
+        //wait for job ready semaphore
+        iRetVal = wait_event_interruptible_timeout(pShbMemHeader->m_WaitQueueJobReady,
+            (pShbMemHeader->m_fJobReady != FALSE), lTimeOut);
+    }
+    else
+    {
+        //wait for job ready semaphore
+        iRetVal = wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady,
+            (pShbMemHeader->m_fJobReady != FALSE));
+    }
+
+    if (pShbMemInst->m_pfnSigHndlrJobReady != NULL)
+    {
+        //call Handler
+        pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, !pShbMemHeader->m_fJobReady);
+    }
+
+    pShbMemInst->m_pfnSigHndlrJobReady=NULL;
+    return 0;
+}
+
+
+
+//Build the crc table
+static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256])
+{
+    unsigned long       ulCrc,ulPoly;
+    int                 iIndexI,iIndexJ;
+
+    ulPoly = 0xEDB88320L;
+    for (iIndexI = 0; iIndexI < 256; iIndexI++)
+    {
+        ulCrc = iIndexI;
+        for (iIndexJ = 8; iIndexJ > 0; iIndexJ--)
+        {
+            if (ulCrc & 1)
+            {
+                ulCrc = (ulCrc >> 1) ^ ulPoly;
+            }
+            else
+            {
+                ulCrc >>= 1;
+            }
+        }
+        aulCrcTable[iIndexI] = ulCrc;
+    }
+}
+
+//Calculate the crc value
+static unsigned long ShbIpcCrc32GetCrc(const char *pcString,unsigned long aulCrcTable[256])
+{
+    unsigned long   ulCrc;
+    int             iIndex;
+
+    ulCrc = 0xFFFFFFFF;
+    for (iIndex=0;iIndex<strlen(pcString);iIndex++)
+    {
+        ulCrc = ((ulCrc>>8) & 0x00FFFFFF) ^ aulCrcTable[ (ulCrc^pcString[iIndex]) & 0xFF ];
+    }
+    return( ulCrc^0xFFFFFFFF );
+
+}
+
+static void ShbIpcAppendListElement (struct sShbMemTable *psNewMemTableElement)
+{
+    struct sShbMemTable *psMemTableElement=psMemTableElementFirst_g;
+    psNewMemTableElement->m_psNextMemTableElement=NULL;
+
+    if (psMemTableElementFirst_g!= NULL )
+    {      /* sind Elemente vorhanden */
+       while (psMemTableElement->m_psNextMemTableElement != NULL )
+       {    /* suche das letzte Element */
+           psMemTableElement=psMemTableElement->m_psNextMemTableElement;
+       }
+       psMemTableElement->m_psNextMemTableElement=psNewMemTableElement;              /*  Haenge das Element hinten an */
+    }
+    else
+    {                           /* wenn die liste leer ist, bin ich das erste Element */
+        psMemTableElementFirst_g=psNewMemTableElement;
+    }
+}
+
+
+
+
+static int ShbIpcFindListElement (int iBufferId, struct sShbMemTable **ppsReturnMemTableElement)
+{
+    struct sShbMemTable *psMemTableElement=psMemTableElementFirst_g;
+    while (psMemTableElement!=NULL)
+    {
+        if(psMemTableElement->m_iBufferId==iBufferId)
+        {
+//printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",psMemTableElement->m_pBuffer,psMemTableElement->m_iBufferId);
+             *ppsReturnMemTableElement=psMemTableElement;
+//printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",(*ppsReturnMemTableElement)->m_pBuffer,(*ppsReturnMemTableElement)->m_iBufferId);
+             return 0;
+        }
+        psMemTableElement=psMemTableElement->m_psNextMemTableElement;
+    }
+    return -1;
+}
+
+static void ShbIpcDeleteListElement(int iBufferId)
+{
+   struct sShbMemTable *psMemTableElement=psMemTableElementFirst_g;
+   struct sShbMemTable *psMemTableElementOld=psMemTableElementFirst_g;
+   if (psMemTableElement!=NULL)
+   {
+        while((psMemTableElement!=NULL)&&(psMemTableElement->m_iBufferId!=iBufferId))
+        {
+            psMemTableElementOld=psMemTableElement;
+            psMemTableElement=psMemTableElement->m_psNextMemTableElement;
+        }
+        if (psMemTableElement!=NULL)
+        {
+            if (psMemTableElement!=psMemTableElementFirst_g)
+            {
+                psMemTableElementOld->m_psNextMemTableElement=psMemTableElement->m_psNextMemTableElement;
+                kfree(psMemTableElement);
+            }
+            else
+            {
+                kfree(psMemTableElement);
+                psMemTableElementFirst_g=NULL;
+            }
+
+        }
+   }
+
+}
+
+#endif
diff --git a/drivers/staging/epl/ShbIpc-Win32.c b/drivers/staging/epl/ShbIpc-Win32.c
new file mode 100644 (file)
index 0000000..a528266
--- /dev/null
@@ -0,0 +1,1328 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      Project independend shared buffer (linear + circular)
+
+  Description:  Implementation of platform specific part for the
+                shared buffer
+                (Implementation for Win32)
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+  2006/06/27 -rs:   V 1.00 (initial version)
+
+****************************************************************************/
+
+#define WINVER       0x0400             // #defines necessary for usage of
+#define _WIN32_WINNT 0x0400             // function <SignalObjectAndWait>
+
+#include <windows.h>
+#include <stdio.h>
+#include "global.h"
+#include "sharedbuff.h"
+#include "shbipc.h"
+
+
+
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Configuration
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Constant definitions
+//---------------------------------------------------------------------------
+
+#define MAX_LEN_BUFFER_ID       MAX_PATH
+
+#define IDX_EVENT_NEW_DATA      0
+#define IDX_EVENT_TERM_REQU     1
+#define IDX_EVENT_TERM_RESP     2
+
+#define NAME_MUTEX_BUFF_ACCESS  "BuffAccess"
+#define NAME_EVENT_NEW_DATA     "NewData"
+#define NAME_EVENT_TERM_REQU    "TermRequ"
+#define NAME_EVENT_TERM_RESP    "TermResp"
+#define NAME_EVENT_JOB_READY    "JobReady"
+
+#define TIMEOUT_ENTER_ATOMIC    1000        // for debgging: INFINITE
+#define TIMEOUT_TERM_THREAD     2000
+
+#define SBI_MAGIC_ID            0x5342492B  // magic ID ("SBI+")
+#define SBH_MAGIC_ID            0x5342482A  // magic ID ("SBH*")
+
+
+
+//---------------------------------------------------------------------------
+//  Local types
+//---------------------------------------------------------------------------
+
+// This structure is the common header for the shared memory region used
+// by all processes attached this shared memory. It includes common
+// information to administrate/manage the shared buffer from a couple of
+// separated processes (e.g. the refernce counter). This structure is
+// located at the start of the shared memory region itself and exists
+// consequently only one times per shared memory instance.
+typedef struct
+{
+    unsigned long       m_SbhMagicID;       // magic ID ("SBH*")
+    unsigned long       m_ulShMemSize;
+    unsigned long       m_ulRefCount;
+    char                m_szBufferID[MAX_LEN_BUFFER_ID];
+
+    #ifndef NDEBUG
+        unsigned long   m_ulOwnerProcID;
+    #endif
+
+} tShbMemHeader;
+
+
+// This structure is the "external entry point" from a separate process
+// to get access to a shared buffer. This structure includes all platform
+// resp. target specific information to administrate/manage the shared
+// buffer from a separate process. Every process attached to the shared
+// buffer has its own runtime instance of this structure with its individual
+// runtime data (e.g. the scope of an event handle is limitted to the
+// owner process only). The structure member <m_pShbMemHeader> points
+// to the (process specific) start address of the shared memory region
+// itself.
+typedef struct
+{
+    unsigned long       m_SbiMagicID;           // magic ID ("SBI+")
+    HANDLE              m_hSharedMem;
+    HANDLE              m_hMutexBuffAccess;
+    HANDLE              m_hThreadNewData;       // thraed to signal that new data are available
+    HANDLE              m_ahEventNewData[3];    // IDX_EVENT_NEW_DATA + IDX_EVENT_TERM_REQU + ID_EVENT_TERM_RESP
+    tSigHndlrNewData    m_pfnSigHndlrNewData;
+    HANDLE              m_hThreadJobReady;      // thread to signal that a job/operation is ready now (e.g. reset buffer)
+    HANDLE              m_hEventJobReady;
+    unsigned long       m_ulTimeOutJobReady;
+    tSigHndlrJobReady   m_pfnSigHndlrJobReady;
+    tShbMemHeader*      m_pShbMemHeader;
+
+    #ifndef NDEBUG
+        unsigned long   m_ulThreadIDNewData;
+        unsigned long   m_ulThreadIDJobReady;
+    #endif
+
+} tShbMemInst;
+
+
+
+//---------------------------------------------------------------------------
+//  Global variables
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Local variables
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+//  Prototypes of internal functions
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+//  Get pointer to process local information structure
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbMemInst*  ShbIpcGetShbMemInst (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+
+
+    pShbMemInst = (tShbMemInst*)pShbInstance_p;
+    ASSERT (pShbMemInst->m_SbiMagicID == SBI_MAGIC_ID);
+
+    return (pShbMemInst);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get pointer to shared memory header
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbMemHeader*  ShbIpcGetShbMemHeader (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+
+
+    pShbMemInst   = ShbIpcGetShbMemInst (pShbInstance_p);
+    pShbMemHeader = pShbMemInst->m_pShbMemHeader;
+    ASSERT(pShbMemHeader->m_SbhMagicID == SBH_MAGIC_ID);
+
+    return (pShbMemHeader);
+
+}
+
+
+// not inlined internal functions
+DWORD  WINAPI   ShbIpcThreadSignalNewData  (LPVOID pvThreadParam_p);
+DWORD  WINAPI   ShbIpcThreadSignalJobReady (LPVOID pvThreadParam_p);
+const char*     ShbIpcGetUniformObjectName (const char* pszEventJobName_p, const char* pszBufferID_p, BOOL fGlobalObject_p);
+
+#endif
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+// true internal functions (not inlined)
+static void*        ShbIpcAllocPrivateMem      (unsigned long ulMemSize_p);
+static void         ShbIpcReleasePrivateMem    (void* pMem_p);
+#endif
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+// not inlined external functions
+
+//---------------------------------------------------------------------------
+//  Initialize IPC for Shared Buffer Module
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcInit (void)
+{
+
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Deinitialize IPC for Shared Buffer Module
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcExit (void)
+{
+
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Allocate Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcAllocBuffer (
+    unsigned long ulBufferSize_p,
+    const char* pszBufferID_p,
+    tShbInstance* ppShbInstance_p,
+    unsigned int* pfShbNewCreated_p)
+{
+
+HANDLE          hSharedMem;
+LPVOID          pSharedMem;
+unsigned long   ulShMemSize;
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+tShbInstance    pShbInstance;
+unsigned int    fShMemNewCreated;
+const char*     pszObjectName;
+HANDLE          hMutexBuffAccess;
+HANDLE          hEventNewData;
+HANDLE          hEventJobReady;
+tShbError       ShbError;
+
+
+    ulShMemSize      = ulBufferSize_p + sizeof(tShbMemHeader);
+    pSharedMem       = NULL;
+    pShbInstance     = NULL;
+    fShMemNewCreated = FALSE;
+    ShbError         = kShbOk;
+
+
+    //---------------------------------------------------------------
+    // (1) open an existing or create a new shared memory
+    //---------------------------------------------------------------
+    // try to open an already existing shared memory
+    // (created by an another process)
+    hSharedMem = OpenFileMapping (FILE_MAP_ALL_ACCESS,      // DWORD dwDesiredAccess
+                                  FALSE,                    // BOOL bInheritHandle
+                                  pszBufferID_p);           // LPCTSTR lpName
+    if (hSharedMem != NULL)
+    {
+        // a shared memory already exists
+        fShMemNewCreated = FALSE;
+    }
+    else
+    {
+        // it seams that this process is the first who wants to use the
+        // shared memory, so it has to create a new shared memory
+        hSharedMem = CreateFileMapping(INVALID_HANDLE_VALUE,// HANDLE hFile
+                                       NULL,                // LPSECURITY_ATTRIBUTES lpAttributes
+                                       PAGE_READWRITE,      // DWORD flProtect
+                                       0,                   // DWORD dwMaximumSizeHigh
+                                       ulShMemSize,         // DWORD dwMaximumSizeLow
+                                       pszBufferID_p);      // LPCTSTR lpName
+
+        fShMemNewCreated = TRUE;
+    }
+
+    if (hSharedMem == NULL)
+    {
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+
+
+    //---------------------------------------------------------------
+    // (2) get the pointer to the shared memory
+    //---------------------------------------------------------------
+    pSharedMem = MapViewOfFile (hSharedMem,                 // HANDLE hFileMappingObject
+                                FILE_MAP_ALL_ACCESS,        // DWORD dwDesiredAccess,
+                                0,                          // DWORD dwFileOffsetHigh,
+                                0,                          // DWORD dwFileOffsetLow,
+                                ulShMemSize);               // SIZE_T dwNumberOfBytesToMap
+
+    if (pSharedMem == NULL)
+    {
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+
+
+    //---------------------------------------------------------------
+    // (3) setup or update header and management information
+    //---------------------------------------------------------------
+    pShbMemHeader = (tShbMemHeader*)pSharedMem;
+
+    // allocate a memory block from process specific mempool to save
+    // process local information to administrate/manage the shared buffer
+    pShbMemInst = (tShbMemInst*) ShbIpcAllocPrivateMem (sizeof(tShbMemInst));
+    if (pShbMemInst == NULL)
+    {
+        ShbError = kShbOutOfMem;
+        goto Exit;
+    }
+
+    // reset complete header to default values
+    pShbMemInst->m_SbiMagicID                          = SBI_MAGIC_ID;
+    pShbMemInst->m_hSharedMem                          = hSharedMem;
+    pShbMemInst->m_hMutexBuffAccess                    = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_hThreadNewData                      = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]  = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_pfnSigHndlrNewData                  = NULL;
+    pShbMemInst->m_hThreadJobReady                     = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_hEventJobReady                      = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_ulTimeOutJobReady                   = 0;
+    pShbMemInst->m_pfnSigHndlrJobReady                 = NULL;
+    pShbMemInst->m_pShbMemHeader                       = pShbMemHeader;
+
+    #ifndef NDEBUG
+    {
+        pShbMemInst->m_ulThreadIDNewData  = 0;
+        pShbMemInst->m_ulThreadIDJobReady = 0;
+    }
+    #endif
+
+    // create mutex for buffer access
+    pszObjectName = ShbIpcGetUniformObjectName (NAME_MUTEX_BUFF_ACCESS, pszBufferID_p, TRUE);
+    hMutexBuffAccess = CreateMutex (NULL,                   // LPSECURITY_ATTRIBUTES lpMutexAttributes
+                                    FALSE,                  // BOOL bInitialOwner
+                                    pszObjectName);         // LPCTSTR lpName
+    pShbMemInst->m_hMutexBuffAccess = hMutexBuffAccess;
+    ASSERT(pShbMemInst->m_hMutexBuffAccess != NULL);
+
+    // The EventNewData is used for signaling of new data after a write
+    // operation (SetEvent) as well as for waiting for new data on the
+    // reader side (WaitForMultipleObjects). Because it's not known if
+    // this process will be read or write data, the event will be
+    // always created here.
+    pszObjectName = ShbIpcGetUniformObjectName (NAME_EVENT_NEW_DATA, pszBufferID_p, TRUE);
+    hEventNewData = CreateEvent (NULL,                      // LPSECURITY_ATTRIBUTES lpEventAttributes
+                                 FALSE,                     // BOOL bManualReset
+                                 FALSE,                     // BOOL bInitialState
+                                 pszObjectName);            // LPCTSTR lpName
+    pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = hEventNewData;
+    ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != NULL);
+
+    // The EventJobReady is used for signaling that a job is done (SetEvent)
+    // as well as for waiting for finishing of a job (WaitForMultipleObjects).
+    // Because it's not known if this process will signal or wait, the event
+    // will be always created here.
+    pszObjectName = ShbIpcGetUniformObjectName (NAME_EVENT_JOB_READY, pszBufferID_p, TRUE);
+    hEventJobReady = CreateEvent (NULL,                     // LPSECURITY_ATTRIBUTES lpEventAttributes
+                                  FALSE,                    // BOOL bManualReset
+                                  FALSE,                    // BOOL bInitialState
+                                  pszObjectName);           // LPCTSTR lpName
+    pShbMemInst->m_hEventJobReady = hEventJobReady;
+    ASSERT(pShbMemInst->m_hEventJobReady != NULL);
+
+    if ( fShMemNewCreated )
+    {
+        // this process was the first who wanted to use the shared memory,
+        // so a new shared memory was created
+        // -> setup new header information inside the shared memory region
+        //    itself
+        pShbMemHeader->m_SbhMagicID  = SBH_MAGIC_ID;
+        pShbMemHeader->m_ulShMemSize = ulShMemSize;
+        pShbMemHeader->m_ulRefCount  = 1;
+        strncpy (pShbMemHeader->m_szBufferID, pszBufferID_p, sizeof(pShbMemHeader->m_szBufferID)-1);
+
+        #ifndef NDEBUG
+        {
+            pShbMemHeader->m_ulOwnerProcID = GetCurrentProcessId();
+        }
+        #endif
+    }
+    else
+    {
+        // any other process has created the shared memory and this
+        // process has only attached to it
+        // -> check and update existing header information inside the
+        //    shared memory region itself
+        if (pShbMemHeader->m_ulShMemSize != ulShMemSize)
+        {
+            ShbError = kShbOpenMismatch;
+            goto Exit;
+        }
+
+        #ifndef NDEBUG
+        {
+            if ( strncmp(pShbMemHeader->m_szBufferID, pszBufferID_p, sizeof(pShbMemHeader->m_szBufferID)-1) )
+            {
+                ShbError = kShbOpenMismatch;
+                goto Exit;
+            }
+        }
+        #endif
+
+        pShbMemHeader->m_ulRefCount++;
+    }
+
+
+    // set abstarct "handle" for returning to application
+    pShbInstance = (tShbInstance*)pShbMemInst;
+
+
+Exit:
+
+    if (ShbError != kShbOk)
+    {
+        if (pShbMemInst != NULL)
+        {
+            ShbIpcReleasePrivateMem (pShbMemInst);
+        }
+        if (pSharedMem != NULL)
+        {
+            UnmapViewOfFile (pSharedMem);
+        }
+        if (hSharedMem != NULL)
+        {
+            CloseHandle (hSharedMem);
+        }
+    }
+
+    *pfShbNewCreated_p = fShMemNewCreated;
+    *ppShbInstance_p   = pShbInstance;
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Release Shared Buffer
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcReleaseBuffer (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+HANDLE          hEventNewData;
+HANDLE          hMutexBuffAccess;
+tShbError       ShbError;
+tShbError       ShbError2;
+
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbOk);
+    }
+
+
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p);
+
+
+    if ( !--pShbMemHeader->m_ulRefCount )
+    {
+        ShbError = kShbOk;
+    }
+    else
+    {
+        ShbError = kShbMemUsedByOtherProcs;
+    }
+
+
+    ShbError2 = ShbIpcStopSignalingNewData (pShbInstance_p);
+    hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
+    if (hEventNewData != INVALID_HANDLE_VALUE)
+    {
+        CloseHandle (hEventNewData);
+        pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = INVALID_HANDLE_VALUE;
+    }
+
+    hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
+    if (hMutexBuffAccess != INVALID_HANDLE_VALUE)
+    {
+        CloseHandle (hMutexBuffAccess);
+        pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
+    }
+
+    UnmapViewOfFile (pShbMemHeader);
+    if (pShbMemInst->m_hSharedMem != INVALID_HANDLE_VALUE)
+    {
+        CloseHandle (pShbMemInst->m_hSharedMem);
+        pShbMemInst->m_hSharedMem = INVALID_HANDLE_VALUE;
+    }
+
+    ShbIpcReleasePrivateMem (pShbMemInst);
+
+
+    if (ShbError == kShbOk)
+    {
+        ShbError = ShbError2;
+    }
+
+    return (ShbError);
+
+}
+
+#endif  // !defined(SHBIPC_INLINE_ENABLED)
+
+#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Enter atomic section for Shared Buffer access
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcEnterAtomicSection (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+HANDLE        hMutexBuffAccess;
+DWORD         dwWaitResult;
+tShbError     ShbError;
+
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
+    ShbError = kShbOk;
+
+    hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
+    if (hMutexBuffAccess != INVALID_HANDLE_VALUE)
+    {
+        dwWaitResult = WaitForSingleObject (hMutexBuffAccess, TIMEOUT_ENTER_ATOMIC);
+        switch (dwWaitResult)
+        {
+            case WAIT_OBJECT_0 + 0:
+            {
+                break;
+            }
+
+            case WAIT_TIMEOUT:
+            {
+                TRACE0("\nShbIpcEnterAtomicSection(): WAIT_TIMEOUT");
+                ASSERT(0);
+                ShbError = kShbBufferInvalid;
+                break;
+            }
+
+            case WAIT_ABANDONED:
+            {
+                TRACE0("\nShbIpcEnterAtomicSection(): WAIT_ABANDONED");
+                ASSERT(0);
+                ShbError = kShbBufferInvalid;
+                break;
+            }
+
+            case WAIT_FAILED:
+            {
+                TRACE1("\nShbIpcEnterAtomicSection(): WAIT_FAILED -> LastError=%ld", GetLastError());
+                ASSERT(0);
+                ShbError = kShbBufferInvalid;
+                break;
+            }
+
+            default:
+            {
+                TRACE1("\nShbIpcEnterAtomicSection(): unknown error -> LastError=%ld", GetLastError());
+                ASSERT(0);
+                ShbError = kShbBufferInvalid;
+                break;
+            }
+        }
+    }
+    else
+    {
+        ShbError = kShbBufferInvalid;
+    }
+
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Leave atomic section for Shared Buffer access
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcLeaveAtomicSection (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+HANDLE        hMutexBuffAccess;
+BOOL          fRes;
+tShbError     ShbError;
+
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
+    ShbError = kShbOk;
+
+    hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
+    if (hMutexBuffAccess != INVALID_HANDLE_VALUE)
+    {
+        fRes = ReleaseMutex (hMutexBuffAccess);
+        ASSERT( fRes );
+    }
+    else
+    {
+        ShbError = kShbBufferInvalid;
+    }
+
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Start signaling of new data (called from reading process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcStartSignalingNewData (
+    tShbInstance pShbInstance_p,
+    tSigHndlrNewData pfnSignalHandlerNewData_p,
+    tShbPriority ShbPriority_p)
+{
+
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+const char*     pszObjectName;
+HANDLE          hEventTermRequ;
+HANDLE          hEventTermResp;
+HANDLE          hThreadNewData;
+unsigned long   ulThreadIDNewData;
+tShbError       ShbError;
+int             iPriority;
+
+    if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p);
+    ShbError = kShbOk;
+
+    if ( (pShbMemInst->m_hThreadNewData                      != INVALID_HANDLE_VALUE) ||
+         (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != INVALID_HANDLE_VALUE) ||
+         (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != INVALID_HANDLE_VALUE) ||
+         (pShbMemInst->m_pfnSigHndlrNewData                  != NULL) )
+    {
+        ShbError = kShbAlreadySignaling;
+        goto Exit;
+    }
+
+
+    pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
+
+
+    // Because the event <pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]>
+    // is used for signaling of new data after a write operation too (using
+    // SetEvent), it is always created here (see <ShbIpcAllocBuffer>).
+
+    pszObjectName = ShbIpcGetUniformObjectName (NAME_EVENT_TERM_REQU, pShbMemHeader->m_szBufferID, FALSE);
+    hEventTermRequ = CreateEvent (NULL,                         // LPSECURITY_ATTRIBUTES lpEventAttributes
+                                  FALSE,                        // BOOL bManualReset
+                                  FALSE,                        // BOOL bInitialState
+                                  pszObjectName);               // LPCTSTR lpName
+    pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = hEventTermRequ;
+    ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != NULL);
+
+    pszObjectName = ShbIpcGetUniformObjectName (NAME_EVENT_TERM_RESP, pShbMemHeader->m_szBufferID, FALSE);
+    hEventTermResp = CreateEvent (NULL,                         // LPSECURITY_ATTRIBUTES lpEventAttributes
+                                  FALSE,                        // BOOL bManualReset
+                                  FALSE,                        // BOOL bInitialState
+                                  pszObjectName);               // LPCTSTR lpName
+    pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = hEventTermResp;
+    ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != NULL);
+
+    hThreadNewData = CreateThread (NULL,                        // LPSECURITY_ATTRIBUTES lpThreadAttributes
+                                   0,                           // SIZE_T dwStackSize
+                                   ShbIpcThreadSignalNewData,   // LPTHREAD_START_ROUTINE lpStartAddress
+                                   pShbInstance_p,              // LPVOID lpParameter
+                                   0,                           // DWORD dwCreationFlags
+                                   &ulThreadIDNewData);         // LPDWORD lpThreadId
+
+    switch (ShbPriority_p)
+    {
+        case kShbPriorityLow:
+            iPriority = THREAD_PRIORITY_BELOW_NORMAL;
+            break;
+
+        case kShbPriorityNormal:
+            iPriority = THREAD_PRIORITY_NORMAL;
+            break;
+
+        case kshbPriorityHigh:
+            iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
+            break;
+
+    }
+
+    ASSERT(pShbMemInst->m_hThreadNewData != NULL);
+
+    SetThreadPriority(hThreadNewData, iPriority);
+
+    pShbMemInst->m_hThreadNewData = hThreadNewData;
+
+    #ifndef NDEBUG
+    {
+        pShbMemInst->m_ulThreadIDNewData = ulThreadIDNewData;
+    }
+    #endif
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Stop signaling of new data (called from reading process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcStopSignalingNewData (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+HANDLE        hEventTermRequ;
+HANDLE        hEventTermResp;
+DWORD         dwWaitResult;
+
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+
+    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
+
+
+    // terminate new data signaling thread
+    // (set event <hEventTermRequ> to wakeup the thread and dispose it
+    // to exit, then wait for confirmation using event <hEventTermResp>)
+    hEventTermRequ = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU];
+    hEventTermResp = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP];
+    if ( (hEventTermRequ != INVALID_HANDLE_VALUE) &&
+         (hEventTermResp != INVALID_HANDLE_VALUE)  )
+    {
+        TRACE0("\nShbIpcStopSignalingNewData(): enter wait state");
+        dwWaitResult = SignalObjectAndWait (hEventTermRequ,         // HANDLE hObjectToSignal
+                                            hEventTermResp,         // HANDLE hObjectToWaitOn
+                                            TIMEOUT_TERM_THREAD,    // DWORD dwMilliseconds
+                                            FALSE);                 // BOOL bAlertable
+        TRACE0("\nShbIpcStopSignalingNewData(): wait state leaved: ---> ");
+        switch (dwWaitResult)
+        {
+            case WAIT_OBJECT_0 + 0:     // event "new data signaling thread terminated"
+            {
+                TRACE0("Event = WAIT_OBJECT_0+0");
+                break;
+            }
+
+            default:
+            {
+                TRACE0("Unhandled Event");
+                ASSERT(0);
+                break;
+            }
+        }
+    }
+
+
+    if (pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE)
+    {
+        CloseHandle (pShbMemInst->m_hThreadNewData);
+        pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
+    }
+
+    if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != INVALID_HANDLE_VALUE)
+    {
+        CloseHandle (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU]);
+        pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = INVALID_HANDLE_VALUE;
+    }
+
+    if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != INVALID_HANDLE_VALUE)
+    {
+        CloseHandle (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
+        pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = INVALID_HANDLE_VALUE;
+    }
+
+    pShbMemInst->m_pfnSigHndlrNewData = NULL;
+
+
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Signal new data (called from writing process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcSignalNewData (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+HANDLE  hEventNewData;
+BOOL    fRes;
+
+
+    // TRACE0("\nShbIpcSignalNewData(): enter\n");
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
+
+    ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != INVALID_HANDLE_VALUE);
+    hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
+    if (hEventNewData != INVALID_HANDLE_VALUE)
+    {
+        fRes = SetEvent (hEventNewData);
+        // TRACE1("\nShbIpcSignalNewData(): EventNewData set (Result=%d)\n", (int)fRes);
+        ASSERT( fRes );
+    }
+
+    // TRACE0("\nShbIpcSignalNewData(): leave\n");
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Start signaling for job ready (called from waiting process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcStartSignalingJobReady (
+    tShbInstance pShbInstance_p,
+    unsigned long ulTimeOut_p,
+    tSigHndlrJobReady pfnSignalHandlerJobReady_p)
+{
+
+tShbMemInst*    pShbMemInst;
+tShbMemHeader*  pShbMemHeader;
+HANDLE          hThreadJobReady;
+unsigned long   ulThreadIDJobReady;
+tShbError       ShbError;
+
+
+    if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL))
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p);
+    ShbError = kShbOk;
+
+    if ( (pShbMemInst->m_hThreadJobReady     != INVALID_HANDLE_VALUE) ||
+         (pShbMemInst->m_pfnSigHndlrJobReady != NULL) )
+    {
+        ShbError = kShbAlreadySignaling;
+        goto Exit;
+    }
+
+
+    pShbMemInst->m_ulTimeOutJobReady   = ulTimeOut_p;
+    pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
+
+
+    // Because the event <pShbMemInst->m_ahEventJobReady> is used for
+    // signaling of a finished job too (using SetEvent), it is always
+    // created here (see <ShbIpcAllocBuffer>).
+
+    hThreadJobReady = CreateThread (NULL,                       // LPSECURITY_ATTRIBUTES lpThreadAttributes
+                                    0,                          // SIZE_T dwStackSize
+                                    ShbIpcThreadSignalJobReady, // LPTHREAD_START_ROUTINE lpStartAddress
+                                    pShbInstance_p,             // LPVOID lpParameter
+                                    0,                          // DWORD dwCreationFlags
+                                    &ulThreadIDJobReady);       // LPDWORD lpThreadId
+
+    pShbMemInst->m_hThreadJobReady = hThreadJobReady;
+    ASSERT(pShbMemInst->m_hThreadJobReady != NULL);
+
+    #ifndef NDEBUG
+    {
+        pShbMemInst->m_ulThreadIDJobReady = ulThreadIDJobReady;
+    }
+    #endif
+
+
+Exit:
+
+    return (ShbError);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Signal job ready (called from executing process)
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION tShbError  ShbIpcSignalJobReady (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemInst*  pShbMemInst;
+HANDLE  hEventJobReady;
+BOOL    fRes;
+
+
+    // TRACE0("\nShbIpcSignalJobReady(): enter\n");
+
+    if (pShbInstance_p == NULL)
+    {
+        return (kShbInvalidArg);
+    }
+
+
+    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
+
+    ASSERT(pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE);
+    hEventJobReady = pShbMemInst->m_hEventJobReady;
+    if (hEventJobReady != INVALID_HANDLE_VALUE)
+    {
+        fRes = SetEvent (hEventJobReady);
+        // TRACE1("\nShbIpcSignalJobReady(): EventJobReady set (Result=%d)\n", (int)fRes);
+        ASSERT( fRes );
+    }
+
+    // TRACE0("\nShbIpcSignalJobReady(): leave\n");
+    return (kShbOk);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Get pointer to common used share memory area
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void*  ShbIpcGetShMemPtr (
+    tShbInstance pShbInstance_p)
+{
+
+tShbMemHeader*  pShbMemHeader;
+void*  pShbShMemPtr;
+
+
+    pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p);
+    if (pShbMemHeader != NULL)
+    {
+        pShbShMemPtr = (BYTE*)pShbMemHeader + sizeof(tShbMemHeader);
+    }
+    else
+    {
+        pShbShMemPtr = NULL;
+    }
+
+    return (pShbShMemPtr);
+
+}
+
+#endif
+
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+//  Allocate a memory block from process specific mempool
+//---------------------------------------------------------------------------
+
+static void*  ShbIpcAllocPrivateMem (
+    unsigned long ulMemSize_p)
+{
+
+HGLOBAL  hMem;
+void*    pMem;
+
+
+    hMem = GlobalAlloc (GMEM_FIXED, ulMemSize_p+sizeof(HGLOBAL));
+    pMem = GlobalLock  (hMem);
+    if (pMem != NULL)
+    {
+        *(HGLOBAL*)pMem = hMem;
+        (BYTE*)pMem += sizeof(HGLOBAL);
+    }
+
+
+    #ifndef NDEBUG
+    {
+        memset (pMem, 0xaa, ulMemSize_p);
+    }
+    #endif
+
+
+    return (pMem);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Release a memory block from process specific mempool
+//---------------------------------------------------------------------------
+
+static void  ShbIpcReleasePrivateMem (
+    void* pMem_p)
+{
+
+HGLOBAL  hMem;
+
+
+    if (pMem_p == NULL)
+    {
+        return;
+    }
+
+
+    (BYTE*)pMem_p -= sizeof(HGLOBAL);
+    hMem = *(HGLOBAL*)pMem_p;
+
+    GlobalUnlock (hMem);
+    GlobalFree   (hMem);
+
+    return;
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Create uniform object name (needed for inter-process communication)
+//---------------------------------------------------------------------------
+
+const char*  ShbIpcGetUniformObjectName (
+    const char* pszObjectJobName_p,
+    const char* pszBufferID_p,
+    BOOL fGlobalObject_p)
+{
+
+static  char  szObjectName[MAX_PATH];
+char  szObjectPrefix[MAX_PATH];
+
+
+    if ( fGlobalObject_p )
+    {
+        strncpy (szObjectPrefix, "Global\\", sizeof(szObjectPrefix));
+    }
+    else
+    {
+        _snprintf (szObjectPrefix, sizeof(szObjectPrefix), "PID%08lX_",
+                   (unsigned long)GetCurrentProcessId());
+    }
+
+
+    _snprintf (szObjectName, sizeof(szObjectName), "%s%s#%s",
+               szObjectPrefix, pszBufferID_p, pszObjectJobName_p);
+
+
+    return (szObjectName);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Thread for new data signaling
+//---------------------------------------------------------------------------
+
+DWORD  WINAPI  ShbIpcThreadSignalNewData (
+    LPVOID pvThreadParam_p)
+{
+
+tShbInstance  pShbInstance;
+tShbMemInst*  pShbMemInst;
+DWORD         dwWaitResult;
+BOOL          fTermRequ;
+int           fCallAgain;
+
+
+    TRACE1("\nShbIpcThreadSignalNewData(): SignalThread started (pShbInstance=0x%08lX)\n", (DWORD)pvThreadParam_p);
+
+    pShbInstance = (tShbMemInst*)pvThreadParam_p;
+    pShbMemInst  = ShbIpcGetShbMemInst (pShbInstance);
+    fTermRequ    = FALSE;
+
+    do
+    {
+        ASSERT((pShbMemInst->m_ahEventNewData[0] != INVALID_HANDLE_VALUE) && (pShbMemInst->m_ahEventNewData[0] != NULL));
+        ASSERT((pShbMemInst->m_ahEventNewData[1] != INVALID_HANDLE_VALUE) && (pShbMemInst->m_ahEventNewData[1] != NULL));
+
+        TRACE0("\nShbIpcThreadSignalNewData(): enter wait state");
+        dwWaitResult = WaitForMultipleObjects (2,                               // DWORD nCount
+                                               pShbMemInst->m_ahEventNewData,   // const HANDLE* lpHandles
+                                               FALSE,                           // BOOL bWaitAll
+                                               INFINITE);                       // DWORD dwMilliseconds
+        TRACE0("\nShbIpcThreadSignalNewData(): wait state leaved: ---> ");
+        switch (dwWaitResult)
+        {
+            case WAIT_OBJECT_0 + 0:     // event "new data"
+            {
+                TRACE0("Event = WAIT_OBJECT_0+0");
+                if (pShbMemInst->m_pfnSigHndlrNewData != NULL)
+                {
+                    TRACE0("\nShbIpcThreadSignalNewData(): calling SignalHandlerNewData");
+                    do
+                    {
+                        fCallAgain = pShbMemInst->m_pfnSigHndlrNewData (pShbInstance);
+                        // d.k.: try to run any shared buffer which has higher priority.
+                        //           under Windows this is not really necessary because the Windows scheduler
+                        //           already preempts tasks with lower priority.
+                    } while (fCallAgain != FALSE);
+                }
+                break;
+            }
+
+            case WAIT_OBJECT_0 + 1:     // event "terminate"
+            {
+                TRACE0("Event = WAIT_OBJECT_0+1");
+                fTermRequ = TRUE;
+                break;
+            }
+
+            default:
+            {
+                TRACE0("Unhandled Event");
+                ASSERT(0);
+                fTermRequ = TRUE;
+                break;
+            }
+        }
+    }
+    while ( !fTermRequ );
+
+
+    if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != INVALID_HANDLE_VALUE)
+    {
+        SetEvent (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
+    }
+
+    TRACE1("\nShbIpcThreadSignalNewData(): SignalThread terminated (pShbInstance=0x%08lX)\n", (DWORD)pShbInstance);
+
+    ExitThread (0);
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Thread for new data signaling
+//---------------------------------------------------------------------------
+
+DWORD  WINAPI  ShbIpcThreadSignalJobReady (
+    LPVOID pvThreadParam_p)
+{
+
+tShbInstance*  pShbInstance;
+tShbMemInst*   pShbMemInst;
+DWORD          ulTimeOut;
+DWORD          dwWaitResult;
+unsigned int   fTimeOut;
+
+
+    TRACE1("\nShbIpcThreadSignalJobReady(): SignalThread started (pShbInstance=0x%08lX)\n", (DWORD)pvThreadParam_p);
+
+
+    pShbInstance = (tShbInstance*)pvThreadParam_p;
+    pShbMemInst  = ShbIpcGetShbMemInst (pShbInstance);
+    fTimeOut     = FALSE;
+
+    if (pShbMemInst->m_ulTimeOutJobReady != 0)
+    {
+        ulTimeOut = pShbMemInst->m_ulTimeOutJobReady;
+    }
+    else
+    {
+        ulTimeOut = INFINITE;
+    }
+
+    ASSERT((pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE) && (pShbMemInst->m_hEventJobReady != NULL));
+
+    TRACE0("\nShbIpcThreadSignalJobReady(): enter wait state");
+    dwWaitResult = WaitForSingleObject (pShbMemInst->m_hEventJobReady,          // HANDLE hHandle
+                                        ulTimeOut);                             // DWORD dwMilliseconds
+    TRACE0("\nShbIpcThreadSignalJobReady(): wait state leaved: ---> ");
+    switch (dwWaitResult)
+    {
+        case WAIT_OBJECT_0 + 0:     // event "new data"
+        {
+            TRACE0("Event = WAIT_OBJECT_0+0");
+            fTimeOut = FALSE;
+            break;
+        }
+
+        case WAIT_TIMEOUT:
+        {
+            TRACE0("\nEvent = WAIT_TIMEOUT");
+            fTimeOut = TRUE;
+            // ASSERT(0);
+            break;
+        }
+
+        default:
+        {
+            TRACE0("Unhandled Event");
+            fTimeOut = TRUE;
+            ASSERT(0);
+            break;
+        }
+    }
+
+
+    if (pShbMemInst->m_pfnSigHndlrJobReady != NULL)
+    {
+        TRACE0("\nShbIpcThreadSignalJobReady(): calling SignalHandlerJobReady");
+        pShbMemInst->m_pfnSigHndlrJobReady (pShbInstance, fTimeOut);
+    }
+
+
+    pShbMemInst->m_hThreadJobReady     = INVALID_HANDLE_VALUE;
+    pShbMemInst->m_pfnSigHndlrJobReady = NULL;
+
+
+    TRACE1("\nShbIpcThreadSignalJobReady(): SignalThread terminated (pShbInstance=0x%08lX)\n", (DWORD)pShbInstance);
+
+    ExitThread (0);
+
+}
+
+#endif
+
+// EOF
+
diff --git a/drivers/staging/epl/ShbIpc.h b/drivers/staging/epl/ShbIpc.h
new file mode 100644 (file)
index 0000000..7840b03
--- /dev/null
@@ -0,0 +1,120 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      Project independend shared buffer (linear + circular)
+
+  Description:  Declaration of platform specific part for the
+                shared buffer
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+  2006/06/27 -rs:   V 1.00 (initial version)
+
+****************************************************************************/
+
+#ifndef _SHBIPC_H_
+#define _SHBIPC_H_
+
+
+
+//---------------------------------------------------------------------------
+//  Type definitions
+//---------------------------------------------------------------------------
+
+typedef  int   (*tSigHndlrNewData)  (tShbInstance pShbInstance_p);
+typedef  void  (*tSigHndlrJobReady) (tShbInstance pShbInstance_p, unsigned int fTimeOut_p);
+
+
+#if (TARGET_SYSTEM == _WIN32_)
+    #if defined(INLINE_FUNCTION_DEF)
+        #undef  INLINE_FUNCTION
+        #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+        #define SHBIPC_INLINE_ENABLED      TRUE
+        #define SHBIPC_INLINED
+        #include "ShbIpc-Win32.c"
+    #endif
+
+#elif (TARGET_SYSTEM == _LINUX_)
+    #if defined(INLINE_FUNCTION_DEF)
+        #undef  INLINE_FUNCTION
+        #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+        #define SHBIPC_INLINE_ENABLED      TRUE
+        #define SHBIPC_INLINED
+        #include "ShbIpc-LinuxKernel.c"
+    #endif
+#endif
+
+
+//---------------------------------------------------------------------------
+//  Prototypes
+//---------------------------------------------------------------------------
+
+tShbError  ShbIpcInit (void);
+tShbError  ShbIpcExit (void);
+
+tShbError  ShbIpcAllocBuffer            (unsigned long ulBufferSize_p, const char* pszBufferID_p, tShbInstance* ppShbInstance_p, unsigned int* pfShbNewCreated_p);
+tShbError  ShbIpcReleaseBuffer          (tShbInstance pShbInstance_p);
+
+#if !defined(SHBIPC_INLINE_ENABLED)
+
+tShbError  ShbIpcEnterAtomicSection     (tShbInstance pShbInstance_p);
+tShbError  ShbIpcLeaveAtomicSection     (tShbInstance pShbInstance_p);
+
+tShbError  ShbIpcStartSignalingNewData  (tShbInstance pShbInstance_p, tSigHndlrNewData pfnSignalHandlerNewData_p, tShbPriority ShbPriority_p);
+tShbError  ShbIpcStopSignalingNewData   (tShbInstance pShbInstance_p);
+tShbError  ShbIpcSignalNewData          (tShbInstance pShbInstance_p);
+
+tShbError  ShbIpcStartSignalingJobReady (tShbInstance pShbInstance_p, unsigned long ulTimeOut_p, tSigHndlrJobReady pfnSignalHandlerJobReady_p);
+tShbError  ShbIpcSignalJobReady         (tShbInstance pShbInstance_p);
+
+void*      ShbIpcGetShMemPtr            (tShbInstance pShbInstance_p);
+#endif
+
+#undef  SHBIPC_INLINE_ENABLED              // disable actual inlining of functions
+#undef  INLINE_FUNCTION
+#define INLINE_FUNCTION             // define INLINE_FUNCTION to nothing
+
+#endif // #ifndef _SHBIPC_H_
+
diff --git a/drivers/staging/epl/ShbLinuxKernel.h b/drivers/staging/epl/ShbLinuxKernel.h
new file mode 100644 (file)
index 0000000..30b5faf
--- /dev/null
@@ -0,0 +1,68 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      Project independend shared buffer (linear + circular)
+
+  Description:  Declaration of platform specific part for the
+                shared buffer
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+  2006/07/20 -rs:   V 1.00 (initial version)
+
+****************************************************************************/
+
+#ifndef _SHBLINUXKERNEL_H_
+#define _SHBLINUXKERNEL_H_
+
+struct sShbMemTable{
+    int                 m_iBufferId;
+    void*               m_pBuffer;
+    struct sShbMemTable *m_psNextMemTableElement;
+};
+
+extern struct sShbMemTable *psMemTableElementFirst_g;
+
+#endif // _SHBLINUXKERNEL_H_
diff --git a/drivers/staging/epl/SocketLinuxKernel.c b/drivers/staging/epl/SocketLinuxKernel.c
new file mode 100644 (file)
index 0000000..c78a6eb
--- /dev/null
@@ -0,0 +1,210 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Wrapper for BSD socket API for Linux kernel
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: SocketLinuxKernel.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Dev C++ and GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/08/25 d.k.:   start of implementation
+
+****************************************************************************/
+
+
+#include <linux/net.h>
+#include <linux/in.h>
+#include "SocketLinuxKernel.h"
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+//  Kernel Module specific Data Structures
+//---------------------------------------------------------------------------
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+SOCKET socket(int af, int type, int protocol)
+{
+int rc;
+SOCKET socket;
+
+    rc = sock_create_kern(af, type, protocol, &socket);
+    if (rc < 0)
+    {
+        socket = NULL;
+        goto Exit;
+    }
+
+Exit:
+    return socket;
+}
+
+int bind(SOCKET socket_p, const struct sockaddr *addr, int addrlen)
+{
+int rc;
+
+    rc = socket_p->ops->bind(socket_p,
+                          (struct sockaddr *)addr,
+                          addrlen);
+
+    return rc;
+}
+
+int closesocket(SOCKET socket_p)
+{
+    sock_release(socket_p);
+
+    return 0;
+}
+
+int recvfrom(SOCKET socket_p, char* buf, int len, int flags, struct sockaddr *from, int * fromlen)
+{
+int rc;
+struct msghdr msg;
+struct kvec iov;
+
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_name = from;     // will be struct sock_addr
+    msg.msg_namelen = *fromlen;
+    iov.iov_len = len;
+    iov.iov_base = buf;
+
+    rc = kernel_recvmsg(socket_p, &msg, &iov, 1, iov.iov_len, 0);
+
+    return rc;
+}
+
+int sendto(SOCKET socket_p, const char* buf, int len, int flags, const struct sockaddr *to, int tolen)
+{
+int rc;
+struct msghdr msg;
+struct kvec iov;
+
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_name = (struct sockaddr *)to;     // will be struct sock_addr
+    msg.msg_namelen = tolen;
+    msg.msg_flags = 0;
+    iov.iov_len = len;
+    iov.iov_base = (char *)buf;
+
+    rc = kernel_sendmsg(socket_p, &msg, &iov, 1, len);
+
+    return rc;
+}
+
+
+// EOF
+
diff --git a/drivers/staging/epl/SocketLinuxKernel.h b/drivers/staging/epl/SocketLinuxKernel.h
new file mode 100644 (file)
index 0000000..c248a78
--- /dev/null
@@ -0,0 +1,108 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for BSD socket API for Linux kernel
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: SocketLinuxKernel.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/08/25 d.k.:   start of the implementation
+
+
+****************************************************************************/
+
+
+#ifndef _SOCKETLINUXKERNEL_H_
+#define _SOCKETLINUXKERNEL_H_
+
+#include <linux/net.h>
+#include <linux/in.h>
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define INVALID_SOCKET  0
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef struct socket* SOCKET;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+int bind(SOCKET s, const struct sockaddr *addr, int addrlen);
+
+int closesocket(SOCKET s);
+
+int recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr *from, int * fromlen);
+
+int sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr *to, int tolen);
+
+SOCKET socket(int af, int type, int protocol);
+
+#endif  // #ifndef _SOCKETLINUXKERNEL_H_
+
+
diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c
new file mode 100644 (file)
index 0000000..70ba2d6
--- /dev/null
@@ -0,0 +1,555 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  target specific implementation of
+                high resolution timer module for X86 under Linux
+                The Linux kernel has to be compiled with high resolution
+                timers enabled. This is done by configuring the kernel
+                with CONFIG_HIGH_RES_TIMERS enabled.
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: TimerHighReskX86.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:38:01 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GNU
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+****************************************************************************/
+
+#include "EplInc.h"
+#include "kernel/EplTimerHighResk.h"
+#include "Benchmark.h"
+
+//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hrtimer.h>
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#define TIMER_COUNT           2            /* max 15 timers selectable */
+#define TIMER_MIN_VAL_SINGLE  5000         /* min 5us */
+#define TIMER_MIN_VAL_CYCLE   100000       /* min 100us */
+
+#define PROVE_OVERRUN
+
+
+#ifndef CONFIG_HIGH_RES_TIMERS
+    #error "Kernel symbol CONFIG_HIGH_RES_TIMERS is required."
+#endif
+
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+    #define TGT_DBG_POST_TRACE_VALUE(v)
+#endif
+#define HRT_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
+    TGT_DBG_POST_TRACE_VALUE((0xE << 28) | (Event_p << 24) \
+                             | (uiNodeId_p << 16) | wErrorCode_p)
+
+#define TIMERHDL_MASK         0x0FFFFFFF
+#define TIMERHDL_SHIFT        28
+#define HDL_TO_IDX(Hdl)       ((Hdl >> TIMERHDL_SHIFT) - 1)
+#define HDL_INIT(Idx)         ((Idx + 1) << TIMERHDL_SHIFT)
+#define HDL_INC(Hdl)          (((Hdl + 1) & TIMERHDL_MASK) \
+                               | (Hdl & ~TIMERHDL_MASK))
+
+//---------------------------------------------------------------------------
+// modul global types
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    tEplTimerEventArg    m_EventArg;
+    tEplTimerkCallback   m_pfnCallback;
+    struct hrtimer       m_Timer;
+    BOOL                 m_fContinuously;
+    unsigned long long   m_ullPeriod;
+
+} tEplTimerHighReskTimerInfo;
+
+typedef struct
+{
+    tEplTimerHighReskTimerInfo  m_aTimerInfo[TIMER_COUNT];
+
+} tEplTimerHighReskInstance;
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+static tEplTimerHighReskInstance    EplTimerHighReskInstance_l;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+enum hrtimer_restart EplTimerHighReskCallback (struct hrtimer* pTimer_p);
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimerHighReskInit()
+//
+// Description: initializes the high resolution timer module.
+//
+// Parameters:  void
+//
+// Return:      tEplKernel      = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimerHighReskInit(void)
+{
+tEplKernel  Ret;
+
+    Ret = EplTimerHighReskAddInstance();
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimerHighReskAddInstance()
+//
+// Description: initializes the high resolution timer module.
+//
+// Parameters:  void
+//
+// Return:      tEplKernel      = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
+{
+tEplKernel                   Ret;
+unsigned int                 uiIndex;
+
+    Ret = kEplSuccessful;
+
+    EPL_MEMSET(&EplTimerHighReskInstance_l, 0, sizeof (EplTimerHighReskInstance_l));
+
+#ifndef CONFIG_HIGH_RES_TIMERS
+    printk("EplTimerHighResk: Kernel symbol CONFIG_HIGH_RES_TIMERS is required.\n");
+    Ret = kEplNoResource;
+    return Ret;
+#endif
+
+    /*
+     * Initialize hrtimer structures for all usable timers.
+     */
+    for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++)
+    {
+    tEplTimerHighReskTimerInfo*  pTimerInfo;
+    struct hrtimer*              pTimer;
+
+        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
+        pTimer = &pTimerInfo->m_Timer;
+        hrtimer_init(pTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+
+        pTimer->function = EplTimerHighReskCallback;
+
+        /*
+         * We use HRTIMER_CB_SOFTIRQ here.
+         * HRTIMER_CB_IRQSAFE is critical as the callback function
+         * would be called with IRQs disabled.
+         */
+        pTimer->cb_mode = HRTIMER_CB_SOFTIRQ;
+    }
+
+    return Ret;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimerHighReskDelInstance()
+//
+// Description: shuts down the high resolution timer module.
+//
+// Parameters:  void
+//
+// Return:      tEplKernel      = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimerHighReskDelInstance(void)
+{
+tEplTimerHighReskTimerInfo*  pTimerInfo;
+tEplKernel                   Ret;
+unsigned int                 uiIndex;
+
+    Ret = kEplSuccessful;
+
+    for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++)
+    {
+        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
+        pTimerInfo->m_pfnCallback = NULL;
+        pTimerInfo->m_EventArg.m_TimerHdl = 0;
+        /*
+         * In this case we can not just try to cancel the timer.
+         * We actually have to wait until its callback function
+         * has returned.
+         */
+        hrtimer_cancel(&pTimerInfo->m_Timer);
+    }
+
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimerHighReskModifyTimerNs()
+//
+// Description: modifies the timeout of the timer with the specified handle.
+//              If the handle the pointer points to is zero, the timer must
+//              be created first.
+//              If it is not possible to stop the old timer,
+//              this function always assures that the old timer does not
+//              trigger the callback function with the same handle as the new
+//              timer. That means the callback function must check the passed
+//              handle with the one returned by this function. If these are
+//              unequal, the call can be discarded.
+//
+// Parameters:  pTimerHdl_p     = pointer to timer handle
+//              ullTimeNs_p     = relative timeout in [ns]
+//              pfnCallback_p   = callback function, which is called mutual
+//                                exclusive with the Edrv callback functions
+//                                (Rx and Tx).
+//              ulArgument_p    = user-specific argument
+//              fContinuously_p = if TRUE, callback function will be called
+//                                continuously;
+//                                otherwise, it is a oneshot timer.
+//
+// Return:      tEplKernel      = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl*     pTimerHdl_p,
+                                    unsigned long long  ullTimeNs_p,
+                                    tEplTimerkCallback  pfnCallback_p,
+                                    unsigned long       ulArgument_p,
+                                    BOOL                fContinuously_p)
+{
+tEplKernel                   Ret;
+unsigned int                 uiIndex;
+tEplTimerHighReskTimerInfo*  pTimerInfo;
+ktime_t                      RelTime;
+
+    Ret = kEplSuccessful;
+
+    // check pointer to handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    if (*pTimerHdl_p == 0)
+    {   // no timer created yet
+
+        // search free timer info structure
+        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
+        for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++, pTimerInfo++)
+        {
+            if (pTimerInfo->m_EventArg.m_TimerHdl == 0)
+            {   // free structure found
+                break;
+            }
+        }
+        if (uiIndex >= TIMER_COUNT)
+        {   // no free structure found
+            Ret = kEplTimerNoTimerCreated;
+            goto Exit;
+        }
+
+        pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex);
+    }
+    else
+    {
+        uiIndex = HDL_TO_IDX(*pTimerHdl_p);
+        if (uiIndex >= TIMER_COUNT)
+        {   // invalid handle
+            Ret = kEplTimerInvalidHandle;
+            goto Exit;
+        }
+
+        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
+    }
+
+    /*
+     * increment timer handle
+     * (if timer expires right after this statement, the user
+     * would detect an unknown timer handle and discard it)
+     */
+    pTimerInfo->m_EventArg.m_TimerHdl = HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl);
+    *pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl;
+
+    // reject too small time values
+    if (    (fContinuously_p  && (ullTimeNs_p < TIMER_MIN_VAL_CYCLE))
+         || (!fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_SINGLE)) )
+    {
+        Ret = kEplTimerNoTimerCreated;
+        goto Exit;
+    }
+
+    pTimerInfo->m_EventArg.m_ulArg = ulArgument_p;
+    pTimerInfo->m_pfnCallback      = pfnCallback_p;
+    pTimerInfo->m_fContinuously    = fContinuously_p;
+    pTimerInfo->m_ullPeriod        = ullTimeNs_p;
+
+    /*
+     * HRTIMER_MODE_REL does not influence general handling of this timer.
+     * It only sets relative mode for this start operation.
+     * -> Expire time is calculated by: Now + RelTime
+     * hrtimer_start also skips pending timer events.
+     * The state HRTIMER_STATE_CALLBACK is ignored.
+     * We have to cope with that in our callback function.
+     */
+    RelTime = ktime_add_ns(ktime_set(0,0), ullTimeNs_p);
+    hrtimer_start(&pTimerInfo->m_Timer, RelTime, HRTIMER_MODE_REL);
+
+Exit:
+    return Ret;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimerHighReskDeleteTimer()
+//
+// Description: deletes the timer with the specified handle. Afterward the
+//              handle is set to zero.
+//
+// Parameters:  pTimerHdl_p     = pointer to timer handle
+//
+// Return:      tEplKernel      = error code
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl* pTimerHdl_p)
+{
+tEplKernel                  Ret = kEplSuccessful;
+unsigned int                uiIndex;
+tEplTimerHighReskTimerInfo* pTimerInfo;
+
+    // check pointer to handle
+    if(pTimerHdl_p == NULL)
+    {
+        Ret = kEplTimerInvalidHandle;
+        goto Exit;
+    }
+
+    if (*pTimerHdl_p == 0)
+    {   // no timer created yet
+        goto Exit;
+    }
+    else
+    {
+        uiIndex = HDL_TO_IDX(*pTimerHdl_p);
+        if (uiIndex >= TIMER_COUNT)
+        {   // invalid handle
+            Ret = kEplTimerInvalidHandle;
+            goto Exit;
+        }
+        pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
+        if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p)
+        {   // invalid handle
+            goto Exit;
+        }
+    }
+
+    *pTimerHdl_p = 0;
+    pTimerInfo->m_EventArg.m_TimerHdl = 0;
+    pTimerInfo->m_pfnCallback = NULL;
+
+    /*
+     * Three return cases of hrtimer_try_to_cancel have to be tracked:
+     *  1 - timer has been removed
+     *  0 - timer was not active
+     *      We need not do anything. hrtimer timers just consist of
+     *      a hrtimer struct, which we might enqueue in the hrtimers
+     *      event list by calling hrtimer_start().
+     *      If a timer is not enqueued, it is not present in hrtimers.
+     * -1 - callback function is running
+     *      In this case we have to ensure that the timer is not
+     *      continuously restarted. This has been done by clearing
+     *      its handle.
+     */
+    hrtimer_try_to_cancel(&pTimerInfo->m_Timer);
+
+Exit:
+    return Ret;
+
+}
+
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    EplTimerHighReskCallback()
+//
+// Description: Callback function commonly used for all timers.
+//
+// Parameters:  pTimer_p = pointer to hrtimer
+//
+// Return:
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+enum hrtimer_restart EplTimerHighReskCallback (struct hrtimer* pTimer_p)
+{
+unsigned int                 uiIndex;
+tEplTimerHighReskTimerInfo*  pTimerInfo;
+tEplTimerHdl                 OrgTimerHdl;
+enum hrtimer_restart         Ret;
+
+    BENCHMARK_MOD_24_SET(4);
+
+    Ret        = HRTIMER_NORESTART;
+    pTimerInfo = container_of(pTimer_p, tEplTimerHighReskTimerInfo, m_Timer);
+    uiIndex    = HDL_TO_IDX(pTimerInfo->m_EventArg.m_TimerHdl);
+    if (uiIndex >= TIMER_COUNT)
+    {   // invalid handle
+        goto Exit;
+    }
+
+    /*
+     * We store the timer handle before calling the callback function
+     * as the timer can be modified inside it.
+     */
+    OrgTimerHdl = pTimerInfo->m_EventArg.m_TimerHdl;
+
+    if (pTimerInfo->m_pfnCallback != NULL)
+    {
+        pTimerInfo->m_pfnCallback(&pTimerInfo->m_EventArg);
+    }
+
+    if (pTimerInfo->m_fContinuously)
+    {
+    ktime_t        Interval;
+#ifdef PROVE_OVERRUN
+    ktime_t        Now;
+    unsigned long  Overruns;
+#endif
+
+        if (OrgTimerHdl != pTimerInfo->m_EventArg.m_TimerHdl)
+        {
+            /* modified timer has already been restarted */
+            goto Exit;
+        }
+
+#ifdef PROVE_OVERRUN
+        Now      = ktime_get();
+        Interval = ktime_add_ns(ktime_set(0,0), pTimerInfo->m_ullPeriod);
+        Overruns = hrtimer_forward(pTimer_p, Now, Interval);
+        if (Overruns > 1)
+        {
+            printk("EplTimerHighResk: Continuous timer (handle 0x%lX) had to skip %lu interval(s)!\n", pTimerInfo->m_EventArg.m_TimerHdl, Overruns-1);
+        }
+#else
+        pTimer_p->expires = ktime_add_ns(pTimer_p->expires,
+                                         pTimerInfo->m_ullPeriod);
+#endif
+
+        Ret = HRTIMER_RESTART;
+    }
+
+Exit:
+    BENCHMARK_MOD_24_RESET(4);
+    return Ret;
+}
+
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c
new file mode 100644 (file)
index 0000000..c21189c
--- /dev/null
@@ -0,0 +1,358 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Virtual Ethernet Driver for Linux
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: VirtualEthernetLinux.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/11/20 17:06:51 $
+
+                $State: Exp $
+
+                Build Environment:
+
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/12 -ar:   start of the implementation, version 1.00
+
+  2006/09/18 d.k.:  integration into EPL DLLk module
+
+  ToDo:
+
+  void netif_carrier_off(struct net_device *dev);
+  void netif_carrier_on(struct net_device *dev);
+
+****************************************************************************/
+
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/if_arp.h>
+#include <net/arp.h>
+
+#include <net/protocol.h>
+#include <net/pkt_sched.h>
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>  /* for struct sk_buff */
+
+#include "kernel/VirtualEthernet.h"
+#include "kernel/EplDllkCal.h"
+#include "kernel/EplDllk.h"
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef EPL_VETH_TX_TIMEOUT
+//#define EPL_VETH_TX_TIMEOUT (2*HZ)
+#define EPL_VETH_TX_TIMEOUT 0       // d.k.: we use no timeout
+#endif
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+static struct net_device * pVEthNetDevice_g = NULL;
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static int VEthOpen(struct net_device *pNetDevice_p);
+static int VEthClose(struct net_device *pNetDevice_p);
+static int VEthXmit(struct sk_buff *pSkb_p, struct net_device *pNetDevice_p);
+static struct net_device_stats* VEthGetStats(struct net_device *pNetDevice_p);
+static void VEthTimeout(struct net_device *pNetDevice_p);
+static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p);
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+static int VEthOpen(struct net_device *pNetDevice_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    //open the device
+//    struct net_device_stats* pStats = (struct net_device_stats*)pNetDevice_p->priv;
+
+    //start the interface queue for the network subsystem
+    netif_start_queue(pNetDevice_p);
+
+    // register callback function in DLL
+    Ret = EplDllkRegAsyncHandler(VEthRecvFrame);
+
+    EPL_DBGLVL_VETH_TRACE1("VEthOpen: EplDllkRegAsyncHandler returned 0x%02X\n", Ret);
+
+    return 0;
+}
+
+static int VEthClose(struct net_device *pNetDevice_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    EPL_DBGLVL_VETH_TRACE0("VEthClose\n");
+
+    Ret = EplDllkDeregAsyncHandler(VEthRecvFrame);
+
+    //stop the interface queue for the network subsystem
+    netif_stop_queue(pNetDevice_p);
+    return 0;
+}
+
+
+static int VEthXmit(struct sk_buff *pSkb_p, struct net_device *pNetDevice_p)
+{
+tEplKernel      Ret = kEplSuccessful;
+tEplFrameInfo   FrameInfo;
+
+    //transmit function
+    struct net_device_stats* pStats = (struct net_device_stats*)pNetDevice_p->priv;
+
+    //save timestemp
+    pNetDevice_p->trans_start = jiffies;
+
+    FrameInfo.m_pFrame = (tEplFrame *)pSkb_p->data;
+    FrameInfo.m_uiFrameSize = pSkb_p->len;
+
+    //call send fkt on DLL
+    Ret = EplDllkCalAsyncSend(&FrameInfo, kEplDllAsyncReqPrioGeneric);
+    if (Ret != kEplSuccessful)
+    {
+        EPL_DBGLVL_VETH_TRACE1("VEthXmit: EplDllkCalAsyncSend returned 0x%02X\n", Ret);
+        netif_stop_queue(pNetDevice_p);
+        goto Exit;
+    }
+    else
+    {
+        EPL_DBGLVL_VETH_TRACE0("VEthXmit: frame passed to DLL\n");
+        dev_kfree_skb(pSkb_p);
+
+        //set stats for the device
+        pStats->tx_packets++;
+        pStats->tx_bytes += FrameInfo.m_uiFrameSize;
+    }
+
+Exit:
+    return 0;
+
+}
+
+
+static struct net_device_stats* VEthGetStats(struct net_device *pNetDevice_p)
+{
+    EPL_DBGLVL_VETH_TRACE0("VEthGetStats\n");
+
+    return (struct net_device_stats *)pNetDevice_p->priv;
+}
+
+
+
+static void VEthTimeout(struct net_device *pNetDevice_p)
+{
+    EPL_DBGLVL_VETH_TRACE0("VEthTimeout(\n");
+
+    // $$$ d.k.: move to extra function, which is called by DLL when new space is available in TxFifo
+    if (netif_queue_stopped (pNetDevice_p))
+    {
+        netif_wake_queue (pNetDevice_p);
+    }
+}
+
+
+
+static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+    struct net_device* pNetDevice = pVEthNetDevice_g;
+    struct net_device_stats* pStats = (struct net_device_stats*)pNetDevice->priv;
+    struct sk_buff *pSkb;
+
+    EPL_DBGLVL_VETH_TRACE1("VEthRecvFrame: FrameSize=%u\n", pFrameInfo_p->m_uiFrameSize);
+
+    pSkb = dev_alloc_skb(pFrameInfo_p->m_uiFrameSize + 2);
+    if (pSkb == NULL)
+    {
+        pStats->rx_dropped++;
+        goto Exit;
+    }
+    pSkb->dev = pNetDevice;
+
+    skb_reserve(pSkb, 2);
+
+    memcpy((void *)skb_put(pSkb, pFrameInfo_p->m_uiFrameSize), pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
+
+    pSkb->protocol = eth_type_trans(pSkb, pNetDevice);
+    pSkb->ip_summed = CHECKSUM_UNNECESSARY;
+
+    // call netif_rx with skb
+    netif_rx(pSkb);
+
+    EPL_DBGLVL_VETH_TRACE1("VEthRecvFrame: SrcMAC=0x%llx\n", AmiGetQword48FromBe(pFrameInfo_p->m_pFrame->m_be_abSrcMac));
+
+    // update receive statistics
+    pStats->rx_packets++;
+    pStats->rx_bytes += pFrameInfo_p->m_uiFrameSize;
+
+Exit:
+    return Ret;
+}
+
+
+tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    // allocate net device structure with priv pointing to stats structure
+    pVEthNetDevice_g = alloc_netdev(sizeof (struct net_device_stats), EPL_VETH_NAME, ether_setup);
+//    pVEthNetDevice_g = alloc_etherdev(sizeof (struct net_device_stats));
+
+    if (pVEthNetDevice_g == NULL)
+    {
+        Ret = kEplNoResource;
+        goto Exit;
+    }
+
+    pVEthNetDevice_g->open               = VEthOpen;
+    pVEthNetDevice_g->stop               = VEthClose;
+    pVEthNetDevice_g->get_stats          = VEthGetStats;
+    pVEthNetDevice_g->hard_start_xmit    = VEthXmit;
+    pVEthNetDevice_g->tx_timeout         = VEthTimeout;
+    pVEthNetDevice_g->watchdog_timeo     = EPL_VETH_TX_TIMEOUT;
+    pVEthNetDevice_g->destructor         = free_netdev;
+
+    // copy own MAC address to net device structure
+    memcpy(pVEthNetDevice_g->dev_addr, pInitParam_p->m_be_abSrcMac, 6);
+
+    //register VEth to the network subsystem
+    if (register_netdev(pVEthNetDevice_g))
+    {
+        EPL_DBGLVL_VETH_TRACE0("VEthAddInstance: Could not register VEth...\n");
+    }
+    else
+    {
+        EPL_DBGLVL_VETH_TRACE0("VEthAddInstance: Register VEth successfull...\n");
+    }
+
+Exit:
+    return Ret;
+}
+
+
+tEplKernel PUBLIC VEthDelInstance(void)
+{
+tEplKernel  Ret = kEplSuccessful;
+
+    if (pVEthNetDevice_g != NULL)
+    {
+        //unregister VEth from the network subsystem
+        unregister_netdev(pVEthNetDevice_g);
+        // destructor was set to free_netdev,
+        // so we do not need to call free_netdev here
+        pVEthNetDevice_g = NULL;
+    }
+
+    return Ret;
+}
+
+#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
diff --git a/drivers/staging/epl/amix86.c b/drivers/staging/epl/amix86.c
new file mode 100644 (file)
index 0000000..808fa64
--- /dev/null
@@ -0,0 +1,945 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  Abstract Memory Interface for x86 compatible
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: amix86.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    ...
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  r.s.: first implemetation
+
+  2006-06-13  d.k.: duplicate functions for little endian and big endian
+
+****************************************************************************/
+
+//#include "global.h"
+//#include "EplAmi.h"
+#include "EplInc.h"
+
+#if (!defined(EPL_AMI_INLINED)) || defined(INLINE_ENABLED)
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+   WORD  m_wWord;
+
+} twStruct;
+
+typedef struct
+{
+   DWORD  m_dwDword;
+
+} tdwStruct;
+
+typedef struct
+{
+   QWORD  m_qwQword;
+
+} tqwStruct;
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetXXXToBe()
+//
+// Description: writes the specified value to the absolute address in
+//              big endian
+//
+// Parameters:  pAddr_p                 = absolute address
+//              xXXXVal_p               = value
+//
+// Returns:     (none)
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+//------------< write BYTE in big endian >--------------------------
+/*
+void  PUBLIC  AmiSetByteToBe (void FAR* pAddr_p, BYTE bByteVal_p)
+{
+
+   *(BYTE FAR*)pAddr_p = bByteVal_p;
+
+}
+*/
+
+
+
+//------------< write WORD in big endian >--------------------------
+
+INLINE_FUNCTION void  PUBLIC  AmiSetWordToBe (void FAR* pAddr_p, WORD wWordVal_p)
+{
+twStruct FAR*  pwStruct;
+twStruct wValue;
+
+   wValue.m_wWord   = (WORD)((wWordVal_p & 0x00FF) << 8); //LSB to MSB
+   wValue.m_wWord  |= (WORD)((wWordVal_p & 0xFF00) >> 8); //MSB to LSB
+
+   pwStruct = (twStruct FAR*)pAddr_p;
+   pwStruct->m_wWord = wValue.m_wWord;
+
+}
+
+
+
+//------------< write DWORD in big endian >-------------------------
+
+INLINE_FUNCTION void  PUBLIC  AmiSetDwordToBe (void FAR* pAddr_p, DWORD dwDwordVal_p)
+{
+tdwStruct FAR*  pdwStruct;
+tdwStruct dwValue;
+
+
+   dwValue.m_dwDword = ((dwDwordVal_p & 0x000000FF)<<24); //LSB to MSB
+   dwValue.m_dwDword|= ((dwDwordVal_p & 0x0000FF00)<<8);
+   dwValue.m_dwDword|= ((dwDwordVal_p & 0x00FF0000)>>8 );
+   dwValue.m_dwDword|= ((dwDwordVal_p & 0xFF000000)>>24); //MSB to LSB
+
+   pdwStruct = (tdwStruct FAR*)pAddr_p;
+   pdwStruct->m_dwDword = dwValue.m_dwDword;
+
+}
+
+
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetXXXToLe()
+//
+// Description: writes the specified value to the absolute address in
+//              little endian
+//
+// Parameters:  pAddr_p                 = absolute address
+//              xXXXVal_p               = value
+//
+// Returns:     (none)
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+//------------< write BYTE in little endian >--------------------------
+/*
+void  PUBLIC  AmiSetByteToLe (void FAR* pAddr_p, BYTE bByteVal_p)
+{
+
+   *(BYTE FAR*)pAddr_p = bByteVal_p;
+
+}
+*/
+
+
+
+//------------< write WORD in little endian >--------------------------
+
+INLINE_FUNCTION void  PUBLIC  AmiSetWordToLe (void FAR* pAddr_p, WORD wWordVal_p)
+{
+twStruct FAR*  pwStruct;
+
+   pwStruct = (twStruct FAR*)pAddr_p;
+   pwStruct->m_wWord = wWordVal_p;
+
+}
+
+
+
+//------------< write DWORD in little endian >-------------------------
+
+INLINE_FUNCTION void  PUBLIC  AmiSetDwordToLe (void FAR* pAddr_p, DWORD dwDwordVal_p)
+{
+tdwStruct FAR*  pdwStruct;
+
+   pdwStruct = (tdwStruct FAR*)pAddr_p;
+   pdwStruct->m_dwDword = dwDwordVal_p;
+
+}
+
+
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetXXXFromBe()
+//
+// Description: reads the specified value from the absolute address in
+//              big endian
+//
+// Parameters:  pAddr_p                 = absolute address
+//
+// Returns:     XXX                     = value
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+//------------< read BYTE in big endian >---------------------------
+/*
+BYTE  PUBLIC  AmiGetByteFromBe (void FAR* pAddr_p)
+{
+
+   return ( *(BYTE FAR*)pAddr_p );
+
+}
+*/
+
+
+
+//------------< read WORD in big endian >---------------------------
+
+INLINE_FUNCTION WORD  PUBLIC  AmiGetWordFromBe (void FAR* pAddr_p)
+{
+twStruct FAR*  pwStruct;
+twStruct wValue;
+
+   pwStruct = (twStruct FAR*)pAddr_p;
+
+   wValue.m_wWord   = (WORD)((pwStruct->m_wWord & 0x00FF) << 8); //LSB to MSB
+   wValue.m_wWord  |= (WORD)((pwStruct->m_wWord & 0xFF00) >> 8); //MSB to LSB
+
+   return ( wValue.m_wWord );
+
+}
+
+
+
+
+//------------< read DWORD in big endian >--------------------------
+
+INLINE_FUNCTION DWORD  PUBLIC  AmiGetDwordFromBe (void FAR* pAddr_p)
+{
+tdwStruct FAR*  pdwStruct;
+tdwStruct dwValue;
+
+   pdwStruct = (tdwStruct FAR*)pAddr_p;
+
+   dwValue.m_dwDword = ((pdwStruct->m_dwDword & 0x000000FF)<<24); //LSB to MSB
+   dwValue.m_dwDword|= ((pdwStruct->m_dwDword & 0x0000FF00)<<8);
+   dwValue.m_dwDword|= ((pdwStruct->m_dwDword & 0x00FF0000)>>8 );
+   dwValue.m_dwDword|= ((pdwStruct->m_dwDword & 0xFF000000)>>24); //MSB to LSB
+
+   return ( dwValue.m_dwDword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetXXXFromLe()
+//
+// Description: reads the specified value from the absolute address in
+//              little endian
+//
+// Parameters:  pAddr_p                 = absolute address
+//
+// Returns:     XXX                     = value
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+//------------< read BYTE in little endian >---------------------------
+/*
+BYTE  PUBLIC  AmiGetByteFromLe (void FAR* pAddr_p)
+{
+
+   return ( *(BYTE FAR*)pAddr_p );
+
+}
+*/
+
+
+
+//------------< read WORD in little endian >---------------------------
+
+INLINE_FUNCTION WORD  PUBLIC  AmiGetWordFromLe (void FAR* pAddr_p)
+{
+twStruct FAR*  pwStruct;
+
+   pwStruct = (twStruct FAR*)pAddr_p;
+   return ( pwStruct->m_wWord );
+
+}
+
+
+
+
+//------------< read DWORD in little endian >--------------------------
+
+INLINE_FUNCTION DWORD  PUBLIC  AmiGetDwordFromLe (void FAR* pAddr_p)
+{
+tdwStruct FAR*  pdwStruct;
+
+   pdwStruct = (tdwStruct FAR*)pAddr_p;
+   return ( pdwStruct->m_dwDword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetDword24ToBe()
+//
+// Description: sets a 24 bit value to a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              dwDwordVal_p    = value to set
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetDword24ToBe (void FAR* pAddr_p, DWORD dwDwordVal_p)
+{
+
+    ((BYTE FAR*) pAddr_p)[0] = ((BYTE FAR*) &dwDwordVal_p)[2];
+    ((BYTE FAR*) pAddr_p)[1] = ((BYTE FAR*) &dwDwordVal_p)[1];
+    ((BYTE FAR*) pAddr_p)[2] = ((BYTE FAR*) &dwDwordVal_p)[0];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetDword24ToLe()
+//
+// Description: sets a 24 bit value to a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              dwDwordVal_p    = value to set
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetDword24ToLe (void FAR* pAddr_p, DWORD dwDwordVal_p)
+{
+
+    ((BYTE FAR*) pAddr_p)[0] = ((BYTE FAR*) &dwDwordVal_p)[0];
+    ((BYTE FAR*) pAddr_p)[1] = ((BYTE FAR*) &dwDwordVal_p)[1];
+    ((BYTE FAR*) pAddr_p)[2] = ((BYTE FAR*) &dwDwordVal_p)[2];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetDword24FromBe()
+//
+// Description: reads a 24 bit value from a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      DWORD           = read value
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromBe (void FAR* pAddr_p)
+{
+
+tdwStruct      dwStruct;
+
+    dwStruct.m_dwDword  = AmiGetDwordFromBe (pAddr_p);
+    dwStruct.m_dwDword >>= 8;
+
+    return ( dwStruct.m_dwDword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetDword24FromLe()
+//
+// Description: reads a 24 bit value from a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      DWORD           = read value
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromLe (void FAR* pAddr_p)
+{
+
+tdwStruct      dwStruct;
+
+    dwStruct.m_dwDword  = AmiGetDwordFromLe (pAddr_p);
+    dwStruct.m_dwDword &= 0x00FFFFFF;
+
+    return ( dwStruct.m_dwDword );
+
+}
+
+
+//#ifdef USE_VAR64
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword64ToBe()
+//
+// Description: sets a 64 bit value to a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword64ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((BYTE FAR*) pAddr_p)[0] = ((BYTE FAR*) &qwQwordVal_p)[7];
+    ((BYTE FAR*) pAddr_p)[1] = ((BYTE FAR*) &qwQwordVal_p)[6];
+    ((BYTE FAR*) pAddr_p)[2] = ((BYTE FAR*) &qwQwordVal_p)[5];
+    ((BYTE FAR*) pAddr_p)[3] = ((BYTE FAR*) &qwQwordVal_p)[4];
+    ((BYTE FAR*) pAddr_p)[4] = ((BYTE FAR*) &qwQwordVal_p)[3];
+    ((BYTE FAR*) pAddr_p)[5] = ((BYTE FAR*) &qwQwordVal_p)[2];
+    ((BYTE FAR*) pAddr_p)[6] = ((BYTE FAR*) &qwQwordVal_p)[1];
+    ((BYTE FAR*) pAddr_p)[7] = ((BYTE FAR*) &qwQwordVal_p)[0];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword64ToLe()
+//
+// Description: sets a 64 bit value to a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword64ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+QWORD FAR* pqwDst;
+
+    pqwDst  = (QWORD FAR*) pAddr_p;
+    *pqwDst = qwQwordVal_p;
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword64FromBe()
+//
+// Description: reads a 64 bit value from a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromBe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    ((BYTE FAR*) &qwStruct.m_qwQword)[0] = ((BYTE FAR*) pAddr_p)[7];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[1] = ((BYTE FAR*) pAddr_p)[6];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[2] = ((BYTE FAR*) pAddr_p)[5];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[3] = ((BYTE FAR*) pAddr_p)[4];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[4] = ((BYTE FAR*) pAddr_p)[3];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[5] = ((BYTE FAR*) pAddr_p)[2];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[6] = ((BYTE FAR*) pAddr_p)[1];
+    ((BYTE FAR*) &qwStruct.m_qwQword)[7] = ((BYTE FAR*) pAddr_p)[0];
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword64FromLe()
+//
+// Description: reads a 64 bit value from a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromLe (void FAR* pAddr_p)
+{
+
+tqwStruct FAR* pqwStruct;
+tqwStruct      qwStruct;
+
+    pqwStruct = (tqwStruct FAR*) pAddr_p;
+    qwStruct.m_qwQword = pqwStruct->m_qwQword;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword40ToBe()
+//
+// Description: sets a 40 bit value to a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword40ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((BYTE FAR*) pAddr_p)[0] = ((BYTE FAR*) &qwQwordVal_p)[4];
+    ((BYTE FAR*) pAddr_p)[1] = ((BYTE FAR*) &qwQwordVal_p)[3];
+    ((BYTE FAR*) pAddr_p)[2] = ((BYTE FAR*) &qwQwordVal_p)[2];
+    ((BYTE FAR*) pAddr_p)[3] = ((BYTE FAR*) &qwQwordVal_p)[1];
+    ((BYTE FAR*) pAddr_p)[4] = ((BYTE FAR*) &qwQwordVal_p)[0];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword40ToLe()
+//
+// Description: sets a 40 bit value to a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword40ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((DWORD FAR*) pAddr_p)[0] = ((DWORD FAR*) &qwQwordVal_p)[0];
+    ((BYTE  FAR*) pAddr_p)[4] = ((BYTE  FAR*) &qwQwordVal_p)[4];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword40FromBe()
+//
+// Description: reads a 40 bit value from a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromBe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    qwStruct.m_qwQword  = AmiGetQword64FromBe (pAddr_p);
+    qwStruct.m_qwQword >>= 24;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword40FromLe()
+//
+// Description: reads a 40 bit value from a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromLe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    qwStruct.m_qwQword  = AmiGetQword64FromLe (pAddr_p);
+    qwStruct.m_qwQword &= 0x000000FFFFFFFFFFLL;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword48ToBe()
+//
+// Description: sets a 48 bit value to a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword48ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((BYTE FAR*) pAddr_p)[0] = ((BYTE FAR*) &qwQwordVal_p)[5];
+    ((BYTE FAR*) pAddr_p)[1] = ((BYTE FAR*) &qwQwordVal_p)[4];
+    ((BYTE FAR*) pAddr_p)[2] = ((BYTE FAR*) &qwQwordVal_p)[3];
+    ((BYTE FAR*) pAddr_p)[3] = ((BYTE FAR*) &qwQwordVal_p)[2];
+    ((BYTE FAR*) pAddr_p)[4] = ((BYTE FAR*) &qwQwordVal_p)[1];
+    ((BYTE FAR*) pAddr_p)[5] = ((BYTE FAR*) &qwQwordVal_p)[0];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword48ToLe()
+//
+// Description: sets a 48 bit value to a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword48ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((DWORD FAR*) pAddr_p)[0] = ((DWORD FAR*) &qwQwordVal_p)[0];
+    ((WORD  FAR*) pAddr_p)[2] = ((WORD  FAR*) &qwQwordVal_p)[2];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword48FromBe()
+//
+// Description: reads a 48 bit value from a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromBe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    qwStruct.m_qwQword  = AmiGetQword64FromBe (pAddr_p);
+    qwStruct.m_qwQword >>= 16;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword48FromLe()
+//
+// Description: reads a 48 bit value from a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromLe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    qwStruct.m_qwQword  = AmiGetQword64FromLe (pAddr_p);
+    qwStruct.m_qwQword &= 0x0000FFFFFFFFFFFFLL;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword56ToBe()
+//
+// Description: sets a 56 bit value to a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword56ToBe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((BYTE FAR*) pAddr_p)[0] = ((BYTE FAR*) &qwQwordVal_p)[6];
+    ((BYTE FAR*) pAddr_p)[1] = ((BYTE FAR*) &qwQwordVal_p)[5];
+    ((BYTE FAR*) pAddr_p)[2] = ((BYTE FAR*) &qwQwordVal_p)[4];
+    ((BYTE FAR*) pAddr_p)[3] = ((BYTE FAR*) &qwQwordVal_p)[3];
+    ((BYTE FAR*) pAddr_p)[4] = ((BYTE FAR*) &qwQwordVal_p)[2];
+    ((BYTE FAR*) pAddr_p)[5] = ((BYTE FAR*) &qwQwordVal_p)[1];
+    ((BYTE FAR*) pAddr_p)[6] = ((BYTE FAR*) &qwQwordVal_p)[0];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetQword56ToLe()
+//
+// Description: sets a 56 bit value to a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              qwQwordVal_p    = quadruple word value
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetQword56ToLe (void FAR* pAddr_p, QWORD qwQwordVal_p)
+{
+
+    ((DWORD FAR*) pAddr_p)[0] = ((DWORD FAR*) &qwQwordVal_p)[0];
+    ((WORD  FAR*) pAddr_p)[2] = ((WORD  FAR*) &qwQwordVal_p)[2];
+    ((BYTE  FAR*) pAddr_p)[6] = ((BYTE  FAR*) &qwQwordVal_p)[6];
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword56FromBe()
+//
+// Description: reads a 56 bit value from a buffer in big endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromBe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    qwStruct.m_qwQword  = AmiGetQword64FromBe (pAddr_p);
+    qwStruct.m_qwQword >>= 8;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetQword56FromLe()
+//
+// Description: reads a 56 bit value from a buffer in little endian
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//
+// Return:      QWORD
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromLe (void FAR* pAddr_p)
+{
+
+tqwStruct      qwStruct;
+
+    qwStruct.m_qwQword  = AmiGetQword64FromLe (pAddr_p);
+    qwStruct.m_qwQword &= 0x00FFFFFFFFFFFFFFLL;
+
+    return ( qwStruct.m_qwQword );
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiSetTimeOfDay()
+//
+// Description: sets a TIME_OF_DAY (CANopen) value to a buffer
+//
+// Parameters:  pAddr_p         = pointer to destination buffer
+//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay (void FAR* pAddr_p, tTimeOfDay FAR* pTimeOfDay_p)
+{
+
+    AmiSetDwordToLe (((BYTE FAR*) pAddr_p),     pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
+    AmiSetWordToLe  (((BYTE FAR*) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
+
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AmiGetTimeOfDay()
+//
+// Description: reads a TIME_OF_DAY (CANopen) value from a buffer
+//
+// Parameters:  pAddr_p         = pointer to source buffer
+//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
+//
+// Return:      void
+//
+// State:       not tested
+//
+//---------------------------------------------------------------------------
+
+INLINE_FUNCTION void PUBLIC AmiGetTimeOfDay (void FAR* pAddr_p, tTimeOfDay FAR* pTimeOfDay_p)
+{
+
+    pTimeOfDay_p->m_dwMs  = AmiGetDwordFromLe (((BYTE FAR*) pAddr_p)) & 0x0FFFFFFF;
+    pTimeOfDay_p->m_wDays = AmiGetWordFromLe  (((BYTE FAR*) pAddr_p) + 4);
+
+}
+
+
+#endif
+
+
+
+// EOF
+
+// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
+// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
+
diff --git a/drivers/staging/epl/demo_main.c b/drivers/staging/epl/demo_main.c
new file mode 100644 (file)
index 0000000..24e4b71
--- /dev/null
@@ -0,0 +1,937 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  demoapplication for EPL MN (with SDO over UDP)
+                under Linux on X86 with RTL8139 Ethernet controller
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: demo_main.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.10 $  $Date: 2008/11/19 18:11:43 $
+
+                $State: Exp $
+
+                Build Environment:
+                GCC
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/09/01 d.k.:   start of implementation
+
+****************************************************************************/
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/sched.h>
+#include <linux/kmod.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+
+
+#include "Epl.h"
+#include "proc_fs.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+    // remove ("make invisible") obsolete symbols for kernel versions 2.6
+    // and higher
+    #define MOD_INC_USE_COUNT
+    #define MOD_DEC_USE_COUNT
+    #define EXPORT_NO_SYMBOLS
+#else
+    #error "This driver needs a 2.6.x kernel or higher"
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+// Metainformation
+MODULE_LICENSE("Dual BSD/GPL");
+#ifdef MODULE_AUTHOR
+    MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
+    MODULE_DESCRIPTION("EPL MN demo");
+#endif
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+
+// TracePoint support for realtime-debugging
+#ifdef _DBG_TRACE_POINTS_
+    void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
+#else
+    #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+#endif
+
+#define NODEID      0xF0 //=> MN
+#define CYCLE_LEN   5000 // [us]
+#define IP_ADDR     0xc0a86401  // 192.168.100.1
+#define SUBNET_MASK 0xFFFFFF00  // 255.255.255.0
+#define HOSTNAME    "SYS TEC electronic EPL Stack    "
+#define IF_ETH      EPL_VETH_NAME
+
+
+// LIGHT EFFECT
+#define DEFAULT_MAX_CYCLE_COUNT 20  // 6 is very fast
+#define APP_DEFAULT_MODE        0x01
+#define APP_LED_COUNT           5       // number of LEDs in one row
+#define APP_LED_MASK            ((1 << APP_LED_COUNT) - 1)
+#define APP_DOUBLE_LED_MASK     ((1 << (APP_LED_COUNT * 2)) - 1)
+#define APP_MODE_COUNT          5
+#define APP_MODE_MASK           ((1 << APP_MODE_COUNT) - 1)
+
+
+//---------------------------------------------------------------------------
+// local types
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// modul globale vars
+//---------------------------------------------------------------------------
+
+CONST BYTE abMacAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+BYTE    bVarIn1_l;
+BYTE    bVarOut1_l;
+BYTE    bVarOut1Old_l;
+BYTE    bModeSelect_l;      // state of the pushbuttons to select the mode
+BYTE    bSpeedSelect_l;     // state of the pushbuttons to increase/decrease the speed
+BYTE    bSpeedSelectOld_l;  // old state of the pushbuttons
+DWORD   dwLeds_l;           // current state of all LEDs
+BYTE    bLedsRow1_l;        // current state of the LEDs in row 1
+BYTE    bLedsRow2_l;        // current state of the LEDs in row 2
+BYTE    abSelect_l[3];      // pushbuttons from CNs
+
+DWORD   dwMode_l;           // current mode
+int     iCurCycleCount_l;   // current cycle count
+int     iMaxCycleCount_l;   // maximum cycle count (i.e. number of cycles until next light movement step)
+int     iToggle;            // indicates the light movement direction
+
+BYTE    abDomain_l[3000];
+
+static wait_queue_head_t    WaitQueueShutdown_g; // wait queue for tEplNmtEventSwitchOff
+static atomic_t             AtomicShutdown_g = ATOMIC_INIT(FALSE);
+
+static DWORD    dw_le_CycleLen_g;
+
+static uint uiNodeId_g = EPL_C_ADR_INVALID;
+module_param_named(nodeid, uiNodeId_g, uint, 0);
+
+static uint uiCycleLen_g = CYCLE_LEN;
+module_param_named(cyclelen, uiCycleLen_g, uint, 0);
+
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+// This function is the entry point for your object dictionary. It is defined
+// in OBJDICT.C by define EPL_OBD_INIT_RAM_NAME. Use this function name to define
+// this function prototype here. If you want to use more than one Epl
+// instances then the function name of each object dictionary has to differ.
+
+tEplKernel PUBLIC  EplObdInitRam (tEplObdInitParam MEM* pInitParam_p);
+
+tEplKernel PUBLIC AppCbEvent(
+    tEplApiEventType        EventType_p,   // IN: event type (enum)
+    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
+    void GENERIC*           pUserArg_p);
+
+tEplKernel PUBLIC AppCbSync(void);
+
+static int  __init  EplLinInit (void);
+static void __exit  EplLinExit (void);
+
+//---------------------------------------------------------------------------
+//  Kernel Module specific Data Structures
+//---------------------------------------------------------------------------
+
+EXPORT_NO_SYMBOLS;
+
+
+//module_init(EplLinInit);
+//module_exit(EplLinExit);
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:
+//
+// Description:
+//
+//
+//
+// Parameters:
+//
+//
+// Returns:
+//
+//
+// State:
+//
+//---------------------------------------------------------------------------
+static  int  __init  EplLinInit (void)
+{
+tEplKernel          EplRet;
+int                 iRet;
+static tEplApiInitParam EplApiInitParam = {0};
+char*               sHostname = HOSTNAME;
+char*               argv[4], *envp[3];
+char                sBuffer[16];
+unsigned int        uiVarEntries;
+tEplObdSize         ObdSize;
+
+    atomic_set(&AtomicShutdown_g, TRUE);
+
+    // get node ID from insmod command line
+    EplApiInitParam.m_uiNodeId = uiNodeId_g;
+
+    if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID)
+    {   // invalid node ID set
+        // set default node ID
+        EplApiInitParam.m_uiNodeId = NODEID;
+    }
+
+    uiNodeId_g = EplApiInitParam.m_uiNodeId;
+
+    // calculate IP address
+    EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;
+
+    EplApiInitParam.m_fAsyncOnly = FALSE;
+
+    EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam);
+    EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress));
+//    EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId;
+    EplApiInitParam.m_dwFeatureFlags = -1;
+    EplApiInitParam.m_dwCycleLen = uiCycleLen_g;     // required for error detection
+    EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
+    EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const
+    EplApiInitParam.m_dwPresMaxLatency = 50000;  // const; only required for IdentRes
+    EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes)
+    EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes)
+    EplApiInitParam.m_dwAsndMaxLatency = 150000;   // const; only required for IdentRes
+    EplApiInitParam.m_uiMultiplCycleCnt = 0;  // required for error detection
+    EplApiInitParam.m_uiAsyncMtu = 1500;         // required to set up max frame size
+    EplApiInitParam.m_uiPrescaler = 2;         // required for sync
+    EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
+    EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
+    EplApiInitParam.m_dwWaitSocPreq = 150000;
+    EplApiInitParam.m_dwDeviceType = -1;              // NMT_DeviceType_U32
+    EplApiInitParam.m_dwVendorId = -1;                // NMT_IdentityObject_REC.VendorId_U32
+    EplApiInitParam.m_dwProductCode = -1;             // NMT_IdentityObject_REC.ProductCode_U32
+    EplApiInitParam.m_dwRevisionNumber = -1;          // NMT_IdentityObject_REC.RevisionNo_U32
+    EplApiInitParam.m_dwSerialNumber = -1;            // NMT_IdentityObject_REC.SerialNo_U32
+    EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
+    EplApiInitParam.m_dwDefaultGateway = 0;
+    EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname));
+
+    // currently unset parameters left at default value 0
+    //EplApiInitParam.m_qwVendorSpecificExt1;
+    //EplApiInitParam.m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+    //EplApiInitParam.m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+    //EplApiInitParam.m_dwApplicationSwDate;       // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+    //EplApiInitParam.m_dwApplicationSwTime;       // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+    //EplApiInitParam.m_abVendorSpecificExt2[48];
+
+    // set callback functions
+    EplApiInitParam.m_pfnCbEvent = AppCbEvent;
+    EplApiInitParam.m_pfnCbSync = AppCbSync;
+
+
+    printk("\n\n Hello, I'm a simple POWERLINK node running as %s!\n  (build: %s / %s)\n\n",
+            (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ?
+                "Managing Node" : "Controlled Node"),
+            __DATE__, __TIME__);
+
+    // initialize the Linux a wait queue for shutdown of this module
+    init_waitqueue_head(&WaitQueueShutdown_g);
+
+    // initialize the procfs device
+    EplRet = EplLinProcInit();
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // initialize POWERLINK stack
+    EplRet = EplApiInitialize(&EplApiInitParam);
+    if(EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // link process variables used by CN to object dictionary
+    ObdSize = sizeof(bVarIn1_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x6000, &bVarIn1_l, &uiVarEntries, &ObdSize, 0x01);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    ObdSize = sizeof(bVarOut1_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x6200, &bVarOut1_l, &uiVarEntries, &ObdSize, 0x01);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    // link process variables used by MN to object dictionary
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    ObdSize = sizeof(bLedsRow1_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x2000, &bLedsRow1_l, &uiVarEntries, &ObdSize, 0x01);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    ObdSize = sizeof(bLedsRow2_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x2000, &bLedsRow2_l, &uiVarEntries, &ObdSize, 0x02);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    ObdSize = sizeof(bSpeedSelect_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x2000, &bSpeedSelect_l, &uiVarEntries, &ObdSize, 0x03);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    ObdSize = sizeof(bSpeedSelectOld_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x2000, &bSpeedSelectOld_l, &uiVarEntries, &ObdSize, 0x04);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+
+    ObdSize = sizeof(abSelect_l[0]);
+    uiVarEntries = sizeof(abSelect_l);
+    EplRet = EplApiLinkObject(0x2200, &abSelect_l[0], &uiVarEntries, &ObdSize, 0x01);
+    if (EplRet != kEplSuccessful)
+    {
+        goto Exit;
+    }
+#endif
+
+    // link a DOMAIN to object 0x6100, but do not exit, if it is missing
+    ObdSize = sizeof(abDomain_l);
+    uiVarEntries = 1;
+    EplRet = EplApiLinkObject(0x6100, &abDomain_l, &uiVarEntries, &ObdSize, 0x00);
+    if (EplRet != kEplSuccessful)
+    {
+        printk("EplApiLinkObject(0x6100): returns 0x%X\n", EplRet);
+    }
+
+    // reset old process variables
+    bVarOut1Old_l = 0;
+    bSpeedSelectOld_l = 0;
+    dwMode_l = APP_DEFAULT_MODE;
+    iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
+
+
+    // configure IP address of virtual network interface
+    // for TCP/IP communication over the POWERLINK network
+    sprintf(sBuffer, "%lu.%lu.%lu.%lu", (EplApiInitParam.m_dwIpAddress >> 24), ((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF), ((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF), (EplApiInitParam.m_dwIpAddress & 0xFF));
+    /* set up a minimal environment */
+    iRet = 0;
+    envp[iRet++] = "HOME=/";
+    envp[iRet++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+    envp[iRet] = NULL;
+
+    /* set up the argument list */
+    iRet = 0;
+    argv[iRet++] = "/sbin/ifconfig";
+    argv[iRet++] = IF_ETH;
+    argv[iRet++] = sBuffer;
+    argv[iRet] = NULL;
+
+    /* call ifconfig to configure the virtual network interface */
+    iRet = call_usermodehelper(argv[0], argv, envp, 1);
+    printk("ifconfig %s %s returned %d\n", argv[1], argv[2], iRet);
+
+    // start the NMT state machine
+    EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
+    atomic_set(&AtomicShutdown_g, FALSE);
+
+Exit:
+    printk("EplLinInit(): returns 0x%X\n", EplRet);
+    return EplRet;
+}
+
+static  void  __exit  EplLinExit (void)
+{
+tEplKernel          EplRet;
+
+    // halt the NMT state machine
+    // so the processing of POWERLINK frames stops
+    EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
+
+    // wait until NMT state machine is shut down
+    wait_event_interruptible(WaitQueueShutdown_g,
+                                    (atomic_read(&AtomicShutdown_g) == TRUE));
+/*    if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL))
+    {   // waiting was interrupted by signal or application called wrong function
+        EplRet = kEplShutdown;
+    }*/
+    // delete instance for all modules
+    EplRet = EplApiShutdown();
+    printk("EplApiShutdown():  0x%X\n", EplRet);
+
+    // deinitialize proc fs
+    EplRet = EplLinProcFree();
+    printk("EplLinProcFree():        0x%X\n", EplRet);
+
+}
+
+
+//=========================================================================//
+//                                                                         //
+//          P R I V A T E   F U N C T I O N S                              //
+//                                                                         //
+//=========================================================================//
+
+//---------------------------------------------------------------------------
+//
+// Function:    AppCbEvent
+//
+// Description: event callback function called by EPL API layer within
+//              user part (low priority).
+//
+// Parameters:  EventType_p     = event type
+//              pEventArg_p     = pointer to union, which describes
+//                                the event in detail
+//              pUserArg_p      = user specific argument
+//
+// Returns:     tEplKernel      = error code,
+//                                kEplSuccessful = no error
+//                                kEplReject = reject further processing
+//                                otherwise = post error event to API layer
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC AppCbEvent(
+    tEplApiEventType        EventType_p,   // IN: event type (enum)
+    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
+    void GENERIC*           pUserArg_p)
+{
+tEplKernel          EplRet = kEplSuccessful;
+
+    // check if NMT_GS_OFF is reached
+    switch (EventType_p)
+    {
+        case kEplApiEventNmtStateChange:
+        {
+            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
+            {
+                case kEplNmtGsOff:
+                {   // NMT state machine was shut down,
+                    // because of user signal (CTRL-C) or critical EPL stack error
+                    // -> also shut down EplApiProcess() and main()
+                    EplRet = kEplShutdown;
+
+                    printk("AppCbEvent(kEplNmtGsOff) originating event = 0x%X\n", pEventArg_p->m_NmtStateChange.m_NmtEvent);
+
+                    // wake up EplLinExit()
+                    atomic_set(&AtomicShutdown_g, TRUE);
+                    wake_up_interruptible(&WaitQueueShutdown_g);
+                    break;
+                }
+
+                case kEplNmtGsResetCommunication:
+                {
+                DWORD   dwBuffer;
+
+                    // configure OD for MN in state ResetComm after reseting the OD
+                    // TODO: setup your own network configuration here
+                    dwBuffer = (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS);    // 0x00000003L
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x01, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x02, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x03, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x04, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x05, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x06, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x07, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x08, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x20, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0xFE, &dwBuffer, 4);
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwBuffer, 4);
+
+//                    dwBuffer |= EPL_NODEASSIGN_MANDATORY_CN;    // 0x0000000BL
+//                    EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwBuffer, 4);
+                    dwBuffer = (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS);       // 0x00010001L
+                    EplRet = EplApiWriteLocalObject(0x1F81, 0xF0, &dwBuffer, 4);
+
+                    // continue
+                }
+
+                case kEplNmtGsResetConfiguration:
+                {
+                unsigned int uiSize;
+
+                    // fetch object 0x1006 NMT_CycleLen_U32 from local OD (in little endian byte order)
+                    // for configuration of remote CN
+                    uiSize = 4;
+                    EplRet = EplApiReadObject(NULL, 0, 0x1006, 0x00, &dw_le_CycleLen_g, &uiSize, kEplSdoTypeAsnd, NULL);
+                    if (EplRet != kEplSuccessful)
+                    {   // local OD access failed
+                        break;
+                    }
+
+                    // continue
+                }
+
+                case kEplNmtMsPreOperational1:
+                {
+                    printk("AppCbEvent(0x%X) originating event = 0x%X\n",
+                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
+                           pEventArg_p->m_NmtStateChange.m_NmtEvent);
+
+                    // continue
+                }
+
+                case kEplNmtGsInitialising:
+                case kEplNmtGsResetApplication:
+                case kEplNmtMsNotActive:
+                case kEplNmtCsNotActive:
+                case kEplNmtCsPreOperational1:
+                {
+                    break;
+                }
+
+                case kEplNmtCsOperational:
+                case kEplNmtMsOperational:
+                {
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+
+/*
+            switch (pEventArg_p->m_NmtStateChange.m_NmtEvent)
+            {
+                case kEplNmtEventSwReset:
+                case kEplNmtEventResetNode:
+                case kEplNmtEventResetCom:
+                case kEplNmtEventResetConfig:
+                case kEplNmtEventInternComError:
+                case kEplNmtEventNmtCycleError:
+                {
+                    printk("AppCbEvent(0x%X) originating event = 0x%X\n",
+                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
+                           pEventArg_p->m_NmtStateChange.m_NmtEvent);
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+*/
+            break;
+        }
+
+        case kEplApiEventCriticalError:
+        case kEplApiEventWarning:
+        {   // error or warning occured within the stack or the application
+            // on error the API layer stops the NMT state machine
+
+            printk("AppCbEvent(Err/Warn): Source=%02X EplError=0x%03X", pEventArg_p->m_InternalError.m_EventSource, pEventArg_p->m_InternalError.m_EplError);
+            // check additional argument
+            switch (pEventArg_p->m_InternalError.m_EventSource)
+            {
+                case kEplEventSourceEventk:
+                case kEplEventSourceEventu:
+                {   // error occured within event processing
+                    // either in kernel or in user part
+                    printk(" OrgSource=%02X\n", pEventArg_p->m_InternalError.m_Arg.m_EventSource);
+                    break;
+                }
+
+                case kEplEventSourceDllk:
+                {   // error occured within the data link layer (e.g. interrupt processing)
+                    // the DWORD argument contains the DLL state and the NMT event
+                    printk(" val=%lX\n", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
+                    break;
+                }
+
+                default:
+                {
+                    printk("\n");
+                    break;
+                }
+            }
+            break;
+        }
+
+        case kEplApiEventNode:
+        {
+//            printk("AppCbEvent(Node): Source=%02X EplError=0x%03X", pEventArg_p->m_InternalError.m_EventSource, pEventArg_p->m_InternalError.m_EplError);
+            // check additional argument
+            switch (pEventArg_p->m_Node.m_NodeEvent)
+            {
+                case kEplNmtNodeEventCheckConf:
+                {
+                tEplSdoComConHdl SdoComConHdl;
+                    // update object 0x1006 on CN
+                    EplRet = EplApiWriteObject(&SdoComConHdl, pEventArg_p->m_Node.m_uiNodeId, 0x1006, 0x00, &dw_le_CycleLen_g, 4, kEplSdoTypeAsnd, NULL);
+                    if (EplRet == kEplApiTaskDeferred)
+                    {   // SDO transfer started
+                        EplRet = kEplReject;
+                    }
+                    else if (EplRet == kEplSuccessful)
+                    {   // local OD access (should not occur)
+                        printk("AppCbEvent(Node) write to local OD\n");
+                    }
+                    else
+                    {   // error occured
+                        TGT_DBG_SIGNAL_TRACE_POINT(1);
+
+                        EplRet = EplApiFreeSdoChannel(SdoComConHdl);
+                        SdoComConHdl = 0;
+
+                        EplRet = EplApiWriteObject(&SdoComConHdl, pEventArg_p->m_Node.m_uiNodeId, 0x1006, 0x00, &dw_le_CycleLen_g, 4, kEplSdoTypeAsnd, NULL);
+                        if (EplRet == kEplApiTaskDeferred)
+                        {   // SDO transfer started
+                            EplRet = kEplReject;
+                        }
+                        else
+                        {
+                            printk("AppCbEvent(Node): EplApiWriteObject() returned 0x%02X\n", EplRet);
+                        }
+                    }
+
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+            break;
+        }
+
+        case kEplApiEventSdo:
+        {   // SDO transfer finished
+            EplRet = EplApiFreeSdoChannel(pEventArg_p->m_Sdo.m_SdoComConHdl);
+            if (EplRet != kEplSuccessful)
+            {
+                break;
+            }
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+            if (pEventArg_p->m_Sdo.m_SdoComConState == kEplSdoComTransferFinished)
+            {   // continue boot-up of CN with NMT command Reset Configuration
+                EplRet = EplApiMnTriggerStateChange(pEventArg_p->m_Sdo.m_uiNodeId, kEplNmtNodeCommandConfReset);
+            }
+            else
+            {   // indicate configuration error CN
+                EplRet = EplApiMnTriggerStateChange(pEventArg_p->m_Sdo.m_uiNodeId, kEplNmtNodeCommandConfErr);
+            }
+#endif
+
+            break;
+        }
+
+        default:
+            break;
+    }
+
+    return EplRet;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Function:    AppCbSync
+//
+// Description: sync event callback function called by event module within
+//              kernel part (high priority).
+//              This function sets the outputs, reads the inputs and runs
+//              the control loop.
+//
+// Parameters:  void
+//
+// Returns:     tEplKernel      = error code,
+//                                kEplSuccessful = no error
+//                                otherwise = post error event to API layer
+//
+// State:
+//
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC AppCbSync(void)
+{
+tEplKernel          EplRet = kEplSuccessful;
+
+    if (bVarOut1Old_l != bVarOut1_l)
+    {   // output variable has changed
+        bVarOut1Old_l = bVarOut1_l;
+        // set LEDs
+
+//        printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (WORD) bVarIn_l, (WORD) bVarOut_l);
+    }
+    if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID)
+    {
+        bVarIn1_l++;
+    }
+
+    if (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID)
+    {   // we are the master and must run the control loop
+
+        // collect inputs from CNs and own input
+        bSpeedSelect_l = (bVarIn1_l | abSelect_l[0]) & 0x07;
+
+        bModeSelect_l = abSelect_l[1] | abSelect_l[2];
+
+        if ((bModeSelect_l & APP_MODE_MASK) != 0)
+        {
+            dwMode_l = bModeSelect_l & APP_MODE_MASK;
+        }
+
+        iCurCycleCount_l--;
+
+        if (iCurCycleCount_l <= 0)
+        {
+            if ((dwMode_l & 0x01) != 0)
+            {   // fill-up
+                if (iToggle)
+                {
+                    if ((dwLeds_l & APP_DOUBLE_LED_MASK) == 0x00)
+                    {
+                        dwLeds_l = 0x01;
+                    }
+                    else
+                    {
+                        dwLeds_l <<= 1;
+                        dwLeds_l++;
+                        if (dwLeds_l >= APP_DOUBLE_LED_MASK)
+                        {
+                            iToggle = 0;
+                        }
+                    }
+                }
+                else
+                {
+                    dwLeds_l <<= 1;
+                    if ((dwLeds_l & APP_DOUBLE_LED_MASK) == 0x00)
+                    {
+                        iToggle = 1;
+                    }
+                }
+                bLedsRow1_l = (unsigned char) (dwLeds_l & APP_LED_MASK);
+                bLedsRow2_l = (unsigned char) ((dwLeds_l >> APP_LED_COUNT) & APP_LED_MASK);
+            }
+
+            else if ((dwMode_l & 0x02) != 0)
+            {   // running light forward
+                dwLeds_l <<= 1;
+                if ((dwLeds_l > APP_DOUBLE_LED_MASK) || (dwLeds_l == 0x00000000L))
+                {
+                    dwLeds_l = 0x01;
+                }
+                bLedsRow1_l = (unsigned char) (dwLeds_l & APP_LED_MASK);
+                bLedsRow2_l = (unsigned char) ((dwLeds_l >> APP_LED_COUNT) & APP_LED_MASK);
+            }
+
+            else if ((dwMode_l & 0x04) != 0)
+            {   // running light backward
+                dwLeds_l >>= 1;
+                if ((dwLeds_l > APP_DOUBLE_LED_MASK) || (dwLeds_l == 0x00000000L))
+                {
+                    dwLeds_l = 1 << (APP_LED_COUNT * 2);
+                }
+                bLedsRow1_l = (unsigned char) (dwLeds_l & APP_LED_MASK);
+                bLedsRow2_l = (unsigned char) ((dwLeds_l >> APP_LED_COUNT) & APP_LED_MASK);
+            }
+
+            else if ((dwMode_l & 0x08) != 0)
+            {   // Knightrider
+                if (bLedsRow1_l == 0x00)
+                {
+                    bLedsRow1_l = 0x01;
+                    iToggle = 1;
+                }
+                else if (iToggle)
+                {
+                    bLedsRow1_l <<= 1;
+                    if ( bLedsRow1_l >= (1 << (APP_LED_COUNT - 1)) )
+                    {
+                        iToggle = 0;
+                    }
+                }
+                else
+                {
+                    bLedsRow1_l >>= 1;
+                    if( bLedsRow1_l <= 0x01 )
+                    {
+                        iToggle = 1;
+                    }
+                }
+                bLedsRow2_l = bLedsRow1_l;
+            }
+
+            else if ((dwMode_l & 0x10) != 0)
+            {   // Knightrider
+                if ((bLedsRow1_l == 0x00)
+                    || (bLedsRow2_l == 0x00)
+                    || ((bLedsRow2_l & ~APP_LED_MASK) != 0))
+                {
+                    bLedsRow1_l = 0x01;
+                    bLedsRow2_l = (1 << (APP_LED_COUNT - 1));
+                    iToggle = 1;
+                }
+                else if (iToggle)
+                {
+                    bLedsRow1_l <<= 1;
+                    bLedsRow2_l >>= 1;
+                    if ( bLedsRow1_l >= (1 << (APP_LED_COUNT - 1)) )
+                    {
+                        iToggle = 0;
+                    }
+                }
+                else
+                {
+                    bLedsRow1_l >>= 1;
+                    bLedsRow2_l <<= 1;
+                    if ( bLedsRow1_l <= 0x01 )
+                    {
+                        iToggle = 1;
+                    }
+                }
+            }
+
+            // set own output
+            bVarOut1_l = bLedsRow1_l;
+//            bVarOut1_l = (bLedsRow1_l & 0x03) | (bLedsRow2_l << 2);
+
+            // restart cycle counter
+            iCurCycleCount_l = iMaxCycleCount_l;
+        }
+
+        if (bSpeedSelectOld_l == 0)
+        {
+            if ((bSpeedSelect_l & 0x01) != 0)
+            {
+                if (iMaxCycleCount_l < 200)
+                {
+                    iMaxCycleCount_l++;
+                }
+                bSpeedSelectOld_l = bSpeedSelect_l;
+            }
+            else if ((bSpeedSelect_l & 0x02) != 0)
+            {
+                if (iMaxCycleCount_l > 1)
+                {
+                    iMaxCycleCount_l--;
+                }
+                bSpeedSelectOld_l = bSpeedSelect_l;
+            }
+            else if ((bSpeedSelect_l & 0x04) != 0)
+            {
+                iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
+                bSpeedSelectOld_l = bSpeedSelect_l;
+            }
+        }
+        else if (bSpeedSelect_l == 0)
+        {
+            bSpeedSelectOld_l = 0;
+        }
+    }
+
+    TGT_DBG_SIGNAL_TRACE_POINT(1);
+
+    return EplRet;
+}
+
+
+
+// EOF
+
diff --git a/drivers/staging/epl/edrv.h b/drivers/staging/epl/edrv.h
new file mode 100644 (file)
index 0000000..139523c
--- /dev/null
@@ -0,0 +1,183 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  interface for ethernetdriver
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: edrv.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                Dev C++ and GNU-Compiler for m68k
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2005/08/01 m.b.:   start of implementation
+
+****************************************************************************/
+
+#ifndef _EDRV_H_
+#define _EDRV_H_
+
+#include "EplInc.h"
+#include "EplFrame.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+#define MAX_ETH_DATA_SIZE       1500
+#define MIN_ETH_DATA_SIZE         46
+
+#define ETH_HDR_OFFSET          0      // Ethernet header at the top of the frame
+#define ETH_HDR_SIZE   14      // size of Ethernet header
+#define MIN_ETH_SIZE     (MIN_ETH_DATA_SIZE + ETH_HDR_SIZE)    // without CRC
+
+#define ETH_CRC_SIZE    4      // size of Ethernet CRC, i.e. FCS
+
+
+
+//---------------------------------------------------------------------------
+// types
+//---------------------------------------------------------------------------
+
+// position of a buffer in an ethernet-frame
+typedef enum
+{
+    kEdrvBufferFirstInFrame   = 0x01,  // first data buffer in an ethernet frame
+    kEdrvBufferMiddleInFrame  = 0x02,  // a middle data buffer in an ethernet frame
+    kEdrvBufferLastInFrame    = 0x04   // last data buffer in an ethernet frame
+} tEdrvBufferInFrame;
+
+
+// format of a tx-buffer
+typedef struct _tEdrvTxBuffer
+{
+    tEplMsgType     m_EplMsgType;           // IN: type of EPL message, set by calling function
+    unsigned int    m_uiTxMsgLen;           // IN: length of message to be send (set for each transmit call)
+    // ----------------------
+    unsigned int    m_uiBufferNumber;       // OUT: number of the buffer, set by ethernetdriver
+    BYTE  *         m_pbBuffer;             // OUT: pointer to the buffer, set by ethernetdriver
+    tEplNetTime     m_NetTime;              // OUT: Timestamp of end of transmission, set by ethernetdriver
+    // ----------------------
+    unsigned int    m_uiMaxBufferLen;       // IN/OUT: maximum length of the buffer
+} tEdrvTxBuffer;
+
+// format of a rx-buffer
+typedef struct _tEdrvRxBuffer
+{
+    tEdrvBufferInFrame m_BufferInFrame;   // OUT position of received buffer in an ethernet-frame
+    unsigned int       m_uiRxMsgLen;        // OUT: length of received buffer (without CRC)
+    BYTE  *            m_pbBuffer;          // OUT: pointer to the buffer, set by ethernetdriver
+    tEplNetTime        m_NetTime;           // OUT: Timestamp of end of receiption
+
+} tEdrvRxBuffer;
+
+
+
+//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, tBufferDescr * pbBuffer_p);
+//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, BYTE * pbEthernetData_p, WORD wDataLen_p);
+typedef void (*tEdrvRxHandler) (tEdrvRxBuffer * pRxBuffer_p);
+typedef void (*tEdrvTxHandler) (tEdrvTxBuffer * pTxBuffer_p);
+
+
+// format of init structure
+typedef struct
+{
+    BYTE            m_abMyMacAddr[6];       // the own MAC address
+
+//    BYTE            m_bNoOfRxBuffDescr;     // number of entries in rx bufferdescriptor table
+//    tBufferDescr *  m_pRxBuffDescrTable;    // rx bufferdescriptor table
+//    WORD            m_wRxBufferSize;        // size of the whole rx buffer
+
+    tEdrvRxHandler  m_pfnRxHandler;
+    tEdrvTxHandler  m_pfnTxHandler;
+
+} tEdrvInitParam;
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+tEplKernel EdrvInit                   (tEdrvInitParam* pEdrvInitParam_p);
+
+tEplKernel EdrvShutdown               (void);
+
+tEplKernel EdrvDefineRxMacAddrEntry   (BYTE * pbMacAddr_p);
+tEplKernel EdrvUndefineRxMacAddrEntry (BYTE * pbMacAddr_p);
+
+//tEplKernel EdrvDefineUnicastEntry     (BYTE * pbUCEntry_p);
+//tEplKernel EdrvUndfineUnicastEntry    (BYTE * pbUCEntry_p);
+
+tEplKernel EdrvAllocTxMsgBuffer       (tEdrvTxBuffer * pBuffer_p);
+tEplKernel EdrvReleaseTxMsgBuffer     (tEdrvTxBuffer * pBuffer_p);
+
+//tEplKernel EdrvWriteMsg               (tBufferDescr * pbBuffer_p);
+tEplKernel EdrvSendTxMsg              (tEdrvTxBuffer * pBuffer_p);
+tEplKernel EdrvTxMsgReady              (tEdrvTxBuffer * pBuffer_p);
+tEplKernel EdrvTxMsgStart              (tEdrvTxBuffer * pBuffer_p);
+
+//tEplKernel EdrvReadMsg                (void);
+
+// interrupt handler called by target specific interrupt handler
+void        EdrvInterruptHandler       (void);
+
+
+
+#endif  // #ifndef _EDRV_H_
+
+
diff --git a/drivers/staging/epl/global.h b/drivers/staging/epl/global.h
new file mode 100644 (file)
index 0000000..797e1f2
--- /dev/null
@@ -0,0 +1,1468 @@
+/****************************************************************************
+
+    global project definition file
+
+    12.06.1998   -rs
+    11.02.2002   r.d. Erweiterungen, Ergaenzungen
+    20.08.2002   SYS TEC electronic -as
+                 Definition Schluesselwort 'GENERIC'
+                 fuer das Erzeugen von Generic Pointer
+    28.08.2002   r.d. erweiterter SYS TEC Debug Code
+    16.09.2002   r.d. komplette Uebersetzung in Englisch
+    11.04.2003   f.j. Ergaenzung fuer Mitsubishi NC30 Compiler
+    17.06.2003   -rs  Definition von Basistypen in <#ifndef _WINDEF_> gesetzt
+    16.04.2004   r.d. Ergaenzung fuer Borland C++ Builder
+    30.08.2004   -rs  TRACE5 eingefügt
+    23.12.2005   d.k. Definitions for IAR compiler
+
+    $Id: global.h,v 1.6 2008/11/07 13:55:56 D.Krueger Exp $
+
+****************************************************************************/
+
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_
+
+
+//---------------------------------------------------------------------------
+//  elements of defines for development system
+//---------------------------------------------------------------------------
+
+// these defines are necessary to check some of characteristics of the development system
+#define _DEV_BIGEND_            0x80000000L     // big endian (motorolla format)
+#define _DEV_ALIGNMENT_4_       0x00400000L     //                  the CPU needs alignment of 4 bytes
+#define _DEV_ONLY_INT_MAIN_     0x00004000L     //                  the compiler needs "int main(int)" instead of "void main(void)"
+#define _DEV_COMMA_EXT_         0x00002000L     //                  support of last comma in struct predefinition
+#define _DEV_64BIT_SUPPORT_     0x00001000L     //                  support of 64 bit operations
+#define _DEV_BIT64_             0x00000400L     // count of bits:   64 bit
+#define _DEV_BIT32_             0x00000300L     //                  32 bit
+#define _DEV_BIT16_             0x00000200L     //                  16 bit
+#define _DEV_BIT8_              0x00000100L     //                  8 bit
+#define _DEV_RVCT_ARM_          0x0000001CL     //                  RealView ARM
+#define _DEV_RENESASM32C        0x0000001BL     // compiler from:   Renesas
+#define _DEV_GNUC_MIPS2_        0x0000001AL     //                  GNU for MIPS2
+#define _DEV_MPLAB_C30_         0x00000019L     //                  MPLAB C30 for Microchip dsPIC33F series
+#define _DEV_GNUC_TC_           0x00000018L     //                  GNU for Infineon TriCore
+#define _DEV_GNUC_X86_          0x00000017L     //                  GNU for I386
+#define _DEV_IAR_ARM_           0x00000016L     //                  ARM IAR C/C++ Compiler
+#define _DEV_PARADGM_X86        0x00000015L     //                  Paradigm C/C++ for Beck 1x3
+#define _DEV_GNUC_CF_           0x00000014L     //                  GNU for Coldfire
+#define _DEV_KEIL_ARM_          0x00000013L     //                  Keil ARM
+#define _DEV_MSEVC_             0x00000012L     //                  Microsoft embedded Visual C/C++
+#define _DEV_HIGHTEC_GNUC_X86_  0x00000011L     //                  Hightec elf386 gcc
+#define _DEV_MSVC_RTX_          0x00000010L     //                  VC600 + RTX
+#define _DEV_MSVC_V1_5_         0x0000000FL     //                  Microsoft Visual C/C++ V1.5
+#define _DEV_GNUC_ARM7_         0x0000000EL     //                  GNU Compiler gcc for ARM7
+#define _DEV_METROWERKS_CW_     0x0000000DL     //                  Metrowerks Code Warrior
+#define _DEV_MITSUBISHIM16C_    0x0000000CL     //compiler from:    Mitsubishi
+#define _DEV_GNUC_C16X_         0x0000000BL     //                  GNU Compiler gcc166 for Infineon C16x
+#define _DEV_LINUX_GCC_         0x0000000AL     //                  Linux GNU Compiler gcc
+#define _DEV_GNUC_MPC5X5        0x00000009L     //                  GNU for Motorola PPC5x5
+#define _DEV_TASKINGM16C_       0x00000008L     //                  Tasking for Mitsubishi M16C
+#define _DEV_FUJITSU_           0x00000007L     //                  Fujitsu
+#define _DEV_TASKING8_          0x00000006L     //                  Tasking 8051
+#define _DEV_TASKING16_         0x00000005L     //                  Tasking 166
+#define _DEV_KEIL8_             0x00000004L     //                  Keil C51
+#define _DEV_KEIL16_            0x00000003L     //                  Keil C166
+#define _DEV_BORLANDC_          0x00000002L     //                  Borland C/C++
+#define _DEV_MSVC16_            0x00000001L     //                  Microsoft Visual C/C++
+#define _DEV_MSVC32_            0x00000000L     //                  Microsoft Visual C/C++
+
+// these defines can be used to mask previous elements
+#define _DEV_MASK_COMPILER      0x000000FFL
+#define _DEV_MASK_BITCOUNT      0x00000F00L
+#define _DEV_MASK_ADDSUPPORT    0x0000F000L
+#define _DEV_MASK_ALIGNMENT     0x00F00000L
+
+
+//---------------------------------------------------------------------------
+//  defines for development system (DEV_SYSTEM) including previous elements
+//---------------------------------------------------------------------------
+
+#define _DEV_WIN16_             (_DEV_BIT16_ | _DEV_MSVC16_                  )
+#define _DEV_WIN32_             (_DEV_BIT32_ | _DEV_MSVC32_                   | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_MSVC_DOS_          (_DEV_BIT32_ | _DEV_MSVC_V1_5_               )
+#define _DEV_BORLAND_DOS_       (_DEV_BIT32_ | _DEV_BORLANDC_                ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_KEIL_C51X_         (_DEV_BIT8_  | _DEV_KEIL8_     | _DEV_BIGEND_ | _DEV_COMMA_EXT_) // at least C51 version 7.05 supports comma extension
+#define _DEV_KEIL_C16X_         (_DEV_BIT16_ | _DEV_KEIL16_                   | _DEV_COMMA_EXT_) // at least C166 version 5.03 supports comma extension
+#define _DEV_TASKING_C51X_      (_DEV_BIT8_  | _DEV_TASKING8_  | _DEV_BIGEND_)
+#define _DEV_TASKING_C16X_      (_DEV_BIT16_ | _DEV_TASKING16_               )
+#define _DEV_FUJITSU_F590_      (_DEV_BIT8_  | _DEV_FUJITSU_                  | _DEV_COMMA_EXT_) // softune is not able to support 64 bit variables QWORD !!!
+//f.j.29.04.03 M16C kann effektiv mit Bytes umgehen
+//#define _DEV_TASKING_M16C_      (_DEV_BIT16_ | _DEV_TASKINGM16C_             )
+#define _DEV_TASKING_M16C_      (_DEV_BIT8_  | _DEV_TASKINGM16C_             )
+#define _DEV_MITSUBISHI_M16C_   (_DEV_BIT8_  | _DEV_MITSUBISHIM16C_          )
+#define _DEV_GNU_MPC5X5_        (_DEV_BIT32_ | _DEV_GNUC_MPC5X5| _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_LINUX_             (_DEV_BIT32_ | _DEV_LINUX_GCC_                | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_GNU_C16X_          (_DEV_BIT16_ | _DEV_GNUC_C16X_               ) //| _DEV_COMMA_EXT_)
+#define _DEV_MCW_MPC5X5_        (_DEV_BIT32_ | _DEV_METROWERKS_CW_           ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_GNU_ARM7_          (_DEV_BIT32_ | _DEV_GNUC_ARM7_                | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
+#define _DEV_WIN32_RTX_         (_DEV_BIT32_ | _DEV_MSVC_RTX_                ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_HIGHTEC_X86_       (_DEV_BIT32_ | _DEV_HIGHTEC_GNUC_X86_        ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_WIN_CE_            (_DEV_BIT32_ | _DEV_MSEVC_                   ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_KEIL_CARM_         (_DEV_BIT32_ | _DEV_KEIL_ARM_                 | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_IAR_CARM_          (_DEV_BIT32_ | _DEV_IAR_ARM_                  | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_RVCT_CARM_         (_DEV_BIT32_ | _DEV_RVCT_ARM_                 | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
+#define _DEV_MCW_MCF5XXX_       (_DEV_BIT32_ | _DEV_METROWERKS_CW_           ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_GNU_CF5282_        (_DEV_BIT32_ | _DEV_GNUC_CF_   | _DEV_BIGEND_)
+#define _DEV_PAR_BECK1X3_       (_DEV_BIT16_ | _DEV_PARADGM_X86)
+#define _DEV_GNU_CF548X_        (_DEV_BIT32_ | _DEV_GNUC_CF_   | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
+#define _DEV_GNU_I386_          (_DEV_BIT32_ | _DEV_GNUC_X86_                 | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
+#define _DEV_GNU_TRICORE_       (_DEV_BIT32_ | _DEV_GNUC_TC_                  | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_ | _DEV_ALIGNMENT_4_)
+#define _DEV_MPLAB_DSPIC33F_    (_DEV_BIT16_ | _DEV_MPLAB_C30_               ) //| _DEV_COMMA_EXT_)
+#define _DEV_GNU_MIPSEL_        (_DEV_BIT32_ | _DEV_GNUC_MIPS2_     | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
+
+#define _DEV_RENESAS_M32C_      (_DEV_BIT32_ | _DEV_RENESASM32C)
+
+//---------------------------------------------------------------------------
+//  usefull macros
+//---------------------------------------------------------------------------
+
+#define CHECK_IF_ONLY_INT_MAIN()    (DEV_SYSTEM & _DEV_ONLY_INT_MAIN_)
+#define CHECK_MEMORY_ALINMENT()     (DEV_SYSTEM & _DEV_MASK_ALIGNMENT)
+
+
+//---------------------------------------------------------------------------
+//  defines for target system (TARGET_SYSTEM)
+//---------------------------------------------------------------------------
+
+#define _DOS_              (16 + 0x10000)
+#define _WIN16_             16
+#define _WIN32_             32
+#define _WINCE_            (32 + 0x20000)
+#define _NO_OS_              0
+#define _LINUX_              1
+#define _PXROS_              2
+#define _ECOSPRO_            3
+
+
+//---------------------------------------------------------------------------
+//  definitions for function inlining
+//---------------------------------------------------------------------------
+
+#define INLINE_FUNCTION             // empty define
+#undef  INLINE_ENABLED              // disable actual inlining of functions
+#undef  INLINE_FUNCTION_DEF         // disable inlining for all compilers per default
+
+//---------------------------------------------------------------------------
+//  definitions for Keil C51
+//---------------------------------------------------------------------------
+
+#ifdef  __C51__
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_KEIL_C51X_
+
+    #pragma DEBUG OBJECTEXTEND
+    #pragma WARNINGLEVEL(2)             // maximum warning level
+
+    #define NEAR            idata       // variables mapped to internal data storage location
+    #define FAR             xdata       // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM             code        // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC           xdata       // hardware access through external memory (i.e. CAN)
+    #define LARGE           large       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM             xdata       // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT       reentrant
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+
+//---------------------------------------------------------------------------
+//  definitions for GNU Compiler for Infineon C16x
+//  - it have to be befor Keil (it has __C166__ too)
+//---------------------------------------------------------------------------
+#elif  defined (__GNUC__) && defined (__C166__)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_GNU_C16X_
+
+//    #define NEAR            idata       // variables mapped to internal data storage location
+    #define NEAR            near       // variables mapped to internal data storage location
+//    #define FAR             xhuge       // variables mapped to external data storage location
+    #define FAR             huge       // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+//    #define HWACC           sdata       // hardware access through external memory (i.e. CAN)
+    #define HWACC           huge       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+//    #define GENERIC         xhuge       // generic pointer to point to application data
+    #define GENERIC         huge       // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+
+        #define ASSERT(p)  \
+            if (p)         \
+            {              \
+                ;          \
+            }              \
+            else           \
+            {              \
+                PRINTF0("Assert failed: " #p " (file %s line %d)\n", __FILE__, (int) __LINE__ ); \
+                while (1); \
+            }
+    #else
+        #define ASSERT(p)
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for Keil C166
+//---------------------------------------------------------------------------
+#elif  defined (__C166__)               // 24.01.2005 r.d.: Keil ARM7 needs directive 'defined'
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_KEIL_C16X_
+
+    #pragma CODE
+    #pragma MOD167
+    #pragma NOINIT
+    #pragma DEBUG
+    #pragma WARNINGLEVEL(3)             // maximum warning level
+    #pragma WARNING DISABLE = 47        // warning <unreferenced parameter> = OFF
+    #pragma WARNING DISABLE = 38        // warning <empty translation unit> = OFF
+//  #pragma WARNING DISABLE = 102       // warning <different const/volatile qualifiers> = OFF
+    #pragma WARNING DISABLE = 174       // warning <unreferenced 'static' function> = OFF
+    #pragma WARNING DISABLE = 183       // warning <dead assignement eliminated> = OFF
+
+    #define NEAR            idata       // variables mapped to internal data storage location
+    #define FAR             xhuge       // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+//    #define HWACC           sdata       // hardware access through external memory (i.e. CAN)
+    #define HWACC           huge       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC         xhuge       // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for MPLAB C30 for dsPIC33F series
+//---------------------------------------------------------------------------
+#elif  defined (__C30__)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_MPLAB_DSPIC33F_
+
+    #define NEAR                        // variables mapped to internal data storage location
+    #define FAR                         // variables mapped to external data storage location
+    #define CONST        const          // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+//    #ifndef QWORD
+//        #define QWORD long long
+//    #endif
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for Keil ARM
+//---------------------------------------------------------------------------
+#elif  defined (__CA__)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_KEIL_CARM_
+
+    #define NEAR                        // variables mapped to internal data storage location
+    #define FAR                         // variables mapped to external data storage location
+    #define CONST        const          // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef QWORD
+        #define QWORD long long
+    #endif
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for RealView ARM compilation tools (provided by recent Keil Microcontroller Development Kits)
+//---------------------------------------------------------------------------
+#elif  defined (__ARMCC_VERSION)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_RVCT_CARM_
+
+    #define NEAR                        // variables mapped to internal data storage location
+    #define FAR                         // variables mapped to external data storage location
+    #define CONST        const          // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef QWORD
+        #define QWORD long long
+    #endif
+
+    #ifndef NDEBUG
+        #define ASSERT(expr)    if (!(expr)) {\
+                                   TRACE0 ("Assertion failed: " #expr );\
+                                   while (1);}
+    #else
+        #define ASSERT(expr)
+    #endif
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for ARM IAR C Compiler
+//---------------------------------------------------------------------------
+#elif  defined (__ICCARM__)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_IAR_CARM_
+
+    #define NEAR                        // variables mapped to internal data storage location
+    #define FAR                         // variables mapped to external data storage location
+    #define CONST        const          // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef QWORD
+        #define QWORD long long
+    #endif
+
+    // Workaround:
+    // If we use IAR and want to debug but don't want to use C-Spy Debugger
+    // assert() doesn't work in debug mode because it needs support for FILE descriptors
+    // (_DLIB_FILE_DESCRIPTOR == 1).
+    #ifndef NDEBUG
+        #define ASSERT(expr)    if (!(expr)) {\
+                                   TRACE0 ("Assertion failed: " #expr );\
+                                   while (1);}
+    #else
+        #define ASSERT(expr)
+    #endif
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+//        #define TRACE  PRINTF4
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for Tasking 8051
+//---------------------------------------------------------------------------
+
+#elif defined (_CC51)
+
+    #include <cc51.h>
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_TASKING_C51X_
+
+    #define NEAR            _data       // variables mapped to internal data storage location
+    #define FAR             _xdat       // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC           _xdat       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM             _xdat       // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT       _reentrant
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+
+//---------------------------------------------------------------------------
+//  definitions for Tasking C167CR and C164CI
+//---------------------------------------------------------------------------
+
+#elif defined (_C166)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_TASKING_C16X_
+
+    #define NEAR            near        // variables mapped to internal data storage location
+    #define FAR             far         // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC   /* to be defined */ // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
+    // without checking if it is already included. So an error occurs while compiling.
+    // (r.d.)
+    #include <stdio.h>                  // prototype printf() (for TRACE)
+    #ifndef NDEBUG
+        #define TRACE  printf
+    #endif
+
+
+//---------------------------------------------------------------------------
+//  definitions for FUJITSU FFMC-16LX MB90590
+//---------------------------------------------------------------------------
+
+//#elif (defined (F590) || defined (F543) || defined (F598) || defined (F495) || defined (F350))
+#elif defined(__COMPILER_FCC907__)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_FUJITSU_F590_
+
+    #define NEAR    /* to be defined */ // variables mapped to internal data storage location
+    #define FAR     /* to be defined */ // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM     /* to be defined */ // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC   /* to be defined */ // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    // softune is not able to support 64 bit variables QWORD !!!
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+
+//---------------------------------------------------------------------------
+//  definitions for Mitsubishi M16C family for TASKING Compiler CM16
+//---------------------------------------------------------------------------
+
+#elif defined (_CM16C)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_TASKING_M16C_
+
+    #define NEAR            _near       // variables mapped to internal data storage location
+    #define FAR             _far        // variables mapped to external data storage location
+    #define CONST           _farrom       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC           _near       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC         _far        // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+                                        // do you use memory model SMALL, than you have to set _far
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
+    // without checking if it is already included. So an error occurs while compiling.
+    // (r.d.)
+    #include <stdio.h>                  // prototype printf() (for TRACE)
+    #ifndef NDEBUG
+        #define TRACE  printf
+    #endif
+
+
+//---------------------------------------------------------------------------
+//  definitions for Mitsubishi M16C family for Mitsubishi Compiler NC30
+//---------------------------------------------------------------------------
+// name NC30, andere Form will der Compiler nicht !!
+#elif defined (NC30)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_MITSUBISHI_M16C_
+
+    #define NEAR            near        // variables mapped to internal data storage location
+    #define FAR             far         // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                      // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC           near        // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC         far         // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>                  // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for Renesas M32C family for Renesas Compiler
+//---------------------------------------------------------------------------
+#elif defined (NC308)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_RENESAS_M32C_
+
+    #define NEAR             near       // variables mapped to internal data storage location
+    #define FAR              far        // variables mapped to external data storage location
+    #define CONST            const      // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM              far        // Memory attribute to optimize speed and code of pointer access.
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>                  // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//    #error ("RENESAS o.k.")
+
+//---------------------------------------------------------------------------
+//  definitions for ARM7 family with GNU compiler
+//---------------------------------------------------------------------------
+
+#elif defined(__GNUC__) && defined(__arm__) && !defined(__LINUX_ARM_ARCH__)
+
+    #define TARGET_SYSTEM   _NO_OS_
+    #define DEV_SYSTEM      _DEV_GNU_ARM7_
+
+    #define NEAR                        // variables mapped to internal data storage location
+    #define FAR                         // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef QWORD
+        #define QWORD long long    // i.A. durch Herr Kuschel
+    #endif
+
+    #ifndef NDEBUG
+        #include <stdio.h>                  // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+
+//---------------------------------------------------------------------------
+//  definitions for Motorola PowerPC family 5x5 (555/565)
+//  definitions Linux-PC
+//---------------------------------------------------------------------------
+
+#elif defined (__GNUC__)
+
+    #if defined (LINUX) || defined (linux) || defined (__linux__)
+        #define LINUX_SYSTEM            // define 'LINUX_SYSTEM' uniform for all Linux based systems
+        // r.d.: We will need an other solution here! There are two sections here which do check the preproc-definitions:
+        //     LINUX and __linux__ . The first one was Linux for PC, the second one is this section for embedded Linux (MCF5xxx).
+        //     But Linux for PC does not need the definitions for embedded Linux.
+    #endif
+
+    // GNU C compiler supports function inlining
+    #define INLINE_FUNCTION_DEF extern inline
+
+    // to actually enable inlining just include the following three lines
+    // #undef INLINE_FUNCTION
+    // #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+    // #define INLINE_ENABLED      TRUE
+
+    #ifdef PXROS
+        #define TARGET_SYSTEM       _PXROS_
+        #ifdef __i386__
+            #undef LINUX // this define seems to be set from compiler
+            #define DEV_SYSTEM      _DEV_HIGHTEC_X86_
+           #elif defined (__tricore__)
+            #define DEV_SYSTEM      _DEV_GNU_TRICORE_
+        #else // MPC5x5
+            #define DEV_SYSTEM      _DEV_GNU_MPC5X5_
+        #endif
+
+    #elif defined (LINUX) || defined (__linux__)
+        #define TARGET_SYSTEM       _LINUX_     // Linux definition
+        #define DEV_SYSTEM          _DEV_LINUX_
+
+    #elif defined (GNU_CF5282)
+        #define TARGET_SYSTEM       _NO_OS_
+        #define DEV_SYSTEM          _DEV_GNU_CF5282_
+
+    #elif defined (ECOSPRO_I386_PEAK_PCI)
+        #define TARGET_SYSTEM       _ECOSPRO_
+        #define DEV_SYSTEM          _DEV_GNU_I386_
+
+    #elif defined (GNU_CF548X)
+        #define TARGET_SYSTEM       _NO_OS_
+        #define DEV_SYSTEM          _DEV_GNU_CF548X_
+    #else
+        #error 'ERROR: DEV_SYSTEM not found!'
+    #endif
+
+
+    #ifndef QWORD
+        #define QWORD long long int
+    #endif
+
+    #if (TARGET_SYSTEM == _PXROS_)
+
+        #ifndef __KERNEL__
+            #include <string.h>
+        #endif
+
+
+        #define NEAR                        // variables mapped to internal data storage location
+        #define FAR                         // variables mapped to external data storage location
+        #define CONST           const       // variables mapped to ROM (i.e. flash)
+        #define ROM     /* to be defined */ // code or variables mapped to ROM (i.e. flash)
+                                            // usage: CONST BYTE ROM foo = 0x00;
+        #define LARGE                       // functions set parameters to external data storage location
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                     // generic pointer to point to application data
+                                            // Variables with this attribute can be located in external
+                                            // or internal data memory.
+        #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+        #define HWACC                       // hardware access through external memory (i.e. CAN)
+
+        #define REENTRANT
+        #define PUBLIC
+
+        #ifndef QWORD
+            #define QWORD long long int
+        #endif
+
+        #ifndef NDEBUG
+            #include <stdio.h>              // prototype printf() (for TRACE)
+            #define TRACE  printf
+        #endif
+
+    #endif
+
+    // ------------------ GNUC for I386 ---------------------------------------------
+
+    #if (TARGET_SYSTEM == _LINUX_) || (TARGET_SYSTEM == _ECOSPRO_)
+
+        #ifndef __KERNEL__
+            #include <string.h>
+        #endif
+
+        #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+        #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                 // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+        #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+        #ifndef NEAR
+            #define NEAR                // variables mapped to internal data storage location
+        #endif
+
+        #ifndef FAR
+            #define FAR                 // variables mapped to external data storage location
+        #endif
+
+        #ifndef CONST
+            #define CONST const         // variables mapped to ROM (i.e. flash)
+        #endif
+
+        #define LARGE
+
+        #define REENTRANT
+        #define PUBLIC
+
+        #ifndef NDEBUG
+            #ifndef __KERNEL__
+                #include <stdio.h>              // prototype printf() (for TRACE)
+                #define TRACE  printf
+            #else
+                #define TRACE  printk
+            #endif
+        #endif
+    #endif
+
+    // ------------------ GNU without OS ---------------------------------------------
+
+    #if (TARGET_SYSTEM == _NO_OS_)
+
+        #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+        #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                 // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+        #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+        #ifndef NEAR
+            #define NEAR                // variables mapped to internal data storage location
+        #endif
+
+        #ifndef FAR
+            #define FAR                 // variables mapped to external data storage location
+        #endif
+
+        #ifndef CONST
+            #define CONST const         // variables mapped to ROM (i.e. flash)
+        #endif
+
+        #define LARGE
+
+        #define REENTRANT
+        #define PUBLIC
+
+        #ifndef NDEBUG
+//            #include "xuartdrv.h"
+//            #include <stdio.h>              // prototype printf() (for TRACE)
+            #define TRACE  printf
+//            #define TRACE  mprintf
+//            #ifndef TRACE
+//                #define TRACE trace
+//                void trace (char *fmt, ...);
+//            #endif
+        #endif
+
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for MPC565
+//---------------------------------------------------------------------------
+#elif __MWERKS__
+
+
+#ifdef __MC68K__
+
+    #define TARGET_SYSTEM = _MCF548X_
+    #define DEV_SYSTEM      _DEV_MCW_MCF5XXX_
+
+#else
+    #define TARGET_SYSTEM = _MPC565_
+    #define DEV_SYSTEM      _DEV_MCW_MPC5X5_
+#endif
+
+    #define NEAR                        // variables mapped to internal data storage location
+    #define FAR                         // variables mapped to external data storage location
+    #define CONST           const       // variables mapped to ROM (i.e. flash)
+    #define ROM                         // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+    #define LARGE                       // functions set parameters to external data storage location
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                     // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+    #define MEM                         // Memory attribute to optimize speed and code of pointer access.
+
+    #define HWACC                       // hardware access through external memory (i.e. CAN)
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #include <stdio.h>              // prototype printf() (for TRACE)
+        #define TRACE  printf
+    #endif
+
+//---------------------------------------------------------------------------
+//  definitions for BECK 1x3
+//---------------------------------------------------------------------------
+#elif defined (__BORLANDC__) && defined (__PARADIGM__)
+
+
+     #define TARGET_SYSTEM      _NO_OS_
+     #define DEV_SYSTEM         _DEV_PAR_BECK1X3_
+
+
+
+     #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                     // usage: CONST BYTE ROM foo = 0x00;
+     #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+     // These types can be adjusted by users to match application requirements. The goal is to
+     // minimize code memory and maximize speed.
+     #define GENERIC                 // generic pointer to point to application data
+                                     // Variables with this attribute can be located in external
+                                     // or internal data memory.
+     #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+     #define NEAR __near             // variables mapped to internal data storage location
+     #define FAR  __far              // variables mapped to external data storage location
+     #define CONST const             // variables mapped to ROM (i.e. flash)
+     #define LARGE
+
+     #define REENTRANT
+     #define PUBLIC
+
+     #ifndef NDEBUG
+         #ifndef TRACE
+             #include <stdio.h>
+             #define TRACE printf
+         #endif
+     #endif
+
+
+
+//---------------------------------------------------------------------------
+//  definitions for PC
+//---------------------------------------------------------------------------
+
+#elif defined (__BORLANDC__)
+
+    // ------------------ definition target system --------------------------
+
+    #ifdef _WIN32
+        #define TARGET_SYSTEM   _WIN32_     // WIN32 definition
+        #define DEV_SYSTEM      _DEV_WIN32_
+    #else
+        #define TARGET_SYSTEM   _DOS_
+        #define DEV_SYSTEM      _DEV_BORLAND_DOS_
+    #endif
+
+
+    // ------------------ WIN32 ---------------------------------------------
+
+    #if (TARGET_SYSTEM == _WIN32_)
+
+        #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+        #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                 // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+        #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+        #ifndef NEAR
+            #define NEAR                // variables mapped to internal data storage location
+        #endif
+
+        #ifndef FAR
+            #define FAR                 // variables mapped to external data storage location
+        #endif
+
+        #ifndef CONST
+            #define CONST const         // variables mapped to ROM (i.e. flash)
+        #endif
+
+        #define LARGE
+
+        #define REENTRANT
+        #define PUBLIC __stdcall
+
+        #ifndef NDEBUG
+            #ifndef TRACE
+                    #include <stdio.h>
+            #define TRACE printf
+            #endif
+        #endif
+
+    #elif (TARGET_SYSTEM == _DOS_)
+
+        #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+        #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                 // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+        #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+        #define NEAR near               // variables mapped to internal data storage location
+        #define FAR  far                // variables mapped to external data storage location
+        #define CONST const             // variables mapped to ROM (i.e. flash)
+        #define LARGE
+
+        #define REENTRANT
+        #define PUBLIC
+
+        #ifndef NDEBUG
+            #ifndef TRACE
+                #include <stdio.h>
+                #define TRACE printf
+            #endif
+        #endif
+
+    #endif
+
+#elif (_MSC_VER == 800) // PC MS Visual C/C++ for DOS applications
+
+    #define TARGET_SYSTEM   _DOS_
+    #define DEV_SYSTEM      _DEV_MSVC_DOS_
+
+    #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                    // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC near              // hardware access through external memory (i.e. CAN)
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                 // generic pointer to point to application data
+                                    // Variables with this attribute can be located in external
+                                    // or internal data memory.
+    #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+    #define NEAR near               // variables mapped to internal data storage location
+    #define FAR  far                // variables mapped to external data storage location
+    #define CONST const             // variables mapped to ROM (i.e. flash)
+    #define LARGE
+
+    #define REENTRANT
+    #define PUBLIC
+
+    #ifndef NDEBUG
+        #ifndef TRACE
+            #include <stdio.h>
+            #define TRACE printf
+        #endif
+    #endif
+
+
+//---------------------------------------------------------------------------
+// definitions for RTX under WIN32
+//---------------------------------------------------------------------------
+#elif (defined (UNDER_RTSS) && defined (WIN32))
+
+    // ------------------ definition target system --------------------------
+    #define TARGET_SYSTEM   _WIN32_RTX_
+    #define DEV_SYSTEM      _DEV_WIN32_RTX_
+
+    #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                    // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                 // generic pointer to point to application data
+                                    // Variables with this attribute can be located in external
+                                    // or internal data memory.
+    #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+    #ifndef NEAR
+        #define NEAR                // variables mapped to internal data storage location
+    #endif
+
+    #ifndef FAR
+        #define FAR                 // variables mapped to external data storage location
+    #endif
+
+    #ifndef CONST
+        #define CONST const         // variables mapped to ROM (i.e. flash)
+    #endif
+
+    #define LARGE
+
+    #define REENTRANT
+    #define PUBLIC __stdcall
+
+    #ifndef NDEBUG
+        #ifndef TRACE
+            #define TRACE RtPrintf
+        #endif
+    #endif
+
+//---------------------------------------------------------------------------
+// definitions for WinCE
+//---------------------------------------------------------------------------
+#elif defined (_WIN32_WCE)
+
+    // ------------------ definition target system --------------------------
+    #define TARGET_SYSTEM           _WINCE_
+    #define DEV_SYSTEM              _DEV_WIN_CE_
+
+    #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                    // usage: CONST BYTE ROM foo = 0x00;
+    #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+    // These types can be adjusted by users to match application requirements. The goal is to
+    // minimize code memory and maximize speed.
+    #define GENERIC                 // generic pointer to point to application data
+                                    // Variables with this attribute can be located in external
+                                    // or internal data memory.
+    #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+    #ifndef NEAR
+        #define NEAR                // variables mapped to internal data storage location
+    #endif
+
+    #ifndef FAR
+        #define FAR                 // variables mapped to external data storage location
+    #endif
+
+    #ifndef CONST
+        #define CONST const         // variables mapped to ROM (i.e. flash)
+    #endif
+
+    #define LARGE
+
+    #ifndef QWORD
+      //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
+        #define QWORD __int64
+    #endif
+
+    #define REENTRANT
+    #define PUBLIC __cdecl
+
+    #ifdef ASSERTMSG
+        #undef ASSERTMSG
+    #endif
+
+    #ifndef NDEBUG
+        #ifndef TRACE
+            #define TRACE printf
+//            void trace (char *fmt, ...);
+        #endif
+    #endif
+
+#else   // ===> PC MS Visual C/C++
+
+    // ------------------ definition target system --------------------------
+
+    #ifdef _WIN32
+        #define TARGET_SYSTEM   _WIN32_     // WIN32 definition
+        #define DEV_SYSTEM      _DEV_WIN32_
+    #else
+        #define TARGET_SYSTEM   _WIN16_     // WIN16 definition
+        #define DEV_SYSTEM      _DEV_WIN16_
+    #endif
+
+
+    // ------------------ WIN16 ---------------------------------------------
+
+    #if (TARGET_SYSTEM == _WIN16_)
+
+        #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+        #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                 // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+        #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+        #ifndef NEAR
+            #define NEAR                // variables mapped to internal data storage location
+        #endif
+
+        #ifndef FAR
+            #define FAR far             // variables mapped to external data storage location
+        #endif
+
+        #ifndef CONST
+            #define CONST const         // variables mapped to ROM (i.e. flash)
+        #endif
+
+        #define LARGE
+
+        #define REENTRANT
+        #define PUBLIC _far _pascal _export
+
+        #ifndef NDEBUG
+            #ifndef TRACE
+                #define TRACE trace
+                #ifdef __cplusplus
+                    extern "C"
+                    {
+                #endif
+                    void trace (const char *fmt, ...);
+                #ifdef __cplusplus
+                    }
+                #endif
+            #endif
+        #endif
+
+    #endif
+
+
+    // ------------------ WIN32 ---------------------------------------------
+
+   #if (TARGET_SYSTEM == _WIN32_)
+
+        #define ROM                     // code or variables mapped to ROM (i.e. flash)
+                                        // usage: CONST BYTE ROM foo = 0x00;
+        #define HWACC                   // hardware access through external memory (i.e. CAN)
+
+        // These types can be adjusted by users to match application requirements. The goal is to
+        // minimize code memory and maximize speed.
+        #define GENERIC                 // generic pointer to point to application data
+                                        // Variables with this attribute can be located in external
+                                        // or internal data memory.
+        #define MEM                     // Memory attribute to optimize speed and code of pointer access.
+
+        #ifndef NEAR
+            #define NEAR                // variables mapped to internal data storage location
+        #endif
+
+        #ifndef FAR
+            #define FAR                 // variables mapped to external data storage location
+        #endif
+
+        #ifndef CONST
+            #define CONST const         // variables mapped to ROM (i.e. flash)
+        #endif
+
+        #define LARGE
+
+        #define REENTRANT
+        #define PUBLIC __stdcall
+
+        #ifndef QWORD
+          //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
+            #define QWORD __int64
+        #endif
+
+        #ifndef NDEBUG
+            #ifndef TRACE
+                #define TRACE trace
+                #ifdef __cplusplus
+                    extern "C"
+                    {
+                #endif
+                    void trace (const char *fmt, ...);
+                #ifdef __cplusplus
+                    }
+                #endif
+            #endif
+        #endif
+
+        // MS Visual C++ compiler supports function inlining
+        #define INLINE_FUNCTION_DEF __forceinline
+
+        // to actually enable inlining just include the following two lines
+        // #define INLINE_FUNCTION     INLINE_FUNCTION_DEF
+        // #define INLINE_ENABLED      TRUE
+
+    #endif
+
+#endif  // ===> PC
+
+
+//---------------------------------------------------------------------------
+//  definitions of basic types
+//---------------------------------------------------------------------------
+
+#ifndef _WINDEF_        // defined in WINDEF.H, included by <windows.h>
+
+    // --- arithmetic types ---
+    #ifndef SHORT
+        #define SHORT short int
+    #endif
+
+    #ifndef USHORT
+        #define USHORT unsigned short int
+    #endif
+
+    #ifndef INT
+        #define INT int
+    #endif
+
+    #ifndef UINT
+        #define UINT unsigned int
+    #endif
+
+    #ifndef LONG
+        #define LONG long int
+    #endif
+
+    #ifndef ULONG
+        #define ULONG unsigned long int
+    #endif
+
+
+    // --- logic types ---
+    #ifndef BYTE
+        #define BYTE unsigned char
+    #endif
+
+    #ifndef WORD
+        #define WORD unsigned short int
+    #endif
+
+    #ifndef DWORD
+        #define DWORD unsigned long int
+    #endif
+
+    #ifndef BOOL
+        #define BOOL unsigned char
+    #endif
+
+
+    // --- alias types ---
+    #ifndef TRUE
+        #define TRUE  0xFF
+    #endif
+
+    #ifndef FALSE
+        #define FALSE 0x00
+    #endif
+
+    #ifndef NULL
+        #define NULL ((void *) 0)
+    #endif
+
+#endif
+
+
+#ifndef _TIME_OF_DAY_DEFINED_
+
+    typedef struct
+    {
+        unsigned long  int  m_dwMs;
+        unsigned short int  m_wDays;
+
+    } tTimeOfDay;
+
+    #define _TIME_OF_DAY_DEFINED_
+
+#endif
+
+
+//---------------------------------------------------------------------------
+//  Definition von TRACE
+//---------------------------------------------------------------------------
+
+#ifndef NDEBUG
+
+    #ifndef TRACE0
+        #define TRACE0(p0)                      TRACE(p0)
+    #endif
+
+    #ifndef TRACE1
+        #define TRACE1(p0, p1)                  TRACE(p0, p1)
+    #endif
+
+    #ifndef TRACE2
+        #define TRACE2(p0, p1, p2)              TRACE(p0, p1, p2)
+    #endif
+
+    #ifndef TRACE3
+        #define TRACE3(p0, p1, p2, p3)          TRACE(p0, p1, p2, p3)
+    #endif
+
+    #ifndef TRACE4
+        #define TRACE4(p0, p1, p2, p3, p4)      TRACE(p0, p1, p2, p3, p4)
+    #endif
+
+    #ifndef TRACE5
+        #define TRACE5(p0, p1, p2, p3, p4, p5)  TRACE(p0, p1, p2, p3, p4, p5)
+    #endif
+
+    #ifndef TRACE6
+        #define TRACE6(p0, p1, p2, p3, p4, p5, p6)  TRACE(p0, p1, p2, p3, p4, p5, p6)
+    #endif
+
+#else
+
+    #ifndef TRACE0
+        #define TRACE0(p0)
+    #endif
+
+    #ifndef TRACE1
+        #define TRACE1(p0, p1)
+    #endif
+
+    #ifndef TRACE2
+        #define TRACE2(p0, p1, p2)
+    #endif
+
+    #ifndef TRACE3
+        #define TRACE3(p0, p1, p2, p3)
+    #endif
+
+    #ifndef TRACE4
+        #define TRACE4(p0, p1, p2, p3, p4)
+    #endif
+
+    #ifndef TRACE5
+        #define TRACE5(p0, p1, p2, p3, p4, p5)
+    #endif
+
+    #ifndef TRACE6
+        #define TRACE6(p0, p1, p2, p3, p4, p5, p6)
+    #endif
+
+#endif
+
+
+
+//---------------------------------------------------------------------------
+//  definition of ASSERT
+//---------------------------------------------------------------------------
+
+#ifndef ASSERT
+    #if !defined (__linux__) && !defined (__KERNEL__)
+        #include <assert.h>
+        #ifndef ASSERT
+            #define ASSERT(p)    assert(p)
+        #endif
+    #else
+        #define ASSERT(p)
+    #endif
+#endif
+
+
+//---------------------------------------------------------------------------
+//  SYS TEC extensions
+//---------------------------------------------------------------------------
+
+// This macro doesn't print out C-file and line number of the failed assertion
+// but a string, which exactly names the mistake.
+#ifndef NDEBUG
+
+    #define ASSERTMSG(expr,string)  if (!(expr)) {\
+                                        PRINTF0 ("Assertion failed: " string );\
+                                        while (1);}
+#else
+    #define ASSERTMSG(expr,string)
+#endif
+
+
+
+
+//---------------------------------------------------------------------------
+
+#endif  // #ifndef _GLOBAL_H_
+
+// Please keep an empty line at the end of this file.
+
diff --git a/drivers/staging/epl/kernel/EplDllk.h b/drivers/staging/epl/kernel/EplDllk.h
new file mode 100644 (file)
index 0000000..d48b8af
--- /dev/null
@@ -0,0 +1,171 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernelspace DLL module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDllk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/08 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DLLK_H_
+#define _EPL_DLLK_H_
+
+#include "../EplDll.h"
+#include "../EplEvent.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef tEplKernel (* tEplDllkCbAsync) (tEplFrameInfo * pFrameInfo_p);
+
+typedef struct
+{
+    BYTE                m_be_abSrcMac[6];
+
+} tEplDllkInitParam;
+
+// forward declaration
+struct _tEdrvTxBuffer;
+
+struct _tEplDllkNodeInfo
+{
+    struct _tEplDllkNodeInfo*   m_pNextNodeInfo;
+    struct _tEdrvTxBuffer*      m_pPreqTxBuffer;
+    unsigned int                m_uiNodeId;
+    DWORD                       m_dwPresTimeout;
+    unsigned long               m_ulDllErrorEvents;
+    tEplNmtState                m_NmtState;
+    WORD                        m_wPresPayloadLimit;
+    BYTE                        m_be_abMacAddr[6];
+    BYTE                        m_bSoaFlag1;
+    BOOL                        m_fSoftDelete;      // delete node after error and ignore error
+
+};
+
+typedef struct _tEplDllkNodeInfo tEplDllkNodeInfo;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p);
+
+tEplKernel EplDllkDelInstance(void);
+
+// called before NMT_GS_COMMUNICATING will be entered to configure fixed parameters
+tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p);
+
+// set identity of local node (may be at any time, e.g. in case of hostname change)
+tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p);
+
+// process internal events and do work that cannot be done in interrupt-context
+tEplKernel EplDllkProcess(tEplEvent * pEvent_p);
+
+// registers handler for non-EPL frames
+tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p);
+
+// deregisters handler for non-EPL frames
+tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p);
+
+// register C_DLL_MULTICAST_ASND in ethernet driver if any AsndServiceId is registered
+tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p, tEplDllAsndFilter Filter_p);
+
+// creates the buffer for a Tx frame and registers it to the ethernet driver
+tEplKernel EplDllkCreateTxFrame(unsigned int * puiHandle_p,
+                                tEplFrame ** ppFrame_p,
+                                unsigned int * puiFrameSize_p,
+                                tEplMsgType MsgType_p,
+                                tEplDllAsndServiceId ServiceId_p);
+
+tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p);
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p);
+
+tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p);
+
+tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p);
+
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+
+tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo** ppNodeInfo_p);
+
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+#endif  // #ifndef _EPL_DLLK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplDllkCal.h b/drivers/staging/epl/kernel/EplDllkCal.h
new file mode 100644 (file)
index 0000000..2db6747
--- /dev/null
@@ -0,0 +1,136 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernelspace DLL Communication Abstraction Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDllkCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/11/13 17:13:09 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/13 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DLLKCAL_H_
+#define _EPL_DLLKCAL_H_
+
+#include "../EplDll.h"
+#include "../EplEvent.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef struct
+{
+    unsigned long   m_ulCurTxFrameCountGen;
+    unsigned long   m_ulCurTxFrameCountNmt;
+    unsigned long   m_ulCurRxFrameCount;
+    unsigned long   m_ulMaxTxFrameCountGen;
+    unsigned long   m_ulMaxTxFrameCountNmt;
+    unsigned long   m_ulMaxRxFrameCount;
+
+} tEplDllkCalStatistics;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+tEplKernel EplDllkCalAddInstance(void);
+
+tEplKernel EplDllkCalDelInstance(void);
+
+tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p, unsigned int * puiCount_p);
+tEplKernel EplDllkCalAsyncGetTxFrame(void * pFrame_p, unsigned int * puiFrameSize_p, tEplDllAsyncReqPriority Priority_p);
+// only frames with registered AsndServiceIds are passed to CAL
+tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p);
+
+tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p);
+
+tEplKernel EplDllkCalAsyncClearBuffer(void);
+
+tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics);
+
+tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+tEplKernel EplDllkCalAsyncClearQueues(void);
+
+tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p, unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+
+tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId* pReqServiceId_p, unsigned int* puiNodeId_p);
+
+tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p, tEplDllAsyncReqPriority AsyncReqPrio_p, unsigned int uiCount_p);
+
+#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
+
+#endif  // #ifndef _EPL_DLLKCAL_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplErrorHandlerk.h b/drivers/staging/epl/kernel/EplErrorHandlerk.h
new file mode 100644 (file)
index 0000000..0f09ef3
--- /dev/null
@@ -0,0 +1,104 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernel error handler module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplErrorHandlerk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/10/02 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_ERRORHANDLERK_H_
+#define _EPL_ERRORHANDLERK_H_
+
+#include "../EplEvent.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+// init function
+tEplKernel PUBLIC EplErrorHandlerkInit(void);
+
+// add instance
+tEplKernel PUBLIC EplErrorHandlerkAddInstance(void);
+
+// delete instance
+tEplKernel PUBLIC EplErrorHandlerkDelInstance(void);
+
+// processes error events
+tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p);
+
+
+#endif  // #ifndef _EPL_ERRORHANDLERK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplEventk.h b/drivers/staging/epl/kernel/EplEventk.h
new file mode 100644 (file)
index 0000000..b889a62
--- /dev/null
@@ -0,0 +1,114 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernel event module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplEventk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/12 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_EVENTK_H_
+#define _EPL_EVENTK_H_
+
+#include "../EplEvent.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+// init function
+tEplKernel PUBLIC EplEventkInit(tEplSyncCb fpSyncCb);
+
+// add instance
+tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb fpSyncCb);
+
+// delete instance
+tEplKernel PUBLIC EplEventkDelInstance(void);
+
+// Kernelthread that dispatches events in kernelspace
+tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p);
+
+// post events from kernelspace
+tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p);
+
+// post errorevents from kernelspace
+tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
+                                     tEplKernel      EplError_p,
+                                     unsigned int    uiArgSize_p,
+                                     void*           pArg_p);
+
+
+
+#endif  // #ifndef _EPL_EVENTK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplNmtk.h b/drivers/staging/epl/kernel/EplNmtk.h
new file mode 100644 (file)
index 0000000..a54dae6
--- /dev/null
@@ -0,0 +1,110 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for NMT-Kernelspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#ifndef _EPLNMTK_H_
+#define _EPLNMTK_H_
+
+#include "../EplNmt.h"
+#include "EplEventk.h"
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
+                                              tEplEvent * pEvent_p);
+
+EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
+
+
+
+#endif  // #ifndef _EPLNMTK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplNmtkCal.h b/drivers/staging/epl/kernel/EplNmtkCal.h
new file mode 100644 (file)
index 0000000..2c76793
--- /dev/null
@@ -0,0 +1,96 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for communication abstraction layer of the
+                NMT-Kernel-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtkCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/16 -k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "EplNmtk.h"
+
+#ifndef _EPLNMTKCAL_H_
+#define _EPLNMTKCAL_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPLNMTKCAL_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplObdk.h b/drivers/staging/epl/kernel/EplObdk.h
new file mode 100644 (file)
index 0000000..ac2b17f
--- /dev/null
@@ -0,0 +1,196 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Epl-Obd-Kernel-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObdk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.8 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplObd.h"
+
+#ifndef _EPLOBDK_H_
+#define _EPLOBDK_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// global variables
+//---------------------------------------------------------------------------
+
+extern BYTE MEM abEplObdTrashObject_g[8];
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdInit (EPL_MCO_DECL_PTR_INSTANCE_PTR_
+    tEplObdInitParam MEM*      pInitParam_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance (EPL_MCO_DECL_PTR_INSTANCE_PTR_
+    tEplObdInitParam MEM*      pInitParam_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance (EPL_MCO_DECL_INSTANCE_PTR);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int  uiIndex_p,
+    unsigned int  uiSubIndex_p,
+    void * pSrcData_p,
+    tEplObdSize   Size_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int        uiIndex_p,
+    unsigned int        uiSubIndex_p,
+    void *       pDstData_p,
+    tEplObdSize *pSize_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdSetStoreLoadObjCallback (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdStoreLoadObjCallback fpCallback_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplObdPart ObdPart_p,
+    tEplObdDir Direction_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar (EPL_MCO_DECL_INSTANCE_PTR_
+    tEplVarParam MEM*          pVarParam_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT void* PUBLIC EplObdGetObjectDataPtr (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p);
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd (EPL_MCO_DECL_INSTANCE_PTR_
+                                        tEplObdEntryPtr pUserOd_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT void PUBLIC EplObdInitVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                        tEplObdVarEntry MEM* pVarEntry_p,
+                                        tEplObdType Type_p, tEplObdSize ObdSize_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_
+                                         unsigned int uiNodeId_p,
+                                         tEplObdNodeIdType NodeIdType_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        BOOL*   pfEntryNumerical);
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        void * pSrcData_p,
+                                        tEplObdSize   Size_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int        uiIndex_p,
+                                        unsigned int        uiSubIndex_p,
+                                        void *       pDstData_p,
+                                        tEplObdSize *pSize_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p,
+                                        tEplObdAccess* pAccessTyp_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObdSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+    unsigned int            uiIndex_p,
+    unsigned int            uiSubindex_p,
+    tEplObdVarEntry MEM**   ppVarEntry_p);
+
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
+
+#endif  // #ifndef _EPLOBDK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplObdkCal.h b/drivers/staging/epl/kernel/EplObdkCal.h
new file mode 100644 (file)
index 0000000..7f4f5ad
--- /dev/null
@@ -0,0 +1,96 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for communication abstraction layer
+                for the Epl-Obd-Kernelspace-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObdkCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplObd.h"
+
+#ifndef _EPLOBDKCAL_H_
+#define _EPLOBDKCAL_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+
+#endif  // #ifndef _EPLOBDKCAL_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplPdok.h b/drivers/staging/epl/kernel/EplPdok.h
new file mode 100644 (file)
index 0000000..a9358ec
--- /dev/null
@@ -0,0 +1,116 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernel PDO module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdok.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/06/23 14:56:33 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_PDOK_H_
+#define _EPL_PDOK_H_
+
+#include "../EplPdo.h"
+#include "../EplEvent.h"
+#include "../EplDll.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+// process events from queue (PDOs/frames and SoA for synchronization)
+tEplKernel EplPdokProcess(tEplEvent * pEvent_p);
+
+// copies RPDO to event queue for processing
+// is called by DLL in NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL
+// PDO needs not to be valid
+tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p);
+
+// posts pointer and size of TPDO to event queue
+// is called by DLL in NMT_CS_PRE_OPERATIONAL_2,
+//     NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL
+tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p);
+
+// posts SoA event to queue
+tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p);
+
+tEplKernel EplPdokAddInstance(void);
+
+tEplKernel EplPdokDelInstance(void);
+
+
+#endif  // #ifndef _EPL_PDOK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplPdokCal.h b/drivers/staging/epl/kernel/EplPdokCal.h
new file mode 100644 (file)
index 0000000..c852c77
--- /dev/null
@@ -0,0 +1,106 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernel PDO Communication Abstraction Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdokCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_PDOKCAL_H_
+#define _EPL_PDOKCAL_H_
+
+#include "../EplInc.h"
+//#include "EplPdo.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdokCalAddInstance(void);
+
+tEplKernel EplPdokCalDelInstance(void);
+
+// sets flag for validity of TPDOs in shared memory
+tEplKernel EplPdokCalSetTpdosValid(BOOL fValid_p);
+
+// gets flag for validity of TPDOs from shared memory
+tEplKernel EplPdokCalAreTpdosValid(BOOL * pfValid_p);
+
+
+
+#endif  // #ifndef _EPL_PDOKCAL_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplTimerHighResk.h b/drivers/staging/epl/kernel/EplTimerHighResk.h
new file mode 100644 (file)
index 0000000..abee2fd
--- /dev/null
@@ -0,0 +1,112 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for EPL high resolution Timermodule
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimerHighResk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/09/29 d.k.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplTimer.h"
+
+#ifndef _EPLTIMERHIGHRESK_H_
+#define _EPLTIMERHIGHRESK_H_
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimerHighReskInit(void);
+
+tEplKernel PUBLIC EplTimerHighReskAddInstance(void);
+
+tEplKernel PUBLIC EplTimerHighReskDelInstance(void);
+
+tEplKernel PUBLIC EplTimerHighReskSetTimerNs(tEplTimerHdl*     pTimerHdl_p,
+                                    unsigned long long  ullTimeNs_p,
+                                    tEplTimerkCallback  pfnCallback_p,
+                                    unsigned long       ulArgument_p,
+                                    BOOL                fContinuously_p);
+
+tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl*     pTimerHdl_p,
+                                    unsigned long long  ullTimeNs_p,
+                                    tEplTimerkCallback  pfnCallback_p,
+                                    unsigned long       ulArgument_p,
+                                    BOOL                fContinuously_p);
+
+tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl*     pTimerHdl_p);
+
+#endif  // #ifndef _EPLTIMERHIGHRESK_H_
+
+
diff --git a/drivers/staging/epl/kernel/EplTimerk.h b/drivers/staging/epl/kernel/EplTimerk.h
new file mode 100644 (file)
index 0000000..ab2bb05
--- /dev/null
@@ -0,0 +1,122 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for EPL Kernel-Timermodule
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimerk.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/06 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplTimer.h"
+#include "../user/EplEventu.h"
+
+#ifndef _EPLTIMERK_H_
+#define _EPLTIMERK_H_
+
+#if EPL_TIMER_USE_USER != FALSE
+#include "../user/EplTimeru.h"
+#endif
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#if EPL_TIMER_USE_USER != FALSE
+#define EplTimerkInit           EplTimeruInit
+#define EplTimerkAddInstance    EplTimeruAddInstance
+#define EplTimerkDelInstance    EplTimeruDelInstance
+#define EplTimerkSetTimerMs     EplTimeruSetTimerMs
+#define EplTimerkModifyTimerMs  EplTimeruModifyTimerMs
+#define EplTimerkDeleteTimer    EplTimeruDeleteTimer
+#endif
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+#if EPL_TIMER_USE_USER == FALSE
+tEplKernel PUBLIC EplTimerkInit(void);
+
+tEplKernel PUBLIC EplTimerkAddInstance(void);
+
+tEplKernel PUBLIC EplTimerkDelInstance(void);
+
+tEplKernel PUBLIC EplTimerkSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long ulTime_p,
+                                        tEplTimerArg  Argument_p);
+
+tEplKernel PUBLIC EplTimerkModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long     ulTime_p,
+                                        tEplTimerArg      Argument_p);
+
+tEplKernel PUBLIC EplTimerkDeleteTimer(tEplTimerHdl*     pTimerHdl_p);
+#endif
+#endif  // #ifndef _EPLTIMERK_H_
+
+
diff --git a/drivers/staging/epl/kernel/VirtualEthernet.h b/drivers/staging/epl/kernel/VirtualEthernet.h
new file mode 100644 (file)
index 0000000..8501747
--- /dev/null
@@ -0,0 +1,101 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for virtual ethernet driver module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: VirtualEthernet.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                KEIL uVision 2
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/09/19 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_VETH_H_
+#define _EPL_VETH_H_
+
+#include "EplDllk.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
+
+tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p);
+
+tEplKernel PUBLIC VEthDelInstance(void);
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
+
+#endif  // #ifndef _EPL_VETH_H_
+
+
diff --git a/drivers/staging/epl/proc_fs.c b/drivers/staging/epl/proc_fs.c
new file mode 100644 (file)
index 0000000..5258e49
--- /dev/null
@@ -0,0 +1,420 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  proc fs entry with diagnostic information under Linux
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: proc_fs.c,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.13 $  $Date: 2008/11/07 13:55:56 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GNU
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/31 d.k.:   start of implementation
+
+****************************************************************************/
+
+#include "kernel/EplNmtk.h"
+#include "user/EplNmtu.h"
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+#include "user/EplNmtMnu.h"
+#endif
+
+#include "kernel/EplDllkCal.h"
+
+//#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+
+#ifdef CONFIG_COLDFIRE
+    #include <asm/coldfire.h>
+    #include "fec.h"
+#endif
+
+
+/***************************************************************************/
+/*                                                                         */
+/*                                                                         */
+/*          G L O B A L   D E F I N I T I O N S                            */
+/*                                                                         */
+/*                                                                         */
+/***************************************************************************/
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+#ifndef EPL_PROC_DEV_NAME
+#define EPL_PROC_DEV_NAME    "epl"
+#endif
+
+#ifndef DBG_TRACE_POINTS
+#define DBG_TRACE_POINTS    23  // # of supported debug trace points
+#endif
+
+#ifndef DBG_TRACE_VALUES
+#define DBG_TRACE_VALUES    24 // # of supported debug trace values (size of circular buffer)
+#endif
+
+//---------------------------------------------------------------------------
+// modul global types
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// local vars
+//---------------------------------------------------------------------------
+
+#ifdef _DBG_TRACE_POINTS_
+    atomic_t            aatmDbgTracePoint_l[DBG_TRACE_POINTS];
+    DWORD               adwDbgTraceValue_l[DBG_TRACE_VALUES];
+    DWORD               dwDbgTraceValueOld_l;
+    unsigned int        uiDbgTraceValuePos_l;
+    spinlock_t          spinlockDbgTraceValue_l;
+    unsigned long       ulDbTraceValueFlags_l;
+#endif
+
+//---------------------------------------------------------------------------
+// local function prototypes
+//---------------------------------------------------------------------------
+
+static  int        EplLinProcRead       (char* pcBuffer_p, char** ppcStart_p, off_t Offset_p, int nBufferSize_p, int* pEof_p, void* pData_p);
+static int EplLinProcWrite(struct file *file, const char __user *buffer, unsigned long count, void *data);
+
+void  PUBLIC  TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
+void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p);
+
+
+EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void);
+
+
+//=========================================================================//
+//                                                                         //
+//          P U B L I C   F U N C T I O N S                                //
+//                                                                         //
+//=========================================================================//
+
+tEplKernel EplLinProcInit(void)
+{
+    struct proc_dir_entry*  pProcDirEntry;
+    pProcDirEntry = create_proc_entry (EPL_PROC_DEV_NAME, S_IRUGO, NULL);
+    if (pProcDirEntry != NULL)
+    {
+        pProcDirEntry->read_proc  = EplLinProcRead;
+        pProcDirEntry->write_proc = EplLinProcWrite;
+        pProcDirEntry->data       = NULL; // device number or something else
+
+    }
+    else
+    {
+        return kEplNoResource;
+    }
+
+#ifdef _DBG_TRACE_POINTS_
+    // initialize spinlock and circular buffer position
+    spin_lock_init(&spinlockDbgTraceValue_l);
+    uiDbgTraceValuePos_l = 0;
+    dwDbgTraceValueOld_l = 0;
+#endif
+
+    return kEplSuccessful;
+}
+
+tEplKernel EplLinProcFree(void)
+{
+    remove_proc_entry (EPL_PROC_DEV_NAME, NULL);
+
+    return kEplSuccessful;
+}
+
+//---------------------------------------------------------------------------
+//  Target specific event signaling (FEC Tx-/Rx-Interrupt, used by Edrv)
+//---------------------------------------------------------------------------
+
+#ifdef _DBG_TRACE_POINTS_
+void  PUBLIC  TgtDbgSignalTracePoint (
+    BYTE bTracePointNumber_p)
+{
+
+    if (bTracePointNumber_p >= (sizeof(aatmDbgTracePoint_l) / sizeof(aatmDbgTracePoint_l[0])))
+    {
+        goto Exit;
+    }
+
+
+    atomic_inc (&aatmDbgTracePoint_l[bTracePointNumber_p]);
+
+Exit:
+
+    return;
+
+}
+
+void  PUBLIC  TgtDbgPostTraceValue (DWORD dwTraceValue_p)
+{
+
+    spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
+    if (dwDbgTraceValueOld_l != dwTraceValue_p)
+    {
+        adwDbgTraceValue_l[uiDbgTraceValuePos_l] = dwTraceValue_p;
+        uiDbgTraceValuePos_l = (uiDbgTraceValuePos_l + 1) % DBG_TRACE_VALUES;
+        dwDbgTraceValueOld_l = dwTraceValue_p;
+    }
+    spin_unlock_irqrestore(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
+
+    return;
+
+}
+#endif
+
+
+//---------------------------------------------------------------------------
+//  Read function for PROC-FS read access
+//---------------------------------------------------------------------------
+
+static  int  EplLinProcRead (
+    char* pcBuffer_p,
+    char** ppcStart_p,
+    off_t Offset_p,
+    int nBufferSize_p,
+    int* pEof_p,
+    void* pData_p)
+{
+
+int             nSize;
+int             Eof;
+tEplDllkCalStatistics* pDllkCalStats;
+
+    nSize = 0;
+    Eof   = 0;
+
+    // count calls of this function
+#ifdef _DBG_TRACE_POINTS_
+    TgtDbgSignalTracePoint(0);
+#endif
+
+    //---------------------------------------------------------------
+    // generate static information
+    //---------------------------------------------------------------
+
+    // ---- Driver information ----
+    nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                       "%s    %s    (c) 2006 %s\n",
+                       EPL_PRODUCT_NAME, EPL_PRODUCT_VERSION, EPL_PRODUCT_MANUFACTURER);
+
+
+    //---------------------------------------------------------------
+    // generate process information
+    //---------------------------------------------------------------
+
+    // ---- EPL state ----
+    nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                       "NMT state:                  0x%04X\n",
+                       (WORD) EplNmtkGetNmtState());
+
+    EplDllkCalGetStatistics(&pDllkCalStats);
+
+    nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                       "CurAsyncTxGen=%lu CurAsyncTxNmt=%lu CurAsyncRx=%lu\nMaxAsyncTxGen=%lu MaxAsyncTxNmt=%lu MaxAsyncRx=%lu\n", pDllkCalStats->m_ulCurTxFrameCountGen, pDllkCalStats->m_ulCurTxFrameCountNmt, pDllkCalStats->m_ulCurRxFrameCount, pDllkCalStats->m_ulMaxTxFrameCountGen, pDllkCalStats->m_ulMaxTxFrameCountNmt, pDllkCalStats->m_ulMaxRxFrameCount);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+    // fetch running IdentRequests
+    nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                       "running IdentRequests:      0x%08lX\n",
+                       EplIdentuGetRunningRequests());
+
+    // fetch state of NmtMnu module
+    {
+    unsigned int    uiMandatorySlaveCount;
+    unsigned int    uiSignalSlaveCount;
+    WORD            wFlags;
+
+        EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount,
+                                   &uiSignalSlaveCount,
+                                   &wFlags);
+
+
+        nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                           "MN  MandSlaveCount: %u  SigSlaveCount: %u  Flags: 0x%X\n",
+                           uiMandatorySlaveCount, uiSignalSlaveCount, wFlags);
+
+    }
+#endif
+
+    // ---- FEC state ----
+    #ifdef CONFIG_COLDFIRE
+    {
+        // Receive the base address
+        unsigned long base_addr;
+        #if (EDRV_USED_ETH_CTRL == 0)
+            // Set the base address of FEC0
+            base_addr = FEC_BASE_ADDR_FEC0;
+        #else
+            // Set the base address of FEC1
+            base_addr = FEC_BASE_ADDR_FEC1;
+        #endif
+
+        nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                           "FEC_ECR = 0x%08X FEC_EIR = 0x%08X FEC_EIMR = 0x%08X\nFEC_TCR = 0x%08X FECTFSR = 0x%08X FECRFSR = 0x%08X\n",
+                           FEC_ECR(base_addr), FEC_EIR(base_addr), FEC_EIMR(base_addr), FEC_TCR(base_addr), FEC_FECTFSR(base_addr), FEC_FECRFSR(base_addr));
+    }
+    #endif
+
+
+    // ---- DBG: TracePoints ----
+    #ifdef _DBG_TRACE_POINTS_
+    {
+        int nNum;
+
+        nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                           "DbgTracePoints:\n");
+        for (nNum=0; nNum<(sizeof(aatmDbgTracePoint_l)/sizeof(atomic_t)); nNum++)
+        {
+            nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                               " TracePoint[%2d]: %d\n", (int)nNum,
+                               atomic_read(&aatmDbgTracePoint_l[nNum]));
+        }
+
+        nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                           "DbgTraceValues:\n");
+        for (nNum=0; nNum<DBG_TRACE_VALUES; nNum++)
+        {
+            if (nNum == uiDbgTraceValuePos_l)
+            {   // next value will be stored at that position
+                nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                                   "*%08lX", adwDbgTraceValue_l[nNum]);
+            }
+            else
+            {
+                nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                                   " %08lX", adwDbgTraceValue_l[nNum]);
+            }
+            if ((nNum & 0x00000007) == 0x00000007)
+            {   // 8 values printed -> end of line reached
+                nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                                   "\n");
+            }
+        }
+        if ((nNum & 0x00000007) != 0x00000007)
+        {   // number of values printed is not a multiple of 8 -> print new line
+            nSize += snprintf (pcBuffer_p + nSize, nBufferSize_p - nSize,
+                               "\n");
+        }
+    }
+    #endif
+
+
+    Eof = 1;
+    goto Exit;
+
+
+Exit:
+
+    *pEof_p = Eof;
+
+    return (nSize);
+
+}
+
+
+//---------------------------------------------------------------------------
+//  Write function for PROC-FS write access
+//---------------------------------------------------------------------------
+
+static int EplLinProcWrite(struct file *file, const char __user *buffer, unsigned long count, void *data)
+{
+char            abBuffer[count + 1];
+int             iErr;
+int             iVal = 0;
+tEplNmtEvent    NmtEvent;
+
+    if (count > 0)
+    {
+        iErr = copy_from_user(abBuffer, buffer, count);
+        if (iErr != 0)
+        {
+            return count;
+        }
+        abBuffer[count] = '\0';
+
+        iErr = sscanf(abBuffer, "%i", &iVal);
+    }
+    if ((iVal <= 0) || (iVal > 0x2F))
+    {
+        NmtEvent = kEplNmtEventSwReset;
+    }
+    else
+    {
+        NmtEvent = (tEplNmtEvent) iVal;
+    }
+    // execute specified NMT command on write access of /proc/epl
+    EplNmtuNmtEvent(NmtEvent);
+
+    return count;
+}
+
+
diff --git a/drivers/staging/epl/proc_fs.h b/drivers/staging/epl/proc_fs.h
new file mode 100644 (file)
index 0000000..5af2d3a
--- /dev/null
@@ -0,0 +1,94 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  interface for proc fs entry under Linux
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: proc_fs.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:33 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GNU
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/31 d.k.:   start of implementation
+
+****************************************************************************/
+
+#ifndef _EPLPROCFS_H_
+#define _EPLPROCFS_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// types
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel EplLinProcInit(void);
+tEplKernel EplLinProcFree(void);
+
+
+#endif  // #ifndef _EPLPROCFS_H_
+
+
diff --git a/drivers/staging/epl/user/EplCfgMau.h b/drivers/staging/epl/user/EplCfgMau.h
new file mode 100644 (file)
index 0000000..3d96daf
--- /dev/null
@@ -0,0 +1,299 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Epl Configuration Manager Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplCfgMau.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                VC7
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/14 k.t.:   start of the implementation
+                     -> based on CANopen CfgMa-Modul (CANopen version 5.34)
+
+****************************************************************************/
+
+#include "../EplInc.h"
+
+#ifndef _EPLCFGMA_H_
+#define _EPLCFGMA_H_
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
+
+#include "EplObdu.h"
+#include "EplSdoComu.h"
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+//define max number of timeouts for configuration of 1 device
+#define EPL_CFGMA_MAX_TIMEOUT   3
+
+//callbackfunction, called if configuration is finished
+typedef void (PUBLIC* tfpEplCfgMaCb) (unsigned int uiNodeId_p,
+                                tEplKernel Errorstate_p);
+
+//State for configuartion manager Statemachine
+typedef enum
+{
+    // general states
+    kEplCfgMaIdle                  = 0x0000,  // Configurationsprocess
+                                              // is idle
+    kEplCfgMaWaitForSdocEvent      = 0x0001,  // wait until the last
+                                              // SDOC is finisched
+    kEplCfgMaSkipMappingSub0       = 0x0002,  // write Sub0 of mapping
+                                              // parameter with 0
+
+    kEplCfgMaFinished              = 0x0004   // configuartion is finished
+
+} tEplCfgState;
+
+typedef enum
+{
+    kEplCfgMaDcfTypSystecSeg     = 0x00,
+    kEplCfgMaDcfTypConDcf        = 0x01,
+    kEplCfgMaDcfTypDcf           = 0x02, // not supported
+    kEplCfgMaDcfTypXdc           = 0x03  // not supported
+
+
+}tEplCfgMaDcfTyp;
+
+typedef enum
+{
+    kEplCfgMaCommon                = 0,        // all other index
+    kEplCfgMaPdoComm               = 1,        // communication index
+    kEplCfgMaPdoMapp               = 2,        // mapping index
+    kEplCfgMaPdoCommAfterMapp      = 3,        // write PDO Cob-Id after mapping subindex 0(set PDO valid)
+
+} tEplCfgMaIndexType;
+
+
+//bitcoded answer about the last sdo transfer saved in m_SdocState
+// also used to singal start of the State Maschine
+typedef enum
+{
+    kEplCfgMaSdocBusy           =   0x00,   // SDOC activ
+    kEplCfgMaSdocReady          =   0x01,   // SDOC finished
+    kEplCfgMaSdocTimeout        =   0x02,   // SDOC Timeout
+    kEplCfgMaSdocAbortReceived  =   0x04,   // SDOC Abort, see Abortcode
+    kEplCfgMaSdocStart          =   0x08    // start State Mschine
+}tEplSdocState;
+
+//internal structure (instancetable for modul configuration manager)
+typedef struct
+{
+    tEplCfgState        m_CfgState;             // state of the configuration state maschine
+    tEplSdoComConHdl    m_SdoComConHdl;         // handle for sdo connection
+    DWORD               m_dwLastAbortCode;
+    unsigned int        m_uiLastIndex;          // last index of configuration, to compair with actual index
+    BYTE*               m_pbConcise;            // Ptr to concise DCF
+    BYTE*               m_pbActualIndex;        // Ptr to actual index in the DCF segment
+    tfpEplCfgMaCb       m_pfnCfgMaCb;           // Ptr to CfgMa Callback, is call if configuration finished
+    tEplKernel          m_EplKernelError;       // errorcode
+    DWORD               m_dwNumValueCopy;       // numeric values are copied in this variable
+    unsigned int        m_uiPdoNodeId;          // buffer for PDO node id
+    BYTE                m_bNrOfMappedObject;    // number of mapped objects
+    unsigned int        m_uiNodeId;             // Epl node addresse
+    tEplSdocState       m_SdocState;            // bitcoded state of the SDO transfer
+    unsigned int        m_uiLastSubIndex;       // last subindex of configuration
+    BOOL                m_fOneTranferOk;        // atleased one transfer was successful
+    BYTE                m_bEventFlag;           // for Eventsignaling to the State Maschine
+    DWORD               m_dwCntObjectInDcf;     // number of Objects in DCF
+    tEplCfgMaIndexType  m_SkipCfg;              // TRUE if a adsitional Configurationprocess
+                                                // have to insert e.g. PDO-mapping
+    WORD                m_wTimeOutCnt;          // Timeout Counter, break configuration is
+                                                // m_wTimeOutCnt == CFGMA_MAX_TIMEOUT
+
+} tEplCfgMaNode;
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaInit()
+//
+// Description: Function creates first instance of Configuration Manager
+//
+// Parameters:
+//
+// Returns:     tEplKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaInit();
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaAddInstance()
+//
+// Description: Function creates additional instance of Configuration Manager
+//
+// Parameters:
+//
+// Returns:     tEplKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaAddInstance();
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaDelInstance()
+//
+// Description: Function delete instance of Configuration Manager
+//
+// Parameters:
+//
+// Returns:     tEplKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaDelInstance();
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaStartConfig()
+//
+// Description: Function starts the configuration process
+//              initialization the statemachine for CfgMa- process
+//
+// Parameters:  uiNodeId_p              = NodeId of the node to configure
+//              pbConcise_p             = pointer to DCF
+//              fpCfgMaCb_p             = pointer to callback function (should not be NULL)
+//              SizeOfConcise_p         = size of DCF in BYTE -> for future use
+//              DcfType_p               = type of the DCF
+//
+// Returns:     tCopKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaStartConfig(unsigned int    uiNodeId_p,
+                                    BYTE*             pbConcise_p,
+                                    tfpEplCfgMaCb     fpCfgMaCb_p,
+                                    tEplObdSize       SizeOfConcise_p,
+                                    tEplCfgMaDcfTyp   DcfType_p);
+
+
+//---------------------------------------------------------------------------
+// Function:    CfgMaStartConfigurationNode()
+//
+// Description: Function started the configuration process
+//              with the DCF from according OD-entry Subindex == bNodeId_p
+//
+// Parameters:  uiNodeId_p              = NodeId of the node to configure
+//              fpCfgMaCb_p             = pointer to callback function (should not be NULL)
+//              DcfType_p               = type of the DCF
+//
+// Returns:     tCopKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
+                                    tfpEplCfgMaCb      fpCfgMaCb_p,
+                                    tEplCfgMaDcfTyp    DcfType_p);
+
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaStartConfigNodeDcf()
+//
+// Description: Function starts the configuration process
+//              and links the configuration data to the OD
+//
+// Parameters:  uiNodeId_p              = NodeId of the node to configure
+//              pbConcise_p             = pointer to DCF
+//              fpCfgMaCb_p             = pointer to callback function (should not be NULL)
+//              SizeOfConcise_p         = size of DCF in BYTE -> for future use
+//              DcfType_p               = type of the DCF
+//
+// Returns:     tCopKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaStartConfigNodeDcf(unsigned int    uiNodeId_p,
+                                    BYTE*             pbConcise_p,
+                                    tfpEplCfgMaCb     fpCfgMaCb_p,
+                                    tEplObdSize       SizeOfConcise_p,
+                                    tEplCfgMaDcfTyp   DcfType_p);
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaLinkDcf()
+//
+// Description: Function links the configuration data to the OD
+//
+// Parameters:  uiNodeId_p              = NodeId of the node to configure
+//              pbConcise_p             = pointer to DCF
+//              SizeOfConcise_p        = size of DCF in BYTE -> for future use
+//              DcfType_p               = type of the DCF
+//
+// Returns:     tCopKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaLinkDcf(unsigned int    uiNodeId_p,
+                                    BYTE*             pbConcise_p,
+                                    tEplObdSize       SizeOfConcise_p,
+                                    tEplCfgMaDcfTyp   DcfType_p);
+
+//---------------------------------------------------------------------------
+// Function:    EplCfgMaCheckDcf()
+//
+// Description: Function check if there is allready a configuration file linked
+//              to the OD (type is given by DcfType_p)
+//
+// Parameters:  uiNodeId_p              = NodeId
+//              DcfType_p               = type of the DCF
+//
+// Returns:     tCopKernel              = error code
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplCfgMaCheckDcf(unsigned int      uiNodeId_p,
+                                    tEplCfgMaDcfTyp  DcfType_p);
+
+
+
+
+
+#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
+
+#endif // _EPLCFGMA_H_
+
+// EOF
diff --git a/drivers/staging/epl/user/EplDllu.h b/drivers/staging/epl/user/EplDllu.h
new file mode 100644 (file)
index 0000000..2beb390
--- /dev/null
@@ -0,0 +1,108 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for userspace DLL module for asynchronous communication
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDllu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/20 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DLLU_H_
+#define _EPL_DLLU_H_
+
+#include "../EplDll.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef tEplKernel (PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+
+tEplKernel EplDlluAddInstance(void);
+
+tEplKernel EplDlluDelInstance(void);
+
+tEplKernel EplDlluRegAsndService(tEplDllAsndServiceId ServiceId_p, tEplDlluCbAsnd pfnDlluCbAsnd_p, tEplDllAsndFilter Filter_p);
+
+tEplKernel EplDlluAsyncSend(tEplFrameInfo * pFrameInfo_p, tEplDllAsyncReqPriority Priority_p);
+
+// processes asynch frames
+tEplKernel EplDlluProcess(tEplFrameInfo * pFrameInfo_p);
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
+
+#endif  // #ifndef _EPL_DLLU_H_
+
+
diff --git a/drivers/staging/epl/user/EplDlluCal.h b/drivers/staging/epl/user/EplDlluCal.h
new file mode 100644 (file)
index 0000000..b2b85ba
--- /dev/null
@@ -0,0 +1,120 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for DLL Communication Abstraction Layer module in EPL user part
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplDlluCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/20 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_DLLUCAL_H_
+#define _EPL_DLLUCAL_H_
+
+#include "../EplDll.h"
+#include "../EplEvent.h"
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef tEplKernel (PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel EplDlluCalAddInstance(void);
+
+tEplKernel EplDlluCalDelInstance(void);
+
+tEplKernel EplDlluCalRegAsndService(tEplDllAsndServiceId ServiceId_p,
+                                    tEplDlluCbAsnd pfnDlluCbAsnd_p,
+                                    tEplDllAsndFilter Filter_p);
+
+tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo, tEplDllAsyncReqPriority Priority_p);
+
+tEplKernel EplDlluCalProcess(tEplEvent * pEvent_p);
+
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+tEplKernel EplDlluCalAddNode(tEplDllNodeInfo * pNodeInfo_p);
+
+tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p);
+
+tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p);
+
+tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p, unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+
+#endif
+
+
+#endif  // #ifndef _EPL_DLLUCAL_H_
+
+
diff --git a/drivers/staging/epl/user/EplEventu.h b/drivers/staging/epl/user/EplEventu.h
new file mode 100644 (file)
index 0000000..57f8b42
--- /dev/null
@@ -0,0 +1,115 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for kernel event module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplEventu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/12 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_EVENTU_H_
+#define _EPL_EVENTU_H_
+
+#include "../EplEvent.h"
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+// init function
+tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
+
+// add instance
+tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p);
+
+// delete instance
+tEplKernel PUBLIC EplEventuDelInstance(void);
+
+// Task that dispatches events in userspace
+tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p);
+
+// post events from userspace
+tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p);
+
+// post errorevents from userspace
+tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
+                                     tEplKernel      EplError_p,
+                                     unsigned int    uiArgSize_p,
+                                     void*           pArg_p);
+
+
+
+#endif  // #ifndef _EPL_EVENTU_H_
+
+
diff --git a/drivers/staging/epl/user/EplIdentu.h b/drivers/staging/epl/user/EplIdentu.h
new file mode 100644 (file)
index 0000000..b53afa0
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Identu-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplIdentu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/11/15 d.k.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplDll.h"
+
+#ifndef _EPLIDENTU_H_
+#define _EPLIDENTU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef tEplKernel (PUBLIC * tEplIdentuCbResponse) (
+                                  unsigned int        uiNodeId_p,
+                                  tEplIdentResponse* pIdentResponse_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplIdentuInit(void);
+
+tEplKernel PUBLIC EplIdentuAddInstance(void);
+
+tEplKernel PUBLIC EplIdentuDelInstance(void);
+
+tEplKernel PUBLIC EplIdentuReset(void);
+
+tEplKernel PUBLIC EplIdentuGetIdentResponse(
+                                  unsigned int        uiNodeId_p,
+                                  tEplIdentResponse** ppIdentResponse_p);
+
+tEplKernel PUBLIC EplIdentuRequestIdentResponse(
+                                  unsigned int        uiNodeId_p,
+                                  tEplIdentuCbResponse pfnCbResponse_p);
+
+#endif  // #ifndef _EPLIDENTU_H_
+
+
diff --git a/drivers/staging/epl/user/EplLedu.h b/drivers/staging/epl/user/EplLedu.h
new file mode 100644 (file)
index 0000000..10a8b6b
--- /dev/null
@@ -0,0 +1,116 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for status and error LED user part module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplLedu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.1 $  $Date: 2008/11/17 16:40:39 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2008/11/17 d.k.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplLed.h"
+#include "../EplNmt.h"
+#include "EplEventu.h"
+
+#ifndef _EPLLEDU_H_
+#define _EPLLEDU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+typedef tEplKernel (PUBLIC * tEplLeduStateChangeCallback) (
+    tEplLedType LedType_p, BOOL fOn_p);
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+
+tEplKernel PUBLIC EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
+
+tEplKernel PUBLIC EplLeduAddInstance(tEplLeduStateChangeCallback pfnCbStateChange_p);
+
+tEplKernel PUBLIC EplLeduDelInstance(void);
+
+tEplKernel PUBLIC EplLeduCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
+
+tEplKernel PUBLIC EplLeduProcessEvent(
+                                tEplEvent* pEplEvent_p);
+
+
+#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
+
+#endif  // #ifndef _EPLLEDU_H_
+
+
diff --git a/drivers/staging/epl/user/EplNmtCnu.h b/drivers/staging/epl/user/EplNmtCnu.h
new file mode 100644 (file)
index 0000000..93a3289
--- /dev/null
@@ -0,0 +1,112 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for NMT-CN-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtCnu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "EplNmtu.h"
+#include "../EplDll.h"
+#include "../EplFrame.h"
+
+#ifndef _EPLNMTCNU_H_
+#define _EPLNMTCNU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance(void);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest (unsigned int uiNodeId_p,
+                                    tEplNmtCommand  NmtCommand_p);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuRegisterCheckEventCb(
+            tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p);
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
+
+#endif  // #ifndef _EPLNMTCNU_H_
+
+
diff --git a/drivers/staging/epl/user/EplNmtMnu.h b/drivers/staging/epl/user/EplNmtMnu.h
new file mode 100644 (file)
index 0000000..a101fde
--- /dev/null
@@ -0,0 +1,136 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for NMT-MN-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtMnu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "EplNmtu.h"
+
+#ifndef _EPLNMTMNU_H_
+#define _EPLNMTMNU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef tEplKernel (PUBLIC * tEplNmtMnuCbNodeEvent) (
+    unsigned int uiNodeId_p,
+    tEplNmtNodeEvent NodeEvent_p,
+    tEplNmtState NmtState_p,
+    WORD wErrorCode_p,
+    BOOL fMandatory_p);
+
+
+typedef tEplKernel (PUBLIC * tEplNmtMnuCbBootEvent) (
+    tEplNmtBootEvent BootEvent_p,
+    tEplNmtState NmtState_p,
+    WORD wErrorCode_p);
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
+
+tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
+                         tEplNmtMnuCbBootEvent pfnCbBootEvent_p);
+
+tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
+                                tEplNmtMnuCbBootEvent pfnCbBootEvent_p);
+
+tEplKernel EplNmtMnuDelInstance(void);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(
+            tEplEvent* pEvent_p);
+
+tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
+                                   tEplNmtCommand  NmtCommand_p);
+
+tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
+                                       tEplNmtNodeCommand  NodeCommand_p);
+
+tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
+
+tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
+
+tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int* puiMandatorySlaveCount_p,
+                                             unsigned int* puiSignalSlaveCount_p,
+                                             WORD* pwFlags_p);
+
+#endif
+
+#endif  // #ifndef _EPLNMTMNU_H_
+
+
diff --git a/drivers/staging/epl/user/EplNmtu.h b/drivers/staging/epl/user/EplNmtu.h
new file mode 100644 (file)
index 0000000..0ed7fff
--- /dev/null
@@ -0,0 +1,161 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for NMT-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/09 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplNmt.h"
+#include "EplEventu.h"
+
+#ifndef _EPLNMTU_H_
+#define _EPLNMTU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+// nmt commands
+typedef enum
+{
+    // requestable ASnd ServiceIds    0x01..0x1F
+    kEplNmtCmdIdentResponse             = 0x01,
+    kEplNmtCmdStatusResponse            = 0x02,
+    // plain NMT state commands       0x20..0x3F
+    kEplNmtCmdStartNode                 = 0x21,
+    kEplNmtCmdStopNode                  = 0x22,
+    kEplNmtCmdEnterPreOperational2      = 0x23,
+    kEplNmtCmdEnableReadyToOperate      = 0x24,
+    kEplNmtCmdResetNode                 = 0x28,
+    kEplNmtCmdResetCommunication        = 0x29,
+    kEplNmtCmdResetConfiguration        = 0x2A,
+    kEplNmtCmdSwReset                   = 0x2B,
+    // extended NMT state commands    0x40..0x5F
+    kEplNmtCmdStartNodeEx               = 0x41,
+    kEplNmtCmdStopNodeEx                = 0x42,
+    kEplNmtCmdEnterPreOperational2Ex    = 0x43,
+    kEplNmtCmdEnableReadyToOperateEx    = 0x44,
+    kEplNmtCmdResetNodeEx               = 0x48,
+    kEplNmtCmdResetCommunicationEx      = 0x49,
+    kEplNmtCmdResetConfigurationEx      = 0x4A,
+    kEplNmtCmdSwResetEx                 = 0x4B,
+    // NMT managing commands          0x60..0x7F
+    kEplNmtCmdNetHostNameSet            = 0x62,
+    kEplNmtCmdFlushArpEntry             = 0x63,
+    // NMT info services              0x80..0xBF
+    kEplNmtCmdPublishConfiguredCN       = 0x80,
+    kEplNmtCmdPublishActiveCN           = 0x90,
+    kEplNmtCmdPublishPreOperational1    = 0x91,
+    kEplNmtCmdPublishPreOperational2    = 0x92,
+    kEplNmtCmdPublishReadyToOperate     = 0x93,
+    kEplNmtCmdPublishOperational        = 0x94,
+    kEplNmtCmdPublishStopped            = 0x95,
+    kEplNmtCmdPublishEmergencyNew       = 0xA0,
+    kEplNmtCmdPublishTime               = 0xB0,
+
+    kEplNmtCmdInvalidService            = 0xFF
+
+} tEplNmtCommand;
+
+typedef tEplKernel (PUBLIC * tEplNmtuStateChangeCallback) (
+    tEplEventNmtStateChange  NmtStateChange_p);
+
+typedef tEplKernel (PUBLIC * tEplNmtuCheckEventCallback) (
+    tEplNmtEvent  NmtEvent_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit(void);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance(void);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance(void);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
+
+EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState(void);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(
+                                tEplEvent* pEplEvent_p);
+
+EPLDLLEXPORT tEplKernel PUBLIC EplNmtuRegisterStateChangeCb(
+                tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p);
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
+
+#endif  // #ifndef _EPLNMTU_H_
+
+
diff --git a/drivers/staging/epl/user/EplNmtuCal.h b/drivers/staging/epl/user/EplNmtuCal.h
new file mode 100644 (file)
index 0000000..6d964bb
--- /dev/null
@@ -0,0 +1,97 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for communication abstraction layer of the
+                NMT-Userspace-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplNmtuCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/16 -k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "EplNmtu.h"
+#include "../kernel/EplNmtk.h"
+
+#ifndef _EPLNMTUCAL_H_
+#define _EPLNMTUCAL_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState(void);
+
+#endif  // #ifndef _EPLNMTUCAL_H_
+
+
diff --git a/drivers/staging/epl/user/EplObdu.h b/drivers/staging/epl/user/EplObdu.h
new file mode 100644 (file)
index 0000000..14dd879
--- /dev/null
@@ -0,0 +1,196 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Epl-Obd-Userspace-module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObdu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplObd.h"
+
+#ifndef _EPLOBDU_H_
+#define _EPLOBDU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+
+#if EPL_OBD_USE_KERNEL != FALSE
+#error "EPL OBDu module enabled, but OBD_USE_KERNEL == TRUE"
+#endif
+
+EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry (unsigned int  uiIndex_p,
+                                unsigned int  uiSubIndex_p,
+                                void * pSrcData_p,
+                                tEplObdSize   Size_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry (unsigned int        uiIndex_p,
+                                unsigned int        uiSubIndex_p,
+                                void *       pDstData_p,
+                                tEplObdSize *pSize_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart (tEplObdPart ObdPart_p,
+                                tEplObdDir Direction_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar (tEplVarParam MEM* pVarParam_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT void* PUBLIC EplObduGetObjectDataPtr (unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p);
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd (
+                                        tEplObdEntryPtr pUserOd_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT void PUBLIC EplObduInitVarEntry (tEplObdVarEntry MEM* pVarEntry_p,
+                                        BYTE bType_p,
+                                        tEplObdSize ObdSize_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId(void);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
+                                         tEplObdNodeIdType NodeIdType_p);
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
+                                        unsigned int   uiSubIndex_p,
+                                        tEplObdAccess* pAccessTyp_p);
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe (unsigned int        uiIndex_p,
+                                        unsigned int        uiSubIndex_p,
+                                        void *              pDstData_p,
+                                        tEplObdSize *       pSize_p);
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe (unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        void *        pSrcData_p,
+                                        tEplObdSize   Size_p);
+
+// ---------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int            uiIndex_p,
+                                        unsigned int            uiSubindex_p,
+                                        tEplObdVarEntry MEM**   ppVarEntry_p);
+
+#elif EPL_OBD_USE_KERNEL != FALSE
+#include "../kernel/EplObdk.h"
+
+#define EplObduWriteEntry       EplObdWriteEntry
+
+#define EplObduReadEntry        EplObdReadEntry
+
+#define EplObduAccessOdPart     EplObdAccessOdPart
+
+#define EplObduDefineVar        EplObdDefineVar
+
+#define EplObduGetObjectDataPtr EplObdGetObjectDataPtr
+
+#define EplObduRegisterUserOd   EplObdRegisterUserOd
+
+#define EplObduInitVarEntry     EplObdInitVarEntry
+
+#define EplObduGetDataSize      EplObdGetDataSize
+
+#define EplObduGetNodeId        EplObdGetNodeId
+
+#define EplObduSetNodeId        EplObdSetNodeId
+
+#define EplObduGetAccessType    EplObdGetAccessType
+
+#define EplObduReadEntryToLe    EplObdReadEntryToLe
+
+#define EplObduWriteEntryFromLe EplObdWriteEntryFromLe
+
+#define EplObduSearchVarEntry   EplObdSearchVarEntry
+
+#define EplObduIsNumerical      EplObdIsNumerical
+
+#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
+
+#endif  // #ifndef _EPLOBDU_H_
+
+
diff --git a/drivers/staging/epl/user/EplObduCal.h b/drivers/staging/epl/user/EplObduCal.h
new file mode 100644 (file)
index 0000000..26d23c5
--- /dev/null
@@ -0,0 +1,148 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for communication abstraction layer
+                for the Epl-Obd-Userspace-Modul
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplObduCal.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/19 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplObd.h"
+
+#ifndef _EPLOBDUCAL_H_
+#define _EPLOBDUCAL_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry (
+                                                unsigned int  uiIndex_p,
+                                                unsigned int  uiSubIndex_p,
+                                                void * pSrcData_p,
+                                                tEplObdSize   Size_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry (
+                                            unsigned int        uiIndex_p,
+                                            unsigned int        uiSubIndex_p,
+                                            void *       pDstData_p,
+                                            tEplObdSize *pSize_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart (
+                                                    tEplObdPart ObdPart_p,
+                                                    tEplObdDir Direction_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar (tEplVarParam MEM* pVarParam_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT void* PUBLIC EplObduCalGetObjectDataPtr ( unsigned int uiIndex_p,
+                                            unsigned int uiSubIndex_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd (tEplObdEntryPtr pUserOd_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry (tEplObdVarEntry MEM* pVarEntry_p,
+                                        BYTE bType_p, tEplObdSize ObdSize_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
+                                        unsigned int uiSubIndex_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId(void);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
+                                         tEplObdNodeIdType NodeIdType_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
+                                        unsigned int   uiSubIndex_p,
+                                        tEplObdAccess* pAccessTyp_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe (unsigned int        uiIndex_p,
+                                        unsigned int        uiSubIndex_p,
+                                        void *              pDstData_p,
+                                        tEplObdSize *       pSize_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe (unsigned int  uiIndex_p,
+                                        unsigned int  uiSubIndex_p,
+                                        void *        pSrcData_p,
+                                        tEplObdSize   Size_p);
+//---------------------------------------------------------------------------
+EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
+                                        unsigned int            uiIndex_p,
+                                        unsigned int            uiSubindex_p,
+                                        tEplObdVarEntry MEM**   ppVarEntry_p);
+
+
+#endif  // #ifndef _EPLOBDUCAL_H_
+
+
diff --git a/drivers/staging/epl/user/EplPdou.h b/drivers/staging/epl/user/EplPdou.h
new file mode 100644 (file)
index 0000000..293f0f7
--- /dev/null
@@ -0,0 +1,114 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for userspace PDO module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplPdou.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/11/19 17:14:38 $
+
+                $State: Exp $
+
+                Build Environment:
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/05/22 d.k.:   start of the implementation, version 1.00
+
+
+****************************************************************************/
+
+#ifndef _EPL_PDOU_H_
+#define _EPL_PDOU_H_
+
+#include "../EplPdo.h"
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel EplPdouAddInstance(void);
+
+tEplKernel EplPdouDelInstance(void);
+
+#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
+tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM* pParam_p);
+#else
+#define EplPdouCbObdAccess             NULL
+#endif
+
+// returns error if bPdoId_p is already valid
+/*
+tEplKernel EplPdouSetMapping(
+    BYTE bPdoId_p, BOOL fTxRx_p, BYTE bNodeId, BYTE bMappingVersion,
+    tEplPdoMapping * pMapping_p, BYTE bMaxEntries_p);
+
+tEplKernel EplPdouGetMapping(
+    BYTE bPdoId_p, BOOL fTxRx_p, BYTE * pbNodeId, BYTE * pbMappingVersion,
+    tEplPdoMapping * pMapping_p, BYTE * pbMaxEntries_p);
+*/
+
+#endif  // #ifndef _EPL_PDOU_H_
+
+
diff --git a/drivers/staging/epl/user/EplSdoAsndu.h b/drivers/staging/epl/user/EplSdoAsndu.h
new file mode 100644 (file)
index 0000000..bc2650e
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for SDO/Asnd-Protocolabstractionlayer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoAsndu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/07 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplSdo.h"
+#include "../EplDll.h"
+
+#ifndef _EPLSDOASNDU_H_
+#define _EPLSDOASNDU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+
+tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+
+tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+
+tEplKernel PUBLIC EplSdoAsnduDelInstance(void);
+
+tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl*  pSdoConHandle_p,
+                               unsigned int    uiTargetNodeId_p);
+
+tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl       SdoConHandle_p,
+                                    tEplFrame *          pSrcData_p,
+                                    DWORD                dwDataSize_p);
+
+tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
+
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
+
+#endif  // #ifndef _EPLSDOASNDU_H_
+
+
diff --git a/drivers/staging/epl/user/EplSdoAsySequ.h b/drivers/staging/epl/user/EplSdoAsySequ.h
new file mode 100644 (file)
index 0000000..a9017ed
--- /dev/null
@@ -0,0 +1,123 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for asychrionus SDO Sequence Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoAsySequ.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplSdo.h"
+#include "EplSdoUdpu.h"
+#include "EplSdoAsndu.h"
+#include "../EplEvent.h"
+#include "EplTimeru.h"
+
+#ifndef _EPLSDOASYSEQU_H_
+#define _EPLSDOASYSEQU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+                                   tEplSdoComConCb fpSdoComConCb_p);
+
+tEplKernel PUBLIC EplSdoAsySeqAddInstance (tEplSdoComReceiveCb fpSdoComCb_p,
+                                   tEplSdoComConCb fpSdoComConCb_p);
+
+tEplKernel PUBLIC EplSdoAsySeqDelInstance(void);
+
+tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl* pSdoSeqConHdl_p,
+                                unsigned int uiNodeId_p,
+                                tEplSdoType   SdoType);
+
+tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+                                 unsigned int    uiDataSize_p,
+                                 tEplFrame*      pData_p );
+
+tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent* pEvent_p);
+
+tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
+
+
+
+
+
+
+
+#endif  // #ifndef _EPLSDOASYSEQU_H_
+
+
diff --git a/drivers/staging/epl/user/EplSdoComu.h b/drivers/staging/epl/user/EplSdoComu.h
new file mode 100644 (file)
index 0000000..16c8d7c
--- /dev/null
@@ -0,0 +1,135 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for SDO Command Layer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoComu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplSdo.h"
+#include "../EplObd.h"
+#include "../EplSdoAc.h"
+#include "EplObdu.h"
+#include "EplSdoAsySequ.h"
+
+#ifndef _EPLSDOCOMU_H_
+#define _EPLSDOCOMU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+tEplKernel PUBLIC EplSdoComInit(void);
+
+tEplKernel PUBLIC EplSdoComAddInstance(void);
+
+tEplKernel PUBLIC EplSdoComDelInstance(void);
+
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
+
+tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl*  pSdoComConHdl_p,
+                                      unsigned int      uiTargetNodeId_p,
+                                      tEplSdoType        ProtType_p);
+
+tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex* pSdoComTransParam_p);
+
+tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl  SdoComConHdl_p);
+
+tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+                                    tEplSdoComFinished* pSdoComFinished_p);
+
+tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+                              DWORD           dwAbortCode_p);
+
+#endif
+
+// for future extention
+/*
+tEplKernel PUBLIC EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
+
+tEplKernel PUBLIC EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
+
+tEplKernel PUBLIC EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
+
+*/
+
+
+
+
+
+#endif  // #ifndef _EPLSDOCOMU_H_
+
+
diff --git a/drivers/staging/epl/user/EplSdoUdpu.h b/drivers/staging/epl/user/EplSdoUdpu.h
new file mode 100644 (file)
index 0000000..ecd6814
--- /dev/null
@@ -0,0 +1,114 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for SDO/UDP-Protocollabstractionlayer module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplSdoUdpu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/06/26 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+
+#include "../EplSdo.h"
+
+#ifndef _EPLSDOUDPU_H_
+#define _EPLSDOUDPU_H_
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+
+tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+
+tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+
+tEplKernel PUBLIC EplSdoUdpuDelInstance(void);
+
+tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p);
+
+tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl*  pSdoConHandle_p,
+                               unsigned int    uiTargetNodeId_p);
+
+tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl       SdoConHandle_p,
+                                    tEplFrame *          pSrcData_p,
+                                    DWORD                dwDataSize_p);
+
+tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
+
+#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
+
+#endif  // #ifndef _EPLSDOUDPU_H_
+
+
diff --git a/drivers/staging/epl/user/EplStatusu.h b/drivers/staging/epl/user/EplStatusu.h
new file mode 100644 (file)
index 0000000..22547eb
--- /dev/null
@@ -0,0 +1,109 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Statusu-Module
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplStatusu.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/11/15 d.k.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplDll.h"
+
+#ifndef _EPLSTATUSU_H_
+#define _EPLSTATUSU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+typedef tEplKernel (PUBLIC * tEplStatusuCbResponse) (
+                                  unsigned int        uiNodeId_p,
+                                  tEplStatusResponse* pStatusResponse_p);
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplStatusuInit(void);
+
+tEplKernel PUBLIC EplStatusuAddInstance(void);
+
+tEplKernel PUBLIC EplStatusuDelInstance(void);
+
+tEplKernel PUBLIC EplStatusuReset(void);
+
+tEplKernel PUBLIC EplStatusuRequestStatusResponse(
+                                  unsigned int        uiNodeId_p,
+                                  tEplStatusuCbResponse pfnCbResponse_p);
+
+#endif  // #ifndef _EPLSTATUSU_H_
+
+
diff --git a/drivers/staging/epl/user/EplTimeru.h b/drivers/staging/epl/user/EplTimeru.h
new file mode 100644 (file)
index 0000000..d5f1eaf
--- /dev/null
@@ -0,0 +1,113 @@
+/****************************************************************************
+
+  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
+      www.systec-electronic.com
+
+  Project:      openPOWERLINK
+
+  Description:  include file for Epl Userspace-Timermodule
+
+  License:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+    3. Neither the name of SYSTEC electronic GmbH nor the names of its
+       contributors may be used to endorse or promote products derived
+       from this software without prior written permission. For written
+       permission, please contact info@systec-electronic.com.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+    Severability Clause:
+
+        If a provision of this License is or becomes illegal, invalid or
+        unenforceable in any jurisdiction, that shall not affect:
+        1. the validity or enforceability in that jurisdiction of any other
+           provision of this License; or
+        2. the validity or enforceability in other jurisdictions of that or
+           any other provision of this License.
+
+  -------------------------------------------------------------------------
+
+                $RCSfile: EplTimeru.h,v $
+
+                $Author: D.Krueger $
+
+                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
+
+                $State: Exp $
+
+                Build Environment:
+                    GCC V3.4
+
+  -------------------------------------------------------------------------
+
+  Revision History:
+
+  2006/07/06 k.t.:   start of the implementation
+
+
+****************************************************************************/
+
+#include "../EplTimer.h"
+#include "EplEventu.h"
+
+#ifndef _EPLTIMERU_H_
+#define _EPLTIMERU_H_
+
+
+//---------------------------------------------------------------------------
+// const defines
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// typedef
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// function prototypes
+//---------------------------------------------------------------------------
+
+tEplKernel PUBLIC EplTimeruInit(void);
+
+tEplKernel PUBLIC EplTimeruAddInstance(void);
+
+tEplKernel PUBLIC EplTimeruDelInstance(void);
+
+tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long ulTime_p,
+                                        tEplTimerArg  Argument_p);
+
+tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl*     pTimerHdl_p,
+                                        unsigned long     ulTime_p,
+                                        tEplTimerArg      Argument_p);
+
+tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl*     pTimerHdl_p);
+
+BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
+
+#endif  // #ifndef _EPLTIMERU_H_
+
+