IgH EtherCAT Master  1.7.0
ioctl.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2006-2026 Florian Pose, Ingenieurgemeinschaft IgH
4  *
5  * This file is part of the IgH EtherCAT Master.
6  *
7  * The IgH EtherCAT Master is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License version 2, as
9  * published by the Free Software Foundation.
10  *
11  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with the IgH EtherCAT Master; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
26 /****************************************************************************/
27 
28 #include <linux/module.h>
29 #include <linux/vmalloc.h>
30 
31 #include "master.h"
32 #include "slave_config.h"
33 #include "voe_handler.h"
34 #include "ethernet.h"
35 #include "ioctl.h"
36 
41 #define DEBUG_LATENCY 0
42 
45 #if 0
46 #define ATTRIBUTES __attribute__ ((__noinline__))
47 #else
48 #define ATTRIBUTES
49 #endif
50 
51 #ifdef EC_IOCTL_RTDM
52 # include "rtdm_details.h"
53 /* RTDM does not support locking yet,
54  * therefore no send/receive callbacks are set too. */
55 # define ec_ioctl_lock(lock) do {} while(0)
56 # define ec_ioctl_unlock(lock) do {} while(0)
57 # define ec_ioctl_lock_interruptible(lock) (0)
58 # define ec_copy_to_user(to, from, n, ctx) \
59  rtdm_safe_copy_to_user(ec_ioctl_to_rtdm(ctx), to, from, n)
60 # define ec_copy_from_user(to, from, n, ctx) \
61  rtdm_safe_copy_from_user(ec_ioctl_to_rtdm(ctx), to, from, n)
62 #else
63 # define ec_ioctl_lock(lock) rt_mutex_lock(lock)
64 # define ec_ioctl_unlock(lock) rt_mutex_unlock(lock)
65 # if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) || \
66  (defined(CONFIG_PREEMPT_RT_FULL) && \
67  LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
68 # define ec_ioctl_lock_interruptible(lock) \
69  rt_mutex_lock_interruptible(lock)
70 # else
71 # define ec_ioctl_lock_interruptible(lock) \
72  rt_mutex_lock_interruptible(lock, 0)
73 # endif
74 # define ec_copy_to_user(to, from, n, ctx) copy_to_user(to, from, n)
75 # define ec_copy_from_user(to, from, n, ctx) copy_from_user(to, from, n)
76 #endif // EC_IOCTL_RTDM
77 
78 /****************************************************************************/
79 
82 static void ec_ioctl_strcpy(
83  char *target,
84  const char *source
85  )
86 {
87  if (source) {
88  strncpy(target, source, EC_IOCTL_STRING_SIZE);
89  target[EC_IOCTL_STRING_SIZE - 1] = 0;
90  } else {
91  target[0] = 0;
92  }
93 }
94 
95 /****************************************************************************/
96 
102  void *arg,
103  ec_ioctl_context_t *ctx
104  )
105 {
106  ec_ioctl_module_t data;
107 
108  data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
109  data.master_count = ec_master_count();
110 
111  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
112  return -EFAULT;
113 
114  return 0;
115 }
116 
117 /****************************************************************************/
118 
125  void *arg
126  )
127 {
128  ec_ioctl_master_t io;
129  unsigned int dev_idx, j;
130 
131  if (down_interruptible(&master->master_sem)) {
132  return -EINTR;
133  }
134 
135  io.slave_count = master->slave_count;
136  io.scan_index = master->scan_index;
137  io.config_count = ec_master_config_count(master);
138  io.domain_count = ec_master_domain_count(master);
139 #ifdef EC_EOE
140  io.eoe_handler_count = ec_master_eoe_handler_count(master);
141 #else
142  io.eoe_handler_count = 0;
143 #endif
144  io.phase = (uint8_t) master->phase;
145  io.active = (uint8_t) master->active;
146  io.scan_busy = master->scan_busy;
147  io.sii_caching = master->sii_caching;
148 
149  up(&master->master_sem);
150 
151  if (down_interruptible(&master->device_sem)) {
152  return -EINTR;
153  }
154 
155  for (dev_idx = EC_DEVICE_MAIN;
156  dev_idx < ec_master_num_devices(master); dev_idx++) {
157  ec_device_t *device = &master->devices[dev_idx];
158 
159  if (device->dev) {
160  memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
161  ETH_ALEN);
162  } else {
163  memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
164  ETH_ALEN);
165  }
166  io.devices[dev_idx].attached = device->dev ? 1 : 0;
167  io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
168  io.devices[dev_idx].tx_count = device->tx_count;
169  io.devices[dev_idx].rx_count = device->rx_count;
170  io.devices[dev_idx].tx_bytes = device->tx_bytes;
171  io.devices[dev_idx].rx_bytes = device->rx_bytes;
172  io.devices[dev_idx].tx_errors = device->tx_errors;
173  for (j = 0; j < EC_RATE_COUNT; j++) {
174  io.devices[dev_idx].tx_frame_rates[j] =
175  device->tx_frame_rates[j];
176  io.devices[dev_idx].rx_frame_rates[j] =
177  device->rx_frame_rates[j];
178  io.devices[dev_idx].tx_byte_rates[j] =
179  device->tx_byte_rates[j];
180  io.devices[dev_idx].rx_byte_rates[j] =
181  device->rx_byte_rates[j];
182  }
183  }
184  io.num_devices = ec_master_num_devices(master);
185 
186  io.tx_count = master->device_stats.tx_count;
187  io.rx_count = master->device_stats.rx_count;
188  io.tx_bytes = master->device_stats.tx_bytes;
189  io.rx_bytes = master->device_stats.rx_bytes;
190  for (j = 0; j < EC_RATE_COUNT; j++) {
191  io.tx_frame_rates[j] =
193  io.rx_frame_rates[j] =
195  io.tx_byte_rates[j] =
197  io.rx_byte_rates[j] =
199  io.loss_rates[j] =
201  }
202 
203  up(&master->device_sem);
204 
205  io.app_time = master->app_time;
206  io.dc_ref_time = master->dc_ref_time;
207  io.ref_clock =
209 
210  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
211  return -EFAULT;
212  }
213 
214  return 0;
215 }
216 
217 /****************************************************************************/
218 
225  void *arg
226  )
227 {
228  ec_ioctl_slave_t data;
229  const ec_slave_t *slave;
230  int i;
231 
232  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
233  return -EFAULT;
234  }
235 
236  if (down_interruptible(&master->master_sem))
237  return -EINTR;
238 
239  if (!(slave = ec_master_find_slave_const(
240  master, 0, data.position))) {
241  up(&master->master_sem);
242  EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
243  return -EINVAL;
244  }
245 
246  data.device_index = slave->device_index;
247  data.vendor_id = slave->sii.vendor_id;
248  data.product_code = slave->sii.product_code;
249  data.revision_number = slave->sii.revision_number;
250  data.serial_number = slave->sii.serial_number;
251  data.alias = slave->effective_alias;
252  data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
253  data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
254  data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
255  data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
256  data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
257  data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
258  data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
259  data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
260  data.mailbox_protocols = slave->sii.mailbox_protocols;
261  data.has_general_category = slave->sii.has_general;
262  data.coe_details = slave->sii.coe_details;
263  data.general_flags = slave->sii.general_flags;
264  data.current_on_ebus = slave->sii.current_on_ebus;
265  for (i = 0; i < EC_MAX_PORTS; i++) {
266  data.ports[i].desc = slave->ports[i].desc;
267  data.ports[i].link.link_up = slave->ports[i].link.link_up;
268  data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
269  data.ports[i].link.signal_detected =
270  slave->ports[i].link.signal_detected;
271  data.ports[i].receive_time = slave->ports[i].receive_time;
272  if (slave->ports[i].next_slave) {
273  data.ports[i].next_slave =
274  slave->ports[i].next_slave->ring_position;
275  } else {
276  data.ports[i].next_slave = 0xffff;
277  }
278  data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
279  }
280  data.fmmu_bit = slave->base_fmmu_bit_operation;
281  data.dc_supported = slave->base_dc_supported;
282  data.dc_range = slave->base_dc_range;
283  data.has_dc_system_time = slave->has_dc_system_time;
284  data.transmission_delay = slave->transmission_delay;
285  data.al_state = slave->current_state;
286  data.error_flag = slave->error_flag;
287 
288  data.sync_count = slave->sii.sync_count;
289  data.sdo_count = ec_slave_sdo_count(slave);
290  data.sii_nwords = slave->sii_page.word_count;
291  data.sii_parallel_words = slave->sii_parallel_words;
292  ec_ioctl_strcpy(data.group, slave->sii.group);
293  ec_ioctl_strcpy(data.image, slave->sii.image);
294  ec_ioctl_strcpy(data.order, slave->sii.order);
295  ec_ioctl_strcpy(data.name, slave->sii.name);
296 
297  up(&master->master_sem);
298 
299  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
300  return -EFAULT;
301 
302  return 0;
303 }
304 
305 /****************************************************************************/
306 
313  void *arg
314  )
315 {
316  ec_ioctl_slave_sync_t data;
317  const ec_slave_t *slave;
318  const ec_sync_t *sync;
319 
320  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
321  return -EFAULT;
322  }
323 
324  if (down_interruptible(&master->master_sem))
325  return -EINTR;
326 
327  if (!(slave = ec_master_find_slave_const(
328  master, 0, data.slave_position))) {
329  up(&master->master_sem);
330  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
331  data.slave_position);
332  return -EINVAL;
333  }
334 
335  if (data.sync_index >= slave->sii.sync_count) {
336  up(&master->master_sem);
337  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
338  data.sync_index);
339  return -EINVAL;
340  }
341 
342  sync = &slave->sii.syncs[data.sync_index];
343 
345  data.default_size = sync->default_length;
346  data.control_register = sync->control_register;
347  data.enable = sync->enable;
348  data.pdo_count = ec_pdo_list_count(&sync->pdos);
349 
350  up(&master->master_sem);
351 
352  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
353  return -EFAULT;
354 
355  return 0;
356 }
357 
358 /****************************************************************************/
359 
366  void *arg
367  )
368 {
369  ec_ioctl_slave_sync_pdo_t data;
370  const ec_slave_t *slave;
371  const ec_sync_t *sync;
372  const ec_pdo_t *pdo;
373 
374  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
375  return -EFAULT;
376  }
377 
378  if (down_interruptible(&master->master_sem))
379  return -EINTR;
380 
381  if (!(slave = ec_master_find_slave_const(
382  master, 0, data.slave_position))) {
383  up(&master->master_sem);
384  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
385  data.slave_position);
386  return -EINVAL;
387  }
388 
389  if (data.sync_index >= slave->sii.sync_count) {
390  up(&master->master_sem);
391  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
392  data.sync_index);
393  return -EINVAL;
394  }
395 
396  sync = &slave->sii.syncs[data.sync_index];
398  &sync->pdos, data.pdo_pos))) {
399  up(&master->master_sem);
400  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
401  "position %u!\n", data.sync_index, data.pdo_pos);
402  return -EINVAL;
403  }
404 
405  data.index = pdo->index;
406  data.entry_count = ec_pdo_entry_count(pdo);
407  ec_ioctl_strcpy(data.name, pdo->name);
408 
409  up(&master->master_sem);
410 
411  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
412  return -EFAULT;
413 
414  return 0;
415 }
416 
417 /****************************************************************************/
418 
425  void *arg
426  )
427 {
428  ec_ioctl_slave_sync_pdo_entry_t data;
429  const ec_slave_t *slave;
430  const ec_sync_t *sync;
431  const ec_pdo_t *pdo;
432  const ec_pdo_entry_t *entry;
433 
434  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
435  return -EFAULT;
436  }
437 
438  if (down_interruptible(&master->master_sem))
439  return -EINTR;
440 
441  if (!(slave = ec_master_find_slave_const(
442  master, 0, data.slave_position))) {
443  up(&master->master_sem);
444  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
445  data.slave_position);
446  return -EINVAL;
447  }
448 
449  if (data.sync_index >= slave->sii.sync_count) {
450  up(&master->master_sem);
451  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
452  data.sync_index);
453  return -EINVAL;
454  }
455 
456  sync = &slave->sii.syncs[data.sync_index];
458  &sync->pdos, data.pdo_pos))) {
459  up(&master->master_sem);
460  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
461  "position %u!\n", data.sync_index, data.pdo_pos);
462  return -EINVAL;
463  }
464 
465  if (!(entry = ec_pdo_find_entry_by_pos_const(
466  pdo, data.entry_pos))) {
467  up(&master->master_sem);
468  EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
469  "position %u!\n", data.pdo_pos, data.entry_pos);
470  return -EINVAL;
471  }
472 
473  data.index = entry->index;
474  data.subindex = entry->subindex;
475  data.bit_length = entry->bit_length;
476  ec_ioctl_strcpy(data.name, entry->name);
477 
478  up(&master->master_sem);
479 
480  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
481  return -EFAULT;
482 
483  return 0;
484 }
485 
486 /****************************************************************************/
487 
494  void *arg
495  )
496 {
497  ec_ioctl_domain_t data;
498  const ec_domain_t *domain;
499  unsigned int dev_idx;
500 
501  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
502  return -EFAULT;
503  }
504 
505  if (down_interruptible(&master->master_sem))
506  return -EINTR;
507 
508  if (!(domain = ec_master_find_domain_const(master, data.index))) {
509  up(&master->master_sem);
510  EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
511  return -EINVAL;
512  }
513 
514  data.data_size = domain->data_size;
515  data.logical_base_address = domain->logical_base_address;
516  for (dev_idx = EC_DEVICE_MAIN;
517  dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
518  data.working_counter[dev_idx] = domain->working_counter[dev_idx];
519  }
520  data.expected_working_counter = domain->expected_working_counter;
521  data.fmmu_count = ec_domain_fmmu_count(domain);
522 
523  up(&master->master_sem);
524 
525  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
526  return -EFAULT;
527 
528  return 0;
529 }
530 
531 /****************************************************************************/
532 
539  void *arg
540  )
541 {
542  ec_ioctl_domain_fmmu_t data;
543  const ec_domain_t *domain;
544  const ec_fmmu_config_t *fmmu;
545 
546  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
547  return -EFAULT;
548  }
549 
550  if (down_interruptible(&master->master_sem))
551  return -EINTR;
552 
553  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
554  up(&master->master_sem);
555  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
556  data.domain_index);
557  return -EINVAL;
558  }
559 
560  if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
561  up(&master->master_sem);
562  EC_MASTER_ERR(master, "Domain %u has less than %u"
563  " fmmu configurations.\n",
564  data.domain_index, data.fmmu_index + 1);
565  return -EINVAL;
566  }
567 
568  data.slave_config_alias = fmmu->sc->alias;
569  data.slave_config_position = fmmu->sc->position;
570  data.sync_index = fmmu->sync_index;
571  data.dir = fmmu->dir;
572  data.logical_address = fmmu->logical_start_address;
573  data.data_size = fmmu->data_size;
574 
575  up(&master->master_sem);
576 
577  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
578  return -EFAULT;
579 
580  return 0;
581 }
582 
583 /****************************************************************************/
584 
591  void *arg
592  )
593 {
594  ec_ioctl_domain_data_t data;
595  const ec_domain_t *domain;
596 
597  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
598  return -EFAULT;
599  }
600 
601  if (down_interruptible(&master->master_sem))
602  return -EINTR;
603 
604  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
605  up(&master->master_sem);
606  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
607  data.domain_index);
608  return -EINVAL;
609  }
610 
611  if (domain->data_size != data.data_size) {
612  up(&master->master_sem);
613  EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
614  data.data_size, domain->data_size);
615  return -EFAULT;
616  }
617 
618  if (copy_to_user((void __user *) data.target, domain->data,
619  domain->data_size)) {
620  up(&master->master_sem);
621  return -EFAULT;
622  }
623 
624  up(&master->master_sem);
625  return 0;
626 }
627 
628 /****************************************************************************/
629 
636  void *arg
637  )
638 {
639  return ec_master_debug_level(master, (unsigned long) arg);
640 }
641 
642 /****************************************************************************/
643 
650  void *arg
651  )
652 {
653  EC_MASTER_DBG(master, 1, "Got rescan command via ioctl()."
654  " Re-scanning on next possibility.\n");
656  return 0;
657 }
658 
659 /****************************************************************************/
660 
667  void *arg
668  )
669 {
670  ec_ioctl_slave_state_t data;
671  ec_slave_t *slave;
672 
673  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
674  return -EFAULT;
675  }
676 
677  if (down_interruptible(&master->master_sem))
678  return -EINTR;
679 
680  if (!(slave = ec_master_find_slave(
681  master, 0, data.slave_position))) {
682  up(&master->master_sem);
683  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
684  data.slave_position);
685  return -EINVAL;
686  }
687 
688  ec_slave_request_state(slave, data.al_state);
689 
690  up(&master->master_sem);
691  return 0;
692 }
693 
694 /****************************************************************************/
695 
702  void *arg
703  )
704 {
705  ec_ioctl_slave_sdo_t data;
706  const ec_slave_t *slave;
707  const ec_sdo_t *sdo;
708 
709  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
710  return -EFAULT;
711  }
712 
713  if (down_interruptible(&master->master_sem))
714  return -EINTR;
715 
716  if (!(slave = ec_master_find_slave_const(
717  master, 0, data.slave_position))) {
718  up(&master->master_sem);
719  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
720  data.slave_position);
721  return -EINVAL;
722  }
723 
724  if (!(sdo = ec_slave_get_sdo_by_pos_const(
725  slave, data.sdo_position))) {
726  up(&master->master_sem);
727  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
728  return -EINVAL;
729  }
730 
731  data.sdo_index = sdo->index;
732  data.max_subindex = sdo->max_subindex;
733  ec_ioctl_strcpy(data.name, sdo->name);
734 
735  up(&master->master_sem);
736 
737  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
738  return -EFAULT;
739 
740  return 0;
741 }
742 
743 /****************************************************************************/
744 
751  void *arg
752  )
753 {
754  ec_ioctl_slave_sdo_entry_t data;
755  const ec_slave_t *slave;
756  const ec_sdo_t *sdo;
757  const ec_sdo_entry_t *entry;
758 
759  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
760  return -EFAULT;
761  }
762 
763  if (down_interruptible(&master->master_sem))
764  return -EINTR;
765 
766  if (!(slave = ec_master_find_slave_const(
767  master, 0, data.slave_position))) {
768  up(&master->master_sem);
769  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
770  data.slave_position);
771  return -EINVAL;
772  }
773 
774  if (data.sdo_spec <= 0) {
775  if (!(sdo = ec_slave_get_sdo_by_pos_const(
776  slave, -data.sdo_spec))) {
777  up(&master->master_sem);
778  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
779  return -EINVAL;
780  }
781  } else {
782  if (!(sdo = ec_slave_get_sdo_const(
783  slave, data.sdo_spec))) {
784  up(&master->master_sem);
785  EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
786  data.sdo_spec);
787  return -EINVAL;
788  }
789  }
790 
791  if (!(entry = ec_sdo_get_entry_const(
792  sdo, data.sdo_entry_subindex))) {
793  up(&master->master_sem);
794  EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
795  sdo->index, data.sdo_entry_subindex);
796  return -EINVAL;
797  }
798 
799  data.data_type = entry->data_type;
800  data.bit_length = entry->bit_length;
801  data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
803  data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
805  data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
807  data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
809  data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
811  data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
813  ec_ioctl_strcpy(data.description, entry->description);
814 
815  up(&master->master_sem);
816 
817  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
818  return -EFAULT;
819 
820  return 0;
821 }
822 
823 /****************************************************************************/
824 
831  void *arg
832  )
833 {
834  ec_ioctl_slave_sdo_upload_t data;
835  uint8_t *target;
836  int ret;
837 
838  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
839  return -EFAULT;
840  }
841 
842  if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
843  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
844  " for SDO upload.\n", data.target_size);
845  return -ENOMEM;
846  }
847 
848  ret = ecrt_master_sdo_upload(master, data.slave_position,
849  data.sdo_index, data.sdo_entry_subindex, target,
850  data.target_size, &data.data_size, &data.abort_code);
851 
852  if (!ret) {
853  if (copy_to_user((void __user *) data.target,
854  target, data.data_size)) {
855  kfree(target);
856  return -EFAULT;
857  }
858  }
859 
860  kfree(target);
861 
862  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
863  return -EFAULT;
864  }
865 
866  return ret;
867 }
868 
869 /****************************************************************************/
870 
877  void *arg
878  )
879 {
880  ec_ioctl_slave_sdo_download_t data;
881  uint8_t *sdo_data;
882  int retval;
883 
884  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
885  return -EFAULT;
886  }
887 
888  if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
889  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
890  " for SDO download.\n", data.data_size);
891  return -ENOMEM;
892  }
893 
894  if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
895  kfree(sdo_data);
896  return -EFAULT;
897  }
898 
899  if (data.complete_access) {
901  data.slave_position, data.sdo_index, sdo_data, data.data_size,
902  &data.abort_code);
903  } else {
904  retval = ecrt_master_sdo_download(master, data.slave_position,
905  data.sdo_index, data.sdo_entry_subindex, sdo_data,
906  data.data_size, &data.abort_code);
907  }
908 
909  kfree(sdo_data);
910 
911  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
912  retval = -EFAULT;
913  }
914 
915  return retval;
916 }
917 
918 /****************************************************************************/
919 
926  void *arg
927  )
928 {
929  ec_ioctl_slave_sii_t data;
930  const ec_slave_t *slave;
931  int retval;
932 
933  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
934  return -EFAULT;
935  }
936 
937  if (down_interruptible(&master->master_sem))
938  return -EINTR;
939 
940  if (!(slave = ec_master_find_slave_const(
941  master, 0, data.slave_position))) {
942  up(&master->master_sem);
943  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
944  data.slave_position);
945  return -EINVAL;
946  }
947 
948  if (!data.nwords
949  || data.offset + data.nwords > slave->sii_page.word_count) {
950  up(&master->master_sem);
951  EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
952  " size %zu!\n", data.offset, data.nwords,
953  slave->sii_page.word_count);
954  return -EINVAL;
955  }
956 
957  if (copy_to_user((void __user *) data.words,
958  slave->sii_page.words + data.offset, data.nwords * 2))
959  retval = -EFAULT;
960  else
961  retval = 0;
962 
963  up(&master->master_sem);
964  return retval;
965 }
966 
967 /****************************************************************************/
968 
975  void *arg
976  )
977 {
978  ec_ioctl_slave_sii_t data;
979  ec_slave_t *slave;
980  unsigned int byte_size;
981  uint16_t *words;
982  ec_sii_write_request_t request;
983 
984  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
985  return -EFAULT;
986  }
987 
988  if (!data.nwords) {
989  return 0;
990  }
991 
992  byte_size = sizeof(uint16_t) * data.nwords;
993  if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
994  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
995  " for SII contents.\n", byte_size);
996  return -ENOMEM;
997  }
998 
999  if (copy_from_user(words,
1000  (void __user *) data.words, byte_size)) {
1001  kfree(words);
1002  return -EFAULT;
1003  }
1004 
1005  if (down_interruptible(&master->master_sem)) {
1006  kfree(words);
1007  return -EINTR;
1008  }
1009 
1010  if (!(slave = ec_master_find_slave(
1011  master, 0, data.slave_position))) {
1012  up(&master->master_sem);
1013  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1014  data.slave_position);
1015  kfree(words);
1016  return -EINVAL;
1017  }
1018 
1019  // init SII write request
1020  INIT_LIST_HEAD(&request.list);
1021  request.slave = slave;
1022  request.words = words;
1023  request.offset = data.offset;
1024  request.nwords = data.nwords;
1025  request.state = EC_INT_REQUEST_QUEUED;
1026 
1027  // schedule SII write request.
1028  list_add_tail(&request.list, &master->sii_requests);
1029 
1030  up(&master->master_sem);
1031 
1032  // wait for processing through FSM
1033  if (wait_event_interruptible(master->request_queue,
1034  request.state != EC_INT_REQUEST_QUEUED)) {
1035  // interrupted by signal
1036  down(&master->master_sem);
1037  if (request.state == EC_INT_REQUEST_QUEUED) {
1038  // abort request
1039  list_del(&request.list);
1040  up(&master->master_sem);
1041  kfree(words);
1042  return -EINTR;
1043  }
1044  up(&master->master_sem);
1045  }
1046 
1047  // wait until master FSM has finished processing
1048  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1049 
1050  kfree(words);
1051 
1052  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1053 }
1054 
1055 /****************************************************************************/
1056 
1062  ec_master_t *master,
1063  void *arg
1064  )
1065 {
1066  ec_ioctl_slave_reg_t io;
1067  ec_slave_t *slave;
1068  ec_reg_request_t request;
1069  int ret;
1070 
1071  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1072  return -EFAULT;
1073  }
1074 
1075  if (!io.size) {
1076  return 0;
1077  }
1078 
1079  // init register request
1080  ret = ec_reg_request_init(&request, io.size);
1081  if (ret) {
1082  return ret;
1083  }
1084 
1085  ret = ecrt_reg_request_read(&request, io.address, io.size);
1086  if (ret) {
1087  return ret;
1088  }
1089 
1090  if (down_interruptible(&master->master_sem)) {
1091  ec_reg_request_clear(&request);
1092  return -EINTR;
1093  }
1094 
1095  if (!(slave = ec_master_find_slave(
1096  master, 0, io.slave_position))) {
1097  up(&master->master_sem);
1098  ec_reg_request_clear(&request);
1099  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1100  io.slave_position);
1101  return -EINVAL;
1102  }
1103 
1104  // schedule request.
1105  list_add_tail(&request.list, &slave->reg_requests);
1106 
1107  up(&master->master_sem);
1108 
1109  // wait for processing through FSM
1110  if (wait_event_interruptible(master->request_queue,
1111  request.state != EC_INT_REQUEST_QUEUED)) {
1112  // interrupted by signal
1113  down(&master->master_sem);
1114  if (request.state == EC_INT_REQUEST_QUEUED) {
1115  // abort request
1116  list_del(&request.list);
1117  up(&master->master_sem);
1118  ec_reg_request_clear(&request);
1119  return -EINTR;
1120  }
1121  up(&master->master_sem);
1122  }
1123 
1124  // wait until master FSM has finished processing
1125  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1126 
1127  if (request.state == EC_INT_REQUEST_SUCCESS) {
1128  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1129  return -EFAULT;
1130  }
1131  }
1132  ec_reg_request_clear(&request);
1133 
1134  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1135 }
1136 
1137 /****************************************************************************/
1138 
1144  ec_master_t *master,
1145  void *arg
1146  )
1147 {
1148  ec_ioctl_slave_reg_t io;
1149  ec_slave_t *slave;
1150  ec_reg_request_t request;
1151  int ret;
1152 
1153  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1154  return -EFAULT;
1155  }
1156 
1157  if (!io.size) {
1158  return 0;
1159  }
1160 
1161  // init register request
1162  ret = ec_reg_request_init(&request, io.size);
1163  if (ret) {
1164  return ret;
1165  }
1166 
1167  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1168  ec_reg_request_clear(&request);
1169  return -EFAULT;
1170  }
1171 
1172  ret = ecrt_reg_request_write(&request, io.address, io.size);
1173  if (ret) {
1174  return ret;
1175  }
1176 
1177  if (down_interruptible(&master->master_sem)) {
1178  ec_reg_request_clear(&request);
1179  return -EINTR;
1180  }
1181 
1182  if (io.emergency) {
1183  request.ring_position = io.slave_position;
1184  // schedule request.
1185  list_add_tail(&request.list, &master->emerg_reg_requests);
1186  }
1187  else {
1188  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1189  up(&master->master_sem);
1190  ec_reg_request_clear(&request);
1191  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1192  io.slave_position);
1193  return -EINVAL;
1194  }
1195 
1196  // schedule request.
1197  list_add_tail(&request.list, &slave->reg_requests);
1198  }
1199 
1200  up(&master->master_sem);
1201 
1202  // wait for processing through FSM
1203  if (wait_event_interruptible(master->request_queue,
1204  request.state != EC_INT_REQUEST_QUEUED)) {
1205  // interrupted by signal
1206  down(&master->master_sem);
1207  if (request.state == EC_INT_REQUEST_QUEUED) {
1208  // abort request
1209  list_del(&request.list);
1210  up(&master->master_sem);
1211  ec_reg_request_clear(&request);
1212  return -EINTR;
1213  }
1214  up(&master->master_sem);
1215  }
1216 
1217  // wait until master FSM has finished processing
1218  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1219 
1220  ec_reg_request_clear(&request);
1221 
1222  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1223 }
1224 
1225 /****************************************************************************/
1226 
1232  ec_master_t *master,
1233  void *arg
1234  )
1235 {
1236  ec_ioctl_config_t data;
1237  const ec_slave_config_t *sc;
1238  uint8_t i;
1239 
1240  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1241  return -EFAULT;
1242  }
1243 
1244  if (down_interruptible(&master->master_sem))
1245  return -EINTR;
1246 
1247  if (!(sc = ec_master_get_config_const(
1248  master, data.config_index))) {
1249  up(&master->master_sem);
1250  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1251  data.config_index);
1252  return -EINVAL;
1253  }
1254 
1255  data.alias = sc->alias;
1256  data.position = sc->position;
1257  data.vendor_id = sc->vendor_id;
1258  data.product_code = sc->product_code;
1259  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1260  data.syncs[i].dir = sc->sync_configs[i].dir;
1261  data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1262  data.syncs[i].pdo_count =
1264  }
1265  data.watchdog_divider = sc->watchdog_divider;
1266  data.watchdog_intervals = sc->watchdog_intervals;
1267  data.pdo_assign_mode = sc->pdo_assign_mode;
1268  data.pdo_config_mode = sc->pdo_config_mode;
1269  data.sdo_count = ec_slave_config_sdo_count(sc);
1270  data.idn_count = ec_slave_config_idn_count(sc);
1271  data.flag_count = ec_slave_config_flag_count(sc);
1272  data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1273  data.dc_assign_activate = sc->dc_assign_activate;
1274  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1275  data.dc_sync[i] = sc->dc_sync[i];
1276  }
1277 
1278  up(&master->master_sem);
1279 
1280  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1281  return -EFAULT;
1282 
1283  return 0;
1284 }
1285 
1286 /****************************************************************************/
1287 
1293  ec_master_t *master,
1294  void *arg
1295  )
1296 {
1297  ec_ioctl_config_pdo_t data;
1298  const ec_slave_config_t *sc;
1299  const ec_pdo_t *pdo;
1300 
1301  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1302  return -EFAULT;
1303  }
1304 
1305  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1306  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1307  data.sync_index);
1308  return -EINVAL;
1309  }
1310 
1311  if (down_interruptible(&master->master_sem))
1312  return -EINTR;
1313 
1314  if (!(sc = ec_master_get_config_const(
1315  master, data.config_index))) {
1316  up(&master->master_sem);
1317  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1318  data.config_index);
1319  return -EINVAL;
1320  }
1321 
1323  &sc->sync_configs[data.sync_index].pdos,
1324  data.pdo_pos))) {
1325  up(&master->master_sem);
1326  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1327  return -EINVAL;
1328  }
1329 
1330  data.index = pdo->index;
1331  data.entry_count = ec_pdo_entry_count(pdo);
1332  ec_ioctl_strcpy(data.name, pdo->name);
1333 
1334  up(&master->master_sem);
1335 
1336  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1337  return -EFAULT;
1338 
1339  return 0;
1340 }
1341 
1342 /****************************************************************************/
1343 
1349  ec_master_t *master,
1350  void *arg
1351  )
1352 {
1353  ec_ioctl_config_pdo_entry_t data;
1354  const ec_slave_config_t *sc;
1355  const ec_pdo_t *pdo;
1356  const ec_pdo_entry_t *entry;
1357 
1358  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1359  return -EFAULT;
1360  }
1361 
1362  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1363  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1364  data.sync_index);
1365  return -EINVAL;
1366  }
1367 
1368  if (down_interruptible(&master->master_sem))
1369  return -EINTR;
1370 
1371  if (!(sc = ec_master_get_config_const(
1372  master, data.config_index))) {
1373  up(&master->master_sem);
1374  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1375  data.config_index);
1376  return -EINVAL;
1377  }
1378 
1380  &sc->sync_configs[data.sync_index].pdos,
1381  data.pdo_pos))) {
1382  up(&master->master_sem);
1383  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1384  return -EINVAL;
1385  }
1386 
1387  if (!(entry = ec_pdo_find_entry_by_pos_const(
1388  pdo, data.entry_pos))) {
1389  up(&master->master_sem);
1390  EC_MASTER_ERR(master, "Entry not found!\n");
1391  return -EINVAL;
1392  }
1393 
1394  data.index = entry->index;
1395  data.subindex = entry->subindex;
1396  data.bit_length = entry->bit_length;
1397  ec_ioctl_strcpy(data.name, entry->name);
1398 
1399  up(&master->master_sem);
1400 
1401  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1402  return -EFAULT;
1403 
1404  return 0;
1405 }
1406 
1407 /****************************************************************************/
1408 
1414  ec_master_t *master,
1415  void *arg
1416  )
1417 {
1418  ec_ioctl_config_sdo_t *ioctl;
1419  const ec_slave_config_t *sc;
1420  const ec_sdo_request_t *req;
1421 
1422  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1423  return -ENOMEM;
1424  }
1425 
1426  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1427  kfree(ioctl);
1428  return -EFAULT;
1429  }
1430 
1431  if (down_interruptible(&master->master_sem)) {
1432  kfree(ioctl);
1433  return -EINTR;
1434  }
1435 
1436  if (!(sc = ec_master_get_config_const(
1437  master, ioctl->config_index))) {
1438  up(&master->master_sem);
1439  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1440  ioctl->config_index);
1441  kfree(ioctl);
1442  return -EINVAL;
1443  }
1444 
1446  sc, ioctl->sdo_pos))) {
1447  up(&master->master_sem);
1448  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1449  kfree(ioctl);
1450  return -EINVAL;
1451  }
1452 
1453  ioctl->index = req->index;
1454  ioctl->subindex = req->subindex;
1455  ioctl->size = req->data_size;
1456  memcpy(ioctl->data, req->data,
1457  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1458  ioctl->complete_access = req->complete_access;
1459 
1460  up(&master->master_sem);
1461 
1462  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1463  kfree(ioctl);
1464  return -EFAULT;
1465  }
1466 
1467  kfree(ioctl);
1468  return 0;
1469 }
1470 
1471 /****************************************************************************/
1472 
1478  ec_master_t *master,
1479  void *arg
1480  )
1481 {
1482  ec_ioctl_config_idn_t *ioctl;
1483  const ec_slave_config_t *sc;
1484  const ec_soe_request_t *req;
1485 
1486  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1487  return -ENOMEM;
1488  }
1489 
1490  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1491  kfree(ioctl);
1492  return -EFAULT;
1493  }
1494 
1495  if (down_interruptible(&master->master_sem)) {
1496  kfree(ioctl);
1497  return -EINTR;
1498  }
1499 
1500  if (!(sc = ec_master_get_config_const(
1501  master, ioctl->config_index))) {
1502  up(&master->master_sem);
1503  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1504  ioctl->config_index);
1505  kfree(ioctl);
1506  return -EINVAL;
1507  }
1508 
1510  sc, ioctl->idn_pos))) {
1511  up(&master->master_sem);
1512  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1513  kfree(ioctl);
1514  return -EINVAL;
1515  }
1516 
1517  ioctl->drive_no = req->drive_no;
1518  ioctl->idn = req->idn;
1519  ioctl->state = req->al_state;
1520  ioctl->size = req->data_size;
1521  memcpy(ioctl->data, req->data,
1522  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1523 
1524  up(&master->master_sem);
1525 
1526  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1527  kfree(ioctl);
1528  return -EFAULT;
1529  }
1530 
1531  kfree(ioctl);
1532  return 0;
1533 }
1534 
1535 /****************************************************************************/
1536 
1542  ec_master_t *master,
1543  void *arg
1544  )
1545 {
1546  ec_ioctl_config_flag_t *ioctl;
1547  const ec_slave_config_t *sc;
1548  const ec_flag_t *flag;
1549  size_t size;
1550 
1551  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1552  return -ENOMEM;
1553  }
1554 
1555  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1556  kfree(ioctl);
1557  return -EFAULT;
1558  }
1559 
1560  if (down_interruptible(&master->master_sem)) {
1561  kfree(ioctl);
1562  return -EINTR;
1563  }
1564 
1565  if (!(sc = ec_master_get_config_const(
1566  master, ioctl->config_index))) {
1567  up(&master->master_sem);
1568  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1569  ioctl->config_index);
1570  kfree(ioctl);
1571  return -EINVAL;
1572  }
1573 
1575  sc, ioctl->flag_pos))) {
1576  up(&master->master_sem);
1577  EC_MASTER_ERR(master, "Invalid flag position!\n");
1578  kfree(ioctl);
1579  return -EINVAL;
1580  }
1581 
1582  size = min((u32) strlen(flag->key), (u32) EC_MAX_FLAG_KEY_SIZE - 1);
1583  memcpy(ioctl->key, flag->key, size);
1584  ioctl->key[size] = 0x00;
1585  ioctl->value = flag->value;
1586 
1587  up(&master->master_sem);
1588 
1589  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1590  kfree(ioctl);
1591  return -EFAULT;
1592  }
1593 
1594  kfree(ioctl);
1595  return 0;
1596 }
1597 
1598 /****************************************************************************/
1599 
1600 #ifdef EC_EOE
1601 
1607  ec_master_t *master,
1608  void *arg
1609  )
1610 {
1611  ec_ioctl_eoe_ip_t *ioctl;
1612  const ec_slave_config_t *sc;
1613  const ec_eoe_request_t *req;
1614 
1615  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1616  return -ENOMEM;
1617  }
1618 
1619  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1620  kfree(ioctl);
1621  return -EFAULT;
1622  }
1623 
1624  if (down_interruptible(&master->master_sem)) {
1625  kfree(ioctl);
1626  return -EINTR;
1627  }
1628 
1629  if (!(sc = ec_master_get_config_const(master, ioctl->config_index))) {
1630  up(&master->master_sem);
1631  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1632  ioctl->config_index);
1633  kfree(ioctl);
1634  return -EINVAL;
1635  }
1636 
1637  req = &sc->eoe_ip_param_request;
1638 
1639  ioctl->mac_address_included = req->mac_address_included;
1640  ioctl->ip_address_included = req->ip_address_included;
1641  ioctl->subnet_mask_included = req->subnet_mask_included;
1642  ioctl->gateway_included = req->gateway_included;
1643  ioctl->dns_included = req->dns_included;
1644  ioctl->name_included = req->name_included;
1645 
1646  memcpy(ioctl->mac_address, req->mac_address, EC_ETH_ALEN);
1647  ioctl->ip_address = req->ip_address;
1648  ioctl->subnet_mask = req->subnet_mask;
1649  ioctl->gateway = req->gateway;
1650  ioctl->dns = req->dns;
1651  strncpy(ioctl->name, req->name, EC_MAX_HOSTNAME_SIZE);
1652 
1653  up(&master->master_sem);
1654 
1655  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1656  kfree(ioctl);
1657  return -EFAULT;
1658  }
1659 
1660  kfree(ioctl);
1661  return 0;
1662 }
1663 
1664 #endif
1665 
1666 /****************************************************************************/
1667 
1668 #ifdef EC_EOE
1669 
1675  ec_master_t *master,
1676  void *arg
1677  )
1678 {
1679  ec_ioctl_eoe_handler_t data;
1680  const ec_eoe_t *eoe;
1681 
1682  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1683  return -EFAULT;
1684  }
1685 
1686  if (down_interruptible(&master->master_sem))
1687  return -EINTR;
1688 
1689  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1690  up(&master->master_sem);
1691  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1692  data.eoe_index);
1693  return -EINVAL;
1694  }
1695 
1696  if (eoe->slave) {
1697  data.slave_position = eoe->slave->ring_position;
1698  } else {
1699  data.slave_position = 0xffff;
1700  }
1701  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1702  data.open = eoe->opened;
1703  data.rx_bytes = eoe->stats.tx_bytes;
1704  data.rx_rate = eoe->tx_rate;
1705  data.tx_bytes = eoe->stats.rx_bytes;
1706  data.tx_rate = eoe->tx_rate;
1707  data.tx_queued_frames = eoe->tx_queued_frames;
1708  data.tx_queue_size = eoe->tx_queue_size;
1709 
1710  up(&master->master_sem);
1711 
1712  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1713  return -EFAULT;
1714 
1715  return 0;
1716 }
1717 
1718 #endif
1719 
1720 /****************************************************************************/
1721 
1722 #ifdef EC_EOE
1723 
1729  ec_master_t *master,
1730  void *arg
1731  )
1732 {
1733  ec_ioctl_eoe_ip_t io;
1734  ec_eoe_request_t req;
1735  ec_slave_t *slave;
1736 
1737  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1738  return -EFAULT;
1739  }
1740 
1741  // init EoE request
1742  ec_eoe_request_init(&req);
1743 
1744  req.mac_address_included = io.mac_address_included;
1745  req.ip_address_included = io.ip_address_included;
1746  req.subnet_mask_included = io.subnet_mask_included;
1747  req.gateway_included = io.gateway_included;
1748  req.dns_included = io.dns_included;
1749  req.name_included = io.name_included;
1750 
1751  memcpy(req.mac_address, io.mac_address, EC_ETH_ALEN);
1752  req.ip_address = io.ip_address;
1753  req.subnet_mask = io.subnet_mask;
1754  req.gateway = io.gateway;
1755  req.dns = io.dns;
1756  memcpy(req.name, io.name, EC_MAX_HOSTNAME_SIZE);
1757 
1758  req.state = EC_INT_REQUEST_QUEUED;
1759 
1760  if (down_interruptible(&master->master_sem)) {
1761  return -EINTR;
1762  }
1763 
1764  if (!(slave = ec_master_find_slave(
1765  master, 0, io.slave_position))) {
1766  up(&master->master_sem);
1767  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1768  io.slave_position);
1769  return -EINVAL;
1770  }
1771 
1772  EC_MASTER_DBG(master, 1, "Scheduling EoE request.\n");
1773 
1774  // schedule request.
1775  list_add_tail(&req.list, &slave->eoe_requests);
1776 
1777  up(&master->master_sem);
1778 
1779  // wait for processing through FSM
1780  if (wait_event_interruptible(master->request_queue,
1781  req.state != EC_INT_REQUEST_QUEUED)) {
1782  // interrupted by signal
1783  down(&master->master_sem);
1784  if (req.state == EC_INT_REQUEST_QUEUED) {
1785  // abort request
1786  list_del(&req.list);
1787  up(&master->master_sem);
1788  return -EINTR;
1789  }
1790  up(&master->master_sem);
1791  }
1792 
1793  // wait until master FSM has finished processing
1794  wait_event(master->request_queue, req.state != EC_INT_REQUEST_BUSY);
1795 
1796  io.result = req.result;
1797 
1798  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
1799  return -EFAULT;
1800  }
1801 
1802  return req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1803 }
1804 
1805 #endif
1806 
1807 /****************************************************************************/
1808 
1814  ec_master_t *master,
1815  void *arg,
1816  ec_ioctl_context_t *ctx
1817  )
1818 {
1819  ec_master_t *m;
1820  int ret = 0;
1821 
1823  if (IS_ERR(m)) {
1824  ret = PTR_ERR(m);
1825  } else {
1826  ctx->requested = 1;
1827  }
1828 
1829  return ret;
1830 }
1831 
1832 /****************************************************************************/
1833 
1839  ec_master_t *master,
1840  void *arg,
1841  ec_ioctl_context_t *ctx
1842  )
1843 {
1844  ec_domain_t *domain;
1845 
1846  if (unlikely(!ctx->requested))
1847  return -EPERM;
1848 
1850  if (IS_ERR(domain))
1851  return PTR_ERR(domain);
1852 
1853  return domain->index;
1854 }
1855 
1856 /****************************************************************************/
1857 
1863  ec_master_t *master,
1864  void *arg,
1865  ec_ioctl_context_t *ctx
1866  )
1867 {
1868  ec_ioctl_config_t data;
1869  ec_slave_config_t *sc, *entry;
1870 
1871  if (unlikely(!ctx->requested))
1872  return -EPERM;
1873 
1874  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1875  return -EFAULT;
1876  }
1877 
1878  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1879  data.vendor_id, data.product_code);
1880  if (IS_ERR(sc))
1881  return PTR_ERR(sc);
1882 
1883  data.config_index = 0;
1884 
1885  if (down_interruptible(&master->master_sem))
1886  return -EINTR;
1887 
1888  list_for_each_entry(entry, &master->configs, list) {
1889  if (entry == sc)
1890  break;
1891  data.config_index++;
1892  }
1893 
1894  up(&master->master_sem);
1895 
1896  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1897  return -EFAULT;
1898 
1899  return 0;
1900 }
1901 
1902 /****************************************************************************/
1903 
1909  ec_master_t *master,
1910  void *arg,
1911  ec_ioctl_context_t *ctx
1912  )
1913 {
1914  unsigned long config_index = (unsigned long) arg;
1915  ec_slave_config_t *sc = NULL;
1916  int ret = 0;
1917 
1918  if (unlikely(!ctx->requested)) {
1919  ret = -EPERM;
1920  goto out_return;
1921  }
1922 
1923  if (down_interruptible(&master->master_sem)) {
1924  ret = -EINTR;
1925  goto out_return;
1926  }
1927 
1928  if (config_index != 0xFFFFFFFF) {
1929  if (!(sc = ec_master_get_config(master, config_index))) {
1930  ret = -ENOENT;
1931  goto out_up;
1932  }
1933  }
1934 
1936 
1937 out_up:
1938  up(&master->master_sem);
1939 out_return:
1940  return ret;
1941 }
1942 
1943 /****************************************************************************/
1944 
1950  ec_master_t *master,
1951  void *arg,
1952  ec_ioctl_context_t *ctx
1953  )
1954 {
1955  ec_ioctl_master_activate_t io;
1956  ec_domain_t *domain;
1957  off_t offset;
1958  int ret;
1959 
1960  if (unlikely(!ctx->requested))
1961  return -EPERM;
1962 
1963  io.process_data = NULL;
1964 
1965  /* Get the sum of the domains' process data sizes. */
1966 
1967  ctx->process_data_size = 0;
1968 
1969  if (down_interruptible(&master->master_sem))
1970  return -EINTR;
1971 
1972  list_for_each_entry(domain, &master->domains, list) {
1973  ctx->process_data_size += ecrt_domain_size(domain);
1974  }
1975 
1976  up(&master->master_sem);
1977 
1978  if (ctx->process_data_size) {
1979  ctx->process_data = vmalloc(ctx->process_data_size);
1980  if (!ctx->process_data) {
1981  ctx->process_data_size = 0;
1982  return -ENOMEM;
1983  }
1984 
1985  /* Set the memory as external process data memory for the
1986  * domains.
1987  */
1988  offset = 0;
1989  list_for_each_entry(domain, &master->domains, list) {
1991  ctx->process_data + offset);
1992  offset += ecrt_domain_size(domain);
1993  }
1994 
1995 #if defined(EC_IOCTL_RTDM) && !defined(EC_RTDM_XENOMAI_V3)
1996  /* RTDM uses a different approach for memory-mapping, which has to be
1997  * initiated by the kernel.
1998  */
1999  ret = ec_rtdm_mmap(ctx, &io.process_data);
2000  if (ret < 0) {
2001  EC_MASTER_ERR(master, "Failed to map process data"
2002  " memory to user space (code %i).\n", ret);
2003  return ret;
2004  }
2005 #endif
2006  }
2007 
2008  io.process_data_size = ctx->process_data_size;
2009 
2010 #ifndef EC_IOCTL_RTDM
2011  /* RTDM does not support locking yet. */
2014 #endif
2015 
2017  if (ret < 0)
2018  return ret;
2019 
2020  if (copy_to_user((void __user *) arg, &io,
2021  sizeof(ec_ioctl_master_activate_t)))
2022  return -EFAULT;
2023 
2024  return 0;
2025 }
2026 
2027 /****************************************************************************/
2028 
2034  ec_master_t *master,
2035  void *arg,
2036  ec_ioctl_context_t *ctx
2037  )
2038 {
2039  if (unlikely(!ctx->requested))
2040  return -EPERM;
2041 
2043 }
2044 
2045 /****************************************************************************/
2046 
2052  ec_master_t *master,
2053  void *arg,
2054  ec_ioctl_context_t *ctx
2055  )
2056 {
2057  size_t send_interval;
2058 
2059  if (unlikely(!ctx->requested)) {
2060  return -EPERM;
2061  }
2062 
2063  if (copy_from_user(&send_interval, (void __user *) arg,
2064  sizeof(send_interval))) {
2065  return -EFAULT;
2066  }
2067 
2068  if (down_interruptible(&master->master_sem))
2069  return -EINTR;
2070 
2071  ec_master_set_send_interval(master, send_interval);
2072 
2073  up(&master->master_sem);
2074  return 0;
2075 }
2076 
2077 /****************************************************************************/
2078 
2084  ec_master_t *master,
2085  void *arg,
2086  ec_ioctl_context_t *ctx
2087  )
2088 {
2089  int ret;
2090 
2091  if (unlikely(!ctx->requested)) {
2092  return -EPERM;
2093  }
2094 
2095  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2096  return -EINTR;
2097 
2098  ret = ecrt_master_send(master);
2099  ec_ioctl_unlock(&master->io_mutex);
2100  return ret;
2101 }
2102 
2103 /****************************************************************************/
2104 
2110  ec_master_t *master,
2111  void *arg,
2112  ec_ioctl_context_t *ctx
2113  )
2114 {
2115  int ret;
2116 
2117  if (unlikely(!ctx->requested)) {
2118  return -EPERM;
2119  }
2120 
2121  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2122  return -EINTR;
2123 
2124  ret = ecrt_master_receive(master);
2125  ec_ioctl_unlock(&master->io_mutex);
2126  return ret;
2127 }
2128 
2129 /****************************************************************************/
2130 
2136  ec_master_t *master,
2137  void *arg,
2138  ec_ioctl_context_t *ctx
2139  )
2140 {
2141  ec_master_state_t data;
2142  int ret;
2143 
2144  ret = ecrt_master_state(master, &data);
2145  if (ret)
2146  return ret;
2147 
2148  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
2149  return -EFAULT;
2150 
2151  return 0;
2152 }
2153 
2154 /****************************************************************************/
2155 
2161  ec_master_t *master,
2162  void *arg,
2163  ec_ioctl_context_t *ctx
2164  )
2165 {
2166  ec_ioctl_link_state_t ioctl;
2167  ec_master_link_state_t state;
2168  int ret;
2169 
2170  if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl), ctx)) {
2171  return -EFAULT;
2172  }
2173 
2174  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
2175  if (ret < 0) {
2176  return ret;
2177  }
2178 
2179  if (ec_copy_to_user((void __user *) ioctl.state,
2180  &state, sizeof(state), ctx)) {
2181  return -EFAULT;
2182  }
2183 
2184  return 0;
2185 }
2186 
2187 /****************************************************************************/
2188 
2194  ec_master_t *master,
2195  void *arg,
2196  ec_ioctl_context_t *ctx
2197  )
2198 {
2199  uint64_t time;
2200 
2201  if (unlikely(!ctx->requested))
2202  return -EPERM;
2203 
2204  if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) {
2205  return -EFAULT;
2206  }
2207 
2208  return ecrt_master_application_time(master, time);
2209 }
2210 
2211 /****************************************************************************/
2212 
2218  ec_master_t *master,
2219  void *arg,
2220  ec_ioctl_context_t *ctx
2221  )
2222 {
2223  int ret;
2224 
2225  if (unlikely(!ctx->requested)) {
2226  return -EPERM;
2227  }
2228 
2229  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2230  return -EINTR;
2231 
2233  ec_ioctl_unlock(&master->io_mutex);
2234  return ret;
2235 }
2236 
2237 /****************************************************************************/
2238 
2244  ec_master_t *master,
2245  void *arg,
2246  ec_ioctl_context_t *ctx
2247  )
2248 {
2249  int ret;
2250  uint64_t time;
2251 
2252  if (unlikely(!ctx->requested))
2253  return -EPERM;
2254 
2255  if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) {
2256  return -EFAULT;
2257  }
2258 
2259  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2260  return -EINTR;
2261 
2263  ec_ioctl_unlock(&master->io_mutex);
2264  return ret;
2265 }
2266 
2267 /****************************************************************************/
2268 
2274  ec_master_t *master,
2275  void *arg,
2276  ec_ioctl_context_t *ctx
2277  )
2278 {
2279  int ret;
2280 
2281  if (unlikely(!ctx->requested)) {
2282  return -EPERM;
2283  }
2284 
2285  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2286  return -EINTR;
2287 
2289  ec_ioctl_unlock(&master->io_mutex);
2290  return ret;
2291 }
2292 
2293 /****************************************************************************/
2294 
2300  ec_master_t *master,
2301  void *arg,
2302  ec_ioctl_context_t *ctx
2303  )
2304 {
2305  uint32_t time;
2306  int ret;
2307 
2308  if (unlikely(!ctx->requested)) {
2309  return -EPERM;
2310  }
2311 
2313  if (ret) {
2314  return ret;
2315  }
2316 
2317  if (ec_copy_to_user((void __user *) arg, &time, sizeof(time), ctx)) {
2318  return -EFAULT;
2319  }
2320 
2321  return 0;
2322 }
2323 
2324 /****************************************************************************/
2325 
2331  ec_master_t *master,
2332  void *arg,
2333  ec_ioctl_context_t *ctx
2334  )
2335 {
2336  int ret;
2337 
2338  if (unlikely(!ctx->requested)) {
2339  return -EPERM;
2340  }
2341 
2342  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2343  return -EINTR;
2344 
2346  ec_ioctl_unlock(&master->io_mutex);
2347  return ret;
2348 }
2349 
2350 /****************************************************************************/
2351 
2357  ec_master_t *master,
2358  void *arg,
2359  ec_ioctl_context_t *ctx
2360  )
2361 {
2362  uint32_t time_diff;
2363 
2364  if (unlikely(!ctx->requested))
2365  return -EPERM;
2366 
2368 
2369  if (ec_copy_to_user((void __user *) arg, &time_diff,
2370  sizeof(time_diff), ctx))
2371  return -EFAULT;
2372 
2373  return 0;
2374 }
2375 
2376 /****************************************************************************/
2377 
2383  ec_master_t *master,
2384  void *arg,
2385  ec_ioctl_context_t *ctx
2386  )
2387 {
2388 #ifdef EC_IOCTL_RTDM
2389  /* Xenomai/LXRT is like NMI context, so we do a two-stage schedule. */
2390  irq_work_queue(&master->sc_reset_work_kicker);
2391 #else
2392  schedule_work(&master->sc_reset_work);
2393 #endif
2394  return 0;
2395 }
2396 
2397 /****************************************************************************/
2398 
2404  ec_master_t *master,
2405  void *arg,
2406  ec_ioctl_context_t *ctx
2407  )
2408 {
2409  int ret = 0;
2410  ret = ecrt_master_sii_caching(master, (unsigned long) arg);
2411  return ret;
2412 }
2413 
2414 /****************************************************************************/
2415 
2421  ec_master_t *master,
2422  void *arg,
2423  ec_ioctl_context_t *ctx
2424  )
2425 {
2426  ec_ioctl_config_t data;
2427  ec_slave_config_t *sc;
2428  unsigned int i;
2429  int ret = 0;
2430 
2431  if (unlikely(!ctx->requested)) {
2432  ret = -EPERM;
2433  goto out_return;
2434  }
2435 
2436  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2437  ret = -EFAULT;
2438  goto out_return;
2439  }
2440 
2441  if (down_interruptible(&master->master_sem)) {
2442  ret = -EINTR;
2443  goto out_return;
2444  }
2445 
2446  if (!(sc = ec_master_get_config(master, data.config_index))) {
2447  ret = -ENOENT;
2448  goto out_up;
2449  }
2450 
2451  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2452  if (data.syncs[i].config_this) {
2453  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2454  data.syncs[i].watchdog_mode);
2455  if (ret) {
2456  goto out_up;
2457  }
2458  }
2459  }
2460 
2461 out_up:
2462  up(&master->master_sem);
2463 out_return:
2464  return ret;
2465 }
2466 
2467 /****************************************************************************/
2468 
2474  ec_master_t *master,
2475  void *arg,
2476  ec_ioctl_context_t *ctx
2477  )
2478 {
2479  ec_ioctl_config_t data;
2480  ec_slave_config_t *sc;
2481  int ret = 0;
2482 
2483  if (unlikely(!ctx->requested)) {
2484  ret = -EPERM;
2485  goto out_return;
2486  }
2487 
2488  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2489  ret = -EFAULT;
2490  goto out_return;
2491  }
2492 
2493  if (down_interruptible(&master->master_sem)) {
2494  ret = -EINTR;
2495  goto out_return;
2496  }
2497 
2498  if (!(sc = ec_master_get_config(master, data.config_index))) {
2499  ret = -ENOENT;
2500  goto out_up;
2501  }
2502 
2503  ret = ecrt_slave_config_watchdog(sc,
2504  data.watchdog_divider, data.watchdog_intervals);
2505 
2506 out_up:
2507  up(&master->master_sem);
2508 out_return:
2509  return ret;
2510 }
2511 
2512 /****************************************************************************/
2513 
2519  ec_master_t *master,
2520  void *arg,
2521  ec_ioctl_context_t *ctx
2522  )
2523 {
2524  ec_ioctl_config_t data;
2525  ec_slave_config_t *sc;
2526  int ret = 0;
2527 
2528  if (unlikely(!ctx->requested)) {
2529  ret = -EPERM;
2530  goto out_return;
2531  }
2532 
2533  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2534  ret = -EFAULT;
2535  goto out_return;
2536  }
2537 
2538  if (down_interruptible(&master->master_sem)) {
2539  ret = -EINTR;
2540  goto out_return;
2541  }
2542 
2543  if (!(sc = ec_master_get_config(master, data.config_index))) {
2544  ret = -ENOENT;
2545  goto out_up;
2546  }
2547 
2548  ret = ecrt_slave_config_pdo_mode(sc,
2549  data.pdo_assign_mode, data.pdo_config_mode);
2550 
2551 out_up:
2552  up(&master->master_sem);
2553 out_return:
2554  return ret;
2555 }
2556 
2557 /****************************************************************************/
2558 
2564  ec_master_t *master,
2565  void *arg,
2566  ec_ioctl_context_t *ctx
2567  )
2568 {
2569  ec_ioctl_config_pdo_t data;
2570  ec_slave_config_t *sc;
2571 
2572  if (unlikely(!ctx->requested))
2573  return -EPERM;
2574 
2575  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2576  return -EFAULT;
2577 
2578  if (down_interruptible(&master->master_sem))
2579  return -EINTR;
2580 
2581  if (!(sc = ec_master_get_config(master, data.config_index))) {
2582  up(&master->master_sem);
2583  return -ENOENT;
2584  }
2585 
2586  up(&master->master_sem);
2588  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2589 }
2590 
2591 /****************************************************************************/
2592 
2598  ec_master_t *master,
2599  void *arg,
2600  ec_ioctl_context_t *ctx
2601  )
2602 {
2603  ec_ioctl_config_pdo_t data;
2604  ec_slave_config_t *sc;
2605 
2606  if (unlikely(!ctx->requested))
2607  return -EPERM;
2608 
2609  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2610  return -EFAULT;
2611 
2612  if (down_interruptible(&master->master_sem))
2613  return -EINTR;
2614 
2615  if (!(sc = ec_master_get_config(master, data.config_index))) {
2616  up(&master->master_sem);
2617  return -ENOENT;
2618  }
2619 
2620  up(&master->master_sem);
2622  return ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2623 }
2624 
2625 /****************************************************************************/
2626 
2632  ec_master_t *master,
2633  void *arg,
2634  ec_ioctl_context_t *ctx
2635  )
2636 {
2637  ec_ioctl_add_pdo_entry_t data;
2638  ec_slave_config_t *sc;
2639 
2640  if (unlikely(!ctx->requested))
2641  return -EPERM;
2642 
2643  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2644  return -EFAULT;
2645 
2646  if (down_interruptible(&master->master_sem))
2647  return -EINTR;
2648 
2649  if (!(sc = ec_master_get_config(master, data.config_index))) {
2650  up(&master->master_sem);
2651  return -ENOENT;
2652  }
2653 
2654  up(&master->master_sem);
2656  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2657  data.entry_index, data.entry_subindex, data.entry_bit_length);
2658 }
2659 
2660 /****************************************************************************/
2661 
2667  ec_master_t *master,
2668  void *arg,
2669  ec_ioctl_context_t *ctx
2670  )
2671 {
2672  ec_ioctl_config_pdo_t data;
2673  ec_slave_config_t *sc;
2674 
2675  if (unlikely(!ctx->requested))
2676  return -EPERM;
2677 
2678  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2679  return -EFAULT;
2680 
2681  if (down_interruptible(&master->master_sem))
2682  return -EINTR;
2683 
2684  if (!(sc = ec_master_get_config(master, data.config_index))) {
2685  up(&master->master_sem);
2686  return -ENOENT;
2687  }
2688 
2689  up(&master->master_sem);
2691  return ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2692 }
2693 
2694 /****************************************************************************/
2695 
2701  ec_master_t *master,
2702  void *arg,
2703  ec_ioctl_context_t *ctx
2704  )
2705 {
2706  ec_ioctl_reg_pdo_entry_t data;
2707  ec_slave_config_t *sc;
2708  ec_domain_t *domain;
2709  int ret;
2710 
2711  if (unlikely(!ctx->requested))
2712  return -EPERM;
2713 
2714  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2715  return -EFAULT;
2716 
2717  if (down_interruptible(&master->master_sem))
2718  return -EINTR;
2719 
2720  if (!(sc = ec_master_get_config(master, data.config_index))) {
2721  up(&master->master_sem);
2722  return -ENOENT;
2723  }
2724 
2725  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2726  up(&master->master_sem);
2727  return -ENOENT;
2728  }
2729 
2730  up(&master->master_sem);
2732  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2733  data.entry_subindex, domain, &data.bit_position);
2734 
2735  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2736  return -EFAULT;
2737 
2738  return ret;
2739 }
2740 
2741 /****************************************************************************/
2742 
2748  ec_master_t *master,
2749  void *arg,
2750  ec_ioctl_context_t *ctx
2751  )
2752 {
2753  ec_ioctl_reg_pdo_pos_t io;
2754  ec_slave_config_t *sc;
2755  ec_domain_t *domain;
2756  int ret;
2757 
2758  if (unlikely(!ctx->requested)) {
2759  return -EPERM;
2760  }
2761 
2762  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2763  return -EFAULT;
2764  }
2765 
2766  if (down_interruptible(&master->master_sem)) {
2767  return -EINTR;
2768  }
2769 
2770  if (!(sc = ec_master_get_config(master, io.config_index))) {
2771  up(&master->master_sem);
2772  return -ENOENT;
2773  }
2774 
2775  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2776  up(&master->master_sem);
2777  return -ENOENT;
2778  }
2779 
2780  up(&master->master_sem);
2782  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2783  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2784 
2785  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2786  return -EFAULT;
2787 
2788  return ret;
2789 }
2790 
2791 /****************************************************************************/
2792 
2798  ec_master_t *master,
2799  void *arg,
2800  ec_ioctl_context_t *ctx
2801  )
2802 {
2803  ec_ioctl_config_t data;
2804  ec_slave_config_t *sc;
2805  int ret;
2806 
2807  if (unlikely(!ctx->requested))
2808  return -EPERM;
2809 
2810  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2811  return -EFAULT;
2812 
2813  if (down_interruptible(&master->master_sem))
2814  return -EINTR;
2815 
2816  if (!(sc = ec_master_get_config(master, data.config_index))) {
2817  up(&master->master_sem);
2818  return -ENOENT;
2819  }
2820 
2822  data.dc_sync[0].cycle_time,
2823  data.dc_sync[0].shift_time,
2824  data.dc_sync[1].cycle_time,
2825  data.dc_sync[1].shift_time);
2826 
2827  up(&master->master_sem);
2828 
2829  return ret;
2830 }
2831 
2832 /****************************************************************************/
2833 
2839  ec_master_t *master,
2840  void *arg,
2841  ec_ioctl_context_t *ctx
2842  )
2843 {
2844  ec_ioctl_sc_sdo_t data;
2845  ec_slave_config_t *sc;
2846  uint8_t *sdo_data = NULL;
2847  int ret;
2848 
2849  if (unlikely(!ctx->requested))
2850  return -EPERM;
2851 
2852  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2853  return -EFAULT;
2854 
2855  if (!data.size)
2856  return -EINVAL;
2857 
2858  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2859  return -ENOMEM;
2860  }
2861 
2862  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2863  kfree(sdo_data);
2864  return -EFAULT;
2865  }
2866 
2867  if (down_interruptible(&master->master_sem)) {
2868  kfree(sdo_data);
2869  return -EINTR;
2870  }
2871 
2872  if (!(sc = ec_master_get_config(master, data.config_index))) {
2873  up(&master->master_sem);
2874  kfree(sdo_data);
2875  return -ENOENT;
2876  }
2877 
2878  up(&master->master_sem);
2880  if (data.complete_access) {
2882  data.index, sdo_data, data.size);
2883  } else {
2884  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2885  data.size);
2886  }
2887  kfree(sdo_data);
2888  return ret;
2889 }
2890 
2891 /****************************************************************************/
2892 
2898  ec_master_t *master,
2899  void *arg,
2900  ec_ioctl_context_t *ctx
2901  )
2902 {
2903  ec_ioctl_sc_emerg_t io;
2904  ec_slave_config_t *sc;
2905  int ret;
2906 
2907  if (unlikely(!ctx->requested))
2908  return -EPERM;
2909 
2910  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2911  return -EFAULT;
2912 
2913  if (down_interruptible(&master->master_sem)) {
2914  return -EINTR;
2915  }
2916 
2917  if (!(sc = ec_master_get_config(master, io.config_index))) {
2918  up(&master->master_sem);
2919  return -ENOENT;
2920  }
2921 
2922  ret = ecrt_slave_config_emerg_size(sc, io.size);
2923 
2924  up(&master->master_sem);
2925 
2926  return ret;
2927 }
2928 
2929 /****************************************************************************/
2930 
2936  ec_master_t *master,
2937  void *arg,
2938  ec_ioctl_context_t *ctx
2939  )
2940 {
2941  ec_ioctl_sc_emerg_t io;
2942  ec_slave_config_t *sc;
2943  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
2944  int ret;
2945 
2946  if (unlikely(!ctx->requested)) {
2947  return -EPERM;
2948  }
2949 
2950  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2951  return -EFAULT;
2952  }
2953 
2954  /* no locking of master_sem needed, because configuration will not be
2955  * deleted in the meantime. */
2956 
2957  if (!(sc = ec_master_get_config(master, io.config_index))) {
2958  return -ENOENT;
2959  }
2960 
2961  ret = ecrt_slave_config_emerg_pop(sc, msg);
2962  if (ret < 0) {
2963  return ret;
2964  }
2965 
2966  if (ec_copy_to_user((void __user *) io.target, msg, sizeof(msg), ctx)) {
2967  return -EFAULT;
2968  }
2969 
2970  return ret;
2971 }
2972 
2973 /****************************************************************************/
2974 
2980  ec_master_t *master,
2981  void *arg,
2982  ec_ioctl_context_t *ctx
2983  )
2984 {
2985  ec_ioctl_sc_emerg_t io;
2986  ec_slave_config_t *sc;
2987 
2988  if (unlikely(!ctx->requested)) {
2989  return -EPERM;
2990  }
2991 
2992  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2993  return -EFAULT;
2994  }
2995 
2996  /* no locking of master_sem needed, because configuration will not be
2997  * deleted in the meantime. */
2998 
2999  if (!(sc = ec_master_get_config(master, io.config_index))) {
3000  return -ENOENT;
3001  }
3002 
3003  return ecrt_slave_config_emerg_clear(sc);
3004 }
3005 
3006 /****************************************************************************/
3007 
3013  ec_master_t *master,
3014  void *arg,
3015  ec_ioctl_context_t *ctx
3016  )
3017 {
3018  ec_ioctl_sc_emerg_t io;
3019  ec_slave_config_t *sc;
3020  int ret;
3021 
3022  if (unlikely(!ctx->requested)) {
3023  return -EPERM;
3024  }
3025 
3026  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
3027  return -EFAULT;
3028  }
3029 
3030  /* no locking of master_sem needed, because configuration will not be
3031  * deleted in the meantime. */
3032 
3033  if (!(sc = ec_master_get_config(master, io.config_index))) {
3034  return -ENOENT;
3035  }
3036 
3038  if (ret < 0) {
3039  return ret;
3040  }
3041 
3042  io.overruns = ret;
3043 
3044  if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) {
3045  return -EFAULT;
3046  }
3047 
3048  return 0;
3049 }
3050 
3051 /****************************************************************************/
3052 
3058  ec_master_t *master,
3059  void *arg,
3060  ec_ioctl_context_t *ctx
3061  )
3062 {
3063  ec_ioctl_sdo_request_t data;
3064  ec_slave_config_t *sc;
3065  ec_sdo_request_t *req;
3066 
3067  if (unlikely(!ctx->requested))
3068  return -EPERM;
3069 
3070  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3071  return -EFAULT;
3072  }
3073 
3074  data.request_index = 0;
3075 
3076  if (down_interruptible(&master->master_sem))
3077  return -EINTR;
3078 
3079  sc = ec_master_get_config(master, data.config_index);
3080  if (!sc) {
3081  up(&master->master_sem);
3082  return -ENOENT;
3083  }
3084 
3085  list_for_each_entry(req, &sc->sdo_requests, list) {
3086  data.request_index++;
3087  }
3088 
3089  up(&master->master_sem);
3091  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
3092  data.sdo_subindex, data.size);
3093  if (IS_ERR(req))
3094  return PTR_ERR(req);
3095 
3096  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3097  return -EFAULT;
3098 
3099  return 0;
3100 }
3101 
3102 /****************************************************************************/
3103 
3109  ec_master_t *master,
3110  void *arg,
3111  ec_ioctl_context_t *ctx
3112  )
3113 {
3114  ec_ioctl_soe_request_t data;
3115  ec_slave_config_t *sc;
3116  ec_soe_request_t *req;
3117 
3118  if (unlikely(!ctx->requested))
3119  return -EPERM;
3120 
3121  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3122  return -EFAULT;
3123  }
3124 
3125  data.request_index = 0;
3126 
3127  if (down_interruptible(&master->master_sem))
3128  return -EINTR;
3129 
3130  sc = ec_master_get_config(master, data.config_index);
3131  if (!sc) {
3132  up(&master->master_sem);
3133  return -ENOENT;
3134  }
3135 
3136  list_for_each_entry(req, &sc->soe_requests, list) {
3137  data.request_index++;
3138  }
3139 
3140  up(&master->master_sem);
3142  req = ecrt_slave_config_create_soe_request_err(sc, data.drive_no,
3143  data.idn, data.size);
3144  if (IS_ERR(req)) {
3145  return PTR_ERR(req);
3146  }
3147 
3148  if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
3149  return -EFAULT;
3150  }
3151 
3152  return 0;
3153 }
3154 
3155 /****************************************************************************/
3156 
3162  ec_master_t *master,
3163  void *arg,
3164  ec_ioctl_context_t *ctx
3165  )
3166 {
3167  ec_ioctl_reg_request_t io;
3168  ec_slave_config_t *sc;
3169  ec_reg_request_t *reg;
3170 
3171  if (unlikely(!ctx->requested)) {
3172  return -EPERM;
3173  }
3174 
3175  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3176  return -EFAULT;
3177  }
3178 
3179  io.request_index = 0;
3180 
3181  if (down_interruptible(&master->master_sem)) {
3182  return -EINTR;
3183  }
3184 
3185  sc = ec_master_get_config(master, io.config_index);
3186  if (!sc) {
3187  up(&master->master_sem);
3188  return -ENOENT;
3189  }
3190 
3191  list_for_each_entry(reg, &sc->reg_requests, list) {
3192  io.request_index++;
3193  }
3194 
3195  up(&master->master_sem);
3197  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
3198  if (IS_ERR(reg)) {
3199  return PTR_ERR(reg);
3200  }
3201 
3202  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3203  return -EFAULT;
3204  }
3205 
3206  return 0;
3207 }
3208 
3209 /****************************************************************************/
3210 
3216  ec_master_t *master,
3217  void *arg,
3218  ec_ioctl_context_t *ctx
3219  )
3220 {
3221  ec_ioctl_voe_t data;
3222  ec_slave_config_t *sc;
3223  ec_voe_handler_t *voe;
3224 
3225  if (unlikely(!ctx->requested))
3226  return -EPERM;
3227 
3228  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3229  return -EFAULT;
3230  }
3231 
3232  data.voe_index = 0;
3233 
3234  if (down_interruptible(&master->master_sem))
3235  return -EINTR;
3236 
3237  sc = ec_master_get_config(master, data.config_index);
3238  if (!sc) {
3239  up(&master->master_sem);
3240  return -ENOENT;
3241  }
3242 
3243  list_for_each_entry(voe, &sc->voe_handlers, list) {
3244  data.voe_index++;
3245  }
3246 
3247  up(&master->master_sem);
3249  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
3250  if (IS_ERR(voe))
3251  return PTR_ERR(voe);
3252 
3253  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3254  return -EFAULT;
3255 
3256  return 0;
3257 }
3258 
3259 /****************************************************************************/
3260 
3266  ec_master_t *master,
3267  void *arg,
3268  ec_ioctl_context_t *ctx
3269  )
3270 {
3271  ec_ioctl_sc_state_t data;
3272  const ec_slave_config_t *sc;
3274  int ret;
3275 
3276  if (unlikely(!ctx->requested))
3277  return -EPERM;
3278 
3279  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) {
3280  return -EFAULT;
3281  }
3282 
3283  /* no locking of master_sem needed, because sc will not be deleted in the
3284  * meantime. */
3285 
3286  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
3287  return -ENOENT;
3288  }
3289 
3290  ret = ecrt_slave_config_state(sc, &state);
3291  if (ret)
3292  return ret;
3293 
3294  if (ec_copy_to_user((void __user *) data.state,
3295  &state, sizeof(state), ctx))
3296  return -EFAULT;
3297 
3298  return 0;
3299 }
3300 
3301 /****************************************************************************/
3302 
3308  ec_master_t *master,
3309  void *arg,
3310  ec_ioctl_context_t *ctx
3311  )
3312 {
3313  ec_ioctl_sc_idn_t ioctl;
3314  ec_slave_config_t *sc;
3315  uint8_t *data = NULL;
3316  int ret;
3317 
3318  if (unlikely(!ctx->requested))
3319  return -EPERM;
3320 
3321  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
3322  return -EFAULT;
3323 
3324  if (!ioctl.size)
3325  return -EINVAL;
3326 
3327  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
3328  return -ENOMEM;
3329  }
3330 
3331  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
3332  kfree(data);
3333  return -EFAULT;
3334  }
3335 
3336  if (down_interruptible(&master->master_sem)) {
3337  kfree(data);
3338  return -EINTR;
3339  }
3340 
3341  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3342  up(&master->master_sem);
3343  kfree(data);
3344  return -ENOENT;
3345  }
3346 
3347  up(&master->master_sem);
3349  ret = ecrt_slave_config_idn(
3350  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3351  kfree(data);
3352  return ret;
3353 }
3354 
3355 /****************************************************************************/
3356 
3362  ec_master_t *master,
3363  void *arg,
3364  ec_ioctl_context_t *ctx
3365  )
3366 {
3367  ec_ioctl_sc_flag_t ioctl;
3368  ec_slave_config_t *sc;
3369  uint8_t *key;
3370  int ret;
3371 
3372  if (unlikely(!ctx->requested)) {
3373  return -EPERM;
3374  }
3375 
3376  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3377  return -EFAULT;
3378  }
3379 
3380  if (!ioctl.key_size) {
3381  return -EINVAL;
3382  }
3383 
3384  if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3385  return -ENOMEM;
3386  }
3387 
3388  if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3389  kfree(key);
3390  return -EFAULT;
3391  }
3392  key[ioctl.key_size] = '\0';
3393 
3394  if (down_interruptible(&master->master_sem)) {
3395  kfree(key);
3396  return -EINTR;
3397  }
3398 
3399  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3400  up(&master->master_sem);
3401  kfree(key);
3402  return -ENOENT;
3403  }
3404 
3405  up(&master->master_sem);
3407  ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3408  kfree(key);
3409  return ret;
3410 }
3411 
3412 /****************************************************************************/
3413 
3419  ec_master_t *master,
3420  void *arg,
3421  ec_ioctl_context_t *ctx
3422  )
3423 {
3424  ec_ioctl_sc_state_timeout_t ioctl;
3425  ec_slave_config_t *sc;
3426  int ret;
3427 
3428  if (unlikely(!ctx->requested)) {
3429  return -EPERM;
3430  }
3431 
3432  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3433  return -EFAULT;
3434  }
3435 
3436  if (down_interruptible(&master->master_sem)) {
3437  return -EINTR;
3438  }
3439 
3440  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3441  up(&master->master_sem);
3442  return -ENOENT;
3443  }
3444 
3445  up(&master->master_sem);
3447  ret = ecrt_slave_config_state_timeout(sc, ioctl.from_state,
3448  ioctl.to_state, ioctl.timeout_ms);
3449  return ret;
3450 }
3451 
3452 /****************************************************************************/
3453 
3454 #ifdef EC_EOE
3455 
3461  ec_master_t *master,
3462  void *arg,
3463  ec_ioctl_context_t *ctx
3464  )
3465 {
3466  ec_ioctl_eoe_ip_t io;
3467  ec_slave_config_t *sc;
3468 
3469  if (unlikely(!ctx->requested)) {
3470  return -EPERM;
3471  }
3472 
3473  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3474  return -EFAULT;
3475  }
3476 
3477  if (down_interruptible(&master->master_sem)) {
3478  return -EINTR;
3479  }
3480 
3481  if (!(sc = ec_master_get_config(master, io.config_index))) {
3482  up(&master->master_sem);
3483  return -ENOENT;
3484  }
3485 
3486  up(&master->master_sem);
3488  /* the kernel versions of the EoE set IP methods never fail. */
3489  if (io.mac_address_included) {
3490  ecrt_slave_config_eoe_mac_address(sc, io.mac_address);
3491  }
3492  if (io.ip_address_included) {
3493  ecrt_slave_config_eoe_ip_address(sc, io.ip_address);
3494  }
3495  if (io.subnet_mask_included) {
3496  ecrt_slave_config_eoe_subnet_mask(sc, io.subnet_mask);
3497  }
3498  if (io.gateway_included) {
3499  ecrt_slave_config_eoe_default_gateway(sc, io.gateway);
3500  }
3501  if (io.dns_included) {
3503  }
3504  if (io.name_included) {
3505  ecrt_slave_config_eoe_hostname(sc, io.name);
3506  }
3507 
3508  return 0;
3509 }
3510 
3511 #endif
3512 
3513 /****************************************************************************/
3514 
3520  ec_master_t *master,
3521  void *arg,
3522  ec_ioctl_context_t *ctx
3523  )
3524 {
3525  const ec_domain_t *domain;
3526 
3527  if (unlikely(!ctx->requested)) {
3528  return -EPERM;
3529  }
3530 
3531  if (down_interruptible(&master->master_sem)) {
3532  return -EINTR;
3533  }
3534 
3535  list_for_each_entry(domain, &master->domains, list) {
3536  if (domain->index == (unsigned long) arg) {
3537  size_t size = ecrt_domain_size(domain);
3538  up(&master->master_sem);
3539  return size;
3540  }
3541  }
3542 
3543  up(&master->master_sem);
3544  return -ENOENT;
3545 }
3546 
3547 /****************************************************************************/
3548 
3554  ec_master_t *master,
3555  void *arg,
3556  ec_ioctl_context_t *ctx
3557  )
3558 {
3559  int offset = 0;
3560  const ec_domain_t *domain;
3561 
3562  if (unlikely(!ctx->requested))
3563  return -EPERM;
3564 
3565  if (down_interruptible(&master->master_sem)) {
3566  return -EINTR;
3567  }
3568 
3569  list_for_each_entry(domain, &master->domains, list) {
3570  if (domain->index == (unsigned long) arg) {
3571  up(&master->master_sem);
3572  return offset;
3573  }
3574  offset += ecrt_domain_size(domain);
3575  }
3576 
3577  up(&master->master_sem);
3578  return -ENOENT;
3579 }
3580 
3581 /****************************************************************************/
3582 
3588  ec_master_t *master,
3589  void *arg,
3590  ec_ioctl_context_t *ctx
3591  )
3592 {
3593  ec_domain_t *domain;
3594 
3595  if (unlikely(!ctx->requested))
3596  return -EPERM;
3597 
3598  /* no locking of master_sem needed, because domain will not be deleted in
3599  * the meantime. */
3600 
3601  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3602  return -ENOENT;
3603  }
3604 
3605  return ecrt_domain_process(domain);
3606 }
3607 
3608 /****************************************************************************/
3609 
3615  ec_master_t *master,
3616  void *arg,
3617  ec_ioctl_context_t *ctx
3618  )
3619 {
3620  ec_domain_t *domain;
3621  int ret;
3622 
3623  if (unlikely(!ctx->requested))
3624  return -EPERM;
3625 
3626  /* no locking of master_sem needed, because domain will not be deleted in
3627  * the meantime. */
3628 
3629  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3630  return -ENOENT;
3631  }
3632 
3633  if (ec_ioctl_lock_interruptible(&master->io_mutex))
3634  return -EINTR;
3635 
3636  ret = ecrt_domain_queue(domain);
3637  ec_ioctl_unlock(&master->io_mutex);
3638  return ret;
3639 }
3640 
3641 /****************************************************************************/
3642 
3648  ec_master_t *master,
3649  void *arg,
3650  ec_ioctl_context_t *ctx
3651  )
3652 {
3653  ec_ioctl_domain_state_t data;
3654  const ec_domain_t *domain;
3655  ec_domain_state_t state;
3656  int ret;
3657 
3658  if (unlikely(!ctx->requested))
3659  return -EPERM;
3660 
3661  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) {
3662  return -EFAULT;
3663  }
3664 
3665  /* no locking of master_sem needed, because domain will not be deleted in
3666  * the meantime. */
3667 
3668  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3669  return -ENOENT;
3670  }
3671 
3672  ret = ecrt_domain_state(domain, &state);
3673  if (ret)
3674  return ret;
3675 
3676  if (ec_copy_to_user((void __user *) data.state, &state, sizeof(state),
3677  ctx))
3678  return -EFAULT;
3679 
3680  return 0;
3681 }
3682 
3683 /****************************************************************************/
3684 
3690  ec_master_t *master,
3691  void *arg,
3692  ec_ioctl_context_t *ctx
3693  )
3694 {
3695  ec_ioctl_sdo_request_t data;
3696  ec_slave_config_t *sc;
3697  ec_sdo_request_t *req;
3698 
3699  if (unlikely(!ctx->requested))
3700  return -EPERM;
3701 
3702  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3703  return -EFAULT;
3704 
3705  /* no locking of master_sem needed, because neither sc nor req will not be
3706  * deleted in the meantime. */
3707 
3708  if (!(sc = ec_master_get_config(master, data.config_index))) {
3709  return -ENOENT;
3710  }
3711 
3712  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3713  return -ENOENT;
3714  }
3715 
3716  return ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3717 }
3718 
3719 /****************************************************************************/
3720 
3726  ec_master_t *master,
3727  void *arg,
3728  ec_ioctl_context_t *ctx
3729  )
3730 {
3731  ec_ioctl_sdo_request_t data;
3732  ec_slave_config_t *sc;
3733  ec_sdo_request_t *req;
3734 
3735  if (unlikely(!ctx->requested))
3736  return -EPERM;
3737 
3738  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3739  return -EFAULT;
3740 
3741  /* no locking of master_sem needed, because neither sc nor req will not be
3742  * deleted in the meantime. */
3743 
3744  if (!(sc = ec_master_get_config(master, data.config_index))) {
3745  return -ENOENT;
3746  }
3747 
3748  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3749  return -ENOENT;
3750  }
3751 
3752  return ecrt_sdo_request_timeout(req, data.timeout);
3753 }
3754 
3755 /****************************************************************************/
3756 
3764  ec_master_t *master,
3765  void *arg,
3766  ec_ioctl_context_t *ctx
3767  )
3768 {
3769  ec_ioctl_sdo_request_t data;
3770  ec_slave_config_t *sc;
3771  ec_sdo_request_t *req;
3772 
3773  if (unlikely(!ctx->requested))
3774  return -EPERM;
3775 
3776  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3777  return -EFAULT;
3778 
3779  /* no locking of master_sem needed, because neither sc nor req will not be
3780  * deleted in the meantime. */
3781 
3782  if (!(sc = ec_master_get_config(master, data.config_index))) {
3783  return -ENOENT;
3784  }
3785 
3786  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3787  return -ENOENT;
3788  }
3789 
3790  data.state = ecrt_sdo_request_state(req);
3791  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3792  data.size = ecrt_sdo_request_data_size(req);
3793  else
3794  data.size = 0;
3795 
3796  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
3797  return -EFAULT;
3798 
3799  return 0;
3800 }
3801 
3802 /****************************************************************************/
3803 
3809  ec_master_t *master,
3810  void *arg,
3811  ec_ioctl_context_t *ctx
3812  )
3813 {
3814  ec_ioctl_sdo_request_t data;
3815  ec_slave_config_t *sc;
3816  ec_sdo_request_t *req;
3817 
3818  if (unlikely(!ctx->requested))
3819  return -EPERM;
3820 
3821  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3822  return -EFAULT;
3823 
3824  /* no locking of master_sem needed, because neither sc nor req will not be
3825  * deleted in the meantime. */
3826 
3827  if (!(sc = ec_master_get_config(master, data.config_index))) {
3828  return -ENOENT;
3829  }
3830 
3831  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3832  return -ENOENT;
3833  }
3834 
3835  return ecrt_sdo_request_read(req);
3836 }
3837 
3838 /****************************************************************************/
3839 
3845  ec_master_t *master,
3846  void *arg,
3847  ec_ioctl_context_t *ctx
3848  )
3849 {
3850  ec_ioctl_sdo_request_t data;
3851  ec_slave_config_t *sc;
3852  ec_sdo_request_t *req;
3853 
3854  if (unlikely(!ctx->requested))
3855  return -EPERM;
3856 
3857  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3858  return -EFAULT;
3859 
3860  if (!data.size) {
3861  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3862  return -EINVAL;
3863  }
3864 
3865  /* no locking of master_sem needed, because neither sc nor req will not be
3866  * deleted in the meantime. */
3867 
3868  if (!(sc = ec_master_get_config(master, data.config_index))) {
3869  return -ENOENT;
3870  }
3871 
3872  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3873  return -ENOENT;
3874  }
3875 
3876  if (data.size > req->mem_size)
3877  return -ENOBUFS;
3878 
3879  if (ec_copy_from_user(req->data, (void __user *) data.data,
3880  data.size, ctx))
3881  return -EFAULT;
3882 
3883  req->data_size = data.size;
3884  return ecrt_sdo_request_write(req);
3885 }
3886 
3887 /****************************************************************************/
3888 
3894  ec_master_t *master,
3895  void *arg,
3896  ec_ioctl_context_t *ctx
3897  )
3898 {
3899  ec_ioctl_sdo_request_t data;
3900  ec_slave_config_t *sc;
3901  ec_sdo_request_t *req;
3902 
3903  if (unlikely(!ctx->requested))
3904  return -EPERM;
3905 
3906  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3907  return -EFAULT;
3908 
3909  /* no locking of master_sem needed, because neither sc nor req will not be
3910  * deleted in the meantime. */
3911 
3912  if (!(sc = ec_master_get_config(master, data.config_index))) {
3913  return -ENOENT;
3914  }
3915 
3916  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3917  return -ENOENT;
3918  }
3919 
3920  if (ec_copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3921  ecrt_sdo_request_data_size(req), ctx))
3922  return -EFAULT;
3923 
3924  return 0;
3925 }
3926 
3927 /****************************************************************************/
3928 
3934  ec_master_t *master,
3935  void *arg,
3936  ec_ioctl_context_t *ctx
3937  )
3938 {
3939  ec_ioctl_soe_request_t data;
3940  ec_slave_config_t *sc;
3941  ec_soe_request_t *req;
3942 
3943  if (unlikely(!ctx->requested))
3944  return -EPERM;
3945 
3946  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3947  return -EFAULT;
3948 
3949  /* no locking of master_sem needed, because neither sc nor req will not be
3950  * deleted in the meantime. */
3951 
3952  if (!(sc = ec_master_get_config(master, data.config_index))) {
3953  return -ENOENT;
3954  }
3955 
3956  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3957  return -ENOENT;
3958  }
3959 
3960  return ecrt_soe_request_idn(req, data.drive_no, data.idn);
3961 }
3962 
3963 /****************************************************************************/
3964 
3970  ec_master_t *master,
3971  void *arg,
3972  ec_ioctl_context_t *ctx
3973  )
3974 {
3975  ec_ioctl_soe_request_t data;
3976  ec_slave_config_t *sc;
3977  ec_soe_request_t *req;
3978 
3979  if (unlikely(!ctx->requested))
3980  return -EPERM;
3981 
3982  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3983  return -EFAULT;
3984 
3985  /* no locking of master_sem needed, because neither sc nor req will not be
3986  * deleted in the meantime. */
3987 
3988  if (!(sc = ec_master_get_config(master, data.config_index))) {
3989  return -ENOENT;
3990  }
3991 
3992  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3993  return -ENOENT;
3994  }
3995 
3996  return ecrt_soe_request_timeout(req, data.timeout);
3997 }
3998 
3999 /****************************************************************************/
4000 
4006  ec_master_t *master,
4007  void *arg,
4008  ec_ioctl_context_t *ctx
4009  )
4010 {
4011  ec_ioctl_soe_request_t data;
4012  ec_slave_config_t *sc;
4013  ec_soe_request_t *req;
4014 
4015  if (unlikely(!ctx->requested))
4016  return -EPERM;
4017 
4018  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4019  return -EFAULT;
4020 
4021  /* no locking of master_sem needed, because neither sc nor req will not be
4022  * deleted in the meantime. */
4023 
4024  if (!(sc = ec_master_get_config(master, data.config_index))) {
4025  return -ENOENT;
4026  }
4027 
4028  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4029  return -ENOENT;
4030  }
4031 
4032  data.state = ecrt_soe_request_state(req);
4033  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT) {
4034  data.size = ecrt_soe_request_data_size(req);
4035  }
4036  else {
4037  data.size = 0;
4038  }
4039 
4040  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
4041  return -EFAULT;
4042 
4043  return 0;
4044 }
4045 
4046 /****************************************************************************/
4047 
4053  ec_master_t *master,
4054  void *arg,
4055  ec_ioctl_context_t *ctx
4056  )
4057 {
4058  ec_ioctl_soe_request_t data;
4059  ec_slave_config_t *sc;
4060  ec_soe_request_t *req;
4061 
4062  if (unlikely(!ctx->requested))
4063  return -EPERM;
4064 
4065  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4066  return -EFAULT;
4067 
4068  /* no locking of master_sem needed, because neither sc nor req will not be
4069  * deleted in the meantime. */
4070 
4071  if (!(sc = ec_master_get_config(master, data.config_index))) {
4072  return -ENOENT;
4073  }
4074 
4075  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4076  return -ENOENT;
4077  }
4078 
4079  return ecrt_soe_request_read(req);
4080 }
4081 
4082 /****************************************************************************/
4083 
4089  ec_master_t *master,
4090  void *arg,
4091  ec_ioctl_context_t *ctx
4092  )
4093 {
4094  ec_ioctl_soe_request_t data;
4095  ec_slave_config_t *sc;
4096  ec_soe_request_t *req;
4097 
4098  if (unlikely(!ctx->requested))
4099  return -EPERM;
4100 
4101  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4102  return -EFAULT;
4103 
4104  if (!data.size) {
4105  EC_MASTER_ERR(master, "IDN write: Data size may not be zero!\n");
4106  return -EINVAL;
4107  }
4108 
4109  /* no locking of master_sem needed, because neither sc nor req will not be
4110  * deleted in the meantime. */
4111 
4112  if (!(sc = ec_master_get_config(master, data.config_index))) {
4113  return -ENOENT;
4114  }
4115 
4116  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4117  return -ENOENT;
4118  }
4119 
4120  if (data.size > req->mem_size)
4121  return -ENOBUFS;
4122 
4123  if (ec_copy_from_user(req->data, (void __user *) data.data,
4124  data.size, ctx))
4125  return -EFAULT;
4126 
4127  req->data_size = data.size;
4128  return ecrt_soe_request_write(req);
4129 }
4130 
4131 /****************************************************************************/
4132 
4138  ec_master_t *master,
4139  void *arg,
4140  ec_ioctl_context_t *ctx
4141  )
4142 {
4143  ec_ioctl_soe_request_t data;
4144  ec_slave_config_t *sc;
4145  ec_soe_request_t *req;
4146 
4147  if (unlikely(!ctx->requested))
4148  return -EPERM;
4149 
4150  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4151  return -EFAULT;
4152 
4153  /* no locking of master_sem needed, because neither sc nor req will not be
4154  * deleted in the meantime. */
4155 
4156  if (!(sc = ec_master_get_config(master, data.config_index))) {
4157  return -ENOENT;
4158  }
4159 
4160  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4161  return -ENOENT;
4162  }
4163 
4164  if (ec_copy_to_user((void __user *) data.data, ecrt_soe_request_data(req),
4165  ecrt_soe_request_data_size(req), ctx))
4166  return -EFAULT;
4167 
4168  return 0;
4169 }
4170 
4171 /****************************************************************************/
4172 
4178  ec_master_t *master,
4179  void *arg,
4180  ec_ioctl_context_t *ctx
4181  )
4182 {
4183  ec_ioctl_reg_request_t io;
4184  ec_slave_config_t *sc;
4185  ec_reg_request_t *reg;
4186 
4187  if (unlikely(!ctx->requested)) {
4188  return -EPERM;
4189  }
4190 
4191  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4192  return -EFAULT;
4193  }
4194 
4195  if (io.mem_size <= 0) {
4196  return 0;
4197  }
4198 
4199  /* no locking of master_sem needed, because neither sc nor reg will not be
4200  * deleted in the meantime. */
4201 
4202  if (!(sc = ec_master_get_config(master, io.config_index))) {
4203  return -ENOENT;
4204  }
4205 
4206  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4207  return -ENOENT;
4208  }
4209 
4210  if (ec_copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
4211  min(reg->mem_size, io.mem_size), ctx)) {
4212  return -EFAULT;
4213  }
4214 
4215  return 0;
4216 }
4217 
4218 /****************************************************************************/
4219 
4225  ec_master_t *master,
4226  void *arg,
4227  ec_ioctl_context_t *ctx
4228  )
4229 {
4230  ec_ioctl_reg_request_t io;
4231  ec_slave_config_t *sc;
4232  ec_reg_request_t *reg;
4233 
4234  if (unlikely(!ctx->requested)) {
4235  return -EPERM;
4236  }
4237 
4238  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4239  return -EFAULT;
4240  }
4241 
4242  /* no locking of master_sem needed, because neither sc nor reg will not be
4243  * deleted in the meantime. */
4244 
4245  if (!(sc = ec_master_get_config(master, io.config_index))) {
4246  return -ENOENT;
4247  }
4248 
4249  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4250  return -ENOENT;
4251  }
4252 
4253  io.state = ecrt_reg_request_state(reg);
4254  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
4255 
4256  if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) {
4257  return -EFAULT;
4258  }
4259 
4260  return 0;
4261 }
4262 
4263 /****************************************************************************/
4264 
4270  ec_master_t *master,
4271  void *arg,
4272  ec_ioctl_context_t *ctx
4273  )
4274 {
4275  ec_ioctl_reg_request_t io;
4276  ec_slave_config_t *sc;
4277  ec_reg_request_t *reg;
4278 
4279  if (unlikely(!ctx->requested)) {
4280  return -EPERM;
4281  }
4282 
4283  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4284  return -EFAULT;
4285  }
4286 
4287  /* no locking of master_sem needed, because neither sc nor reg will not be
4288  * deleted in the meantime. */
4289 
4290  if (!(sc = ec_master_get_config(master, io.config_index))) {
4291  return -ENOENT;
4292  }
4293 
4294  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4295  return -ENOENT;
4296  }
4297 
4298  if (io.transfer_size > reg->mem_size) {
4299  return -ENOBUFS;
4300  }
4301 
4302  if (ec_copy_from_user(reg->data, (void __user *) io.data,
4303  io.transfer_size, ctx)) {
4304  return -EFAULT;
4305  }
4306 
4307  return ecrt_reg_request_write(reg, io.address, io.transfer_size);
4308 }
4309 
4310 /****************************************************************************/
4311 
4317  ec_master_t *master,
4318  void *arg,
4319  ec_ioctl_context_t *ctx
4320  )
4321 {
4322  ec_ioctl_reg_request_t io;
4323  ec_slave_config_t *sc;
4324  ec_reg_request_t *reg;
4325 
4326  if (unlikely(!ctx->requested)) {
4327  return -EPERM;
4328  }
4329 
4330  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4331  return -EFAULT;
4332  }
4333 
4334  /* no locking of master_sem needed, because neither sc nor reg will not be
4335  * deleted in the meantime. */
4336 
4337  if (!(sc = ec_master_get_config(master, io.config_index))) {
4338  return -ENOENT;
4339  }
4340 
4341  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4342  return -ENOENT;
4343  }
4344 
4345  if (io.transfer_size > reg->mem_size) {
4346  return -ENOBUFS;
4347  }
4348 
4349  return ecrt_reg_request_read(reg, io.address, io.transfer_size);
4350 }
4351 
4352 /****************************************************************************/
4353 
4359  ec_master_t *master,
4360  void *arg,
4361  ec_ioctl_context_t *ctx
4362  )
4363 {
4364  ec_ioctl_voe_t data;
4365  ec_slave_config_t *sc;
4366  ec_voe_handler_t *voe;
4367  uint32_t vendor_id;
4368  uint16_t vendor_type;
4369 
4370  if (unlikely(!ctx->requested))
4371  return -EPERM;
4372 
4373  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4374  return -EFAULT;
4375 
4376  if (ec_copy_from_user(&vendor_id, data.vendor_id, sizeof(vendor_id), ctx))
4377  return -EFAULT;
4378 
4379  if (ec_copy_from_user(&vendor_type, data.vendor_type,
4380  sizeof(vendor_type), ctx))
4381  return -EFAULT;
4382 
4383  /* no locking of master_sem needed, because neither sc nor voe will not be
4384  * deleted in the meantime. */
4385 
4386  if (!(sc = ec_master_get_config(master, data.config_index))) {
4387  return -ENOENT;
4388  }
4389 
4390  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4391  return -ENOENT;
4392  }
4393 
4394  return ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
4395 }
4396 
4397 /****************************************************************************/
4398 
4404  ec_master_t *master,
4405  void *arg,
4406  ec_ioctl_context_t *ctx
4407  )
4408 {
4409  ec_ioctl_voe_t data;
4410  ec_slave_config_t *sc;
4411  ec_voe_handler_t *voe;
4412  uint32_t vendor_id;
4413  uint16_t vendor_type;
4414  int ret;
4415 
4416  if (unlikely(!ctx->requested))
4417  return -EPERM;
4418 
4419  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4420  return -EFAULT;
4421 
4422  /* no locking of master_sem needed, because neither sc nor voe will not be
4423  * deleted in the meantime. */
4424 
4425  if (!(sc = ec_master_get_config(master, data.config_index))) {
4426  return -ENOENT;
4427  }
4428 
4429  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4430  return -ENOENT;
4431  }
4432 
4433  ret = ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
4434  if (ret)
4435  return ret;
4436 
4437  if (likely(data.vendor_id))
4438  if (ec_copy_to_user(data.vendor_id, &vendor_id,
4439  sizeof(vendor_id), ctx))
4440  return -EFAULT;
4441 
4442  if (likely(data.vendor_type))
4443  if (ec_copy_to_user(data.vendor_type, &vendor_type,
4444  sizeof(vendor_type), ctx))
4445  return -EFAULT;
4446 
4447  return 0;
4448 }
4449 
4450 /****************************************************************************/
4451 
4457  ec_master_t *master,
4458  void *arg,
4459  ec_ioctl_context_t *ctx
4460  )
4461 {
4462  ec_ioctl_voe_t data;
4463  ec_slave_config_t *sc;
4464  ec_voe_handler_t *voe;
4465 
4466  if (unlikely(!ctx->requested))
4467  return -EPERM;
4468 
4469  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4470  return -EFAULT;
4471 
4472  /* no locking of master_sem needed, because neither sc nor voe will not be
4473  * deleted in the meantime. */
4474 
4475  if (!(sc = ec_master_get_config(master, data.config_index))) {
4476  return -ENOENT;
4477  }
4478 
4479  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4480  return -ENOENT;
4481  }
4482 
4483  return ecrt_voe_handler_read(voe);
4484 }
4485 
4486 /****************************************************************************/
4487 
4493  ec_master_t *master,
4494  void *arg,
4495  ec_ioctl_context_t *ctx
4496  )
4497 {
4498  ec_ioctl_voe_t data;
4499  ec_slave_config_t *sc;
4500  ec_voe_handler_t *voe;
4501 
4502  if (unlikely(!ctx->requested))
4503  return -EPERM;
4504 
4505  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4506  return -EFAULT;
4507 
4508  /* no locking of master_sem needed, because neither sc nor voe will not be
4509  * deleted in the meantime. */
4510 
4511  if (!(sc = ec_master_get_config(master, data.config_index))) {
4512  return -ENOENT;
4513  }
4514 
4515  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4516  return -ENOENT;
4517  }
4518 
4519  return ecrt_voe_handler_read_nosync(voe);
4520 }
4521 
4522 /****************************************************************************/
4523 
4529  ec_master_t *master,
4530  void *arg,
4531  ec_ioctl_context_t *ctx
4532  )
4533 {
4534  ec_ioctl_voe_t data;
4535  ec_slave_config_t *sc;
4536  ec_voe_handler_t *voe;
4537 
4538  if (unlikely(!ctx->requested))
4539  return -EPERM;
4540 
4541  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4542  return -EFAULT;
4543 
4544  /* no locking of master_sem needed, because neither sc nor voe will not be
4545  * deleted in the meantime. */
4546 
4547  if (!(sc = ec_master_get_config(master, data.config_index))) {
4548  return -ENOENT;
4549  }
4550 
4551  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4552  return -ENOENT;
4553  }
4554 
4555  if (data.size) {
4556  if (data.size > ec_voe_handler_mem_size(voe))
4557  return -ENOBUFS;
4558 
4559  if (ec_copy_from_user(ecrt_voe_handler_data(voe),
4560  (void __user *) data.data, data.size, ctx))
4561  return -EFAULT;
4562  }
4563 
4564  return ecrt_voe_handler_write(voe, data.size);
4565 }
4566 
4567 /****************************************************************************/
4568 
4574  ec_master_t *master,
4575  void *arg,
4576  ec_ioctl_context_t *ctx
4577  )
4578 {
4579  ec_ioctl_voe_t data;
4580  ec_slave_config_t *sc;
4581  ec_voe_handler_t *voe;
4582 
4583  if (unlikely(!ctx->requested))
4584  return -EPERM;
4585 
4586  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4587  return -EFAULT;
4588 
4589  /* no locking of master_sem needed, because neither sc nor voe will not be
4590  * deleted in the meantime. */
4591 
4592  if (!(sc = ec_master_get_config(master, data.config_index))) {
4593  return -ENOENT;
4594  }
4595 
4596  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4597  return -ENOENT;
4598  }
4599 
4600  if (ec_ioctl_lock_interruptible(&master->io_mutex))
4601  return -EINTR;
4602 
4603  data.state = ecrt_voe_handler_execute(voe);
4604  ec_ioctl_unlock(&master->io_mutex);
4605  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
4606  data.size = ecrt_voe_handler_data_size(voe);
4607  else
4608  data.size = 0;
4609 
4610  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
4611  return -EFAULT;
4612 
4613  return 0;
4614 }
4615 
4616 /****************************************************************************/
4617 
4623  ec_master_t *master,
4624  void *arg,
4625  ec_ioctl_context_t *ctx
4626  )
4627 {
4628  ec_ioctl_voe_t data;
4629  ec_slave_config_t *sc;
4630  ec_voe_handler_t *voe;
4631 
4632  if (unlikely(!ctx->requested))
4633  return -EPERM;
4634 
4635  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4636  return -EFAULT;
4637 
4638  /* no locking of master_sem needed, because neither sc nor voe will not be
4639  * deleted in the meantime. */
4640 
4641  if (!(sc = ec_master_get_config(master, data.config_index))) {
4642  return -ENOENT;
4643  }
4644 
4645  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4646  return -ENOENT;
4647  }
4648 
4649  if (ec_copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
4650  ecrt_voe_handler_data_size(voe), ctx))
4651  return -EFAULT;
4652 
4653  return 0;
4654 }
4655 
4656 /****************************************************************************/
4657 
4663  ec_master_t *master,
4664  void *arg
4665  )
4666 {
4667  ec_ioctl_slave_foe_t io;
4668  ec_foe_request_t request;
4669  ec_slave_t *slave;
4670  int ret;
4671 
4672  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4673  return -EFAULT;
4674  }
4675 
4676  ec_foe_request_init(&request, io.file_name);
4677  ret = ec_foe_request_alloc(&request, 10000); // FIXME
4678  if (ret) {
4679  ec_foe_request_clear(&request);
4680  return ret;
4681  }
4682 
4683  ec_foe_request_read(&request);
4684 
4685  if (down_interruptible(&master->master_sem)) {
4686  ec_foe_request_clear(&request);
4687  return -EINTR;
4688  }
4689 
4690  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4691  up(&master->master_sem);
4692  ec_foe_request_clear(&request);
4693  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4694  io.slave_position);
4695  return -EINVAL;
4696  }
4697 
4698  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
4699 
4700  // schedule request.
4701  list_add_tail(&request.list, &slave->foe_requests);
4702 
4703  up(&master->master_sem);
4704 
4705  // wait for processing through FSM
4706  if (wait_event_interruptible(master->request_queue,
4707  request.state != EC_INT_REQUEST_QUEUED)) {
4708  // interrupted by signal
4709  down(&master->master_sem);
4710  if (request.state == EC_INT_REQUEST_QUEUED) {
4711  list_del(&request.list);
4712  up(&master->master_sem);
4713  ec_foe_request_clear(&request);
4714  return -EINTR;
4715  }
4716  // request already processing: interrupt not possible.
4717  up(&master->master_sem);
4718  }
4719 
4720  // wait until master FSM has finished processing
4721  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4722 
4723  io.result = request.result;
4724  io.error_code = request.error_code;
4725 
4726  if (request.state != EC_INT_REQUEST_SUCCESS) {
4727  io.data_size = 0;
4728  ret = -EIO;
4729  } else {
4730  if (request.data_size > io.buffer_size) {
4731  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4732  ec_foe_request_clear(&request);
4733  return -ENOBUFS;
4734  }
4735  io.data_size = request.data_size;
4736  if (copy_to_user((void __user *) io.buffer,
4737  request.buffer, io.data_size)) {
4738  ec_foe_request_clear(&request);
4739  return -EFAULT;
4740  }
4741  ret = 0;
4742  }
4743 
4744  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4745  ret = -EFAULT;
4746  }
4747 
4748  ec_foe_request_clear(&request);
4749  return ret;
4750 }
4751 
4752 /****************************************************************************/
4753 
4759  ec_master_t *master,
4760  void *arg
4761  )
4762 {
4763  ec_ioctl_slave_foe_t io;
4764  ec_foe_request_t request;
4765  ec_slave_t *slave;
4766  int ret;
4767 
4768  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4769  return -EFAULT;
4770  }
4771 
4772  ec_foe_request_init(&request, io.file_name);
4773 
4774  ret = ec_foe_request_alloc(&request, io.buffer_size);
4775  if (ret) {
4776  ec_foe_request_clear(&request);
4777  return ret;
4778  }
4779 
4780  if (copy_from_user(request.buffer,
4781  (void __user *) io.buffer, io.buffer_size)) {
4782  ec_foe_request_clear(&request);
4783  return -EFAULT;
4784  }
4785 
4786  request.data_size = io.buffer_size;
4787  ec_foe_request_write(&request);
4788 
4789  if (down_interruptible(&master->master_sem)) {
4790  ec_foe_request_clear(&request);
4791  return -EINTR;
4792  }
4793 
4794  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4795  up(&master->master_sem);
4796  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4797  io.slave_position);
4798  ec_foe_request_clear(&request);
4799  return -EINVAL;
4800  }
4801 
4802  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4803 
4804  // schedule FoE write request.
4805  list_add_tail(&request.list, &slave->foe_requests);
4806 
4807  up(&master->master_sem);
4808 
4809  // wait for processing through FSM
4810  if (wait_event_interruptible(master->request_queue,
4811  request.state != EC_INT_REQUEST_QUEUED)) {
4812  // interrupted by signal
4813  down(&master->master_sem);
4814  if (request.state == EC_INT_REQUEST_QUEUED) {
4815  // abort request
4816  list_del(&request.list);
4817  up(&master->master_sem);
4818  ec_foe_request_clear(&request);
4819  return -EINTR;
4820  }
4821  up(&master->master_sem);
4822  }
4823 
4824  // wait until master FSM has finished processing
4825  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4826 
4827  io.result = request.result;
4828  io.error_code = request.error_code;
4829 
4830  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4831 
4832  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4833  ret = -EFAULT;
4834  }
4835 
4836  ec_foe_request_clear(&request);
4837  return ret;
4838 }
4839 
4840 /****************************************************************************/
4841 
4847  ec_master_t *master,
4848  void *arg
4849  )
4850 {
4851  ec_ioctl_slave_soe_read_t ioctl;
4852  u8 *data;
4853  int retval;
4854 
4855  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4856  return -EFAULT;
4857  }
4858 
4859  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4860  if (!data) {
4861  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4862  ioctl.mem_size);
4863  return -ENOMEM;
4864  }
4865 
4866  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4867  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4868  &ioctl.error_code);
4869  if (retval) {
4870  kfree(data);
4871  return retval;
4872  }
4873 
4874  if (copy_to_user((void __user *) ioctl.data,
4875  data, ioctl.data_size)) {
4876  kfree(data);
4877  return -EFAULT;
4878  }
4879  kfree(data);
4880 
4881  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4882  retval = -EFAULT;
4883  }
4884 
4885  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4886  return retval;
4887 }
4888 
4889 /****************************************************************************/
4890 
4896  ec_master_t *master,
4897  void *arg
4898  )
4899 {
4900  ec_ioctl_slave_soe_write_t ioctl;
4901  u8 *data;
4902  int retval;
4903 
4904  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4905  return -EFAULT;
4906  }
4907 
4908  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4909  if (!data) {
4910  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4911  ioctl.data_size);
4912  return -ENOMEM;
4913  }
4914  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4915  kfree(data);
4916  return -EFAULT;
4917  }
4918 
4919  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4920  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4921  &ioctl.error_code);
4922  kfree(data);
4923  if (retval) {
4924  return retval;
4925  }
4926 
4927  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4928  retval = -EFAULT;
4929  }
4930 
4931  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4932  return retval;
4933 }
4934 
4935 /*****************************************************************************
4936  * ioctl() file operation functions
4937  ****************************************************************************/
4938 
4944 #ifndef EC_IOCTL_RTDM
4945 static long ec_ioctl_nrt(
4946  ec_master_t *master,
4947  ec_ioctl_context_t *ctx,
4948  unsigned int cmd,
4949  void *arg );
4950 #endif
4951 
4952 /****************************************************************************/
4953 
4959 static long ec_ioctl_both(
4960  ec_master_t *master,
4961  ec_ioctl_context_t *ctx,
4962  unsigned int cmd,
4963  void *arg
4964  )
4965 {
4966  int ret;
4967 
4968  switch (cmd) {
4969  case EC_IOCTL_MODULE:
4970  ret = ec_ioctl_module(arg, ctx);
4971  break;
4972  case EC_IOCTL_MASTER_RESCAN:
4973  if (!ctx->writable) {
4974  ret = -EPERM;
4975  break;
4976  }
4977  ret = ec_ioctl_master_rescan(master, arg);
4978  break;
4979  case EC_IOCTL_MASTER_STATE:
4980  ret = ec_ioctl_master_state(master, arg, ctx);
4981  break;
4982  case EC_IOCTL_MASTER_LINK_STATE:
4983  ret = ec_ioctl_master_link_state(master, arg, ctx);
4984  break;
4985  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4986  if (!ctx->writable) {
4987  ret = -EPERM;
4988  break;
4989  }
4990  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4991  break;
4992  case EC_IOCTL_SDO_REQUEST_DATA:
4993  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4994  break;
4995  case EC_IOCTL_SOE_REQUEST_TIMEOUT:
4996  if (!ctx->writable) {
4997  ret = -EPERM;
4998  break;
4999  }
5000  ret = ec_ioctl_soe_request_timeout(master, arg, ctx);
5001  break;
5002  case EC_IOCTL_SOE_REQUEST_DATA:
5003  ret = ec_ioctl_soe_request_data(master, arg, ctx);
5004  break;
5005  case EC_IOCTL_REG_REQUEST_DATA:
5006  ret = ec_ioctl_reg_request_data(master, arg, ctx);
5007  break;
5008  case EC_IOCTL_VOE_SEND_HEADER:
5009  if (!ctx->writable) {
5010  ret = -EPERM;
5011  break;
5012  }
5013  ret = ec_ioctl_voe_send_header(master, arg, ctx);
5014  break;
5015  case EC_IOCTL_VOE_DATA:
5016  ret = ec_ioctl_voe_data(master, arg, ctx);
5017  break;
5018  default:
5019 #ifdef EC_IOCTL_RTDM
5020  ret = -ENOTTY;
5021 #else
5022  /* chain non-rt commands for normal cdev */
5023  ret = ec_ioctl_nrt(master, ctx, cmd, arg);
5024 #endif
5025  break;
5026  }
5027 
5028  return ret;
5029 }
5030 
5031 /****************************************************************************/
5032 
5038 #ifdef EC_IOCTL_RTDM
5039 long ec_ioctl_rtdm_rt
5040 #else
5041 long ec_ioctl
5042 #endif
5043  (
5044  ec_master_t *master,
5045  ec_ioctl_context_t *ctx,
5046  unsigned int cmd,
5047  void *arg
5048  )
5049 {
5050 #if DEBUG_LATENCY
5051  cycles_t a = get_cycles(), b;
5052  unsigned int t;
5053 #endif
5054  long ret;
5055 
5056  switch (cmd) {
5057  case EC_IOCTL_SEND:
5058  if (!ctx->writable) {
5059  ret = -EPERM;
5060  break;
5061  }
5062  ret = ec_ioctl_send(master, arg, ctx);
5063  break;
5064  case EC_IOCTL_RECEIVE:
5065  if (!ctx->writable) {
5066  ret = -EPERM;
5067  break;
5068  }
5069  ret = ec_ioctl_receive(master, arg, ctx);
5070  break;
5071  case EC_IOCTL_APP_TIME:
5072  if (!ctx->writable) {
5073  ret = -EPERM;
5074  break;
5075  }
5076  ret = ec_ioctl_app_time(master, arg, ctx);
5077  break;
5078  case EC_IOCTL_SYNC_REF:
5079  if (!ctx->writable) {
5080  ret = -EPERM;
5081  break;
5082  }
5083  ret = ec_ioctl_sync_ref(master, arg, ctx);
5084  break;
5085  case EC_IOCTL_SYNC_REF_TO:
5086  if (!ctx->writable) {
5087  ret = -EPERM;
5088  break;
5089  }
5090  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
5091  break;
5092  case EC_IOCTL_SYNC_SLAVES:
5093  if (!ctx->writable) {
5094  ret = -EPERM;
5095  break;
5096  }
5097  ret = ec_ioctl_sync_slaves(master, arg, ctx);
5098  break;
5099  case EC_IOCTL_REF_CLOCK_TIME:
5100  if (!ctx->writable) {
5101  ret = -EPERM;
5102  break;
5103  }
5104  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
5105  break;
5106  case EC_IOCTL_SYNC_MON_QUEUE:
5107  if (!ctx->writable) {
5108  ret = -EPERM;
5109  break;
5110  }
5111  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
5112  break;
5113  case EC_IOCTL_SYNC_MON_PROCESS:
5114  if (!ctx->writable) {
5115  ret = -EPERM;
5116  break;
5117  }
5118  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
5119  break;
5120  case EC_IOCTL_RESET:
5121  if (!ctx->writable) {
5122  ret = -EPERM;
5123  break;
5124  }
5125  ret = ec_ioctl_reset(master, arg, ctx);
5126  break;
5127  case EC_IOCTL_SC_EMERG_POP:
5128  if (!ctx->writable) {
5129  ret = -EPERM;
5130  break;
5131  }
5132  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
5133  break;
5134  case EC_IOCTL_SC_EMERG_CLEAR:
5135  if (!ctx->writable) {
5136  ret = -EPERM;
5137  break;
5138  }
5139  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
5140  break;
5141  case EC_IOCTL_SC_EMERG_OVERRUNS:
5142  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
5143  break;
5144  case EC_IOCTL_SC_STATE:
5145  ret = ec_ioctl_sc_state(master, arg, ctx);
5146  break;
5147  case EC_IOCTL_DOMAIN_PROCESS:
5148  if (!ctx->writable) {
5149  ret = -EPERM;
5150  break;
5151  }
5152  ret = ec_ioctl_domain_process(master, arg, ctx);
5153  break;
5154  case EC_IOCTL_DOMAIN_QUEUE:
5155  if (!ctx->writable) {
5156  ret = -EPERM;
5157  break;
5158  }
5159  ret = ec_ioctl_domain_queue(master, arg, ctx);
5160  break;
5161  case EC_IOCTL_DOMAIN_STATE:
5162  ret = ec_ioctl_domain_state(master, arg, ctx);
5163  break;
5164  case EC_IOCTL_SDO_REQUEST_INDEX:
5165  if (!ctx->writable) {
5166  ret = -EPERM;
5167  break;
5168  }
5169  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
5170  break;
5171  case EC_IOCTL_SDO_REQUEST_STATE:
5172  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
5173  break;
5174  case EC_IOCTL_SDO_REQUEST_READ:
5175  if (!ctx->writable) {
5176  ret = -EPERM;
5177  break;
5178  }
5179  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
5180  break;
5181  case EC_IOCTL_SDO_REQUEST_WRITE:
5182  if (!ctx->writable) {
5183  ret = -EPERM;
5184  break;
5185  }
5186  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
5187  break;
5188  case EC_IOCTL_SOE_REQUEST_IDN:
5189  if (!ctx->writable) {
5190  ret = -EPERM;
5191  break;
5192  }
5193  ret = ec_ioctl_soe_request_index(master, arg, ctx);
5194  break;
5195  case EC_IOCTL_SOE_REQUEST_STATE:
5196  ret = ec_ioctl_soe_request_state(master, arg, ctx);
5197  break;
5198  case EC_IOCTL_SOE_REQUEST_READ:
5199  if (!ctx->writable) {
5200  ret = -EPERM;
5201  break;
5202  }
5203  ret = ec_ioctl_soe_request_read(master, arg, ctx);
5204  break;
5205  case EC_IOCTL_SOE_REQUEST_WRITE:
5206  if (!ctx->writable) {
5207  ret = -EPERM;
5208  break;
5209  }
5210  ret = ec_ioctl_soe_request_write(master, arg, ctx);
5211  break;
5212  case EC_IOCTL_REG_REQUEST_STATE:
5213  ret = ec_ioctl_reg_request_state(master, arg, ctx);
5214  break;
5215  case EC_IOCTL_REG_REQUEST_WRITE:
5216  if (!ctx->writable) {
5217  ret = -EPERM;
5218  break;
5219  }
5220  ret = ec_ioctl_reg_request_write(master, arg, ctx);
5221  break;
5222  case EC_IOCTL_REG_REQUEST_READ:
5223  if (!ctx->writable) {
5224  ret = -EPERM;
5225  break;
5226  }
5227  ret = ec_ioctl_reg_request_read(master, arg, ctx);
5228  break;
5229  case EC_IOCTL_VOE_REC_HEADER:
5230  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
5231  break;
5232  case EC_IOCTL_VOE_READ:
5233  if (!ctx->writable) {
5234  ret = -EPERM;
5235  break;
5236  }
5237  ret = ec_ioctl_voe_read(master, arg, ctx);
5238  break;
5239  case EC_IOCTL_VOE_READ_NOSYNC:
5240  if (!ctx->writable) {
5241  ret = -EPERM;
5242  break;
5243  }
5244  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
5245  break;
5246  case EC_IOCTL_VOE_WRITE:
5247  if (!ctx->writable) {
5248  ret = -EPERM;
5249  break;
5250  }
5251  ret = ec_ioctl_voe_write(master, arg, ctx);
5252  break;
5253  case EC_IOCTL_VOE_EXEC:
5254  if (!ctx->writable) {
5255  ret = -EPERM;
5256  break;
5257  }
5258  ret = ec_ioctl_voe_exec(master, arg, ctx);
5259  break;
5260  default:
5261  ret = ec_ioctl_both(master, ctx, cmd, arg);
5262  break;
5263  }
5264 
5265 #if DEBUG_LATENCY
5266  b = get_cycles();
5267  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5268  if (t > 50) {
5269  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5270  _IOC_NR(cmd), t);
5271  }
5272 #endif
5273 
5274  return ret;
5275 }
5276 
5277 /****************************************************************************/
5278 
5284 #ifdef EC_IOCTL_RTDM
5285 long ec_ioctl_rtdm_nrt
5286 #else
5287 static long ec_ioctl_nrt
5288 #endif
5289  (
5290  ec_master_t *master,
5291  ec_ioctl_context_t *ctx,
5292  unsigned int cmd,
5293  void *arg
5294  )
5295 {
5296 #if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM)
5297  cycles_t a = get_cycles(), b;
5298  unsigned int t;
5299 #endif
5300  int ret;
5301 
5302  switch (cmd) {
5303  case EC_IOCTL_MASTER:
5304  ret = ec_ioctl_master(master, arg);
5305  break;
5306  case EC_IOCTL_SLAVE:
5307  ret = ec_ioctl_slave(master, arg);
5308  break;
5309  case EC_IOCTL_SLAVE_SYNC:
5310  ret = ec_ioctl_slave_sync(master, arg);
5311  break;
5312  case EC_IOCTL_SLAVE_SYNC_PDO:
5313  ret = ec_ioctl_slave_sync_pdo(master, arg);
5314  break;
5315  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
5317  break;
5318  case EC_IOCTL_DOMAIN:
5319  ret = ec_ioctl_domain(master, arg);
5320  break;
5321  case EC_IOCTL_DOMAIN_FMMU:
5322  ret = ec_ioctl_domain_fmmu(master, arg);
5323  break;
5324  case EC_IOCTL_DOMAIN_DATA:
5325  ret = ec_ioctl_domain_data(master, arg);
5326  break;
5327  case EC_IOCTL_MASTER_DEBUG:
5328  if (!ctx->writable) {
5329  ret = -EPERM;
5330  break;
5331  }
5332  ret = ec_ioctl_master_debug(master, arg);
5333  break;
5334  case EC_IOCTL_SLAVE_STATE:
5335  if (!ctx->writable) {
5336  ret = -EPERM;
5337  break;
5338  }
5339  ret = ec_ioctl_slave_state(master, arg);
5340  break;
5341  case EC_IOCTL_SLAVE_SDO:
5342  ret = ec_ioctl_slave_sdo(master, arg);
5343  break;
5344  case EC_IOCTL_SLAVE_SDO_ENTRY:
5345  ret = ec_ioctl_slave_sdo_entry(master, arg);
5346  break;
5347  case EC_IOCTL_SLAVE_SDO_UPLOAD:
5348  if (!ctx->writable) {
5349  ret = -EPERM;
5350  break;
5351  }
5352  ret = ec_ioctl_slave_sdo_upload(master, arg);
5353  break;
5354  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
5355  if (!ctx->writable) {
5356  ret = -EPERM;
5357  break;
5358  }
5359  ret = ec_ioctl_slave_sdo_download(master, arg);
5360  break;
5361  case EC_IOCTL_SLAVE_SII_READ:
5362  ret = ec_ioctl_slave_sii_read(master, arg);
5363  break;
5364  case EC_IOCTL_SLAVE_SII_WRITE:
5365  if (!ctx->writable) {
5366  ret = -EPERM;
5367  break;
5368  }
5369  ret = ec_ioctl_slave_sii_write(master, arg);
5370  break;
5371  case EC_IOCTL_SLAVE_REG_READ:
5372  if (!ctx->writable) {
5373  ret = -EPERM;
5374  break;
5375  }
5376  ret = ec_ioctl_slave_reg_read(master, arg);
5377  break;
5378  case EC_IOCTL_SLAVE_REG_WRITE:
5379  if (!ctx->writable) {
5380  ret = -EPERM;
5381  break;
5382  }
5383  ret = ec_ioctl_slave_reg_write(master, arg);
5384  break;
5385  case EC_IOCTL_SLAVE_FOE_READ:
5386  if (!ctx->writable) {
5387  ret = -EPERM;
5388  break;
5389  }
5390  ret = ec_ioctl_slave_foe_read(master, arg);
5391  break;
5392  case EC_IOCTL_SLAVE_FOE_WRITE:
5393  if (!ctx->writable) {
5394  ret = -EPERM;
5395  break;
5396  }
5397  ret = ec_ioctl_slave_foe_write(master, arg);
5398  break;
5399  case EC_IOCTL_SLAVE_SOE_READ:
5400  if (!ctx->writable) {
5401  ret = -EPERM;
5402  break;
5403  }
5404  ret = ec_ioctl_slave_soe_read(master, arg);
5405  break;
5406  case EC_IOCTL_SLAVE_SOE_WRITE:
5407  if (!ctx->writable) {
5408  ret = -EPERM;
5409  break;
5410  }
5411  ret = ec_ioctl_slave_soe_write(master, arg);
5412  break;
5413 #ifdef EC_EOE
5414  case EC_IOCTL_SLAVE_EOE_IP_PARAM:
5415  if (!ctx->writable) {
5416  ret = -EPERM;
5417  break;
5418  }
5419  ret = ec_ioctl_slave_eoe_ip_param(master, arg);
5420  break;
5421 #endif
5422  case EC_IOCTL_CONFIG:
5423  ret = ec_ioctl_config(master, arg);
5424  break;
5425  case EC_IOCTL_CONFIG_PDO:
5426  ret = ec_ioctl_config_pdo(master, arg);
5427  break;
5428  case EC_IOCTL_CONFIG_PDO_ENTRY:
5429  ret = ec_ioctl_config_pdo_entry(master, arg);
5430  break;
5431  case EC_IOCTL_CONFIG_SDO:
5432  ret = ec_ioctl_config_sdo(master, arg);
5433  break;
5434  case EC_IOCTL_CONFIG_IDN:
5435  ret = ec_ioctl_config_idn(master, arg);
5436  break;
5437  case EC_IOCTL_CONFIG_FLAG:
5438  ret = ec_ioctl_config_flag(master, arg);
5439  break;
5440 #ifdef EC_EOE
5441  case EC_IOCTL_CONFIG_EOE_IP_PARAM:
5442  ret = ec_ioctl_config_ip(master, arg);
5443  break;
5444  case EC_IOCTL_EOE_HANDLER:
5445  ret = ec_ioctl_eoe_handler(master, arg);
5446  break;
5447 #endif
5448 
5449  /* Application interface */
5450 
5451  case EC_IOCTL_REQUEST:
5452  if (!ctx->writable) {
5453  ret = -EPERM;
5454  break;
5455  }
5456  ret = ec_ioctl_request(master, arg, ctx);
5457  break;
5458  case EC_IOCTL_CREATE_DOMAIN:
5459  if (!ctx->writable) {
5460  ret = -EPERM;
5461  break;
5462  }
5463  ret = ec_ioctl_create_domain(master, arg, ctx);
5464  break;
5465  case EC_IOCTL_CREATE_SLAVE_CONFIG:
5466  if (!ctx->writable) {
5467  ret = -EPERM;
5468  break;
5469  }
5470  ret = ec_ioctl_create_slave_config(master, arg, ctx);
5471  break;
5472  case EC_IOCTL_SELECT_REF_CLOCK:
5473  if (!ctx->writable) {
5474  ret = -EPERM;
5475  break;
5476  }
5477  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
5478  break;
5479  case EC_IOCTL_ACTIVATE:
5480  if (!ctx->writable) {
5481  ret = -EPERM;
5482  break;
5483  }
5484  ret = ec_ioctl_activate(master, arg, ctx);
5485  break;
5486  case EC_IOCTL_DEACTIVATE:
5487  if (!ctx->writable) {
5488  ret = -EPERM;
5489  break;
5490  }
5491  ret = ec_ioctl_deactivate(master, arg, ctx);
5492  break;
5493  case EC_IOCTL_SC_SYNC:
5494  if (!ctx->writable) {
5495  ret = -EPERM;
5496  break;
5497  }
5498  ret = ec_ioctl_sc_sync(master, arg, ctx);
5499  break;
5500  case EC_IOCTL_SC_WATCHDOG:
5501  if (!ctx->writable) {
5502  ret = -EPERM;
5503  break;
5504  }
5505  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
5506  break;
5507  case EC_IOCTL_SC_PDO_MODE:
5508  if (!ctx->writable) {
5509  ret = -EPERM;
5510  break;
5511  }
5512  ret = ec_ioctl_sc_pdo_mode(master, arg, ctx);
5513  break;
5514  case EC_IOCTL_SC_ADD_PDO:
5515  if (!ctx->writable) {
5516  ret = -EPERM;
5517  break;
5518  }
5519  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
5520  break;
5521  case EC_IOCTL_SC_CLEAR_PDOS:
5522  if (!ctx->writable) {
5523  ret = -EPERM;
5524  break;
5525  }
5526  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
5527  break;
5528  case EC_IOCTL_SC_ADD_ENTRY:
5529  if (!ctx->writable) {
5530  ret = -EPERM;
5531  break;
5532  }
5533  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
5534  break;
5535  case EC_IOCTL_SC_CLEAR_ENTRIES:
5536  if (!ctx->writable) {
5537  ret = -EPERM;
5538  break;
5539  }
5540  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
5541  break;
5542  case EC_IOCTL_SC_REG_PDO_ENTRY:
5543  if (!ctx->writable) {
5544  ret = -EPERM;
5545  break;
5546  }
5547  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
5548  break;
5549  case EC_IOCTL_SC_REG_PDO_POS:
5550  if (!ctx->writable) {
5551  ret = -EPERM;
5552  break;
5553  }
5554  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
5555  break;
5556  case EC_IOCTL_SC_DC:
5557  if (!ctx->writable) {
5558  ret = -EPERM;
5559  break;
5560  }
5561  ret = ec_ioctl_sc_dc(master, arg, ctx);
5562  break;
5563  case EC_IOCTL_SC_SDO:
5564  if (!ctx->writable) {
5565  ret = -EPERM;
5566  break;
5567  }
5568  ret = ec_ioctl_sc_sdo(master, arg, ctx);
5569  break;
5570  case EC_IOCTL_SC_EMERG_SIZE:
5571  if (!ctx->writable) {
5572  ret = -EPERM;
5573  break;
5574  }
5575  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
5576  break;
5577  case EC_IOCTL_SC_SDO_REQUEST:
5578  if (!ctx->writable) {
5579  ret = -EPERM;
5580  break;
5581  }
5582  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
5583  break;
5584  case EC_IOCTL_SC_SOE_REQUEST:
5585  if (!ctx->writable) {
5586  ret = -EPERM;
5587  break;
5588  }
5589  ret = ec_ioctl_sc_create_soe_request(master, arg, ctx);
5590  break;
5591  case EC_IOCTL_SC_REG_REQUEST:
5592  if (!ctx->writable) {
5593  ret = -EPERM;
5594  break;
5595  }
5596  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
5597  break;
5598  case EC_IOCTL_SC_VOE:
5599  if (!ctx->writable) {
5600  ret = -EPERM;
5601  break;
5602  }
5603  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
5604  break;
5605  case EC_IOCTL_SC_IDN:
5606  if (!ctx->writable) {
5607  ret = -EPERM;
5608  break;
5609  }
5610  ret = ec_ioctl_sc_idn(master, arg, ctx);
5611  break;
5612  case EC_IOCTL_SC_FLAG:
5613  if (!ctx->writable) {
5614  ret = -EPERM;
5615  break;
5616  }
5617  ret = ec_ioctl_sc_flag(master, arg, ctx);
5618  break;
5619  case EC_IOCTL_SC_STATE_TIMEOUT:
5620  if (!ctx->writable) {
5621  ret = -EPERM;
5622  break;
5623  }
5624  ret = ec_ioctl_sc_state_timeout(master, arg, ctx);
5625  break;
5626 #ifdef EC_EOE
5627  case EC_IOCTL_SC_EOE_IP_PARAM:
5628  if (!ctx->writable) {
5629  ret = -EPERM;
5630  break;
5631  }
5632  ret = ec_ioctl_sc_ip(master, arg, ctx);
5633  break;
5634 #endif
5635  case EC_IOCTL_DOMAIN_SIZE:
5636  ret = ec_ioctl_domain_size(master, arg, ctx);
5637  break;
5638  case EC_IOCTL_DOMAIN_OFFSET:
5639  ret = ec_ioctl_domain_offset(master, arg, ctx);
5640  break;
5641  case EC_IOCTL_SET_SEND_INTERVAL:
5642  if (!ctx->writable) {
5643  ret = -EPERM;
5644  break;
5645  }
5646  ret = ec_ioctl_set_send_interval(master, arg, ctx);
5647  break;
5648  case EC_IOCTL_SII_CACHING:
5649  if (!ctx->writable) {
5650  ret = -EPERM;
5651  break;
5652  }
5653  ret = ec_ioctl_sii_caching(master, arg, ctx);
5654  break;
5655  default:
5656 #ifdef EC_IOCTL_RTDM
5657  ret = ec_ioctl_both(master, ctx, cmd, arg);
5658 #else
5659  ret = -ENOTTY;
5660 #endif
5661  break;
5662  }
5663 
5664 #if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM)
5665  b = get_cycles();
5666  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5667  if (t > 50) {
5668  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5669  _IOC_NR(cmd), t);
5670  }
5671 #endif
5672 
5673  return ret;
5674 }
5675 
5676 /****************************************************************************/
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:154
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:49
const ec_slave_config_t * sc
EtherCAT slave config.
Definition: fmmu_config.h:40
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: ioctl.c:492
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:48
static ATTRIBUTES int ec_ioctl_sdo_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request&#39;s timeout.
Definition: ioctl.c:3725
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:509
uint16_t offset
SII word offset.
Definition: fsm_master.h:48
ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req)
Get the current state of the SDO request.
Definition: sdo_request.c:213
uint16_t ring_position
Ring position.
Definition: slave.h:176
uint32_t revision_number
Revision number.
Definition: slave.h:130
const ec_sdo_entry_t * ec_sdo_get_entry_const(const ec_sdo_t *sdo, uint8_t subindex)
Get an SDO entry from an SDO via its subindex.
Definition: sdo.c:108
static ATTRIBUTES int ec_ioctl_sc_emerg_clear(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clear the emergency ring.
Definition: ioctl.c:2979
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:931
int ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2584
uint16_t boot_rx_mailbox_offset
Bootstrap rx mailbox address.
Definition: slave.h:132
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:110
ec_sii_t sii
Extracted SII data.
Definition: slave.h:217
size_t word_count
Size of the SII contents in words.
Definition: sii_page.h:61
ec_reg_request_t * ec_slave_config_find_reg_request(ec_slave_config_t *sc, unsigned int pos)
Finds a register handler via its position in the list.
Definition: slave_config.c:597
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: ioctl.c:665
int ecrt_master_sii_caching(ec_master_t *master, ec_sii_caching_fields_t fields)
Set the SII caching method.
Definition: master.c:3519
static ATTRIBUTES int ec_ioctl_sdo_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO write operation.
Definition: ioctl.c:3844
int ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:232
int ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, uint8_t sync_index)
Clear a sync manager&#39;s PDO assignment.
Definition: slave_config.c:776
int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx, ec_master_link_state_t *state)
Reads the current state of a redundant link.
Definition: master.c:2992
int ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:153
FMMU configuration.
Definition: fmmu_config.h:38
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: ioctl.c:1413
static ATTRIBUTES int ec_ioctl_master_link_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the link state.
Definition: ioctl.c:2160
u64 tx_count
Number of frames sent.
Definition: master.h:149
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave&#39;s registers.
Definition: ioctl.c:1061
struct list_head sii_requests
SII write requests.
Definition: master.h:300
static ATTRIBUTES int ec_ioctl_domain_offset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain&#39;s offset in the total process data.
Definition: ioctl.c:3553
static ATTRIBUTES int ec_ioctl_create_slave_config(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a slave configuration.
Definition: ioctl.c:1862
const ec_soe_request_t * ec_slave_config_get_idn_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an IDN configuration via its position in the list.
Definition: slave_config.c:487
ec_sdo_request_t * ecrt_slave_config_create_sdo_request_err(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
Same as ecrt_slave_config_create_sdo_request(), but with ERR_PTR() return value.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:99
CANopen SDO entry.
Definition: sdo_entry.h:46
static ATTRIBUTES int ec_ioctl_reg_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register read operation.
Definition: ioctl.c:4316
int ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2654
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: ioctl.c:829
size_t data_size
Size of the process data.
Definition: domain.h:53
int ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
Set the timeout for an SDO request.
Definition: sdo_request.c:191
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:77
static ATTRIBUTES int ec_ioctl_voe_send_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the VoE send header.
Definition: ioctl.c:4358
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:166
static long ec_ioctl_nrt(ec_master_t *master, ec_ioctl_context_t *ctx, unsigned int cmd, void *arg)
ioctl() function to use.
Definition: ioctl.c:5289
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:51
ec_slave_config_t * ec_master_get_config(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:1966
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:100
int ecrt_soe_request_timeout(ec_soe_request_t *req, uint32_t timeout)
Set the timeout for an SoE request.
Definition: soe_request.c:290
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:180
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:95
const ec_flag_t * ec_slave_config_get_flag_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds a flag via its position in the list.
Definition: slave_config.c:531
ec_soe_request_t * ec_slave_config_find_soe_request(ec_slave_config_t *sc, unsigned int pos)
Finds a SoE request via its position in the list.
Definition: slave_config.c:575
int ecrt_slave_config_watchdog(ec_slave_config_t *sc, uint16_t divider, uint16_t intervals)
Configure a slave&#39;s watchdog times.
Definition: slave_config.c:709
CANopen SDO request.
Definition: sdo_request.h:40
uint8_t * ecrt_sdo_request_data(const ec_sdo_request_t *req)
Access to the SDO request&#39;s data.
Definition: sdo_request.c:199
ec_slave_state_t current_state
Current application state.
Definition: slave.h:185
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave via complete access.
Definition: master.c:3181
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:326
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: ioctl.c:3587
int ecrt_slave_config_reg_pdo_entry(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry for process data exchange in a domain.
Definition: slave_config.c:924
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
size_t nwords
Number of words.
Definition: fsm_master.h:49
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:55
uint16_t address
Register address.
Definition: reg_request.h:46
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:51
Register request.
Definition: reg_request.h:40
ec_direction_t dir
Direction.
Definition: soe_request.h:50
static ATTRIBUTES int ec_ioctl_slave_eoe_ip_param(ec_master_t *master, void *arg)
Request EoE IP parameter setting.
Definition: ioctl.c:1728
size_t mem_size
Size of data memory.
Definition: reg_request.h:42
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:185
static ATTRIBUTES int ec_ioctl_reg_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an register request&#39;s state.
Definition: ioctl.c:4224
static ATTRIBUTES int ec_ioctl_reg_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register write operation.
Definition: ioctl.c:4269
uint32_t product_code
Slave product code.
Definition: slave_config.h:119
static ATTRIBUTES int ec_ioctl_ref_clock_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the system time of the reference clock.
Definition: ioctl.c:2299
ec_slave_port_link_t link
Port link status.
Definition: slave.h:113
int ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3040
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:599
uint16_t position
Index after alias.
Definition: slave_config.h:116
size_t mem_size
Size of SDO data memory.
Definition: sdo_request.h:45
int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, const uint8_t *data, size_t size)
Add an SDO configuration.
int ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:679
int ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:220
const ec_slave_t * ec_master_find_slave_const(const ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1877
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:75
void ecrt_master_callbacks(ec_master_t *master, void(*send_cb)(void *), void(*receive_cb)(void *), void *cb_data)
Sets the locking callbacks.
Definition: master.c:2954
const ec_sdo_request_t * ec_slave_config_get_sdo_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an SDO configuration via its position in the list.
Definition: slave_config.c:443
int ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:173
int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index, ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
Configure a sync manager.
Definition: slave_config.c:682
uint32_t serial_number
Serial number.
Definition: slave.h:131
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:106
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:112
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:153
char * order
Order number.
Definition: slave.h:150
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:40
const ec_domain_t * ec_master_find_domain_const(const ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:2045
const ec_eoe_t * ec_master_get_eoe_handler_const(const ec_master_t *master, uint16_t index)
Get an EoE handler via its position in the list.
Definition: master.c:2084
uint16_t index
SDO index.
Definition: sdo_request.h:42
unsigned int scan_index
Index of slave currently scanned.
Definition: master.h:242
static ATTRIBUTES int ec_ioctl_sync_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the slave clocks.
Definition: ioctl.c:2273
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:230
static ATTRIBUTES int ec_ioctl_sc_state_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an AL state transition timeout.
Definition: ioctl.c:3418
unsigned int data_size
Covered PDO size.
Definition: fmmu_config.h:45
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:301
uint16_t alias
Slave alias.
Definition: slave_config.h:115
static ATTRIBUTES int ec_ioctl_sc_create_reg_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a register request.
Definition: ioctl.c:3161
struct list_head domains
List of domains.
Definition: master.h:227
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: ioctl.c:4846
ec_eoe_request_t eoe_ip_param_request
EoE IP parameters.
Definition: slave_config.h:153
int ecrt_slave_config_emerg_overruns(const ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
struct list_head reg_requests
Register access requests.
Definition: slave.h:224
int ecrt_soe_request_idn(ec_soe_request_t *req, uint8_t drive_no, uint16_t idn)
Set the request&#39;s drive and Sercos ID numbers.
Definition: soe_request.c:280
int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, ec_al_state_t state, const uint8_t *data, size_t size)
Add an SoE IDN configuration.
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: ioctl.c:749
CANopen SDO.
Definition: sdo.h:41
uint16_t index
SDO index.
Definition: sdo.h:44
int ecrt_slave_config_state_timeout(ec_slave_config_t *sc, ec_al_state_t from, ec_al_state_t to, unsigned int timeout_ms)
Sets the application-layer state transition timeout in ms.
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:44
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: ioctl.c:1292
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:155
ec_slave_t * ec_master_find_slave(ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1861
static ATTRIBUTES int ec_ioctl_sc_add_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add an entry to a PDO&#39;s mapping.
Definition: ioctl.c:2631
uint8_t link_state
device link state
Definition: device.h:85
int ecrt_slave_config_eoe_dns_address(ec_slave_config_t *sc, struct in_addr dns_address)
Sets the IPv4 address of the DNS server for Ethernet-over-EtherCAT (EoE) operation.
unsigned int ec_pdo_list_count(const ec_pdo_list_t *pl)
Get the number of PDOs in the list.
Definition: pdo_list.c:303
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:540
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:135
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:201
uint8_t * ecrt_reg_request_data(const ec_reg_request_t *reg)
Access to the register request&#39;s data.
Definition: reg_request.c:78
uint32_t result
FoE request abort code.
Definition: foe_request.h:60
int ecrt_slave_config_reg_pdo_entry_pos(ec_slave_config_t *sc, uint8_t sync_index, unsigned int pdo_pos, unsigned int entry_pos, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry using its position.
Definition: slave_config.c:979
u64 rx_count
Number of frames received.
Definition: device.h:103
#define EC_MAX_HOSTNAME_SIZE
Maximum hostname size.
Definition: globals.h:116
size_t data_size
Size of SDO data.
Definition: soe_request.h:47
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:304
void ec_eoe_request_init(ec_eoe_request_t *req)
EoE request constructor.
Definition: eoe_request.c:38
ec_pdo_mode_t pdo_config_mode
Whether/how to read resp.
Definition: slave_config.h:129
void ecrt_domain_external_memory(ec_domain_t *domain, uint8_t *mem)
Provide external memory to store the domain&#39;s process data.
Definition: domain.c:433
int ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: ioctl.c:1348
unsigned int sync_count
Number of sync managers.
Definition: slave.h:159
struct list_head list
List head.
Definition: fsm_master.h:46
SII write request.
Definition: fsm_master.h:45
ec_domain_t * ecrt_master_create_domain_err(ec_master_t *master)
Same as ecrt_master_create_domain(), but with ERR_PTR() return value.
Definition: master.c:2463
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:103
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, const uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3345
char * key
Flag key (null-terminated ASCII string.
Definition: flag.h:40
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:137
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: ioctl.c:4662
const ec_slave_config_t * ec_master_get_config_const(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:1981
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:138
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:115
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition: soe_request.h:44
static ATTRIBUTES int ec_ioctl_master_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the master state.
Definition: ioctl.c:2135
ec_direction_t dir
Direction.
Definition: sdo_request.h:52
PDO entry description.
Definition: pdo_entry.h:40
static ATTRIBUTES int ec_ioctl_sc_emerg_overruns(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the number of emergency overruns.
Definition: ioctl.c:3012
EtherCAT master structure.
uint8_t * data
Memory for the process data.
Definition: domain.h:54
int ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master&#39;s datagram queue.
Definition: domain.c:648
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:141
int ecrt_master_reference_clock_time(const ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Definition: master.c:3020
uint16_t index
PDO index.
Definition: pdo.h:43
static ATTRIBUTES int ec_ioctl_soe_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SoE request&#39;s state.
Definition: ioctl.c:4005
static ATTRIBUTES int ec_ioctl_slave_foe_write(ec_master_t *master, void *arg)
Write a file to a slave via FoE.
Definition: ioctl.c:4758
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:100
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: ioctl.c:648
uint16_t boot_tx_mailbox_offset
Bootstrap tx mailbox address.
Definition: slave.h:134
const ec_pdo_entry_t * ec_pdo_find_entry_by_pos_const(const ec_pdo_t *pdo, unsigned int pos)
Finds a PDO entry via its position in the list.
Definition: pdo.c:271
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
static ATTRIBUTES int ec_ioctl_sc_create_sdo_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SDO request.
Definition: ioctl.c:3057
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:47
uint16_t index
PDO entry index.
Definition: pdo_entry.h:42
EtherCAT slave.
Definition: slave.h:169
struct semaphore master_sem
Master semaphore.
Definition: master.h:198
static ATTRIBUTES int ec_ioctl_sdo_request_index(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request&#39;s SDO index and subindex.
Definition: ioctl.c:3689
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition: pdo.c:249
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:44
int ecrt_master_sync_reference_clock_to(ec_master_t *master, uint64_t sync_time)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3053
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:73
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:45
static ATTRIBUTES int ec_ioctl_sdo_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO read operation.
Definition: ioctl.c:3808
uint8_t * ecrt_soe_request_data(const ec_soe_request_t *req)
Access to the SoE request&#39;s data.
Definition: soe_request.c:298
struct irq_work sc_reset_work_kicker
NMI-Safe kicker to trigger reset task above.
Definition: master.h:308
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: ioctl.c:537
ec_voe_handler_t * ecrt_slave_config_create_voe_handler_err(ec_slave_config_t *sc, size_t size)
Same as ecrt_slave_config_create_voe_handler(), but with ERR_PTR() return value.
Master state.
Definition: ecrt.h:346
static ATTRIBUTES int ec_ioctl_sdo_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SDO request&#39;s state.
Definition: ioctl.c:3763
int ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex.
Definition: sdo_request.c:181
char * description
Description.
Definition: sdo_entry.h:54
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2109
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: ioctl.c:48
Slave configuration state.
Definition: ecrt.h:394
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:160
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:168
Ethernet over EtherCAT (EoE)
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:136
ec_pdo_mode_t pdo_assign_mode
Whether/how to read resp.
Definition: slave_config.h:126
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:208
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: ioctl.c:1813
void(* state)(ec_voe_handler_t *)
State function.
Definition: voe_handler.h:51
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:147
static ATTRIBUTES int ec_ioctl_app_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the master DC application time.
Definition: ioctl.c:2193
ec_master_phase_t phase
Master phase.
Definition: master.h:212
Domain state.
Definition: ecrt.h:512
static ATTRIBUTES int ec_ioctl_sc_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the slave configuration&#39;s state.
Definition: ioctl.c:3265
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: ioctl.c:589
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:44
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:42
Slave configutation feature flag.
Definition: flag.h:38
static ATTRIBUTES int ec_ioctl_sc_watchdog(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a slave&#39;s watchdogs.
Definition: ioctl.c:2473
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain&#39;s process data.
Definition: domain.c:426
struct semaphore device_sem
Device semaphore.
Definition: master.h:207
static ATTRIBUTES int ec_ioctl_sc_add_pdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add a PDO to the assignment.
Definition: ioctl.c:2563
PDO description.
Definition: pdo.h:41
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:120
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:144
EtherCAT device.
Definition: device.h:78
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:140
ec_domain_t * ec_master_find_domain(ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:2030
int ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:3008
static ATTRIBUTES int ec_ioctl_sc_dc(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the DC AssignActivate word and the sync signal times.
Definition: ioctl.c:2797
ec_reg_request_t * ecrt_slave_config_create_reg_request_err(ec_slave_config_t *sc, size_t size)
Same as ecrt_slave_config_create_reg_request(), but with ERR_PTR() return value.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:69
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:1996
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:204
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:45
Sync manager.
Definition: sync.h:39
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: ioctl.c:634
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:136
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:202
static ATTRIBUTES int ec_ioctl_sc_flag(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures a feature flag.
Definition: ioctl.c:3361
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:170
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:208
struct rt_mutex io_mutex
Mutex used in IDLE and OP phase.
Definition: master.h:289
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:221
unsigned int scan_busy
Current scan state.
Definition: master.h:241
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:41
int ecrt_voe_handler_received_header(const ec_voe_handler_t *voe, uint32_t *vendor_id, uint16_t *vendor_type)
Reads the header data of a received VoE message.
Definition: voe_handler.c:125
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:146
char * name
SDO name.
Definition: sdo.h:46
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:140
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:163
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave&#39;s SII.
Definition: ioctl.c:924
int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size, size_t *result_size, uint16_t *error_code)
Executes an SoE read request.
Definition: master.c:3421
unsigned int index
Index (just a number).
Definition: domain.h:50
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:118
Main device.
Definition: globals.h:204
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:206
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: ioctl.c:2083
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: ioctl.c:223
long ec_ioctl(ec_master_t *master, ec_ioctl_context_t *ctx, unsigned int cmd, void *arg)
Called when an ioctl() command is issued.
Definition: ioctl.c:5043
int ecrt_reg_request_write(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule an register write operation.
Definition: reg_request.c:92
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:123
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:112
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:86
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: ioctl.c:1477
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: ioctl.c:1231
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:41
unsigned int active
Master has been activated.
Definition: master.h:213
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: ioctl.c:2051
ec_master_t * master
Master owning the slave.
Definition: slave.h:171
struct list_head soe_requests
List of SoE requests.
Definition: slave_config.h:145
size_t ecrt_soe_request_data_size(const ec_soe_request_t *req)
Returns the current IDN data size.
Definition: soe_request.c:305
static ATTRIBUTES int ec_ioctl_voe_read_nosync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation without sending a sync message first.
Definition: ioctl.c:4492
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:421
const ec_sdo_t * ec_slave_get_sdo_by_pos_const(const ec_slave_t *slave, uint16_t sdo_position)
Get an SDO from the dictionary, given its position in the list.
Definition: slave.c:909
static ATTRIBUTES int ec_ioctl_master(ec_master_t *master, void *arg)
Get master information.
Definition: ioctl.c:123
ec_request_state_t ecrt_soe_request_state(const ec_soe_request_t *req)
Get the current state of the SoE request.
Definition: soe_request.c:312
static ATTRIBUTES int ec_ioctl_reg_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read register data.
Definition: ioctl.c:4177
u64 rx_bytes
Number of bytes received.
Definition: device.h:108
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:205
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc, uint8_t sync_index, uint16_t pdo_index)
Add a PDO to a sync manager&#39;s PDO assignment.
Definition: slave_config.c:746
int ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
ec_request_state_t ecrt_reg_request_state(const ec_reg_request_t *reg)
Get the current state of the register request.
Definition: reg_request.c:85
int ecrt_slave_config_eoe_ip_address(ec_slave_config_t *sc, struct in_addr ip_address)
Sets the IP address for Ethernet-over-EtherCAT (EoE) operation.
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:52
static ATTRIBUTES int ec_ioctl_sc_sync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a sync manager.
Definition: ioctl.c:2420
u64 tx_count
Number of frames sent.
Definition: device.h:101
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:331
static ATTRIBUTES int ec_ioctl_sync_ref_to(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: ioctl.c:2243
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave&#39;s SII.
Definition: ioctl.c:973
static ATTRIBUTES int ec_ioctl_sync_mon_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the sync monitoring datagram.
Definition: ioctl.c:2330
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:74
int ecrt_master_select_reference_clock(ec_master_t *master, ec_slave_config_t *sc)
Selects the reference clock for distributed clocks.
Definition: master.c:2845
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:43
uint8_t control_register
Control register value.
Definition: sync.h:43
static ATTRIBUTES int ec_ioctl_sync_ref(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: ioctl.c:2217
Values read by the master.
Definition: ecrt.h:525
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:39
int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address)
Memory-map process data to user space.
Definition: rtdm.c:238
int ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:3082
uint16_t data_type
Data type.
Definition: sdo_entry.h:50
struct list_head configs
List of slave configurations.
Definition: master.h:226
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:133
unsigned int opened
net_device is opened
Definition: ethernet.h:83
Access rights in OP.
Definition: globals.h:197
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: ioctl.c:1838
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: ioctl.c:2382
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:121
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE SDO request via its position in the list.
Definition: slave_config.c:553
static ATTRIBUTES int ec_ioctl_sc_create_soe_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SoE request.
Definition: ioctl.c:3108
static ATTRIBUTES int ec_ioctl_voe_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE write operation.
Definition: ioctl.c:4528
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3614
size_t data_size
Size of FoE data.
Definition: foe_request.h:46
static ATTRIBUTES int ec_ioctl_voe_rec_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the received VoE header.
Definition: ioctl.c:4403
Access rights in SAFEOP.
Definition: globals.h:196
static ATTRIBUTES int ec_ioctl_config_flag(ec_master_t *master, void *arg)
Get slave configuration feature flag information.
Definition: ioctl.c:1541
static ATTRIBUTES int ec_ioctl_soe_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SoE IDN write operation.
Definition: ioctl.c:4088
int ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc, uint16_t pdo_index)
Clear the mapping of a given PDO.
Definition: slave_config.c:832
Ethernet-over-EtherCAT set IP parameter request.
Definition: eoe_request.h:41
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: ioctl.c:2109
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
Definition: domain.h:60
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:59
const ec_sdo_t * ec_slave_get_sdo_const(const ec_slave_t *slave, uint16_t index)
Get an SDO from the dictionary.
Definition: slave.c:887
uint32_t logical_base_address
Logical offset address of the process data.
Definition: domain.h:56
static ATTRIBUTES int ec_ioctl_sc_emerg_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the emergency ring buffer size.
Definition: ioctl.c:2897
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:52
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:40
struct net_device_stats stats
device statistics
Definition: ethernet.h:82
char * name
PDO name.
Definition: pdo.h:45
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:43
FoE request.
Definition: foe_request.h:42
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:62
static ATTRIBUTES int ec_ioctl_slave_sync_pdo_entry(ec_master_t *master, void *arg)
Get slave sync manager PDO entry information.
Definition: ioctl.c:423
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:465
u64 tx_errors
Number of transmit errors.
Definition: device.h:111
uint16_t effective_alias
Effective alias address.
Definition: slave.h:178
char * name
entry name
Definition: pdo_entry.h:44
static ATTRIBUTES int ec_ioctl_sc_pdo_mode(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a slave&#39;s PDO handling mode.
Definition: ioctl.c:2518
unsigned int sii_caching
SII caching mode.
Definition: master.h:279
size_t data_size
Size of SDO data.
Definition: sdo_request.h:46
ec_internal_request_state_t state
Request state.
Definition: eoe_request.h:43
ec_soe_request_t * ecrt_slave_config_create_soe_request_err(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
Same as ecrt_slave_config_create_soe_request(), but with ERR_PTR() return value.
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: ioctl.c:311
struct list_head foe_requests
FoE requests.
Definition: slave.h:225
ec_direction_t dir
Direction.
Definition: voe_handler.h:48
static ATTRIBUTES int ec_ioctl_voe_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation.
Definition: ioctl.c:4456
u64 tx_bytes
Number of bytes sent.
Definition: master.h:154
static ATTRIBUTES int ec_ioctl_sc_create_voe_handler(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a VoE handler.
Definition: ioctl.c:3215
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2062
int ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain&#39;s datagrams.
Definition: domain.c:457
static ATTRIBUTES int ec_ioctl_module(void *arg, ec_ioctl_context_t *ctx)
Get module information.
Definition: ioctl.c:101
uint8_t enable
Enable bit.
Definition: sync.h:44
int ecrt_slave_config_eoe_default_gateway(ec_slave_config_t *sc, struct in_addr gateway_address)
Sets the gateway address for Ethernet-over-EtherCAT (EoE) operation.
static ATTRIBUTES int ec_ioctl_sc_clear_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the PDO assignment.
Definition: ioctl.c:2597
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:43
Vendor specific over EtherCAT protocol handler.
static long ec_ioctl_both(ec_master_t *master, ec_ioctl_context_t *ctx, unsigned int cmd, void *arg)
Called when an ioctl() command is issued.
Definition: ioctl.c:4959
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:133
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:294
static ATTRIBUTES int ec_ioctl_soe_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SoE IDN data.
Definition: ioctl.c:4137
static ATTRIBUTES int ec_ioctl_config_ip(ec_master_t *master, void *arg)
Get configured EoE IP parameters for a given slave configuration.
Definition: ioctl.c:1606
uint16_t * words
Complete SII image.
Definition: sii_page.h:60
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:3102
uint8_t * ecrt_voe_handler_data(const ec_voe_handler_t *voe)
Access to the VoE handler&#39;s data.
Definition: voe_handler.c:139
int ecrt_slave_config_emerg_pop(ec_slave_config_t *sc, uint8_t *target)
Read and remove one record from the CoE emergency ring buffer.
int ecrt_slave_config_complete_sdo(ec_slave_config_t *sc, uint16_t index, const uint8_t *data, size_t size)
Add configuration data for a complete SDO.
static ATTRIBUTES int ec_ioctl_soe_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SoE IDN read operation.
Definition: ioctl.c:4052
Access rights in PREOP.
Definition: globals.h:195
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:114
ec_direction_t dir
Direction.
Definition: reg_request.h:44
static ATTRIBUTES int ec_ioctl_sii_caching(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set SII caching method.
Definition: ioctl.c:2403
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:2033
ec_sii_page_t sii_page
The SII contents, either fetched or taken from the cache.
Definition: slave.h:212
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:118
uint8_t drive_no
Drive number.
Definition: soe_request.h:42
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:115
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:47
int ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id, uint16_t vendor_type)
Sets the VoE header for future send operations.
Definition: voe_handler.c:115
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2838
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:584
int ecrt_slave_config_eoe_hostname(ec_slave_config_t *sc, const char *name)
Sets the host name for Ethernet-over-EtherCAT (EoE) operation.
char * image
Image name.
Definition: slave.h:149
int ecrt_slave_config_pdo_mode(ec_slave_config_t *sc, ec_pdo_mode_t assign_mode, ec_pdo_mode_t config_mode)
Selects how a slave&#39;s PDO assignment and PDO configuration are read from resp.
Definition: slave_config.c:722
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:45
int32_t value
Flag value (meaning depends on key).
Definition: flag.h:41
static ATTRIBUTES int ec_ioctl_soe_request_index(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SoE request&#39;s drive number and IDN.
Definition: ioctl.c:3933
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry.
Definition: ioctl.c:2700
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1949
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:229
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
Definition: slave.c:308
uint16_t physical_start_address
Physical start address.
Definition: sync.h:41
static ATTRIBUTES int ec_ioctl_domain_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the domain state.
Definition: ioctl.c:3647
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:171
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:203
static ATTRIBUTES int ec_ioctl_sc_ip(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures EoE IP parameters.
Definition: ioctl.c:3460
u64 rx_count
Number of frames received.
Definition: master.h:151
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: ioctl.c:700
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2510
struct work_struct sc_reset_work
Task to reset slave configuration.
Definition: master.h:306
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:211
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:65
char * group
Group name.
Definition: slave.h:148
int ecrt_soe_request_read(ec_soe_request_t *req)
Schedule an SoE IDN read operation.
Definition: soe_request.c:319
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:146
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:184
static ATTRIBUTES int ec_ioctl_soe_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an CoE request&#39;s timeout.
Definition: ioctl.c:3969
EtherCAT slave configuration.
Definition: slave_config.h:111
int ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2702
static ATTRIBUTES int ec_ioctl_sc_emerg_pop(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get an emergency message from the ring.
Definition: ioctl.c:2935
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:61
static ATTRIBUTES int ec_ioctl_domain_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain&#39;s data size.
Definition: ioctl.c:3519
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:81
uint32_t ecrt_master_sync_monitor_process(const ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:3091
EtherCAT master character device IOCTL commands.
static void ec_ioctl_strcpy(char *target, const char *source)
Copies a string to an ioctl structure.
Definition: ioctl.c:82
Request was processed successfully.
Definition: ecrt.h:661
EtherCAT slave configuration structure.
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:55
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:53
ec_slave_config_t * ecrt_master_slave_config_err(ec_master_t *master, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
Same as ecrt_master_slave_config(), but with ERR_PTR() return value.
Definition: master.c:2776
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:172
unsigned int index
Index.
Definition: master.h:188
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:1933
uint16_t default_length
Data length in bytes.
Definition: sync.h:42
static ATTRIBUTES int ec_ioctl_voe_exec(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Executes the VoE state machine.
Definition: ioctl.c:4573
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:129
ec_direction_t dir
FMMU direction.
Definition: fmmu_config.h:43
const ec_pdo_t * ec_pdo_list_find_pdo_by_pos_const(const ec_pdo_list_t *pl, unsigned int pos)
Finds a PDO via its position in the list.
Definition: pdo_list.c:281
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:74
int ecrt_slave_config_eoe_mac_address(ec_slave_config_t *sc, const unsigned char *mac_address)
Sets the link/MAC address for Ethernet-over-EtherCAT (EoE) operation.
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:210
u64 rx_bytes
Number of bytes received.
Definition: master.h:156
int ecrt_soe_request_write(ec_soe_request_t *req)
Schedule an SoE IDN write operation.
Definition: soe_request.c:326
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:311
int ecrt_slave_config_eoe_subnet_mask(ec_slave_config_t *sc, struct in_addr subnet_mask)
Sets the subnet mask for Ethernet-over-EtherCAT (EoE) operation.
int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc, uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex, uint8_t entry_bit_length)
Add a PDO entry to the given PDO&#39;s mapping.
Definition: slave_config.c:795
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:186
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:158
size_t mem_size
Size of SDO data memory.
Definition: soe_request.h:46
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:139
EtherCAT master.
Definition: master.h:187
struct list_head list
List item.
Definition: reg_request.h:41
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:227
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_pos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry by its position.
Definition: ioctl.c:2747
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:43
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:285
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:200
static ATTRIBUTES int ec_ioctl_slave_soe_write(ec_master_t *master, void *arg)
Write an IDN to a slave via SoE.
Definition: ioctl.c:4895
u64 tx_bytes
Number of bytes sent.
Definition: device.h:106
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: ioctl.c:364
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:52
static ATTRIBUTES int ec_ioctl_select_ref_clock(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Select the DC reference clock.
Definition: ioctl.c:1908
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:104
int ecrt_reg_request_read(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule a register read operation.
Definition: reg_request.c:104
struct list_head list
List item.
Definition: eoe_request.h:42
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave&#39;s registers.
Definition: ioctl.c:1143
int ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:3069
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:50
int ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:2968
Sercos-over-EtherCAT request.
Definition: soe_request.h:40
static ATTRIBUTES int ec_ioctl_voe_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reads the received VoE data.
Definition: ioctl.c:4622
char * name
Slave name.
Definition: slave.h:151
void ec_master_set_send_interval(ec_master_t *master, unsigned int send_interval)
Sets the expected interval between calls to ecrt_master_send and calculates the maximum amount of dat...
Definition: master.c:943
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:45
static ATTRIBUTES int ec_ioctl_sdo_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SDO data.
Definition: ioctl.c:3893
EtherCAT domain.
Definition: domain.h:46
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:81
static ATTRIBUTES int ec_ioctl_sync_mon_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Processes the sync monitoring datagram.
Definition: ioctl.c:2356
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: ioctl.c:1674
int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, uint8_t *target, size_t target_size, size_t *result_size, uint32_t *abort_code)
Executes an SDO upload request to read data from a slave.
Definition: master.c:3262
uint32_t vendor_id
Vendor ID.
Definition: slave.h:128
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:47
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:117
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: ioctl.c:875
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:239
ec_voe_handler_t * ec_slave_config_find_voe_handler(ec_slave_config_t *sc, unsigned int pos)
Finds a VoE handler via its position in the list.
Definition: slave_config.c:619
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:49
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: ioctl.c:3307
struct list_head list
List item.
Definition: foe_request.h:43
unsigned int has_general
General category present.
Definition: slave.h:147
unsigned int tx_queued_frames
number of frames in the queue
Definition: ethernet.h:97
static ATTRIBUTES int ec_ioctl_sc_clear_entries(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the mapping of a PDO.
Definition: ioctl.c:2666
int ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
Start a VoE read operation without querying the sync manager status.
Definition: voe_handler.c:163
unsigned int sii_parallel_words
How many SII words the slave can read at once.
Definition: slave.h:214
const ec_fmmu_config_t * ec_domain_find_fmmu(const ec_domain_t *domain, unsigned int pos)
Get a certain FMMU configuration via its position in the list.
Definition: domain.c:349