****************************************************************************/
-
// kernel modul and driver
//#include <linux/version.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
+#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"
+#error "This driver needs a 2.6.x kernel or higher"
#endif
-
/***************************************************************************/
/* */
/* */
// Metainformation
MODULE_LICENSE("Dual BSD/GPL");
#ifdef MODULE_AUTHOR
- MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
- MODULE_DESCRIPTION("EPL API driver");
+MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
+MODULE_DESCRIPTION("EPL API driver");
#endif
-
//---------------------------------------------------------------------------
// Configuration
//---------------------------------------------------------------------------
-
-#define EPLLIN_DRV_NAME "systec_epl" // used for <register_chrdev>
-
-
+#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)
+void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#else
- #define TGT_DBG_SIGNAL_TRACE_POINT(p)
+#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 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;
+static int nDrvMajorNumber_g;
#else
// device number (major and minor)
- static dev_t nDevNum_g;
- static struct cdev *pEpl_cdev_g;
+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);
-
+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;
+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 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);
-
-
+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,
+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 //
// -> insmod driver
//---------------------------------------------------------------------------
-static int __init EplLinInit (void)
+static int __init EplLinInit(void)
{
-tEplKernel EplRet;
-int iErr;
-int iRet;
+ tEplKernel EplRet;
+ int iErr;
+ int iRet;
#ifdef CONFIG_DEVFS_FS
-int nMinorNumber;
+ 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);
+ 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;
- }
+ // 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;
- }
-
+ // 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;
- }
+ // create device node in PROCFS
+ EplRet = EplLinProcInit();
+ if (EplRet != kEplSuccessful) {
+ goto Exit;
+ }
+ Exit:
-Exit:
-
- TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet);
- return (iRet);
+ TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet);
+ return (iRet);
}
-
-
//---------------------------------------------------------------------------
// Remove Driver
//---------------------------------------------------------------------------
// -> rmmod driver
//---------------------------------------------------------------------------
-static void __exit EplLinExit (void)
+static void __exit EplLinExit(void)
{
-tEplKernel EplRet;
+ tEplKernel EplRet;
- // delete instance for all modules
+ // 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");
+ // 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);
+ // 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);
+ // unregister character device handler
+ unregister_chrdev(nDrvMajorNumber_g, EPLLIN_DRV_NAME);
#else
- // remove cdev structure
- cdev_del(pEpl_cdev_g);
+ // remove cdev structure
+ cdev_del(pEpl_cdev_g);
- // unregister character device handler
- unregister_chrdev_region (nDevNum_g, 1);
+ // unregister character device handler
+ unregister_chrdev_region(nDevNum_g, 1);
#endif
- TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME);
+ TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME);
-
- TRACE0("EPL: - EplLinExit\n");
+ 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
+static int EplLinOpen(struct inode *pDeviceFile_p, // information about the device to open
+ struct file *pInstance_p) // information about driver instance
{
-int iRet;
+ int iRet;
+ TRACE0("EPL: + EplLinOpen...\n");
- TRACE0("EPL: + EplLinOpen...\n");
+ MOD_INC_USE_COUNT;
- 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);
- 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;
+ }
- uiEplState_g = EPL_STATE_NOTINIT;
- iRet = 0;
- }
-
- TRACE1("EPL: - EplLinOpen (iRet=%d)\n", iRet);
- return (iRet);
+ 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
+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");
+ tEplKernel EplRet = kEplSuccessful;
+ int iRet;
- 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);
+ TRACE0("EPL: + EplLinRelease...\n");
- // pass control to event queue kernel thread
- atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
- wake_up_interruptible(&WaitQueueCbEvent_g);
+ 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);
- if (uiEplState_g == EPL_STATE_RUNNING)
- { // post NmtEventSwitchOff
- EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
+ // 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?
+ 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");
+ }
- 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);
- }
+ // $$$ d.k.: What if waiting was interrupted by signal?
- uiEplState_g = EPL_STATE_NOTOPEN;
- iRet = 0;
+ 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;
+ MOD_DEC_USE_COUNT;
-
- TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet);
- return (iRet);
+ 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
+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");
+ int iRet;
+ TRACE0("EPL: + EplLinRead...\n");
- TRACE0("EPL: Sorry, this operation isn't supported.\n");
- iRet = -EINVAL;
+ TRACE0("EPL: Sorry, this operation isn't supported.\n");
+ iRet = -EINVAL;
-
- TRACE1("EPL: - EplLinRead (iRet=%d)\n", iRet);
- return (iRet);
+ 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
+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");
+ int iRet;
+ TRACE0("EPL: + EplLinWrite...\n");
- TRACE0("EPL: Sorry, this operation isn't supported.\n");
- iRet = -EINVAL;
+ TRACE0("EPL: Sorry, this operation isn't supported.\n");
+ iRet = -EINVAL;
-
- TRACE1("EPL: - EplLinWrite (iRet=%d)\n", iRet);
- return (iRet);
+ 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
+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;
-
+ 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;
- }
-
+ 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;
- }
+ // ----------------------------------------------------------
+ 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:
+ // ----------------------------------------------------------
+ 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);
+ 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 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 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;
+ 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
-