diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2009-07-28 17:05:51 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-15 12:02:11 -0700 |
commit | 0841a555af4e15c1048f69b800a475f2fbf315a9 (patch) | |
tree | f526f8c53e7549c82a08879c8823a25c25722e6d /drivers/staging/epl/EplApiLinuxKernel.c | |
parent | 51be97961fc74de75e9e30a7339804afb77c7b1e (diff) |
Staging: remove epl driver
This is no longer maintained upstream, and no one cares about it at all,
so delete it.
The fact that it is duplicating an existing network driver also is a
good reason to remove it, it's causing nothing but trouble right now.
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>
Diffstat (limited to 'drivers/staging/epl/EplApiLinuxKernel.c')
-rw-r--r-- | drivers/staging/epl/EplApiLinuxKernel.c | 1173 |
1 files changed, 0 insertions, 1173 deletions
diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c deleted file mode 100644 index cb3e275e3aa..00000000000 --- a/drivers/staging/epl/EplApiLinuxKernel.c +++ /dev/null @@ -1,1173 +0,0 @@ -/**************************************************************************** - - (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/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> - -#include "Epl.h" -#include "EplApiLinux.h" -//#include "kernel/EplPdokCal.h" -#include "proc_fs.h" - - -/***************************************************************************/ -/* */ -/* */ -/* 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 TgtDbgSignalTracePoint(u8 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 -//--------------------------------------------------------------------------- - - // device number (major and minor) -static dev_t nDevNum_g; -static struct cdev *pEpl_cdev_g; - -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 EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *pUserArg_p); - -tEplKernel 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 -//--------------------------------------------------------------------------- - -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; - - 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); - - // 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; - } - - // 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"); - - // remove cdev structure - cdev_del(pEpl_cdev_g); - - // unregister character device handler - unregister_chrdev_region(nDevNum_g, 1); - - 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"); - - 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; - - 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 EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum) - tEplApiEventArg *pEventArg_p, // IN: event argument (union) - void *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 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 |