merged stable-1.5
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Sun, 07 Oct 2018 17:05:42 +0200
branchstable-1.5
changeset 2725 e008dc9d8c9f
parent 2722 5e5bec5ee9c1 (diff)
parent 2724 b4a109b9e2a8 (current diff)
child 2726 ca80d6dac4c8
merged
configure.ac
--- a/.hgignore	Fri Oct 05 10:24:11 2018 +0200
+++ b/.hgignore	Sun Oct 07 17:05:42 2018 +0200
@@ -11,6 +11,7 @@
 **/.deps/*.Po
 **/.tmp_*.gcno
 **~
+**.orig
 .tmp_versions
 ChangeLog
 Doxyfile
--- a/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -85,7 +85,7 @@
 
 modules_install:
 	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" \
-		INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)" modules_install
+		$(INSTALL_MOD_PATH_DEFS) modules_install
 
 clean-local:
 	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" clean
--- a/configure.ac	Fri Oct 05 10:24:11 2018 +0200
+++ b/configure.ac	Sun Oct 07 17:05:42 2018 +0200
@@ -152,21 +152,38 @@
 fi
 
 #------------------------------------------------------------------------------
+# Linux module installation directory
+#------------------------------------------------------------------------------
+
+AC_ARG_WITH([module-path],
+    AC_HELP_STRING(
+        [--with-module-path=<DIR>],
+        [Linux module installation path. Default: /lib/modules/kernel_version]
+    ),
+    [modpathdefs="INSTALL_MOD_PATH='$withval'"],
+    [modpathdefs=""]
+)
+
+AC_MSG_CHECKING([for Linux modules installation directory])
+AC_MSG_RESULT([$with_mod_path])
+
+#------------------------------------------------------------------------------
 # Linux module installation subdirectory
 #------------------------------------------------------------------------------
 
 AC_ARG_WITH([module-dir],
     AC_HELP_STRING(
         [--with-module-dir=<DIR>],
-        [Linux module installation dir. Default: ethercat]
-    ),
-    [moddir=[$withval]],
-    [moddir="ethercat"]
-)
-AC_SUBST(INSTALL_MOD_DIR,[$moddir])
-
-AC_MSG_CHECKING([for Linux modules installation directory])
-AC_MSG_RESULT([$INSTALL_MOD_DIR])
+        [Linux module installation subdir. Default: ethercat]
+    ),
+    [modpathdefs="$modpathdefs INSTALL_MOD_DIR='$withval'"],
+    [modpathdefs=""]
+)
+
+AC_MSG_CHECKING([for Linux modules installation subdirectory])
+AC_MSG_RESULT([$with_mod_dir])
+
+AC_SUBST(INSTALL_MOD_PATH_DEFS,[$modpathdefs])
 
 #------------------------------------------------------------------------------
 # Generic Ethernet driver
@@ -192,6 +209,29 @@
 AC_SUBST(ENABLE_GENERIC,[$enablegeneric])
 
 #------------------------------------------------------------------------------
+# RTDM Ethernet driver
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([rtdmnet],
+    AS_HELP_STRING([--enable-rtdmnet],
+                   [Enable RTDM Ethernet driver]),
+    [
+        case "${enableval}" in
+            yes) enablertdmnet=1
+                ;;
+            no) enablertdmnet=0
+                ;;
+            *) AC_MSG_ERROR([Invalid value for --enable-rtdmnet])
+                ;;
+        esac
+    ],
+    [enablertdmnet=$enablekernel]
+)
+
+AM_CONDITIONAL(ENABLE_RTDMNET, test "x$enablertdmnet" = "x1")
+AC_SUBST(ENABLE_RTDMNET,[$enablertdmnet])
+
+#------------------------------------------------------------------------------
 # 8139too driver
 #------------------------------------------------------------------------------
 
@@ -624,22 +664,35 @@
     ]
 )
 
+AC_ARG_WITH([xenomai-config],
+    AC_HELP_STRING(
+        [--with-xenomai-config=<CMD>],
+        [Xenomai config invokation, default to xenomai-dir/bin/xeno-config]
+    ),
+    [
+        xenomaiconfig=[$withval]
+    ],
+    [
+        xenomaiconfig="$xenomaidir/bin/xeno-config"
+    ]
+)
+
 AC_MSG_CHECKING([for Xenomai path])
 
 if test -z "${xenomaidir}"; then
     AC_MSG_RESULT([not specified.])
 else
-    if test \! -r ${xenomaidir}/include/xeno_config.h; then
+    if test \! -r ${xenomaiconfig}; then
         AC_MSG_ERROR([no Xenomai installation found in ${xenomaidir}!])
     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`
-    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`
+    xeno_native_cflags=`$xenomaiconfig --alchemy --cflags`
+    xeno_native_ldflags=`$xenomaiconfig --alchemy --ldflags`
+    xeno_posix_cflags=`$xenomaiconfig --posix --cflags`
+    xeno_posix_ldflags=`$xenomaiconfig --posix --ldflags`
+    xeno_lib_cflags=`$xenomaiconfig --posix --cflags`
+    xeno_lib_ldflags=`$xenomaiconfig --posix --auto-init-solib --ldflags`
 fi
 
 AC_SUBST(XENOMAI_DIR,[$xenomaidir])
@@ -650,8 +703,8 @@
 AC_SUBST(XENOMAI_NATIVE_LDFLAGS,[$xeno_native_ldflags])
 AC_SUBST(XENOMAI_POSIX_CFLAGS,[$xeno_posix_cflags])
 AC_SUBST(XENOMAI_POSIX_LDFLAGS,[$xeno_posix_ldflags])
-AC_SUBST(XENOMAI_RTDM_CFLAGS,[$xeno_rtdm_cflags])
-AC_SUBST(XENOMAI_RTDM_LDFLAGS,[$xeno_rtdm_ldflags])
+AC_SUBST(XENOMAI_LIB_CFLAGS,[$xeno_lib_cflags])
+AC_SUBST(XENOMAI_LIB_LDFLAGS,[$xeno_lib_ldflags])
 
 #------------------------------------------------------------------------------
 # RTDM interface (optional)
--- a/devices/Kbuild.in	Fri Oct 05 10:24:11 2018 +0200
+++ b/devices/Kbuild.in	Sun Oct 07 17:05:42 2018 +0200
@@ -44,6 +44,13 @@
 	CFLAGS_$(EC_GENERIC_OBJ) = -DREV=$(REV)
 endif
 
+ifeq (@ENABLE_RTDMNET@,1)
+	EC_RTDMNET_OBJ := rtdmnet.o
+	obj-m += ec_rtdmnet.o
+	ec_rtdmnet-objs := $(EC_RTDMNET_OBJ)
+	CFLAGS_$(EC_RTDMNET_OBJ) = -DREV=$(REV) -Idrivers/xenomai/net/stack/include
+endif
+
 ifeq (@ENABLE_8139TOO@,1)
 	EC_8139TOO_OBJ := 8139too-@KERNEL_8139TOO@-ethercat.o
 	obj-m += ec_8139too.o
--- a/devices/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/devices/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -137,6 +137,7 @@
 	e100-3.8-orig.c \
 	ecdev.h \
 	generic.c \
+	rtdmnet.c \
 	r8169-2.6.24-ethercat.c \
 	r8169-2.6.24-orig.c \
 	r8169-2.6.27-ethercat.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/rtdmnet.c	Sun Oct 07 17:05:42 2018 +0200
@@ -0,0 +1,566 @@
+/******************************************************************************
+ *
+ *  $Id$
+ *
+ *  Copyright (C) 2006-2008  Florian Pose, Ingenieurgemeinschaft IgH
+ *  Copyright (C) 2014-2018  Edouard Tisserant
+ *
+ *  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 version 2, as
+ *  published by the Free Software Foundation.
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *  ---
+ *
+ *  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
+ * EtherCAT generic Xenomai's RTDM RAW Ethernet socket device module.
+ * Heavily based on generic.c. Should be merged in a single file with #ifdefs
+ */
+
+/*****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/version.h>
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
+#include <linux/etherdevice.h>
+#include <rtdm/rtdm.h>
+
+// for rtnetif_carrier_ok and rtpc_dispatch_call
+// This needs -I@XENOMAI_DIR@/kernel/drivers/net/stack/include in Kbuild.in
+#include <rtnet_port.h>
+#include <rtnet_rtpc.h>
+
+#include "../globals.h"
+#include "ecdev.h"
+
+#define PFX "ec_rtdmnet: "
+
+#define ETH_P_ETHERCAT 0x88A4
+
+#define EC_GEN_RX_BUF_SIZE 1600
+
+/*****************************************************************************/
+
+int __init ec_gen_init_module(void);
+void __exit ec_gen_cleanup_module(void);
+
+/*****************************************************************************/
+
+/** \cond */
+
+MODULE_AUTHOR("Edouard Tisserant <edouard.tisserant@gmail.com>");
+MODULE_DESCRIPTION("EtherCAT generic Xenomai's RTDM RAW Ethernet socket device module.");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(EC_MASTER_VERSION);
+
+/** \endcond */
+
+struct list_head generic_devices;
+
+typedef struct {
+    struct list_head list;
+    struct net_device *netdev;
+    struct rtnet_device *used_netdev;
+    int socket;
+    ec_device_t *ecdev;
+    uint8_t *rx_buf;
+    // struct sockaddr_ll dest_addr;
+} ec_gen_device_t;
+
+typedef struct {
+    struct list_head list;
+    struct rtnet_device *netdev;
+    char name[IFNAMSIZ];
+    int ifindex;
+    uint8_t dev_addr[ETH_ALEN];
+} ec_gen_interface_desc_t;
+
+int ec_gen_device_open(ec_gen_device_t *);
+int ec_gen_device_stop(ec_gen_device_t *);
+int ec_gen_device_start_xmit(ec_gen_device_t *, struct sk_buff *);
+void ec_gen_device_poll(ec_gen_device_t *);
+
+/*****************************************************************************/
+
+static int ec_gen_netdev_open(struct net_device *dev)
+{
+    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
+    return ec_gen_device_open(gendev);
+}
+
+/*****************************************************************************/
+
+static int ec_gen_netdev_stop(struct net_device *dev)
+{
+    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
+    return ec_gen_device_stop(gendev);
+}
+
+/*****************************************************************************/
+
+static int ec_gen_netdev_start_xmit(
+        struct sk_buff *skb,
+        struct net_device *dev
+        )
+{
+    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
+    return ec_gen_device_start_xmit(gendev, skb);
+}
+
+/*****************************************************************************/
+
+void ec_gen_poll(struct net_device *dev)
+{
+    ec_gen_device_t *gendev = *((ec_gen_device_t **) netdev_priv(dev));
+    ec_gen_device_poll(gendev);
+}
+
+/*****************************************************************************/
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+static const struct net_device_ops ec_gen_netdev_ops = {
+    .ndo_open       = ec_gen_netdev_open,
+    .ndo_stop       = ec_gen_netdev_stop,
+    .ndo_start_xmit = ec_gen_netdev_start_xmit,
+};
+#endif
+
+/*****************************************************************************/
+
+/** Init generic device.
+ */
+int ec_gen_device_init(
+        ec_gen_device_t *dev
+        )
+{
+    ec_gen_device_t **priv;
+    char null = 0x00;
+
+    dev->ecdev = NULL;
+    dev->socket = -1;
+    dev->rx_buf = NULL;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+    dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null,
+            NET_NAME_UNKNOWN, ether_setup);
+#else
+    dev->netdev = alloc_netdev(sizeof(ec_gen_device_t *), &null, ether_setup);
+#endif
+    if (!dev->netdev) {
+        return -ENOMEM;
+    }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+    dev->netdev->netdev_ops = &ec_gen_netdev_ops;
+#else
+    dev->netdev->open = ec_gen_netdev_open;
+    dev->netdev->stop = ec_gen_netdev_stop;
+    dev->netdev->hard_start_xmit = ec_gen_netdev_start_xmit;
+#endif
+
+    priv = netdev_priv(dev->netdev);
+    *priv = dev;
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+/** Clear generic device.
+ */
+void ec_gen_device_clear(
+        ec_gen_device_t *dev
+        )
+{
+    if (dev->ecdev) {
+        ecdev_close(dev->ecdev);
+        ecdev_withdraw(dev->ecdev);
+    }
+    if (!(dev->socket < 0)) {
+        rtdm_close(dev->socket);
+        dev->socket = -1;
+    }
+    free_netdev(dev->netdev);
+
+    if (dev->rx_buf) {
+        kfree(dev->rx_buf);
+    }
+}
+
+/*****************************************************************************/
+
+/** Creates a network socket.
+ */
+int ec_gen_device_create_socket(
+        ec_gen_device_t *dev,
+        ec_gen_interface_desc_t *desc
+        )
+{
+    int ret;
+    struct sockaddr_ll sa;
+
+    dev->rx_buf = kmalloc(EC_GEN_RX_BUF_SIZE, GFP_KERNEL);
+    if (!dev->rx_buf) {
+        return -ENOMEM;
+    }
+
+    /* create rt-socket */
+    dev->socket = rtdm_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ETHERCAT));
+    if (dev->socket < 0) {
+        printk(" rtdm_socket() = %d!\n", dev->socket);
+        return dev->socket;
+    }
+
+    printk(KERN_ERR PFX "Binding socket to interface %i (%s).\n",
+            desc->ifindex, desc->name);
+
+    memset(&sa, 0x00, sizeof(sa));
+    sa.sll_family = AF_PACKET;
+    sa.sll_protocol = htons(ETH_P_ETHERCAT);
+    sa.sll_ifindex = desc->ifindex;
+    ret = rtdm_bind(dev->socket, (struct sockaddr *)&sa,
+                      sizeof(struct sockaddr_ll));
+    if (ret < 0) {
+        printk(" rtdm_bind() = %d!\n", ret);
+        rtdm_close(dev->socket);
+        dev->socket = -1;
+        return ret;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************/
+
+/** Offer generic device to master.
+ */
+int ec_gen_device_offer(
+        ec_gen_device_t *dev,
+        ec_gen_interface_desc_t *desc
+        )
+{
+    int ret = 0;
+
+    dev->used_netdev = desc->netdev;
+    memcpy(dev->netdev->dev_addr, desc->dev_addr, ETH_ALEN);
+
+    dev->ecdev = ecdev_offer(dev->netdev, ec_gen_poll, THIS_MODULE);
+    if (dev->ecdev) {
+        if (ec_gen_device_create_socket(dev, desc)) {
+            ecdev_withdraw(dev->ecdev);
+            dev->ecdev = NULL;
+        } else if (ecdev_open(dev->ecdev)) {
+            ecdev_withdraw(dev->ecdev);
+            dev->ecdev = NULL;
+        } else {
+            ecdev_set_link(dev->ecdev, rtnetif_carrier_ok(dev->used_netdev)); // FIXME
+            ret = 1;
+        }
+    }
+
+    return ret;
+}
+
+/*****************************************************************************/
+
+/** Open the device.
+ */
+int ec_gen_device_open(
+        ec_gen_device_t *dev
+        )
+{
+    return 0;
+}
+
+/*****************************************************************************/
+
+/** Stop the device.
+ */
+int ec_gen_device_stop(
+        ec_gen_device_t *dev
+        )
+{
+    return 0;
+}
+
+/*****************************************************************************/
+
+// delegate to some rtdm thread when called from nrt context
+struct sendmsg_params {
+    int socket;
+    struct user_msghdr *msg;
+};
+
+static int sendmsg_handler(struct rt_proc_call *call)
+{
+    struct sendmsg_params *params;
+
+    params = rtpc_get_priv(call, struct sendmsg_params);
+
+    return rtdm_sendmsg(params->socket, params->msg, 0);
+}
+
+static ssize_t
+nrt_rtdm_sendmsg(int socket, struct user_msghdr *msg)
+{
+    int ret;
+    struct sendmsg_params params = {socket, msg};
+
+    ret = rtpc_dispatch_call(sendmsg_handler, 0, &params,
+                             sizeof(params), NULL, NULL);
+    return ret;
+}
+
+int ec_gen_device_start_xmit(
+        ec_gen_device_t *dev,
+        struct sk_buff *skb
+        )
+{
+    struct user_msghdr msg;
+    struct iovec iov;
+    size_t len = skb->len;
+    int ret;
+
+    ecdev_set_link(dev->ecdev, rtnetif_carrier_ok(dev->used_netdev));
+    //ecdev_set_link(dev->ecdev, 1); // FIXME
+
+    iov.iov_base = skb->data;
+    iov.iov_len = len;
+    memset(&msg, 0, sizeof(msg));
+    // msg.msg_name    = &dev->dest_addr;
+    // msg.msg_namelen = sizeof(dev->dest_addr);
+    msg.msg_iov     = &iov;
+    msg.msg_iovlen  = 1;
+
+	if (rtdm_in_rt_context())
+        ret = rtdm_sendmsg(dev->socket, &msg, 0);
+	else
+        ret = nrt_rtdm_sendmsg(dev->socket, &msg);
+
+    return ret == len ? NETDEV_TX_OK : NETDEV_TX_BUSY;
+}
+
+/*****************************************************************************/
+
+/** Polls the device.
+ */
+
+// delegate to some rtdm thread when called from nrt context
+struct recvmsg_params {
+    int socket;
+    struct user_msghdr *msg;
+};
+
+static int recvmsg_handler(struct rt_proc_call *call)
+{
+    struct recvmsg_params *params;
+
+    params = rtpc_get_priv(call, struct recvmsg_params);
+
+    return  rtdm_recvmsg(params->socket, params->msg, MSG_DONTWAIT);
+}
+
+static ssize_t
+nrt_rtdm_recvmsg(int socket, struct user_msghdr *msg)
+{
+    int ret;
+    struct recvmsg_params params = {socket,msg};
+
+    ret = rtpc_dispatch_call(recvmsg_handler, 0, &params,
+                             sizeof(params), NULL, NULL);
+    return ret;
+}
+
+void ec_gen_device_poll(
+        ec_gen_device_t *dev
+        )
+{
+    struct user_msghdr msg;
+    struct iovec iov;
+    int ret, budget = 128; // FIXME
+
+    ecdev_set_link(dev->ecdev, rtnetif_carrier_ok(dev->used_netdev));
+
+    do {
+        iov.iov_base = dev->rx_buf;
+        iov.iov_len = EC_GEN_RX_BUF_SIZE;
+        memset(&msg, 0, sizeof(msg));
+        msg.msg_iov     = &iov;
+        msg.msg_iovlen  = 1;
+
+        if (rtdm_in_rt_context())
+            ret = rtdm_recvmsg(dev->socket, &msg, MSG_DONTWAIT);
+        else
+            ret = nrt_rtdm_recvmsg(dev->socket, &msg);
+
+        if (ret > 0) {
+            ecdev_receive(dev->ecdev, dev->rx_buf, ret);
+        } else if (ret < 0) {
+            break;
+        }
+        budget--;
+    } while (budget);
+}
+
+/*****************************************************************************/
+
+/** Offer device.
+ */
+int offer_device(
+        ec_gen_interface_desc_t *desc
+        )
+{
+    ec_gen_device_t *gendev;
+    int ret = 0;
+
+    gendev = kmalloc(sizeof(ec_gen_device_t), GFP_KERNEL);
+    if (!gendev) {
+        return -ENOMEM;
+    }
+
+    ret = ec_gen_device_init(gendev);
+    if (ret) {
+        kfree(gendev);
+        return ret;
+    }
+
+    if (ec_gen_device_offer(gendev, desc)) {
+        list_add_tail(&gendev->list, &generic_devices);
+    } else {
+        ec_gen_device_clear(gendev);
+        kfree(gendev);
+    }
+
+    return ret;
+}
+
+/*****************************************************************************/
+
+/** Clear devices.
+ */
+void clear_devices(void)
+{
+    ec_gen_device_t *gendev, *next;
+
+    list_for_each_entry_safe(gendev, next, &generic_devices, list) {
+        list_del(&gendev->list);
+        ec_gen_device_clear(gendev);
+        kfree(gendev);
+    }
+}
+
+/*****************************************************************************/
+
+/** Module initialization.
+ *
+ * Initializes \a master_count masters.
+ * \return 0 on success, else < 0
+ */
+int __init ec_gen_init_module(void)
+{
+    int ret = 0;
+    int devices = 0;
+    int i;
+    struct list_head descs;
+    struct rtnet_device *rtdev;
+    ec_gen_interface_desc_t *desc, *next;
+
+    printk(KERN_INFO PFX "EtherCAT master RTnet Ethernet device module %s\n",
+            EC_MASTER_VERSION);
+
+    INIT_LIST_HEAD(&generic_devices);
+    INIT_LIST_HEAD(&descs);
+
+    for (i = 0; i < MAX_RT_DEVICES; i++) {
+
+        rtdev = rtdev_get_by_index(i);
+        if (rtdev != NULL) {
+            mutex_lock(&rtdev->nrt_lock);
+
+            //if (test_bit(PRIV_FLAG_UP, &rtdev->priv_flags)) {
+            //    mutex_unlock(&rtdev->nrt_lock);
+            //    printk(KERN_ERR PFX "%s busy, skipping device!\n", rtdev->name);
+            //    rtdev_dereference(rtdev);
+            //    continue;
+            //}
+
+            desc = kmalloc(sizeof(ec_gen_interface_desc_t), GFP_ATOMIC);
+            if (!desc) {
+                ret = -ENOMEM;
+                goto out_err;
+            }
+            strncpy(desc->name, rtdev->name, IFNAMSIZ);
+            desc->netdev = rtdev;
+            desc->ifindex = rtdev->ifindex;
+            memcpy(desc->dev_addr, rtdev->dev_addr, ETH_ALEN);
+            list_add_tail(&desc->list, &descs);
+              mutex_unlock(&rtdev->nrt_lock);
+
+            devices++;
+        }
+    }
+
+    if (devices == 0) {
+        printk(KERN_ERR PFX "no real-time devices found!\n");
+        ret = -ENODEV;
+        goto out_err;
+    }
+
+    list_for_each_entry_safe(desc, next, &descs, list) {
+        ret = offer_device(desc);
+        if (ret) {
+            goto out_err;
+        }
+        kfree(desc);
+    }
+    return ret;
+
+out_err:
+    list_for_each_entry_safe(desc, next, &descs, list) {
+        list_del(&desc->list);
+        kfree(desc);
+    }
+    clear_devices();
+    return ret;
+}
+
+/*****************************************************************************/
+
+/** Module cleanup.
+ *
+ * Clears all master instances.
+ */
+void __exit ec_gen_cleanup_module(void)
+{
+    clear_devices();
+    printk(KERN_INFO PFX "Unloading.\n");
+}
+
+/*****************************************************************************/
+
+/** \cond */
+
+module_init(ec_gen_init_module);
+module_exit(ec_gen_cleanup_module);
+
+/** \endcond */
+
+/*****************************************************************************/
--- a/examples/xenomai/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/examples/xenomai/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -34,12 +34,10 @@
 ec_xenomai_example_CFLAGS = \
 	-Wall \
 	-I$(top_srcdir)/include \
-	$(XENOMAI_NATIVE_CFLAGS) \
-	$(XENOMAI_RTDM_CFLAGS)
+	$(XENOMAI_NATIVE_CFLAGS)
 
 ec_xenomai_example_LDFLAGS = \
 	-L$(top_builddir)/lib/.libs -lethercat_rtdm \
-	$(XENOMAI_NATIVE_LDFLAGS) \
-	$(XENOMAI_RTDM_LDFLAGS)
+	$(XENOMAI_NATIVE_LDFLAGS)
 
 #------------------------------------------------------------------------------
--- a/examples/xenomai/main.c	Fri Oct 05 10:24:11 2018 +0200
+++ b/examples/xenomai/main.c	Sun Oct 07 17:05:42 2018 +0200
@@ -38,11 +38,10 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <rtdm/rtdm.h>
-#include <native/task.h>
-#include <native/sem.h>
-#include <native/mutex.h>
-#include <native/timer.h>
-#include <rtdk.h>
+#include <alchemy/task.h>
+#include <alchemy/sem.h>
+#include <alchemy/mutex.h>
+#include <alchemy/timer.h>
 #include <pthread.h>
 
 #include "ecrt.h"
@@ -122,11 +121,11 @@
 	ecrt_domain_state(domain1, &ds);
 
     if (ds.working_counter != domain1_state.working_counter) {
-        rt_printf("Domain1: WC %u.\n", ds.working_counter);
+        printf("Domain1: WC %u.\n", ds.working_counter);
     }
 
     if (ds.wc_state != domain1_state.wc_state) {
-        rt_printf("Domain1: State %u.\n", ds.wc_state);
+        printf("Domain1: State %u.\n", ds.wc_state);
     }
 
     domain1_state = ds;
@@ -141,15 +140,15 @@
 	ecrt_master_state(master, &ms);
 
     if (ms.slaves_responding != master_state.slaves_responding) {
-        rt_printf("%u slave(s).\n", ms.slaves_responding);
+        printf("%u slave(s).\n", ms.slaves_responding);
     }
 
     if (ms.al_states != master_state.al_states) {
-        rt_printf("AL states: 0x%02X.\n", ms.al_states);
+        printf("AL states: 0x%02X.\n", ms.al_states);
     }
 
     if (ms.link_up != master_state.link_up) {
-        rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
+        printf("Link is %s.\n", ms.link_up ? "up" : "down");
     }
 
     master_state = ms;
@@ -209,9 +208,6 @@
     ec_slave_config_t *sc;
     int ret;
 
-    /* Perform auto-init of rt_print buffers if the task doesn't do so */
-    rt_print_auto_init(1);
-
     signal(SIGTERM, signal_handler);
     signal(SIGINT, signal_handler);
 
@@ -263,7 +259,7 @@
         return -1;
     }
 
-    ret = rt_task_create(&my_task, "my_task", 0, 80, T_FPU);
+    ret = rt_task_create(&my_task, "my_task", 0, 80, 0);
     if (ret < 0) {
         fprintf(stderr, "Failed to create task: %s\n", strerror(-ret));
         return -1;
--- a/examples/xenomai_posix/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/examples/xenomai_posix/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -34,12 +34,10 @@
 ec_xenomai_posix_example_CFLAGS = \
 	-Wall \
 	-I$(top_srcdir)/include \
-	$(XENOMAI_POSIX_CFLAGS) \
-	$(XENOMAI_RTDM_CFLAGS)
+	$(XENOMAI_POSIX_CFLAGS)
 
 ec_xenomai_posix_example_LDFLAGS = \
 	-L$(top_builddir)/lib/.libs -lethercat_rtdm \
-	$(XENOMAI_POSIX_LDFLAGS) \
-	$(XENOMAI_RTDM_LDFLAGS)
+	$(XENOMAI_POSIX_LDFLAGS)
 
 #------------------------------------------------------------------------------
--- a/examples/xenomai_posix/main.c	Fri Oct 05 10:24:11 2018 +0200
+++ b/examples/xenomai_posix/main.c	Sun Oct 07 17:05:42 2018 +0200
@@ -40,9 +40,6 @@
 #include <sys/mman.h>
 #include <time.h>
 
-#include <rtdm/rtdm.h>
-#include <rtdk.h>
-
 #include "ecrt.h"
 
 #define NSEC_PER_SEC 1000000000
@@ -74,7 +71,7 @@
 #define DigOutSlave01_Pos 0, 1
 
 #define Beckhoff_EK1100 0x00000002, 0x044c2c52
-#define Beckhoff_EL2004 0x00000002, 0x07d43052
+#define Beckhoff_EL2088 0x00000002, 0x08283052
 
 // offsets for PDO entries
 static unsigned int off_dig_out0 = 0;
@@ -82,7 +79,7 @@
 // process data
 
 const static ec_pdo_entry_reg_t domain1_regs[] = {
-   {DigOutSlave01_Pos, Beckhoff_EL2004, 0x7000, 0x01, &off_dig_out0, NULL},
+   {DigOutSlave01_Pos, Beckhoff_EL2088, 0x7000, 0x01, &off_dig_out0, NULL},
    {}
 };
 
@@ -124,11 +121,11 @@
 	ecrt_domain_state(domain1, &ds);
 
     if (ds.working_counter != domain1_state.working_counter) {
-        rt_printf("Domain1: WC %u.\n", ds.working_counter);
+        printf("Domain1: WC %u.\n", ds.working_counter);
     }
 
     if (ds.wc_state != domain1_state.wc_state) {
-        rt_printf("Domain1: State %u.\n", ds.wc_state);
+        printf("Domain1: State %u.\n", ds.wc_state);
     }
 
     domain1_state = ds;
@@ -143,15 +140,15 @@
 	ecrt_master_state(master, &ms);
 
     if (ms.slaves_responding != master_state.slaves_responding) {
-        rt_printf("%u slave(s).\n", ms.slaves_responding);
+        printf("%u slave(s).\n", ms.slaves_responding);
     }
 
     if (ms.al_states != master_state.al_states) {
-        rt_printf("AL states: 0x%02X.\n", ms.al_states);
+        printf("AL states: 0x%02X.\n", ms.al_states);
     }
 
     if (ms.link_up != master_state.link_up) {
-        rt_printf("Link is %s.\n", ms.link_up ? "up" : "down");
+        printf("Link is %s.\n", ms.link_up ? "up" : "down");
     }
 
     master_state = ms;
@@ -164,8 +161,11 @@
     struct timespec next_period;
     int cycle_counter = 0;
 	unsigned int blink = 0;
-
-    clock_gettime(CLOCK_REALTIME, &next_period);
+    struct sched_param  param = { .sched_priority = 80 };
+
+    pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
+    
+    clock_gettime(CLOCK_MONOTONIC, &next_period);
 
     while (run) {
         next_period.tv_nsec += cycle_us * 1000;
@@ -174,7 +174,7 @@
 			next_period.tv_sec++;
 		}
 
-        clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next_period, NULL);
+        clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_period, NULL);
 
         cycle_counter++;
 
@@ -245,7 +245,7 @@
     }
 
     sc_dig_out_01 =
-        ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2004);
+        ecrt_master_slave_config(master, DigOutSlave01_Pos, Beckhoff_EL2088);
     if (!sc_dig_out_01) {
         fprintf(stderr, "Failed to get slave configuration.\n");
         return -1;
@@ -271,15 +271,9 @@
         return -1;
     }
 
-    /* Create cyclic RT-thread */
-    struct sched_param param = { .sched_priority = 82 };
-
     pthread_attr_t thattr;
     pthread_attr_init(&thattr);
     pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
-    pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED);
-    pthread_attr_setschedpolicy(&thattr, SCHED_FIFO);
-    pthread_setschedparam(cyclic_thread, SCHED_FIFO, &param);
 
     ret = pthread_create(&cyclic_thread, &thattr, &my_thread, NULL);
     if (ret) {
--- a/lib/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/lib/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -64,8 +64,8 @@
 libethercat_rtdm_la_LDFLAGS = $(libethercat_la_LDFLAGS)
 
 if ENABLE_XENOMAI
-libethercat_rtdm_la_CFLAGS += $(XENOMAI_RTDM_CFLAGS)
-libethercat_rtdm_la_LDFLAGS += $(XENOMAI_RTDM_LDFLAGS)
+libethercat_rtdm_la_CFLAGS += $(XENOMAI_LIB_CFLAGS)
+libethercat_rtdm_la_LDFLAGS += $(XENOMAI_LIB_LDFLAGS)
 endif
 
 if ENABLE_RTAI
--- a/lib/common.c	Fri Oct 05 10:24:11 2018 +0200
+++ b/lib/common.c	Sun Oct 07 17:05:42 2018 +0200
@@ -87,18 +87,10 @@
     master->first_config = NULL;
 
     snprintf(path, MAX_PATH_LEN - 1,
-#ifdef USE_RTDM
-            "EtherCAT%u",
-#else
             "/dev/EtherCAT%u",
-#endif
             master_index);
 
-#ifdef USE_RTDM
-    master->fd = rt_dev_open(path, O_RDWR);
-#else
     master->fd = open(path, O_RDWR);
-#endif
     if (EC_IOCTL_IS_ERROR(master->fd)) {
         fprintf(stderr, "Failed to open %s: %s\n", path,
                 strerror(EC_IOCTL_ERRNO(master->fd)));
--- a/lib/ioctl.h	Fri Oct 05 10:24:11 2018 +0200
+++ b/lib/ioctl.h	Sun Oct 07 17:05:42 2018 +0200
@@ -33,11 +33,7 @@
 
 /*****************************************************************************/
 
-#ifdef USE_RTDM
-#include <rtdm/rtdm.h>
-#else
 #include <sys/ioctl.h>
-#endif
 
 /*****************************************************************************/
 
@@ -45,17 +41,9 @@
 
 /*****************************************************************************/
 
-#ifdef USE_RTDM
-
-#define ioctl rt_dev_ioctl
-
-/* rt_dev_ioctl() returns negative error code */
-#define EC_IOCTL_IS_ERROR(X) ((X) < 0)
-#define EC_IOCTL_ERRNO(X) (-(X))
-
-#else
-
-#define ioctl ioctl
+/* FIXME : historical code inherited from difference 
+           between RTDM ioctl an normal ioctl 
+           -> should ioctl.h be removed ? */
 
 /* libc's ioctl() always returns -1 on error and sets errno */
 #define EC_IOCTL_IS_ERROR(X) ((X) == -1)
@@ -63,8 +51,6 @@
 
 #include <errno.h>
 
-#endif
-
 /*****************************************************************************/
 
 #endif /* __EC_LIB_IOCTL_H__ */
--- a/lib/master.c	Fri Oct 05 10:24:11 2018 +0200
+++ b/lib/master.c	Sun Oct 07 17:05:42 2018 +0200
@@ -88,11 +88,7 @@
     ec_master_clear_config(master);
 
     if (master->fd != -1) {
-#if USE_RTDM
-        rt_dev_close(master->fd);
-#else
         close(master->fd);
-#endif
     }
 }
 
@@ -547,12 +543,6 @@
     master->process_data_size = io.process_data_size;
 
     if (master->process_data_size) {
-#ifdef USE_RTDM
-        /* memory-mapping was already done in kernel. The user-space addess is
-         * provided in the ioctl data.
-         */
-        master->process_data = io.process_data;
-#else
         master->process_data = mmap(0, master->process_data_size,
                 PROT_READ | PROT_WRITE, MAP_SHARED, master->fd, 0);
         if (master->process_data == MAP_FAILED) {
@@ -562,7 +552,6 @@
             master->process_data_size = 0;
             return -errno;
         }
-#endif
 
         // Access the mapped region to cause the initial page fault
         master->process_data[0] = 0x00;
--- a/master/Kbuild.in	Fri Oct 05 10:24:11 2018 +0200
+++ b/master/Kbuild.in	Sun Oct 07 17:05:42 2018 +0200
@@ -85,7 +85,7 @@
 ec_master-objs += rtdm.o
 
 ifeq (@ENABLE_XENOMAI@, 1)
-CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include
+CFLAGS_rtdm.o := -I@XENOMAI_DIR@/include/xenomai
 endif
 
 ifeq (@ENABLE_RTAI@, 1)
--- a/master/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/master/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -85,7 +85,7 @@
 
 modules_install:
 	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" \
-		INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)" modules_install
+		$(INSTALL_MOD_PATH_DEFS) modules_install
 
 clean-local:
 	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" clean
--- a/master/ioctl.c	Fri Oct 05 10:24:11 2018 +0200
+++ b/master/ioctl.c	Sun Oct 07 17:05:42 2018 +0200
@@ -57,6 +57,17 @@
 #define ATTRIBUTES
 #endif
 
+#ifndef EC_IOCTL_RTDM
+#define ec_copy_to_user copy_to_user
+#define ec_copy_from_user copy_from_user
+#else
+/* RTDM provides rtdm_copy_{to,from}_user but they need fd argument 
+   for no good reason. This is is just a shortcut to real call */
+#define ec_copy_to_user __copy_to_user_inatomic
+#define ec_copy_from_user __copy_from_user_inatomic
+#endif
+
+
 /*****************************************************************************/
 
 /** Copies a string to an ioctl structure.
@@ -89,7 +100,7 @@
     data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
     data.master_count = ec_master_count();
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -183,7 +194,7 @@
     io.ref_clock =
         master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
 
-    if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -205,7 +216,7 @@
     const ec_slave_t *slave;
     int i;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -271,7 +282,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -292,7 +303,7 @@
     const ec_slave_t *slave;
     const ec_sync_t *sync;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -324,7 +335,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -346,7 +357,7 @@
     const ec_sync_t *sync;
     const ec_pdo_t *pdo;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -383,7 +394,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -406,7 +417,7 @@
     const ec_pdo_t *pdo;
     const ec_pdo_entry_t *entry;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -452,7 +463,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -473,7 +484,7 @@
     const ec_domain_t *domain;
     unsigned int dev_idx;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -497,7 +508,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -518,7 +529,7 @@
     const ec_domain_t *domain;
     const ec_fmmu_config_t *fmmu;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -549,7 +560,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -569,7 +580,7 @@
     ec_ioctl_domain_data_t data;
     const ec_domain_t *domain;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -590,7 +601,7 @@
         return -EFAULT;
     }
 
-    if (copy_to_user((void __user *) data.target, domain->data,
+    if (ec_copy_to_user((void __user *) data.target, domain->data,
                 domain->data_size)) {
         up(&master->master_sem);
         return -EFAULT;
@@ -643,7 +654,7 @@
     ec_ioctl_slave_state_t data;
     ec_slave_t *slave;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -679,7 +690,7 @@
     const ec_slave_t *slave;
     const ec_sdo_t *sdo;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -707,7 +718,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -729,7 +740,7 @@
     const ec_sdo_t *sdo;
     const ec_sdo_entry_t *entry;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -787,7 +798,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -808,7 +819,7 @@
     uint8_t *target;
     int ret;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -823,7 +834,7 @@
             data.target_size, &data.data_size, &data.abort_code);
 
     if (!ret) {
-        if (copy_to_user((void __user *) data.target,
+        if (ec_copy_to_user((void __user *) data.target,
                     target, data.data_size)) {
             kfree(target);
             return -EFAULT;
@@ -832,7 +843,7 @@
 
     kfree(target);
 
-    if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -854,7 +865,7 @@
     uint8_t *sdo_data;
     int retval;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -864,7 +875,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
+    if (ec_copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
         kfree(sdo_data);
         return -EFAULT;
     }
@@ -880,7 +891,7 @@
 
     kfree(sdo_data);
 
-    if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data))) {
         retval = -EFAULT;
     }
 
@@ -902,7 +913,7 @@
     const ec_slave_t *slave;
     int retval;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -925,7 +936,7 @@
         return -EINVAL;
     }
 
-    if (copy_to_user((void __user *) data.words,
+    if (ec_copy_to_user((void __user *) data.words,
                 slave->sii_words + data.offset, data.nwords * 2))
         retval = -EFAULT;
     else
@@ -952,7 +963,7 @@
     uint16_t *words;
     ec_sii_write_request_t request;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -967,7 +978,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(words,
+    if (ec_copy_from_user(words,
                 (void __user *) data.words, byte_size)) {
         kfree(words);
         return -EFAULT;
@@ -1039,7 +1050,7 @@
     ec_reg_request_t request;
     int ret;
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -1093,7 +1104,7 @@
     wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
 
     if (request.state == EC_INT_REQUEST_SUCCESS) {
-        if (copy_to_user((void __user *) io.data, request.data, io.size)) {
+        if (ec_copy_to_user((void __user *) io.data, request.data, io.size)) {
             return -EFAULT;
         }
     }
@@ -1118,7 +1129,7 @@
     ec_reg_request_t request;
     int ret;
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -1132,7 +1143,7 @@
         return ret;
     }
 
-    if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
+    if (ec_copy_from_user(request.data, (void __user *) io.data, io.size)) {
         ec_reg_request_clear(&request);
         return -EFAULT;
     }
@@ -1202,7 +1213,7 @@
     const ec_slave_config_t *sc;
     uint8_t i;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -1239,7 +1250,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -1260,7 +1271,7 @@
     const ec_slave_config_t *sc;
     const ec_pdo_t *pdo;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -1295,7 +1306,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -1317,7 +1328,7 @@
     const ec_pdo_t *pdo;
     const ec_pdo_entry_t *entry;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -1360,7 +1371,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -1385,7 +1396,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
+    if (ec_copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
         kfree(ioctl);
         return -EFAULT;
     }
@@ -1421,7 +1432,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
+    if (ec_copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
         kfree(ioctl);
         return -EFAULT;
     }
@@ -1449,7 +1460,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
+    if (ec_copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
         kfree(ioctl);
         return -EFAULT;
     }
@@ -1485,7 +1496,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
+    if (ec_copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
         kfree(ioctl);
         return -EFAULT;
     }
@@ -1510,7 +1521,7 @@
     ec_ioctl_eoe_handler_t data;
     const ec_eoe_t *eoe;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -1540,7 +1551,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -1615,7 +1626,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -1637,7 +1648,7 @@
 
     up(&master->master_sem);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -1704,8 +1715,6 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    io.process_data = NULL;
-
     /* Get the sum of the domains' process data sizes. */
 
     ctx->process_data_size = 0;
@@ -1735,18 +1744,6 @@
                     ctx->process_data + offset);
             offset += ecrt_domain_size(domain);
         }
-
-#ifdef EC_IOCTL_RTDM
-        /* RTDM uses a different approach for memory-mapping, which has to be
-         * initiated by the kernel.
-         */
-        ret = ec_rtdm_mmap(ctx, &io.process_data);
-        if (ret < 0) {
-            EC_MASTER_ERR(master, "Failed to map process data"
-                    " memory to user space (code %i).\n", ret);
-            return ret;
-        }
-#endif
     }
 
     io.process_data_size = ctx->process_data_size;
@@ -1760,7 +1757,7 @@
     if (ret < 0)
         return ret;
 
-    if (copy_to_user((void __user *) arg, &io,
+    if (ec_copy_to_user((void __user *) arg, &io,
                 sizeof(ec_ioctl_master_activate_t)))
         return -EFAULT;
 
@@ -1804,7 +1801,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&send_interval, (void __user *) arg,
+    if (ec_copy_from_user(&send_interval, (void __user *) arg,
                 sizeof(send_interval))) {
         return -EFAULT;
     }
@@ -1874,7 +1871,7 @@
 
     ecrt_master_state(master, &data);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -1896,7 +1893,7 @@
     ec_master_link_state_t state;
     int ret;
 
-    if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
+    if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
         return -EFAULT;
     }
 
@@ -1905,7 +1902,7 @@
         return ret;
     }
 
-    if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
+    if (ec_copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
         return -EFAULT;
     }
 
@@ -1929,7 +1926,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -2001,7 +1998,7 @@
         return ret;
     }
 
-    if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
+    if (ec_copy_to_user((void __user *) arg, &time, sizeof(time))) {
         return -EFAULT;
     }
 
@@ -2047,7 +2044,7 @@
 
     time_diff = ecrt_master_sync_monitor_process(master);
 
-    if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
+    if (ec_copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
         return -EFAULT;
 
     return 0;
@@ -2093,7 +2090,7 @@
         goto out_return;
     }
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         ret = -EFAULT;
         goto out_return;
     }
@@ -2145,7 +2142,7 @@
         goto out_return;
     }
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         ret = -EFAULT;
         goto out_return;
     }
@@ -2187,7 +2184,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem))
@@ -2221,7 +2218,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem))
@@ -2256,7 +2253,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem))
@@ -2291,7 +2288,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem))
@@ -2328,7 +2325,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem))
@@ -2349,7 +2346,7 @@
     ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
             data.entry_subindex, domain, &data.bit_position);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return ret;
@@ -2376,7 +2373,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2399,7 +2396,7 @@
     ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
             io.pdo_pos, io.entry_pos, domain, &io.bit_position);
 
-    if (copy_to_user((void __user *) arg, &io, sizeof(io)))
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io)))
         return -EFAULT;
 
     return ret;
@@ -2423,7 +2420,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem))
@@ -2465,7 +2462,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (!data.size)
@@ -2475,7 +2472,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
+    if (ec_copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
         kfree(sdo_data);
         return -EFAULT;
     }
@@ -2523,7 +2520,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io)))
         return -EFAULT;
 
     if (down_interruptible(&master->master_sem)) {
@@ -2563,7 +2560,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2579,7 +2576,7 @@
         return ret;
     }
 
-    if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
+    if (ec_copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
         return -EFAULT;
     }
 
@@ -2605,7 +2602,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2639,7 +2636,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2657,7 +2654,7 @@
 
     io.overruns = ret;
 
-    if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2683,7 +2680,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -2709,7 +2706,7 @@
     if (IS_ERR(req))
         return PTR_ERR(req);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -2735,7 +2732,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2762,7 +2759,7 @@
         return PTR_ERR(reg);
     }
 
-    if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -2788,7 +2785,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -2813,7 +2810,7 @@
     if (IS_ERR(voe))
         return PTR_ERR(voe);
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -2838,7 +2835,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -2851,7 +2848,7 @@
 
     ecrt_slave_config_state(sc, &state);
 
-    if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
+    if (ec_copy_to_user((void __user *) data.state, &state, sizeof(state)))
         return -EFAULT;
 
     return 0;
@@ -2877,7 +2874,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
+    if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
         return -EFAULT;
 
     if (!ioctl.size)
@@ -2887,7 +2884,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
+    if (ec_copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
         kfree(data);
         return -EFAULT;
     }
@@ -3054,7 +3051,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data))) {
         return -EFAULT;
     }
 
@@ -3067,7 +3064,7 @@
 
     ecrt_domain_state(domain, &state);
 
-    if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
+    if (ec_copy_to_user((void __user *) data.state, &state, sizeof(state)))
         return -EFAULT;
 
     return 0;
@@ -3092,7 +3089,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor req will not be
@@ -3129,7 +3126,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor req will not be
@@ -3166,7 +3163,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor req will not be
@@ -3186,7 +3183,7 @@
     else
         data.size = 0;
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -3211,7 +3208,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor req will not be
@@ -3249,7 +3246,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (!data.size) {
@@ -3272,7 +3269,7 @@
     if (ret)
         return ret;
 
-    if (copy_from_user(req->data, (void __user *) data.data, data.size))
+    if (ec_copy_from_user(req->data, (void __user *) data.data, data.size))
         return -EFAULT;
 
     req->data_size = data.size;
@@ -3299,7 +3296,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor req will not be
@@ -3313,7 +3310,7 @@
         return -ENOENT;
     }
 
-    if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
+    if (ec_copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
                 ecrt_sdo_request_data_size(req)))
         return -EFAULT;
 
@@ -3340,7 +3337,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3359,7 +3356,7 @@
         return -ENOENT;
     }
 
-    if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
+    if (ec_copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
                 min(reg->mem_size, io.mem_size))) {
         return -EFAULT;
     }
@@ -3387,7 +3384,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3405,7 +3402,7 @@
     io.state = ecrt_reg_request_state(reg);
     io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
 
-    if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3432,7 +3429,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3451,7 +3448,7 @@
         return -EOVERFLOW;
     }
 
-    if (copy_from_user(reg->data, (void __user *) io.data,
+    if (ec_copy_from_user(reg->data, (void __user *) io.data,
                 io.transfer_size)) {
         return -EFAULT;
     }
@@ -3480,7 +3477,7 @@
         return -EPERM;
     }
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3524,7 +3521,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     if (get_user(vendor_id, data.vendor_id))
@@ -3569,7 +3566,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor voe will not be
@@ -3615,7 +3612,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor voe will not be
@@ -3652,7 +3649,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor voe will not be
@@ -3689,7 +3686,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor voe will not be
@@ -3707,7 +3704,7 @@
         if (data.size > ec_voe_handler_mem_size(voe))
             return -EOVERFLOW;
 
-        if (copy_from_user(ecrt_voe_handler_data(voe),
+        if (ec_copy_from_user(ecrt_voe_handler_data(voe),
                     (void __user *) data.data, data.size))
             return -EFAULT;
     }
@@ -3735,7 +3732,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor voe will not be
@@ -3755,7 +3752,7 @@
     else
         data.size = 0;
 
-    if (copy_to_user((void __user *) arg, &data, sizeof(data)))
+    if (ec_copy_to_user((void __user *) arg, &data, sizeof(data)))
         return -EFAULT;
 
     return 0;
@@ -3780,7 +3777,7 @@
     if (unlikely(!ctx->requested))
         return -EPERM;
 
-    if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
+    if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data)))
         return -EFAULT;
 
     /* no locking of master_sem needed, because neither sc nor voe will not be
@@ -3794,7 +3791,7 @@
         return -ENOENT;
     }
 
-    if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
+    if (ec_copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
                 ecrt_voe_handler_data_size(voe)))
         return -EFAULT;
 
@@ -3817,7 +3814,7 @@
     ec_slave_t *slave;
     int ret;
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3881,7 +3878,7 @@
             return -EOVERFLOW;
         }
         io.data_size = request.data_size;
-        if (copy_to_user((void __user *) io.buffer,
+        if (ec_copy_to_user((void __user *) io.buffer,
                     request.buffer, io.data_size)) {
             ec_foe_request_clear(&request);
             return -EFAULT;
@@ -3889,7 +3886,7 @@
         ret = 0;
     }
 
-    if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io))) {
         ret = -EFAULT;
     }
 
@@ -3913,7 +3910,7 @@
     ec_slave_t *slave;
     int ret;
 
-    if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
+    if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io))) {
         return -EFAULT;
     }
 
@@ -3925,7 +3922,7 @@
         return ret;
     }
 
-    if (copy_from_user(request.buffer,
+    if (ec_copy_from_user(request.buffer,
                 (void __user *) io.buffer, io.buffer_size)) {
         ec_foe_request_clear(&request);
         return -EFAULT;
@@ -3977,7 +3974,7 @@
 
     ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
 
-    if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
+    if (ec_copy_to_user((void __user *) arg, &io, sizeof(io))) {
         ret = -EFAULT;
     }
 
@@ -4000,7 +3997,7 @@
     u8 *data;
     int retval;
 
-    if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
+    if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
         return -EFAULT;
     }
 
@@ -4019,14 +4016,14 @@
         return retval;
     }
 
-    if (copy_to_user((void __user *) ioctl.data,
+    if (ec_copy_to_user((void __user *) ioctl.data,
                 data, ioctl.data_size)) {
         kfree(data);
         return -EFAULT;
     }
     kfree(data);
 
-    if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
+    if (ec_copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
         retval = -EFAULT;
     }
 
@@ -4049,7 +4046,7 @@
     u8 *data;
     int retval;
 
-    if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
+    if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
         return -EFAULT;
     }
 
@@ -4059,7 +4056,7 @@
                 ioctl.data_size);
         return -ENOMEM;
     }
-    if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
+    if (ec_copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
         kfree(data);
         return -EFAULT;
     }
@@ -4072,7 +4069,7 @@
         return retval;
     }
 
-    if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
+    if (ec_copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
         retval = -EFAULT;
     }
 
--- a/master/ioctl.h	Fri Oct 05 10:24:11 2018 +0200
+++ b/master/ioctl.h	Sun Oct 07 17:05:42 2018 +0200
@@ -592,7 +592,6 @@
 
 typedef struct {
     // outputs
-    void *process_data;
     size_t process_data_size;
 } ec_ioctl_master_activate_t;
 
@@ -774,7 +773,6 @@
 
 long ec_ioctl_rtdm(ec_master_t *, ec_ioctl_context_t *, unsigned int,
         void __user *);
-int ec_rtdm_mmap(ec_ioctl_context_t *, void **);
 
 #endif
 
--- a/master/rtdm.c	Fri Oct 05 10:24:11 2018 +0200
+++ b/master/rtdm.c	Sun Oct 07 17:05:42 2018 +0200
@@ -34,7 +34,7 @@
 #include <linux/slab.h>
 #include <linux/mman.h>
 
-#include <rtdm/rtdm_driver.h>
+#include <rtdm/driver.h>
 
 #include "master.h"
 #include "ioctl.h"
@@ -44,23 +44,35 @@
  */
 #define DEBUG 0
 
-/****************************************************************************/
-
-/** Context structure for an open RTDM file handle.
- */
-typedef struct {
-    rtdm_user_info_t *user_info; /**< RTDM user data. */
-    ec_ioctl_context_t ioctl_ctx; /**< Context structure. */
-} ec_rtdm_context_t;
-
-/****************************************************************************/
-
-int ec_rtdm_open(struct rtdm_dev_context *, rtdm_user_info_t *, int);
-int ec_rtdm_close(struct rtdm_dev_context *, rtdm_user_info_t *);
-int ec_rtdm_ioctl(struct rtdm_dev_context *, rtdm_user_info_t *,
+
+/****************************************************************************/
+
+int ec_rtdm_open(struct rtdm_fd *, int);
+void ec_rtdm_close(struct rtdm_fd *);
+int ec_rtdm_rt_ioctl(struct rtdm_fd *,
         unsigned int, void __user *);
-
-/****************************************************************************/
+int ec_rtdm_ioctl(struct rtdm_fd *,
+        unsigned int, void __user *);
+int ec_rtdm_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma);
+
+/****************************************************************************/
+
+static struct rtdm_driver ec_rtdm_driver = {
+	.profile_info		=	RTDM_PROFILE_INFO(foo,
+							  RTDM_CLASS_EXPERIMENTAL,
+							  222,
+							  1),
+	.device_flags		=	RTDM_NAMED_DEVICE,
+	.device_count		=	1,
+	.context_size		=	sizeof(ec_ioctl_context_t),
+	.ops = {
+        .open      = ec_rtdm_open,
+        .close     = ec_rtdm_close,
+        .ioctl_rt  = ec_rtdm_rt_ioctl,
+        .ioctl_nrt = ec_rtdm_ioctl,
+        .mmap      = ec_rtdm_mmap
+	},
+};
 
 /** Initialize an RTDM device.
  *
@@ -72,6 +84,7 @@
         )
 {
     int ret;
+    char* devlabel;
 
     rtdm_dev->master = master;
 
@@ -80,31 +93,28 @@
         EC_MASTER_ERR(master, "Failed to reserve memory for RTDM device.\n");
         return -ENOMEM;
     }
-
-    rtdm_dev->dev->struct_version = RTDM_DEVICE_STRUCT_VER;
-    rtdm_dev->dev->device_flags = RTDM_NAMED_DEVICE;
-    rtdm_dev->dev->context_size = sizeof(ec_rtdm_context_t);
-    snprintf(rtdm_dev->dev->device_name, RTDM_MAX_DEVNAME_LEN,
+    
+    devlabel = kzalloc(RTDM_MAX_DEVNAME_LEN+1, GFP_KERNEL);
+    if (!devlabel) {
+        EC_MASTER_ERR(master, "Failed to reserve memory for RTDM device name.\n");
+        return -ENOMEM;
+        kfree(rtdm_dev->dev);
+    }
+    snprintf(devlabel, RTDM_MAX_DEVNAME_LEN,
             "EtherCAT%u", master->index);
-    rtdm_dev->dev->open_nrt = ec_rtdm_open;
-    rtdm_dev->dev->ops.close_nrt = ec_rtdm_close;
-    rtdm_dev->dev->ops.ioctl_rt = ec_rtdm_ioctl;
-    rtdm_dev->dev->ops.ioctl_nrt = ec_rtdm_ioctl;
-    rtdm_dev->dev->device_class = RTDM_CLASS_EXPERIMENTAL;
-    rtdm_dev->dev->device_sub_class = 222;
-    rtdm_dev->dev->driver_name = "EtherCAT";
-    rtdm_dev->dev->driver_version = RTDM_DRIVER_VER(1, 0, 2);
-    rtdm_dev->dev->peripheral_name = rtdm_dev->dev->device_name;
-    rtdm_dev->dev->provider_name = "EtherLab Community";
-    rtdm_dev->dev->proc_name = rtdm_dev->dev->device_name;
+
+    rtdm_dev->dev->label = devlabel;
+    rtdm_dev->dev->driver = &ec_rtdm_driver;
     rtdm_dev->dev->device_data = rtdm_dev; /* pointer to parent */
 
+
     EC_MASTER_INFO(master, "Registering RTDM device %s.\n",
-            rtdm_dev->dev->driver_name);
+            devlabel);
     ret = rtdm_dev_register(rtdm_dev->dev);
     if (ret) {
         EC_MASTER_ERR(master, "Initialization of RTDM interface failed"
                 " (return value %i).\n", ret);
+        kfree(rtdm_dev->dev->label);
         kfree(rtdm_dev->dev);
     }
 
@@ -119,16 +129,11 @@
         ec_rtdm_dev_t *rtdm_dev /**< EtherCAT RTDM device. */
         )
 {
-    int ret;
-
     EC_MASTER_INFO(rtdm_dev->master, "Unregistering RTDM device %s.\n",
-            rtdm_dev->dev->driver_name);
-    ret = rtdm_dev_unregister(rtdm_dev->dev, 1000 /* poll delay [ms] */);
-    if (ret < 0) {
-        EC_MASTER_WARN(rtdm_dev->master,
-                "Failed to unregister RTDM device (code %i).\n", ret);
-    }
-
+            rtdm_dev->dev->label);
+    rtdm_dev_unregister(rtdm_dev->dev);
+
+    kfree(rtdm_dev->dev->label);
     kfree(rtdm_dev->dev);
 }
 
@@ -139,21 +144,19 @@
  * \return Always zero (success).
  */
 int ec_rtdm_open(
-        struct rtdm_dev_context *context, /**< Context. */
-        rtdm_user_info_t *user_info, /**< User data. */
+        struct rtdm_fd *fd, /**< User data. */
         int oflags /**< Open flags. */
         )
 {
-    ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
-#if DEBUG
-    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
-#endif
-
-    ctx->user_info = user_info;
-    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;
+    ec_ioctl_context_t *ctx = (ec_ioctl_context_t *) rtdm_fd_to_private(fd);
+#if DEBUG
+    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) rtdm_fd_device(fd)->device_data;
+#endif
+
+    ctx->writable = oflags & O_WRONLY || oflags & O_RDWR;
+    ctx->requested = 0;
+    ctx->process_data = NULL;
+    ctx->process_data_size = 0;
 
 #if DEBUG
     EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s opened.\n",
@@ -168,15 +171,14 @@
  *
  * \return Always zero (success).
  */
-int ec_rtdm_close(
-        struct rtdm_dev_context *context, /**< Context. */
-        rtdm_user_info_t *user_info /**< User data. */
-        )
-{
-    ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
-    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
-
-    if (ctx->ioctl_ctx.requested) {
+void ec_rtdm_close(
+        struct rtdm_fd *fd /**< User data. */
+        )
+{
+    ec_ioctl_context_t *ctx = (ec_ioctl_context_t *) rtdm_fd_to_private(fd);
+    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) rtdm_fd_device(fd)->device_data;
+
+    if (ctx->requested) {
         ecrt_release_master(rtdm_dev->master);
 	}
 
@@ -184,7 +186,6 @@
     EC_MASTER_INFO(rtdm_dev->master, "RTDM device %s closed.\n",
             context->device->device_name);
 #endif
-    return 0;
 }
 
 /****************************************************************************/
@@ -193,49 +194,92 @@
  *
  * \return ioctl() return code.
  */
-int ec_rtdm_ioctl(
-        struct rtdm_dev_context *context, /**< Context. */
-        rtdm_user_info_t *user_info, /**< User data. */
+int ec_rtdm_rt_ioctl(
+        struct rtdm_fd *fd, /**< User data. */
         unsigned int request, /**< Request. */
         void __user *arg /**< Argument. */
         )
 {
-    ec_rtdm_context_t *ctx = (ec_rtdm_context_t *) context->dev_private;
-    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) context->device->device_data;
+    switch (request) {
+        /*
+            Requests to be handled directly in primary domain
+            
+            Note: list was made by selecting calls in ioctl.c 
+                  that seems not to make calls forbiden in primary mode
+        */
+        case EC_IOCTL_MASTER_RESCAN:
+        case EC_IOCTL_SEND:
+        case EC_IOCTL_RECEIVE:
+        case EC_IOCTL_MASTER_STATE:
+        case EC_IOCTL_MASTER_LINK_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_SYNC_MON_QUEUE:
+        case EC_IOCTL_SYNC_MON_PROCESS:
+        case EC_IOCTL_SC_EMERG_POP:
+        case EC_IOCTL_SC_EMERG_CLEAR:
+        case EC_IOCTL_SC_EMERG_OVERRUNS:
+        case EC_IOCTL_SC_STATE:
+        case EC_IOCTL_DOMAIN_STATE:
+        case EC_IOCTL_DOMAIN_PROCESS:
+        case EC_IOCTL_DOMAIN_QUEUE:
+        case EC_IOCTL_SDO_REQUEST_INDEX:
+        case EC_IOCTL_SDO_REQUEST_TIMEOUT:
+        case EC_IOCTL_SDO_REQUEST_STATE:
+        case EC_IOCTL_SDO_REQUEST_READ:
+        case EC_IOCTL_SDO_REQUEST_WRITE:
+        case EC_IOCTL_SDO_REQUEST_DATA:
+        case EC_IOCTL_REG_REQUEST_DATA:
+        case EC_IOCTL_REG_REQUEST_STATE:
+        case EC_IOCTL_REG_REQUEST_WRITE:
+        case EC_IOCTL_REG_REQUEST_READ:
+        case EC_IOCTL_VOE_SEND_HEADER:
+        case EC_IOCTL_VOE_REC_HEADER:
+        case EC_IOCTL_VOE_READ:
+        case EC_IOCTL_VOE_READ_NOSYNC:
+        case EC_IOCTL_VOE_WRITE:
+        case EC_IOCTL_VOE_EXEC:
+        case EC_IOCTL_VOE_DATA:
+            return ec_rtdm_ioctl(fd, request, arg);
+        default:
+            break;
+    }
+    /* When a call is not supposed to happen in primary domain,
+       syscall catches -ENOSYS, then switch to secondary mode,
+       and calls .ioctl_nrt */
+    return -ENOSYS;
+}
+
+int ec_rtdm_ioctl(
+        struct rtdm_fd *fd, /**< User data. */
+        unsigned int request, /**< Request. */
+        void __user *arg /**< Argument. */
+        )
+{
+    ec_ioctl_context_t *ctx = (ec_ioctl_context_t *) rtdm_fd_to_private(fd);
+    ec_rtdm_dev_t *rtdm_dev = (ec_rtdm_dev_t *) rtdm_fd_device(fd)->device_data;
 
 #if DEBUG
     EC_MASTER_INFO(rtdm_dev->master, "ioctl(request = %u, ctl = %02x)"
             " on RTDM device %s.\n", request, _IOC_NR(request),
             context->device->device_name);
 #endif
-    return ec_ioctl_rtdm(rtdm_dev->master, &ctx->ioctl_ctx, request, arg);
+    return ec_ioctl_rtdm(rtdm_dev->master, ctx, request, arg);
 }
 
 /****************************************************************************/
 
 /** Memory-map process data to user space.
  *
- * \return Zero on success, otherwise a negative error code.
- */
-int ec_rtdm_mmap(
-        ec_ioctl_context_t *ioctl_ctx, /**< Context. */
-        void **user_address /**< Userspace address. */
-        )
-{
-    ec_rtdm_context_t *ctx =
-        container_of(ioctl_ctx, ec_rtdm_context_t, ioctl_ctx);
-    int ret;
-
-    ret = rtdm_mmap_to_user(ctx->user_info,
-            ioctl_ctx->process_data, ioctl_ctx->process_data_size,
-            PROT_READ | PROT_WRITE,
-            user_address,
-            NULL, NULL);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return 0;
-}
-
-/****************************************************************************/
+ */
+int ec_rtdm_mmap(struct rtdm_fd *fd, struct vm_area_struct *vma)
+{
+	size_t len;
+    ec_ioctl_context_t *ctx = (ec_ioctl_context_t *) rtdm_fd_to_private(fd);
+	len = vma->vm_end - vma->vm_start;
+	return rtdm_mmap_kmem(vma, (void *)ctx->process_data);
+}
+
+/****************************************************************************/
--- a/script/ethercatctl.in	Fri Oct 05 10:24:11 2018 +0200
+++ b/script/ethercatctl.in	Sun Oct 07 17:05:42 2018 +0200
@@ -108,7 +108,7 @@
             continue # ec_* module not found
         fi
 
-        if [ ${MODULE} != "generic" -a ${MODULE} != "ccat" ]; then
+        if [ ${MODULE} != "generic" -a ${MODULE} != "rtdmnet" -a ${MODULE} != "ccat" ]; then
             # try to unload standard module
             if ${LSMOD} | grep "^${MODULE} " > /dev/null; then
                 if ! ${RMMOD} ${MODULE}; then
@@ -119,7 +119,7 @@
         fi
 
         if ! ${MODPROBE} ${MODPROBE_FLAGS} ${ECMODULE}; then
-            if [ ${MODULE} != "generic" -a ${MODULE} != "ccat" ]; then
+            if [ ${MODULE} != "generic" -a ${MODULE} != "rtdmnet" -a ${MODULE} != "ccat" ]; then
                 ${MODPROBE} ${MODPROBE_FLAGS} ${MODULE} # try to restore
             fi
             ${RMMOD} ${LOADED_MODULES}
@@ -150,7 +150,7 @@
 
     # load standard modules again
     for MODULE in ${DEVICE_MODULES}; do
-        if [ ${MODULE} == "generic" -o ${MODULE} == "ccat" ]; then
+        if [ ${MODULE} == "generic" -o ${MODULE} == "rtdmnet" -o ${MODULE} == "ccat" ]; then
             continue
         fi
         ${MODPROBE} ${MODPROBE_FLAGS} ${MODULE}
--- a/tool/Makefile.am	Fri Oct 05 10:24:11 2018 +0200
+++ b/tool/Makefile.am	Sun Oct 07 17:05:42 2018 +0200
@@ -133,4 +133,5 @@
 	-Wall -DREV=$(REV) \
 	-fno-strict-aliasing
 
+ethercat_CFLAGS = $(ethercat_CXXFLAGS)
 #------------------------------------------------------------------------------