author | Edouard Tisserant <edouard.tisserant@gmail.com> |
Sun, 07 Oct 2018 17:05:42 +0200 | |
branch | stable-1.5 |
changeset 2725 | e008dc9d8c9f |
parent 2722 | 5e5bec5ee9c1 (diff) |
parent 2724 | b4a109b9e2a8 (current diff) |
child 2726 | ca80d6dac4c8 |
configure.ac | file | annotate | diff | comparison | revisions |
--- 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, ¶ms, + 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, ¶ms, + 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, ¶m); + + 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, ¶m); 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}