Hi Edouard, On 10/08/2018 01:05 AM, Edouard Tisserant wrote: > Hello EtherLab users ! > > EtherLab's EtherCAT master is being ported to Xenomai 3, and this is now > getting ready : > > https://hg.beremiz.org/etherlabmaster/ > > I also added a new device : devices/rtdmnet.c. It is really similar to > devices/generic.c, but it uses RTDM's Net drivers instead of Linux > drivers. This new device still needs fixing, and only works in idle mode > for now - working on a fix right now. > > Pre-existing devices/*.c haven't been tested. My current test bench is a > freescale imx6, with xenomai 3.0.7, using RTDM's FEC driver. Feedback > from other targets/devices would be welcome. > > @Florian : keeping compatibility with Xenomai2's RTDM wasn't a priority, > and I only focused on porting to Xenomai 3. Maybe is it still possible > to be compatible using #ifdefs. If this or anything else prevents you to > merge, please tell. >
I tried also to support RTDM of Xenomai3 and to keep compatibility with Xenomai2. I have tested on xenomai 3.0.5 over it is working well. You can refer my patch attached. It is based on the unofficial patchset to version 20180622 of Gavin. Thanks.
From 9567f460411d9a832c24b3ef65252f6f4f902fef Mon Sep 17 00:00:00 2001 From: Joonyoung Shim <jy0922.s...@samsung.com> Date: Fri, 17 Nov 2017 12:21:10 +0900 Subject: [PATCH] Support Xenomai version 3 Xenomai version 3 has different RTDM interface with version 2 and has Alchemy interface instead of native API. This supports RTDM of Xenomai version 3 and to use Alchemy interface. Signed-off-by: Joonyoung Shim <jy0922.s...@samsung.com> --- This is based on the the unofficial patchset to version 20180622 of Gavin and tested on linux-4.9.24 on x64 and linux-4.4.71 on x86 with xenomai 3.0.5 over using r8169, igb and e1000e NICs. configure.ac | 27 +++- lib/Makefile.am | 10 +- lib/common.c | 4 +- lib/master.c | 4 +- master/Kbuild.in | 5 + master/Makefile.am | 1 + master/rtdm_xenomai_v3.c | 350 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 master/rtdm_xenomai_v3.c diff --git a/configure.ac b/configure.ac index e8b056e..6bfceb4 100644 --- a/configure.ac +++ b/configure.ac @@ -689,18 +689,37 @@ else fi AC_MSG_RESULT([$xenomaidir]) - xeno_native_cflags=`$xenomaidir/bin/xeno-config --skin native --cflags` - xeno_native_ldflags=`$xenomaidir/bin/xeno-config --skin native --ldflags` + xenomai_ver=`grep -R "VERSION_STRING" ${xenomaidir}/include/xeno_config.h | awk '{print $3}'` + xenomai_ver=${xenomai_ver##\"} + xenomai_ver=${xenomai_ver%%\"} + echo "xenomai version: " $xenomai_ver + + if test ${xenomai_ver%%.*} -gt 2; then + xeno_alchemy_cflags=`$xenomaidir/bin/xeno-config --skin alchemy --cflags` + xeno_alchemy_ldflags=`$xenomaidir/bin/xeno-config --skin alchemy --auto-init-solib --ldflags` + xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --auto-init-solib --ldflags` + xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --auto-init-solib --ldflags` + xeno_v3=1 + xeno=0 + else + xeno_native_cflags=`$xenomaidir/bin/xeno-config --skin native --cflags` + xeno_native_ldflags=`$xenomaidir/bin/xeno-config --skin native --ldflags` + xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --ldflags` + xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --ldflags` + fi + xeno_posix_cflags=`$xenomaidir/bin/xeno-config --skin posix --cflags` - xeno_posix_ldflags=`$xenomaidir/bin/xeno-config --skin posix --ldflags` xeno_rtdm_cflags=`$xenomaidir/bin/xeno-config --skin rtdm --cflags` - xeno_rtdm_ldflags=`$xenomaidir/bin/xeno-config --skin rtdm --ldflags` fi AC_SUBST(XENOMAI_DIR,[$xenomaidir]) AM_CONDITIONAL(ENABLE_XENOMAI, test "x$xeno" = "x1") AC_SUBST(ENABLE_XENOMAI,[$xeno]) +AM_CONDITIONAL(ENABLE_XENOMAI_V3, test "x$xeno_v3" = "x1") +AC_SUBST(ENABLE_XENOMAI_V3,[$xeno_v3]) +AC_SUBST(XENOMAI_ALCHEMY_CFLAGS,[$xeno_alchemy_cflags]) +AC_SUBST(XENOMAI_ALCHEMY_LDFLAGS,[$xeno_alchemy_ldflags]) AC_SUBST(XENOMAI_NATIVE_CFLAGS,[$xeno_native_cflags]) AC_SUBST(XENOMAI_NATIVE_LDFLAGS,[$xeno_native_ldflags]) AC_SUBST(XENOMAI_POSIX_CFLAGS,[$xeno_posix_cflags]) diff --git a/lib/Makefile.am b/lib/Makefile.am index ef85067..c2e2710 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -62,7 +62,7 @@ if ENABLE_RTDM lib_LTLIBRARIES += libethercat_rtdm.la libethercat_rtdm_la_SOURCES = $(libethercat_la_SOURCES) -libethercat_rtdm_la_CFLAGS = $(libethercat_la_CFLAGS) -DUSE_RTDM +libethercat_rtdm_la_CFLAGS = $(libethercat_la_CFLAGS) libethercat_rtdm_la_LDFLAGS = $(libethercat_la_LDFLAGS) if ENABLE_XENOMAI @@ -70,6 +70,14 @@ libethercat_rtdm_la_CFLAGS += $(XENOMAI_RTDM_CFLAGS) libethercat_rtdm_la_LDFLAGS += $(XENOMAI_RTDM_LDFLAGS) endif +if ENABLE_XENOMAI_V3 +libethercat_rtdm_la_CFLAGS += $(XENOMAI_RTDM_CFLAGS) +libethercat_rtdm_la_LDFLAGS += $(XENOMAI_RTDM_LDFLAGS) +libethercat_rtdm_la_CFLAGS += -DUSE_RTDM_XENOMAI_V3 +else +libethercat_rtdm_la_CFLAGS += -DUSE_RTDM +endif + if ENABLE_RTAI libethercat_rtdm_la_CFLAGS += $(RTAI_LXRT_CFLAGS) libethercat_rtdm_la_LDFLAGS += $(RTAI_LXRT_LDFLAGS) diff --git a/lib/common.c b/lib/common.c index eb66227..77dd205 100644 --- a/lib/common.c +++ b/lib/common.c @@ -87,8 +87,10 @@ ec_master_t *ecrt_open_master(unsigned int master_index) master->first_config = NULL; snprintf(path, MAX_PATH_LEN - 1, -#ifdef USE_RTDM +#if defined(USE_RTDM) "EtherCAT%u", +#elif defined(USE_RTDM_XENOMAI_V3) + "/dev/rtdm/EtherCAT%u", #else "/dev/EtherCAT%u", #endif diff --git a/lib/master.c b/lib/master.c index 8292d1d..350f214 100644 --- a/lib/master.c +++ b/lib/master.c @@ -583,7 +583,7 @@ int ecrt_master_setup_domain_memory(ec_master_t *master) if (io.process_data_size) { master->process_data_size = io.process_data_size; -#ifdef USE_RTDM +#if defined(USE_RTDM) || defined(USE_RTDM_XENOMAI_V3) /* memory-mapping was already done in kernel. The user-space addess is * provided in the ioctl data. */ @@ -625,7 +625,7 @@ int ecrt_master_activate(ec_master_t *master) if (io.process_data_size) { master->process_data_size = io.process_data_size; -#ifdef USE_RTDM +#if defined(USE_RTDM) || defined(USE_RTDM_XENOMAI_V3) /* memory-mapping was already done in kernel. The user-space addess is * provided in the ioctl data. */ diff --git a/master/Kbuild.in b/master/Kbuild.in index 2bf6b8c..904d0ce 100644 --- a/master/Kbuild.in +++ b/master/Kbuild.in @@ -87,7 +87,12 @@ endif ifeq (@ENABLE_RTDM@,1) +ifeq (@ENABLE_XENOMAI_V3@, 1) +ec_master-objs += rtdm_xenomai_v3.o +CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include +else ec_master-objs += rtdm.o +endif ifeq (@ENABLE_XENOMAI@, 1) EXTRA_CFLAGS := -I@XENOMAI_DIR@/include diff --git a/master/Makefile.am b/master/Makefile.am index 09068c9..8682244 100644 --- a/master/Makefile.am +++ b/master/Makefile.am @@ -65,6 +65,7 @@ noinst_HEADERS = \ reg_request.c reg_request.h \ rtdm-ioctl.c \ rtdm.c rtdm.h \ + rtdm_xenomai_v3.c \ sdo.c sdo.h \ sdo_entry.c sdo_entry.h \ sdo_request.c sdo_request.h \ diff --git a/master/rtdm_xenomai_v3.c b/master/rtdm_xenomai_v3.c new file mode 100644 index 0000000..54ff066 --- /dev/null +++ b/master/rtdm_xenomai_v3.c @@ -0,0 +1,350 @@ +/***************************************************************************** + * + * $Id$ + * + * Copyright (C) 2009-2010 Moehwald GmbH B. Benner + * 2011 IgH Andreas Stewering-Bone + * 2012 Florian Pose <f...@igh-essen.com> + * + * This file is part of the IgH EtherCAT master. + * + * The IgH EtherCAT master is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation; version 2 of the License. + * + * The IgH EtherCAT master is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with the IgH EtherCAT master. If not, see <http://www.gnu.org/licenses/>. + * + * The license mentioned above concerns the source code only. Using the + * EtherCAT technology and brand is only permitted in compliance with the + * industrial property and similar rights of Beckhoff Automation GmbH. + * + ****************************************************************************/ + +/** \file + * RTDM interface. + */ + +#include <linux/module.h> +#include <linux/vmalloc.h> +#include <rtdm/driver.h> + +#include "master.h" +#include "ioctl.h" +#include "rtdm.h" + +/** Set to 1 to enable device operations debugging. + */ +#define DEBUG_RTDM 0 + +struct ec_rtdm_context { + struct rtdm_fd *fd; + ec_ioctl_context_t ioctl_ctx; /**< Context structure. */ +}; + +static int ec_rtdm_open(struct rtdm_fd *fd, int oflags) +{ + struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd); +#if DEBUG_RTDM + struct rtdm_device *dev = rtdm_fd_device(fd); + ec_rtdm_dev_t *rtdm_dev = dev->device_data; +#endif + + ctx->fd = fd; + + ctx->ioctl_ctx.writable = oflags & O_WRONLY || oflags & O_RDWR; + ctx->ioctl_ctx.requested = 0; + ctx->ioctl_ctx.process_data = NULL; + ctx->ioctl_ctx.process_data_size = 0; + +#if DEBUG_RTDM + EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s opened.\n", + dev->name); +#endif + + return 0; +} + +static void ec_rtdm_close(struct rtdm_fd *fd) +{ + struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd); + struct rtdm_device *dev = rtdm_fd_device(fd); + ec_rtdm_dev_t *rtdm_dev = dev->device_data; + + if (ctx->ioctl_ctx.requested) + ecrt_release_master(rtdm_dev->master); + + if (ctx->ioctl_ctx.process_data) + vfree(ctx->ioctl_ctx.process_data); + +#if DEBUG_RTDM + EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s closed.\n", + dev->name); +#endif +} + +#if DEBUG_RTDM +struct ec_ioctl_desc { + unsigned int cmd; + const char *name; +}; + +#define EC_IOCTL_DEF(ioctl) \ + [_IOC_NR(ioctl)] = { \ + .cmd = ioctl, \ + .name = #ioctl \ + } + +static const struct ec_ioctl_desc ec_ioctls[] = { + EC_IOCTL_DEF(EC_IOCTL_MODULE), + EC_IOCTL_DEF(EC_IOCTL_MASTER), + EC_IOCTL_DEF(EC_IOCTL_SLAVE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SYNC_PDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_FMMU), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_DATA), + EC_IOCTL_DEF(EC_IOCTL_MASTER_DEBUG), + EC_IOCTL_DEF(EC_IOCTL_MASTER_RESCAN), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_STATE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_UPLOAD), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SDO_DOWNLOAD), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SII_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_FOE_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_READ), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_SOE_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_EOE_IP_PARAM), + EC_IOCTL_DEF(EC_IOCTL_CONFIG), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_PDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_SDO), + EC_IOCTL_DEF(EC_IOCTL_CONFIG_IDN), +#ifdef EC_EOE + EC_IOCTL_DEF(EC_IOCTL_EOE_HANDLER), +#endif + EC_IOCTL_DEF(EC_IOCTL_SLAVE_DICT_UPLOAD), + EC_IOCTL_DEF(EC_IOCTL_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_CREATE_DOMAIN), + EC_IOCTL_DEF(EC_IOCTL_CREATE_SLAVE_CONFIG), + EC_IOCTL_DEF(EC_IOCTL_SELECT_REF_CLOCK), + EC_IOCTL_DEF(EC_IOCTL_ACTIVATE), + EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE), + EC_IOCTL_DEF(EC_IOCTL_SEND), + EC_IOCTL_DEF(EC_IOCTL_RECEIVE), + EC_IOCTL_DEF(EC_IOCTL_MASTER_STATE), + EC_IOCTL_DEF(EC_IOCTL_MASTER_LINK_STATE), + EC_IOCTL_DEF(EC_IOCTL_APP_TIME), + EC_IOCTL_DEF(EC_IOCTL_SYNC_REF), + EC_IOCTL_DEF(EC_IOCTL_SYNC_SLAVES), + EC_IOCTL_DEF(EC_IOCTL_REF_CLOCK_TIME), + EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_QUEUE), + EC_IOCTL_DEF(EC_IOCTL_SYNC_MON_PROCESS), + EC_IOCTL_DEF(EC_IOCTL_RESET), + EC_IOCTL_DEF(EC_IOCTL_SC_SYNC), + EC_IOCTL_DEF(EC_IOCTL_SC_WATCHDOG), + EC_IOCTL_DEF(EC_IOCTL_SC_ADD_PDO), + EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_PDOS), + EC_IOCTL_DEF(EC_IOCTL_SC_ADD_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_SC_CLEAR_ENTRIES), + EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_ENTRY), + EC_IOCTL_DEF(EC_IOCTL_SC_REG_PDO_POS), + EC_IOCTL_DEF(EC_IOCTL_SC_DC), + EC_IOCTL_DEF(EC_IOCTL_SC_SDO), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_SIZE), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_POP), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_CLEAR), + EC_IOCTL_DEF(EC_IOCTL_SC_EMERG_OVERRUNS), + EC_IOCTL_DEF(EC_IOCTL_SC_SDO_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_SC_REG_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_SC_VOE), + EC_IOCTL_DEF(EC_IOCTL_SC_STATE), + EC_IOCTL_DEF(EC_IOCTL_SC_IDN), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_SIZE), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_OFFSET), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_PROCESS), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_QUEUE), + EC_IOCTL_DEF(EC_IOCTL_DOMAIN_STATE), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_INDEX), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_TIMEOUT), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_STATE), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_READ), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_WRITE), + EC_IOCTL_DEF(EC_IOCTL_SDO_REQUEST_DATA), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_DATA), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_STATE), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_WRITE), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READ), + EC_IOCTL_DEF(EC_IOCTL_VOE_SEND_HEADER), + EC_IOCTL_DEF(EC_IOCTL_VOE_REC_HEADER), + EC_IOCTL_DEF(EC_IOCTL_VOE_READ), + EC_IOCTL_DEF(EC_IOCTL_VOE_READ_NOSYNC), + EC_IOCTL_DEF(EC_IOCTL_VOE_WRITE), + EC_IOCTL_DEF(EC_IOCTL_VOE_EXEC), + EC_IOCTL_DEF(EC_IOCTL_VOE_DATA), + EC_IOCTL_DEF(EC_IOCTL_SET_SEND_INTERVAL), + EC_IOCTL_DEF(EC_IOCTL_SC_OVERLAPPING_IO), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REBOOT), + EC_IOCTL_DEF(EC_IOCTL_SLAVE_REG_READWRITE), + EC_IOCTL_DEF(EC_IOCTL_REG_REQUEST_READWRITE), + EC_IOCTL_DEF(EC_IOCTL_SETUP_DOMAIN_MEMORY), + EC_IOCTL_DEF(EC_IOCTL_DEACTIVATE_SLAVES), + EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME_QUEUE), + EC_IOCTL_DEF(EC_IOCTL_64_REF_CLK_TIME), + EC_IOCTL_DEF(EC_IOCTL_SC_FOE_REQUEST), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_FILE), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_TIMEOUT), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_STATE), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_READ), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_WRITE), + EC_IOCTL_DEF(EC_IOCTL_FOE_REQUEST_DATA), + EC_IOCTL_DEF(EC_IOCTL_RT_SLAVE_REQUESTS), + EC_IOCTL_DEF(EC_IOCTL_EXEC_SLAVE_REQUESTS), +}; +#endif + +static int ec_rtdm_ioctl_rt(struct rtdm_fd *fd, unsigned int request, + void __user *arg) +{ + struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd); + struct rtdm_device *dev = rtdm_fd_device(fd); + ec_rtdm_dev_t *rtdm_dev = dev->device_data; + +#if DEBUG_RTDM + unsigned int nr = _IOC_NR(request); + const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr]; + + EC_MASTER_INFO(rtdm_dev->master, "ioctl_rt(request = %u, ctl = %02x %s)" + " on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name, + dev->name); +#endif + + /* + * FIXME: Execute ioctls from non-rt context except below ioctls to + * avoid any unknown system hanging. + */ + switch (request) { + case EC_IOCTL_SEND: + case EC_IOCTL_RECEIVE: + case EC_IOCTL_MASTER_STATE: + case EC_IOCTL_APP_TIME: + case EC_IOCTL_SYNC_REF: + case EC_IOCTL_SYNC_SLAVES: + case EC_IOCTL_REF_CLOCK_TIME: + case EC_IOCTL_SC_STATE: + case EC_IOCTL_DOMAIN_PROCESS: + case EC_IOCTL_DOMAIN_QUEUE: + case EC_IOCTL_DOMAIN_STATE: + break; + default: + return -ENOSYS; + } + + return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg); +} + +static int ec_rtdm_ioctl(struct rtdm_fd *fd, unsigned int request, + void __user *arg) +{ + struct ec_rtdm_context *ctx = rtdm_fd_to_private(fd); + struct rtdm_device *dev = rtdm_fd_device(fd); + ec_rtdm_dev_t *rtdm_dev = dev->device_data; + +#if DEBUG_RTDM + unsigned int nr = _IOC_NR(request); + const struct ec_ioctl_desc *ioctl = &ec_ioctls[nr]; + + EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x %s)" + " on RTDM device %s.\n", request, _IOC_NR(request),ioctl->name, + dev->name); +#endif + + return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg); +} + +static struct rtdm_driver ec_rtdm_driver = { + .profile_info = RTDM_PROFILE_INFO(ec_rtdm, + RTDM_CLASS_EXPERIMENTAL, + 222, + 0), + .device_flags = RTDM_NAMED_DEVICE, + .device_count = 1, + .context_size = sizeof(struct ec_rtdm_context), + .ops = { + .open = ec_rtdm_open, + .close = ec_rtdm_close, + .ioctl_rt = ec_rtdm_ioctl_rt, + .ioctl_nrt = ec_rtdm_ioctl, + }, +}; + +int ec_rtdm_dev_init(ec_rtdm_dev_t *rtdm_dev, ec_master_t *master) +{ + struct rtdm_device *dev; + int ret; + + rtdm_dev->master = master; + + rtdm_dev->dev = kzalloc(sizeof(struct rtdm_device), GFP_KERNEL); + if (!rtdm_dev->dev) { + EC_MASTER_ERR(master, + "Failed to reserve memory for RTDM device.\n"); + return -ENOMEM; + } + + dev = rtdm_dev->dev; + + dev->driver = &ec_rtdm_driver; + dev->device_data = rtdm_dev; + dev->label = "EtherCAT%u"; + + ret = rtdm_dev_register(dev); + if (ret) { + EC_MASTER_ERR(master, "Initialization of RTDM interface failed" + " (return value %i).\n", ret); + kfree(dev); + return ret; + } + + EC_MASTER_INFO(master, "Registered RTDM device %s.\n", dev->name); + + return 0; +} + +void ec_rtdm_dev_clear(ec_rtdm_dev_t *rtdm_dev) +{ + rtdm_dev_unregister(rtdm_dev->dev); + + EC_MASTER_INFO(rtdm_dev->master, "Unregistered RTDM device %s.\n", + rtdm_dev->dev->name); + + kfree(rtdm_dev->dev); +} + +int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address) +{ + struct ec_rtdm_context *ctx = + container_of(ioctl_ctx, struct ec_rtdm_context, ioctl_ctx); + int ret; + + ret = rtdm_mmap_to_user(ctx->fd, + ioctl_ctx->process_data, ioctl_ctx->process_data_size, + PROT_READ | PROT_WRITE, + user_address, + NULL, NULL); + if (ret < 0) + return ret; + + return 0; +} -- 2.7.4
_______________________________________________ etherlab-dev mailing list etherlab-dev@etherlab.org http://lists.etherlab.org/mailman/listinfo/etherlab-dev