master/ioctl.c
changeset 2635 42b62867574d
parent 2630 a380cce7d6f0
--- a/master/ioctl.c	Fri Jan 22 10:11:58 2016 +0100
+++ b/master/ioctl.c	Fri Jan 22 13:09:43 2016 +0100
@@ -544,7 +544,7 @@
     data.slave_config_position = fmmu->sc->position;
     data.sync_index = fmmu->sync_index;
     data.dir = fmmu->dir;
-    data.logical_address = fmmu->logical_start_address;
+    data.logical_address = fmmu->domain->logical_base_address + fmmu->logical_domain_offset;
     data.data_size = fmmu->data_size;
 
     up(&master->master_sem);
@@ -864,7 +864,7 @@
         return -ENOMEM;
     }
 
-    if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
+    if (copy_from_user(sdo_data, (const void __user *) data.data, data.data_size)) {
         kfree(sdo_data);
         return -EFAULT;
     }
@@ -1913,11 +1913,18 @@
         ec_ioctl_context_t *ctx /**< Private data structure of file handle. */
         )
 {
+    size_t sent_bytes;
+
     if (unlikely(!ctx->requested)) {
         return -EPERM;
     }
 
-    ecrt_master_send(master);
+    sent_bytes = ecrt_master_send(master);
+
+    if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) {
+        return -EFAULT;
+    }
+
     return 0;
 }
 
@@ -2254,6 +2261,48 @@
 
 /*****************************************************************************/
 
+/** Configure wether a slave allows overlapping PDOs.
+ */
+static ATTRIBUTES int ec_ioctl_sc_allow_overlapping_pdos(
+        ec_master_t *master, /**< EtherCAT master. */
+        void *arg, /**< ioctl() argument. */
+        ec_ioctl_context_t *ctx /**< Private data structure of file handle. */
+        )
+{
+    ec_ioctl_config_t data;
+    ec_slave_config_t *sc;
+    int ret = 0;
+
+    if (unlikely(!ctx->requested)) {
+        ret = -EPERM;
+        goto out_return;
+    }
+
+    if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
+        ret = -EFAULT;
+        goto out_return;
+    }
+
+    if (down_interruptible(&master->master_sem)) {
+        ret = -EINTR;
+        goto out_return;
+    }
+
+    if (!(sc = ec_master_get_config(master, data.config_index))) {
+        ret = -ENOENT;
+        goto out_up;
+    }
+
+    ecrt_slave_config_overlapping_pdos(sc,
+            data.allow_overlapping_pdos);
+
+out_up:
+    up(&master->master_sem);
+out_return:
+    return ret;
+}
+/*****************************************************************************/
+
 /** Add a PDO to the assignment.
  *
  * \return Zero on success, otherwise a negative error code.
@@ -4447,6 +4496,13 @@
             }
             ret = ec_ioctl_sc_watchdog(master, arg, ctx);
             break;
+        case EC_IOCTL_SC_OVERLAPPING_IO:
+            if (!ctx->writable) {
+                ret = -EPERM;
+                break;
+            }
+            ret = ec_ioctl_sc_allow_overlapping_pdos(master, arg, ctx);
+            break;
         case EC_IOCTL_SC_ADD_PDO:
             if (!ctx->writable) {
                 ret = -EPERM;