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  strscpy(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  strscpy(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  // Resolve the config index under master_sem, then release it before
1924  // calling ecrt_master_select_reference_clock(): that function now takes
1925  // master_sem itself (to apply the selection immediately), so holding it
1926  // here would self-deadlock on the non-recursive semaphore.
1927  if (config_index != 0xFFFFFFFF) {
1928  if (down_interruptible(&master->master_sem)) {
1929  ret = -EINTR;
1930  goto out_return;
1931  }
1932  sc = ec_master_get_config(master, config_index);
1933  up(&master->master_sem);
1934  if (!sc) {
1935  ret = -ENOENT;
1936  goto out_return;
1937  }
1938  }
1939 
1941 
1942 out_return:
1943  return ret;
1944 }
1945 
1946 /****************************************************************************/
1947 
1953  ec_master_t *master,
1954  void *arg,
1955  ec_ioctl_context_t *ctx
1956  )
1957 {
1958  ec_ioctl_master_activate_t io;
1959  ec_domain_t *domain;
1960  off_t offset;
1961  int ret;
1962 
1963  if (unlikely(!ctx->requested))
1964  return -EPERM;
1965 
1966  io.process_data = NULL;
1967 
1968  /* Get the sum of the domains' process data sizes. */
1969 
1970  ctx->process_data_size = 0;
1971 
1972  if (down_interruptible(&master->master_sem))
1973  return -EINTR;
1974 
1975  list_for_each_entry(domain, &master->domains, list) {
1976  ctx->process_data_size += ecrt_domain_size(domain);
1977  }
1978 
1979  up(&master->master_sem);
1980 
1981  if (ctx->process_data_size) {
1982  ctx->process_data = vmalloc(ctx->process_data_size);
1983  if (!ctx->process_data) {
1984  ctx->process_data_size = 0;
1985  return -ENOMEM;
1986  }
1987 
1988  /* Set the memory as external process data memory for the
1989  * domains.
1990  */
1991  offset = 0;
1992  list_for_each_entry(domain, &master->domains, list) {
1994  ctx->process_data + offset);
1995  offset += ecrt_domain_size(domain);
1996  }
1997 
1998 #if defined(EC_IOCTL_RTDM) && !defined(EC_RTDM_XENOMAI_V3)
1999  /* RTDM uses a different approach for memory-mapping, which has to be
2000  * initiated by the kernel.
2001  */
2002  ret = ec_rtdm_mmap(ctx, &io.process_data);
2003  if (ret < 0) {
2004  EC_MASTER_ERR(master, "Failed to map process data"
2005  " memory to user space (code %i).\n", ret);
2006  return ret;
2007  }
2008 #endif
2009  }
2010 
2011  io.process_data_size = ctx->process_data_size;
2012 
2013 #ifndef EC_IOCTL_RTDM
2014  /* RTDM does not support locking yet. */
2017 #endif
2018 
2020  if (ret < 0)
2021  return ret;
2022 
2023  if (copy_to_user((void __user *) arg, &io,
2024  sizeof(ec_ioctl_master_activate_t)))
2025  return -EFAULT;
2026 
2027  return 0;
2028 }
2029 
2030 /****************************************************************************/
2031 
2037  ec_master_t *master,
2038  void *arg,
2039  ec_ioctl_context_t *ctx
2040  )
2041 {
2042  if (unlikely(!ctx->requested))
2043  return -EPERM;
2044 
2046 }
2047 
2048 /****************************************************************************/
2049 
2055  ec_master_t *master,
2056  void *arg,
2057  ec_ioctl_context_t *ctx
2058  )
2059 {
2060  size_t send_interval;
2061 
2062  if (unlikely(!ctx->requested)) {
2063  return -EPERM;
2064  }
2065 
2066  if (copy_from_user(&send_interval, (void __user *) arg,
2067  sizeof(send_interval))) {
2068  return -EFAULT;
2069  }
2070 
2071  if (down_interruptible(&master->master_sem))
2072  return -EINTR;
2073 
2074  ec_master_set_send_interval(master, send_interval);
2075 
2076  up(&master->master_sem);
2077  return 0;
2078 }
2079 
2080 /****************************************************************************/
2081 
2087  ec_master_t *master,
2088  void *arg,
2089  ec_ioctl_context_t *ctx
2090  )
2091 {
2092  int ret;
2093 
2094  if (unlikely(!ctx->requested)) {
2095  return -EPERM;
2096  }
2097 
2098  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2099  return -EINTR;
2100 
2101  ret = ecrt_master_send(master);
2102  ec_ioctl_unlock(&master->io_mutex);
2103  return ret;
2104 }
2105 
2106 /****************************************************************************/
2107 
2113  ec_master_t *master,
2114  void *arg,
2115  ec_ioctl_context_t *ctx
2116  )
2117 {
2118  int ret;
2119 
2120  if (unlikely(!ctx->requested)) {
2121  return -EPERM;
2122  }
2123 
2124  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2125  return -EINTR;
2126 
2127  ret = ecrt_master_receive(master);
2128  ec_ioctl_unlock(&master->io_mutex);
2129  return ret;
2130 }
2131 
2132 /****************************************************************************/
2133 
2139  ec_master_t *master,
2140  void *arg,
2141  ec_ioctl_context_t *ctx
2142  )
2143 {
2144  ec_master_state_t data;
2145  int ret;
2146 
2147  ret = ecrt_master_state(master, &data);
2148  if (ret)
2149  return ret;
2150 
2151  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
2152  return -EFAULT;
2153 
2154  return 0;
2155 }
2156 
2157 /****************************************************************************/
2158 
2164  ec_master_t *master,
2165  void *arg,
2166  ec_ioctl_context_t *ctx
2167  )
2168 {
2169  ec_ioctl_link_state_t ioctl;
2170  ec_master_link_state_t state;
2171  int ret;
2172 
2173  if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl), ctx)) {
2174  return -EFAULT;
2175  }
2176 
2177  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
2178  if (ret < 0) {
2179  return ret;
2180  }
2181 
2182  if (ec_copy_to_user((void __user *) ioctl.state,
2183  &state, sizeof(state), ctx)) {
2184  return -EFAULT;
2185  }
2186 
2187  return 0;
2188 }
2189 
2190 /****************************************************************************/
2191 
2197  ec_master_t *master,
2198  void *arg,
2199  ec_ioctl_context_t *ctx
2200  )
2201 {
2202  uint64_t time;
2203 
2204  if (unlikely(!ctx->requested))
2205  return -EPERM;
2206 
2207  if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) {
2208  return -EFAULT;
2209  }
2210 
2211  return ecrt_master_application_time(master, time);
2212 }
2213 
2214 /****************************************************************************/
2215 
2221  ec_master_t *master,
2222  void *arg,
2223  ec_ioctl_context_t *ctx
2224  )
2225 {
2226  int ret;
2227 
2228  if (unlikely(!ctx->requested)) {
2229  return -EPERM;
2230  }
2231 
2232  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2233  return -EINTR;
2234 
2236  ec_ioctl_unlock(&master->io_mutex);
2237  return ret;
2238 }
2239 
2240 /****************************************************************************/
2241 
2247  ec_master_t *master,
2248  void *arg,
2249  ec_ioctl_context_t *ctx
2250  )
2251 {
2252  int ret;
2253  uint64_t time;
2254 
2255  if (unlikely(!ctx->requested))
2256  return -EPERM;
2257 
2258  if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) {
2259  return -EFAULT;
2260  }
2261 
2262  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2263  return -EINTR;
2264 
2266  ec_ioctl_unlock(&master->io_mutex);
2267  return ret;
2268 }
2269 
2270 /****************************************************************************/
2271 
2277  ec_master_t *master,
2278  void *arg,
2279  ec_ioctl_context_t *ctx
2280  )
2281 {
2282  int ret;
2283 
2284  if (unlikely(!ctx->requested)) {
2285  return -EPERM;
2286  }
2287 
2288  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2289  return -EINTR;
2290 
2292  ec_ioctl_unlock(&master->io_mutex);
2293  return ret;
2294 }
2295 
2296 /****************************************************************************/
2297 
2303  ec_master_t *master,
2304  void *arg,
2305  ec_ioctl_context_t *ctx
2306  )
2307 {
2308  uint32_t time;
2309  int ret;
2310 
2311  if (unlikely(!ctx->requested)) {
2312  return -EPERM;
2313  }
2314 
2316  if (ret) {
2317  return ret;
2318  }
2319 
2320  if (ec_copy_to_user((void __user *) arg, &time, sizeof(time), ctx)) {
2321  return -EFAULT;
2322  }
2323 
2324  return 0;
2325 }
2326 
2327 /****************************************************************************/
2328 
2334  ec_master_t *master,
2335  void *arg,
2336  ec_ioctl_context_t *ctx
2337  )
2338 {
2339  int ret;
2340 
2341  if (unlikely(!ctx->requested)) {
2342  return -EPERM;
2343  }
2344 
2345  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2346  return -EINTR;
2347 
2349  ec_ioctl_unlock(&master->io_mutex);
2350  return ret;
2351 }
2352 
2353 /****************************************************************************/
2354 
2360  ec_master_t *master,
2361  void *arg,
2362  ec_ioctl_context_t *ctx
2363  )
2364 {
2365  uint32_t time_diff;
2366 
2367  if (unlikely(!ctx->requested))
2368  return -EPERM;
2369 
2371 
2372  if (ec_copy_to_user((void __user *) arg, &time_diff,
2373  sizeof(time_diff), ctx))
2374  return -EFAULT;
2375 
2376  return 0;
2377 }
2378 
2379 /****************************************************************************/
2380 
2386  ec_master_t *master,
2387  void *arg,
2388  ec_ioctl_context_t *ctx
2389  )
2390 {
2391 #ifdef EC_IOCTL_RTDM
2392  /* Xenomai/LXRT is like NMI context, so we do a two-stage schedule. */
2393  irq_work_queue(&master->sc_reset_work_kicker);
2394 #else
2395  schedule_work(&master->sc_reset_work);
2396 #endif
2397  return 0;
2398 }
2399 
2400 /****************************************************************************/
2401 
2407  ec_master_t *master,
2408  void *arg,
2409  ec_ioctl_context_t *ctx
2410  )
2411 {
2412  int ret = 0;
2413  ret = ecrt_master_sii_caching(master, (unsigned long) arg);
2414  return ret;
2415 }
2416 
2417 /****************************************************************************/
2418 
2424  ec_master_t *master,
2425  void *arg,
2426  ec_ioctl_context_t *ctx
2427  )
2428 {
2429  ec_ioctl_config_t data;
2430  ec_slave_config_t *sc;
2431  unsigned int i;
2432  int ret = 0;
2433 
2434  if (unlikely(!ctx->requested)) {
2435  ret = -EPERM;
2436  goto out_return;
2437  }
2438 
2439  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2440  ret = -EFAULT;
2441  goto out_return;
2442  }
2443 
2444  if (down_interruptible(&master->master_sem)) {
2445  ret = -EINTR;
2446  goto out_return;
2447  }
2448 
2449  if (!(sc = ec_master_get_config(master, data.config_index))) {
2450  ret = -ENOENT;
2451  goto out_up;
2452  }
2453 
2454  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2455  if (data.syncs[i].config_this) {
2456  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2457  data.syncs[i].watchdog_mode);
2458  if (ret) {
2459  goto out_up;
2460  }
2461  }
2462  }
2463 
2464 out_up:
2465  up(&master->master_sem);
2466 out_return:
2467  return ret;
2468 }
2469 
2470 /****************************************************************************/
2471 
2477  ec_master_t *master,
2478  void *arg,
2479  ec_ioctl_context_t *ctx
2480  )
2481 {
2482  ec_ioctl_config_t data;
2483  ec_slave_config_t *sc;
2484  int ret = 0;
2485 
2486  if (unlikely(!ctx->requested)) {
2487  ret = -EPERM;
2488  goto out_return;
2489  }
2490 
2491  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2492  ret = -EFAULT;
2493  goto out_return;
2494  }
2495 
2496  if (down_interruptible(&master->master_sem)) {
2497  ret = -EINTR;
2498  goto out_return;
2499  }
2500 
2501  if (!(sc = ec_master_get_config(master, data.config_index))) {
2502  ret = -ENOENT;
2503  goto out_up;
2504  }
2505 
2506  ret = ecrt_slave_config_watchdog(sc,
2507  data.watchdog_divider, data.watchdog_intervals);
2508 
2509 out_up:
2510  up(&master->master_sem);
2511 out_return:
2512  return ret;
2513 }
2514 
2515 /****************************************************************************/
2516 
2522  ec_master_t *master,
2523  void *arg,
2524  ec_ioctl_context_t *ctx
2525  )
2526 {
2527  ec_ioctl_config_t data;
2528  ec_slave_config_t *sc;
2529  int ret = 0;
2530 
2531  if (unlikely(!ctx->requested)) {
2532  ret = -EPERM;
2533  goto out_return;
2534  }
2535 
2536  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2537  ret = -EFAULT;
2538  goto out_return;
2539  }
2540 
2541  if (down_interruptible(&master->master_sem)) {
2542  ret = -EINTR;
2543  goto out_return;
2544  }
2545 
2546  if (!(sc = ec_master_get_config(master, data.config_index))) {
2547  ret = -ENOENT;
2548  goto out_up;
2549  }
2550 
2551  ret = ecrt_slave_config_pdo_mode(sc,
2552  data.pdo_assign_mode, data.pdo_config_mode);
2553 
2554 out_up:
2555  up(&master->master_sem);
2556 out_return:
2557  return ret;
2558 }
2559 
2560 /****************************************************************************/
2561 
2567  ec_master_t *master,
2568  void *arg,
2569  ec_ioctl_context_t *ctx
2570  )
2571 {
2572  ec_ioctl_config_pdo_t data;
2573  ec_slave_config_t *sc;
2574 
2575  if (unlikely(!ctx->requested))
2576  return -EPERM;
2577 
2578  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2579  return -EFAULT;
2580 
2581  if (down_interruptible(&master->master_sem))
2582  return -EINTR;
2583 
2584  if (!(sc = ec_master_get_config(master, data.config_index))) {
2585  up(&master->master_sem);
2586  return -ENOENT;
2587  }
2588 
2589  up(&master->master_sem);
2591  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2592 }
2593 
2594 /****************************************************************************/
2595 
2601  ec_master_t *master,
2602  void *arg,
2603  ec_ioctl_context_t *ctx
2604  )
2605 {
2606  ec_ioctl_config_pdo_t data;
2607  ec_slave_config_t *sc;
2608 
2609  if (unlikely(!ctx->requested))
2610  return -EPERM;
2611 
2612  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2613  return -EFAULT;
2614 
2615  if (down_interruptible(&master->master_sem))
2616  return -EINTR;
2617 
2618  if (!(sc = ec_master_get_config(master, data.config_index))) {
2619  up(&master->master_sem);
2620  return -ENOENT;
2621  }
2622 
2623  up(&master->master_sem);
2625  return ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2626 }
2627 
2628 /****************************************************************************/
2629 
2635  ec_master_t *master,
2636  void *arg,
2637  ec_ioctl_context_t *ctx
2638  )
2639 {
2640  ec_ioctl_add_pdo_entry_t data;
2641  ec_slave_config_t *sc;
2642 
2643  if (unlikely(!ctx->requested))
2644  return -EPERM;
2645 
2646  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2647  return -EFAULT;
2648 
2649  if (down_interruptible(&master->master_sem))
2650  return -EINTR;
2651 
2652  if (!(sc = ec_master_get_config(master, data.config_index))) {
2653  up(&master->master_sem);
2654  return -ENOENT;
2655  }
2656 
2657  up(&master->master_sem);
2659  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2660  data.entry_index, data.entry_subindex, data.entry_bit_length);
2661 }
2662 
2663 /****************************************************************************/
2664 
2670  ec_master_t *master,
2671  void *arg,
2672  ec_ioctl_context_t *ctx
2673  )
2674 {
2675  ec_ioctl_config_pdo_t data;
2676  ec_slave_config_t *sc;
2677 
2678  if (unlikely(!ctx->requested))
2679  return -EPERM;
2680 
2681  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2682  return -EFAULT;
2683 
2684  if (down_interruptible(&master->master_sem))
2685  return -EINTR;
2686 
2687  if (!(sc = ec_master_get_config(master, data.config_index))) {
2688  up(&master->master_sem);
2689  return -ENOENT;
2690  }
2691 
2692  up(&master->master_sem);
2694  return ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2695 }
2696 
2697 /****************************************************************************/
2698 
2704  ec_master_t *master,
2705  void *arg,
2706  ec_ioctl_context_t *ctx
2707  )
2708 {
2709  ec_ioctl_reg_pdo_entry_t data;
2710  ec_slave_config_t *sc;
2711  ec_domain_t *domain;
2712  int ret;
2713 
2714  if (unlikely(!ctx->requested))
2715  return -EPERM;
2716 
2717  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2718  return -EFAULT;
2719 
2720  if (down_interruptible(&master->master_sem))
2721  return -EINTR;
2722 
2723  if (!(sc = ec_master_get_config(master, data.config_index))) {
2724  up(&master->master_sem);
2725  return -ENOENT;
2726  }
2727 
2728  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2729  up(&master->master_sem);
2730  return -ENOENT;
2731  }
2732 
2733  up(&master->master_sem);
2735  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2736  data.entry_subindex, domain, &data.bit_position);
2737 
2738  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2739  return -EFAULT;
2740 
2741  return ret;
2742 }
2743 
2744 /****************************************************************************/
2745 
2751  ec_master_t *master,
2752  void *arg,
2753  ec_ioctl_context_t *ctx
2754  )
2755 {
2756  ec_ioctl_reg_pdo_pos_t io;
2757  ec_slave_config_t *sc;
2758  ec_domain_t *domain;
2759  int ret;
2760 
2761  if (unlikely(!ctx->requested)) {
2762  return -EPERM;
2763  }
2764 
2765  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2766  return -EFAULT;
2767  }
2768 
2769  if (down_interruptible(&master->master_sem)) {
2770  return -EINTR;
2771  }
2772 
2773  if (!(sc = ec_master_get_config(master, io.config_index))) {
2774  up(&master->master_sem);
2775  return -ENOENT;
2776  }
2777 
2778  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2779  up(&master->master_sem);
2780  return -ENOENT;
2781  }
2782 
2783  up(&master->master_sem);
2785  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2786  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2787 
2788  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2789  return -EFAULT;
2790 
2791  return ret;
2792 }
2793 
2794 /****************************************************************************/
2795 
2801  ec_master_t *master,
2802  void *arg,
2803  ec_ioctl_context_t *ctx
2804  )
2805 {
2806  ec_ioctl_config_t data;
2807  ec_slave_config_t *sc;
2808  int ret;
2809 
2810  if (unlikely(!ctx->requested))
2811  return -EPERM;
2812 
2813  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2814  return -EFAULT;
2815 
2816  if (down_interruptible(&master->master_sem))
2817  return -EINTR;
2818 
2819  if (!(sc = ec_master_get_config(master, data.config_index))) {
2820  up(&master->master_sem);
2821  return -ENOENT;
2822  }
2823 
2825  data.dc_sync[0].cycle_time,
2826  data.dc_sync[0].shift_time,
2827  data.dc_sync[1].cycle_time,
2828  data.dc_sync[1].shift_time);
2829 
2830  up(&master->master_sem);
2831 
2832  return ret;
2833 }
2834 
2835 /****************************************************************************/
2836 
2842  ec_master_t *master,
2843  void *arg,
2844  ec_ioctl_context_t *ctx
2845  )
2846 {
2847  ec_ioctl_sc_sdo_t data;
2848  ec_slave_config_t *sc;
2849  uint8_t *sdo_data = NULL;
2850  int ret;
2851 
2852  if (unlikely(!ctx->requested))
2853  return -EPERM;
2854 
2855  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2856  return -EFAULT;
2857 
2858  if (!data.size)
2859  return -EINVAL;
2860 
2861  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2862  return -ENOMEM;
2863  }
2864 
2865  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2866  kfree(sdo_data);
2867  return -EFAULT;
2868  }
2869 
2870  if (down_interruptible(&master->master_sem)) {
2871  kfree(sdo_data);
2872  return -EINTR;
2873  }
2874 
2875  if (!(sc = ec_master_get_config(master, data.config_index))) {
2876  up(&master->master_sem);
2877  kfree(sdo_data);
2878  return -ENOENT;
2879  }
2880 
2881  up(&master->master_sem);
2883  if (data.complete_access) {
2885  data.index, sdo_data, data.size);
2886  } else {
2887  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2888  data.size);
2889  }
2890  kfree(sdo_data);
2891  return ret;
2892 }
2893 
2894 /****************************************************************************/
2895 
2901  ec_master_t *master,
2902  void *arg,
2903  ec_ioctl_context_t *ctx
2904  )
2905 {
2906  ec_ioctl_sc_emerg_t io;
2907  ec_slave_config_t *sc;
2908  int ret;
2909 
2910  if (unlikely(!ctx->requested))
2911  return -EPERM;
2912 
2913  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2914  return -EFAULT;
2915 
2916  if (down_interruptible(&master->master_sem)) {
2917  return -EINTR;
2918  }
2919 
2920  if (!(sc = ec_master_get_config(master, io.config_index))) {
2921  up(&master->master_sem);
2922  return -ENOENT;
2923  }
2924 
2925  ret = ecrt_slave_config_emerg_size(sc, io.size);
2926 
2927  up(&master->master_sem);
2928 
2929  return ret;
2930 }
2931 
2932 /****************************************************************************/
2933 
2939  ec_master_t *master,
2940  void *arg,
2941  ec_ioctl_context_t *ctx
2942  )
2943 {
2944  ec_ioctl_sc_emerg_t io;
2945  ec_slave_config_t *sc;
2946  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
2947  int ret;
2948 
2949  if (unlikely(!ctx->requested)) {
2950  return -EPERM;
2951  }
2952 
2953  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2954  return -EFAULT;
2955  }
2956 
2957  /* no locking of master_sem needed, because configuration will not be
2958  * deleted in the meantime. */
2959 
2960  if (!(sc = ec_master_get_config(master, io.config_index))) {
2961  return -ENOENT;
2962  }
2963 
2964  ret = ecrt_slave_config_emerg_pop(sc, msg);
2965  if (ret < 0) {
2966  return ret;
2967  }
2968 
2969  if (ec_copy_to_user((void __user *) io.target, msg, sizeof(msg), ctx)) {
2970  return -EFAULT;
2971  }
2972 
2973  return ret;
2974 }
2975 
2976 /****************************************************************************/
2977 
2983  ec_master_t *master,
2984  void *arg,
2985  ec_ioctl_context_t *ctx
2986  )
2987 {
2988  ec_ioctl_sc_emerg_t io;
2989  ec_slave_config_t *sc;
2990 
2991  if (unlikely(!ctx->requested)) {
2992  return -EPERM;
2993  }
2994 
2995  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2996  return -EFAULT;
2997  }
2998 
2999  /* no locking of master_sem needed, because configuration will not be
3000  * deleted in the meantime. */
3001 
3002  if (!(sc = ec_master_get_config(master, io.config_index))) {
3003  return -ENOENT;
3004  }
3005 
3006  return ecrt_slave_config_emerg_clear(sc);
3007 }
3008 
3009 /****************************************************************************/
3010 
3016  ec_master_t *master,
3017  void *arg,
3018  ec_ioctl_context_t *ctx
3019  )
3020 {
3021  ec_ioctl_sc_emerg_t io;
3022  ec_slave_config_t *sc;
3023  int ret;
3024 
3025  if (unlikely(!ctx->requested)) {
3026  return -EPERM;
3027  }
3028 
3029  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
3030  return -EFAULT;
3031  }
3032 
3033  /* no locking of master_sem needed, because configuration will not be
3034  * deleted in the meantime. */
3035 
3036  if (!(sc = ec_master_get_config(master, io.config_index))) {
3037  return -ENOENT;
3038  }
3039 
3041  if (ret < 0) {
3042  return ret;
3043  }
3044 
3045  io.overruns = ret;
3046 
3047  if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) {
3048  return -EFAULT;
3049  }
3050 
3051  return 0;
3052 }
3053 
3054 /****************************************************************************/
3055 
3061  ec_master_t *master,
3062  void *arg,
3063  ec_ioctl_context_t *ctx
3064  )
3065 {
3066  ec_ioctl_sdo_request_t data;
3067  ec_slave_config_t *sc;
3068  ec_sdo_request_t *req;
3069 
3070  if (unlikely(!ctx->requested))
3071  return -EPERM;
3072 
3073  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3074  return -EFAULT;
3075  }
3076 
3077  data.request_index = 0;
3078 
3079  if (down_interruptible(&master->master_sem))
3080  return -EINTR;
3081 
3082  sc = ec_master_get_config(master, data.config_index);
3083  if (!sc) {
3084  up(&master->master_sem);
3085  return -ENOENT;
3086  }
3087 
3088  list_for_each_entry(req, &sc->sdo_requests, list) {
3089  data.request_index++;
3090  }
3091 
3092  up(&master->master_sem);
3094  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
3095  data.sdo_subindex, data.size);
3096  if (IS_ERR(req))
3097  return PTR_ERR(req);
3098 
3099  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3100  return -EFAULT;
3101 
3102  return 0;
3103 }
3104 
3105 /****************************************************************************/
3106 
3112  ec_master_t *master,
3113  void *arg,
3114  ec_ioctl_context_t *ctx
3115  )
3116 {
3117  ec_ioctl_soe_request_t data;
3118  ec_slave_config_t *sc;
3119  ec_soe_request_t *req;
3120 
3121  if (unlikely(!ctx->requested))
3122  return -EPERM;
3123 
3124  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3125  return -EFAULT;
3126  }
3127 
3128  data.request_index = 0;
3129 
3130  if (down_interruptible(&master->master_sem))
3131  return -EINTR;
3132 
3133  sc = ec_master_get_config(master, data.config_index);
3134  if (!sc) {
3135  up(&master->master_sem);
3136  return -ENOENT;
3137  }
3138 
3139  list_for_each_entry(req, &sc->soe_requests, list) {
3140  data.request_index++;
3141  }
3142 
3143  up(&master->master_sem);
3145  req = ecrt_slave_config_create_soe_request_err(sc, data.drive_no,
3146  data.idn, data.size);
3147  if (IS_ERR(req)) {
3148  return PTR_ERR(req);
3149  }
3150 
3151  if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
3152  return -EFAULT;
3153  }
3154 
3155  return 0;
3156 }
3157 
3158 /****************************************************************************/
3159 
3165  ec_master_t *master,
3166  void *arg,
3167  ec_ioctl_context_t *ctx
3168  )
3169 {
3170  ec_ioctl_reg_request_t io;
3171  ec_slave_config_t *sc;
3172  ec_reg_request_t *reg;
3173 
3174  if (unlikely(!ctx->requested)) {
3175  return -EPERM;
3176  }
3177 
3178  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3179  return -EFAULT;
3180  }
3181 
3182  io.request_index = 0;
3183 
3184  if (down_interruptible(&master->master_sem)) {
3185  return -EINTR;
3186  }
3187 
3188  sc = ec_master_get_config(master, io.config_index);
3189  if (!sc) {
3190  up(&master->master_sem);
3191  return -ENOENT;
3192  }
3193 
3194  list_for_each_entry(reg, &sc->reg_requests, list) {
3195  io.request_index++;
3196  }
3197 
3198  up(&master->master_sem);
3200  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
3201  if (IS_ERR(reg)) {
3202  return PTR_ERR(reg);
3203  }
3204 
3205  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3206  return -EFAULT;
3207  }
3208 
3209  return 0;
3210 }
3211 
3212 /****************************************************************************/
3213 
3219  ec_master_t *master,
3220  void *arg,
3221  ec_ioctl_context_t *ctx
3222  )
3223 {
3224  ec_ioctl_voe_t data;
3225  ec_slave_config_t *sc;
3226  ec_voe_handler_t *voe;
3227 
3228  if (unlikely(!ctx->requested))
3229  return -EPERM;
3230 
3231  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3232  return -EFAULT;
3233  }
3234 
3235  data.voe_index = 0;
3236 
3237  if (down_interruptible(&master->master_sem))
3238  return -EINTR;
3239 
3240  sc = ec_master_get_config(master, data.config_index);
3241  if (!sc) {
3242  up(&master->master_sem);
3243  return -ENOENT;
3244  }
3245 
3246  list_for_each_entry(voe, &sc->voe_handlers, list) {
3247  data.voe_index++;
3248  }
3249 
3250  up(&master->master_sem);
3252  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
3253  if (IS_ERR(voe))
3254  return PTR_ERR(voe);
3255 
3256  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3257  return -EFAULT;
3258 
3259  return 0;
3260 }
3261 
3262 /****************************************************************************/
3263 
3269  ec_master_t *master,
3270  void *arg,
3271  ec_ioctl_context_t *ctx
3272  )
3273 {
3274  ec_ioctl_sc_state_t data;
3275  const ec_slave_config_t *sc;
3277  int ret;
3278 
3279  if (unlikely(!ctx->requested))
3280  return -EPERM;
3281 
3282  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) {
3283  return -EFAULT;
3284  }
3285 
3286  /* no locking of master_sem needed, because sc will not be deleted in the
3287  * meantime. */
3288 
3289  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
3290  return -ENOENT;
3291  }
3292 
3293  ret = ecrt_slave_config_state(sc, &state);
3294  if (ret)
3295  return ret;
3296 
3297  if (ec_copy_to_user((void __user *) data.state,
3298  &state, sizeof(state), ctx))
3299  return -EFAULT;
3300 
3301  return 0;
3302 }
3303 
3304 /****************************************************************************/
3305 
3311  ec_master_t *master,
3312  void *arg,
3313  ec_ioctl_context_t *ctx
3314  )
3315 {
3316  ec_ioctl_sc_idn_t ioctl;
3317  ec_slave_config_t *sc;
3318  uint8_t *data = NULL;
3319  int ret;
3320 
3321  if (unlikely(!ctx->requested))
3322  return -EPERM;
3323 
3324  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
3325  return -EFAULT;
3326 
3327  if (!ioctl.size)
3328  return -EINVAL;
3329 
3330  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
3331  return -ENOMEM;
3332  }
3333 
3334  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
3335  kfree(data);
3336  return -EFAULT;
3337  }
3338 
3339  if (down_interruptible(&master->master_sem)) {
3340  kfree(data);
3341  return -EINTR;
3342  }
3343 
3344  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3345  up(&master->master_sem);
3346  kfree(data);
3347  return -ENOENT;
3348  }
3349 
3350  up(&master->master_sem);
3352  ret = ecrt_slave_config_idn(
3353  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3354  kfree(data);
3355  return ret;
3356 }
3357 
3358 /****************************************************************************/
3359 
3365  ec_master_t *master,
3366  void *arg,
3367  ec_ioctl_context_t *ctx
3368  )
3369 {
3370  ec_ioctl_sc_flag_t ioctl;
3371  ec_slave_config_t *sc;
3372  uint8_t *key;
3373  int ret;
3374 
3375  if (unlikely(!ctx->requested)) {
3376  return -EPERM;
3377  }
3378 
3379  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3380  return -EFAULT;
3381  }
3382 
3383  if (!ioctl.key_size) {
3384  return -EINVAL;
3385  }
3386 
3387  if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3388  return -ENOMEM;
3389  }
3390 
3391  if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3392  kfree(key);
3393  return -EFAULT;
3394  }
3395  key[ioctl.key_size] = '\0';
3396 
3397  if (down_interruptible(&master->master_sem)) {
3398  kfree(key);
3399  return -EINTR;
3400  }
3401 
3402  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3403  up(&master->master_sem);
3404  kfree(key);
3405  return -ENOENT;
3406  }
3407 
3408  up(&master->master_sem);
3410  ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3411  kfree(key);
3412  return ret;
3413 }
3414 
3415 /****************************************************************************/
3416 
3422  ec_master_t *master,
3423  void *arg,
3424  ec_ioctl_context_t *ctx
3425  )
3426 {
3427  ec_ioctl_sc_state_timeout_t ioctl;
3428  ec_slave_config_t *sc;
3429  int ret;
3430 
3431  if (unlikely(!ctx->requested)) {
3432  return -EPERM;
3433  }
3434 
3435  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3436  return -EFAULT;
3437  }
3438 
3439  if (down_interruptible(&master->master_sem)) {
3440  return -EINTR;
3441  }
3442 
3443  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3444  up(&master->master_sem);
3445  return -ENOENT;
3446  }
3447 
3448  up(&master->master_sem);
3450  ret = ecrt_slave_config_state_timeout(sc, ioctl.from_state,
3451  ioctl.to_state, ioctl.timeout_ms);
3452  return ret;
3453 }
3454 
3455 /****************************************************************************/
3456 
3457 #ifdef EC_EOE
3458 
3464  ec_master_t *master,
3465  void *arg,
3466  ec_ioctl_context_t *ctx
3467  )
3468 {
3469  ec_ioctl_eoe_ip_t io;
3470  ec_slave_config_t *sc;
3471 
3472  if (unlikely(!ctx->requested)) {
3473  return -EPERM;
3474  }
3475 
3476  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3477  return -EFAULT;
3478  }
3479 
3480  if (down_interruptible(&master->master_sem)) {
3481  return -EINTR;
3482  }
3483 
3484  if (!(sc = ec_master_get_config(master, io.config_index))) {
3485  up(&master->master_sem);
3486  return -ENOENT;
3487  }
3488 
3489  up(&master->master_sem);
3491  /* the kernel versions of the EoE set IP methods never fail. */
3492  if (io.mac_address_included) {
3493  ecrt_slave_config_eoe_mac_address(sc, io.mac_address);
3494  }
3495  if (io.ip_address_included) {
3496  ecrt_slave_config_eoe_ip_address(sc, io.ip_address);
3497  }
3498  if (io.subnet_mask_included) {
3499  ecrt_slave_config_eoe_subnet_mask(sc, io.subnet_mask);
3500  }
3501  if (io.gateway_included) {
3502  ecrt_slave_config_eoe_default_gateway(sc, io.gateway);
3503  }
3504  if (io.dns_included) {
3506  }
3507  if (io.name_included) {
3508  ecrt_slave_config_eoe_hostname(sc, io.name);
3509  }
3510 
3511  return 0;
3512 }
3513 
3514 #endif
3515 
3516 /****************************************************************************/
3517 
3523  ec_master_t *master,
3524  void *arg,
3525  ec_ioctl_context_t *ctx
3526  )
3527 {
3528  const ec_domain_t *domain;
3529 
3530  if (unlikely(!ctx->requested)) {
3531  return -EPERM;
3532  }
3533 
3534  if (down_interruptible(&master->master_sem)) {
3535  return -EINTR;
3536  }
3537 
3538  list_for_each_entry(domain, &master->domains, list) {
3539  if (domain->index == (unsigned long) arg) {
3540  size_t size = ecrt_domain_size(domain);
3541  up(&master->master_sem);
3542  return size;
3543  }
3544  }
3545 
3546  up(&master->master_sem);
3547  return -ENOENT;
3548 }
3549 
3550 /****************************************************************************/
3551 
3557  ec_master_t *master,
3558  void *arg,
3559  ec_ioctl_context_t *ctx
3560  )
3561 {
3562  int offset = 0;
3563  const ec_domain_t *domain;
3564 
3565  if (unlikely(!ctx->requested))
3566  return -EPERM;
3567 
3568  if (down_interruptible(&master->master_sem)) {
3569  return -EINTR;
3570  }
3571 
3572  list_for_each_entry(domain, &master->domains, list) {
3573  if (domain->index == (unsigned long) arg) {
3574  up(&master->master_sem);
3575  return offset;
3576  }
3577  offset += ecrt_domain_size(domain);
3578  }
3579 
3580  up(&master->master_sem);
3581  return -ENOENT;
3582 }
3583 
3584 /****************************************************************************/
3585 
3591  ec_master_t *master,
3592  void *arg,
3593  ec_ioctl_context_t *ctx
3594  )
3595 {
3596  ec_domain_t *domain;
3597 
3598  if (unlikely(!ctx->requested))
3599  return -EPERM;
3600 
3601  /* no locking of master_sem needed, because domain will not be deleted in
3602  * the meantime. */
3603 
3604  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3605  return -ENOENT;
3606  }
3607 
3608  return ecrt_domain_process(domain);
3609 }
3610 
3611 /****************************************************************************/
3612 
3618  ec_master_t *master,
3619  void *arg,
3620  ec_ioctl_context_t *ctx
3621  )
3622 {
3623  ec_domain_t *domain;
3624  int ret;
3625 
3626  if (unlikely(!ctx->requested))
3627  return -EPERM;
3628 
3629  /* no locking of master_sem needed, because domain will not be deleted in
3630  * the meantime. */
3631 
3632  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3633  return -ENOENT;
3634  }
3635 
3636  if (ec_ioctl_lock_interruptible(&master->io_mutex))
3637  return -EINTR;
3638 
3639  ret = ecrt_domain_queue(domain);
3640  ec_ioctl_unlock(&master->io_mutex);
3641  return ret;
3642 }
3643 
3644 /****************************************************************************/
3645 
3651  ec_master_t *master,
3652  void *arg,
3653  ec_ioctl_context_t *ctx
3654  )
3655 {
3656  ec_ioctl_domain_state_t data;
3657  const ec_domain_t *domain;
3658  ec_domain_state_t state;
3659  int ret;
3660 
3661  if (unlikely(!ctx->requested))
3662  return -EPERM;
3663 
3664  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) {
3665  return -EFAULT;
3666  }
3667 
3668  /* no locking of master_sem needed, because domain will not be deleted in
3669  * the meantime. */
3670 
3671  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3672  return -ENOENT;
3673  }
3674 
3675  ret = ecrt_domain_state(domain, &state);
3676  if (ret)
3677  return ret;
3678 
3679  if (ec_copy_to_user((void __user *) data.state, &state, sizeof(state),
3680  ctx))
3681  return -EFAULT;
3682 
3683  return 0;
3684 }
3685 
3686 /****************************************************************************/
3687 
3693  ec_master_t *master,
3694  void *arg,
3695  ec_ioctl_context_t *ctx
3696  )
3697 {
3698  ec_ioctl_sdo_request_t data;
3699  ec_slave_config_t *sc;
3700  ec_sdo_request_t *req;
3701 
3702  if (unlikely(!ctx->requested))
3703  return -EPERM;
3704 
3705  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3706  return -EFAULT;
3707 
3708  /* no locking of master_sem needed, because neither sc nor req will not be
3709  * deleted in the meantime. */
3710 
3711  if (!(sc = ec_master_get_config(master, data.config_index))) {
3712  return -ENOENT;
3713  }
3714 
3715  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3716  return -ENOENT;
3717  }
3718 
3719  return ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3720 }
3721 
3722 /****************************************************************************/
3723 
3729  ec_master_t *master,
3730  void *arg,
3731  ec_ioctl_context_t *ctx
3732  )
3733 {
3734  ec_ioctl_sdo_request_t data;
3735  ec_slave_config_t *sc;
3736  ec_sdo_request_t *req;
3737 
3738  if (unlikely(!ctx->requested))
3739  return -EPERM;
3740 
3741  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3742  return -EFAULT;
3743 
3744  /* no locking of master_sem needed, because neither sc nor req will not be
3745  * deleted in the meantime. */
3746 
3747  if (!(sc = ec_master_get_config(master, data.config_index))) {
3748  return -ENOENT;
3749  }
3750 
3751  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3752  return -ENOENT;
3753  }
3754 
3755  return ecrt_sdo_request_timeout(req, data.timeout);
3756 }
3757 
3758 /****************************************************************************/
3759 
3767  ec_master_t *master,
3768  void *arg,
3769  ec_ioctl_context_t *ctx
3770  )
3771 {
3772  ec_ioctl_sdo_request_t data;
3773  ec_slave_config_t *sc;
3774  ec_sdo_request_t *req;
3775 
3776  if (unlikely(!ctx->requested))
3777  return -EPERM;
3778 
3779  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3780  return -EFAULT;
3781 
3782  /* no locking of master_sem needed, because neither sc nor req will not be
3783  * deleted in the meantime. */
3784 
3785  if (!(sc = ec_master_get_config(master, data.config_index))) {
3786  return -ENOENT;
3787  }
3788 
3789  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3790  return -ENOENT;
3791  }
3792 
3793  data.state = ecrt_sdo_request_state(req);
3794  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3795  data.size = ecrt_sdo_request_data_size(req);
3796  else
3797  data.size = 0;
3798 
3799  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
3800  return -EFAULT;
3801 
3802  return 0;
3803 }
3804 
3805 /****************************************************************************/
3806 
3812  ec_master_t *master,
3813  void *arg,
3814  ec_ioctl_context_t *ctx
3815  )
3816 {
3817  ec_ioctl_sdo_request_t data;
3818  ec_slave_config_t *sc;
3819  ec_sdo_request_t *req;
3820 
3821  if (unlikely(!ctx->requested))
3822  return -EPERM;
3823 
3824  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3825  return -EFAULT;
3826 
3827  /* no locking of master_sem needed, because neither sc nor req will not be
3828  * deleted in the meantime. */
3829 
3830  if (!(sc = ec_master_get_config(master, data.config_index))) {
3831  return -ENOENT;
3832  }
3833 
3834  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3835  return -ENOENT;
3836  }
3837 
3838  return ecrt_sdo_request_read(req);
3839 }
3840 
3841 /****************************************************************************/
3842 
3848  ec_master_t *master,
3849  void *arg,
3850  ec_ioctl_context_t *ctx
3851  )
3852 {
3853  ec_ioctl_sdo_request_t data;
3854  ec_slave_config_t *sc;
3855  ec_sdo_request_t *req;
3856 
3857  if (unlikely(!ctx->requested))
3858  return -EPERM;
3859 
3860  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3861  return -EFAULT;
3862 
3863  if (!data.size) {
3864  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3865  return -EINVAL;
3866  }
3867 
3868  /* no locking of master_sem needed, because neither sc nor req will not be
3869  * deleted in the meantime. */
3870 
3871  if (!(sc = ec_master_get_config(master, data.config_index))) {
3872  return -ENOENT;
3873  }
3874 
3875  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3876  return -ENOENT;
3877  }
3878 
3879  if (data.size > req->mem_size)
3880  return -ENOBUFS;
3881 
3882  if (ec_copy_from_user(req->data, (void __user *) data.data,
3883  data.size, ctx))
3884  return -EFAULT;
3885 
3886  req->data_size = data.size;
3887  return ecrt_sdo_request_write(req);
3888 }
3889 
3890 /****************************************************************************/
3891 
3897  ec_master_t *master,
3898  void *arg,
3899  ec_ioctl_context_t *ctx
3900  )
3901 {
3902  ec_ioctl_sdo_request_t data;
3903  ec_slave_config_t *sc;
3904  ec_sdo_request_t *req;
3905 
3906  if (unlikely(!ctx->requested))
3907  return -EPERM;
3908 
3909  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3910  return -EFAULT;
3911 
3912  /* no locking of master_sem needed, because neither sc nor req will not be
3913  * deleted in the meantime. */
3914 
3915  if (!(sc = ec_master_get_config(master, data.config_index))) {
3916  return -ENOENT;
3917  }
3918 
3919  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3920  return -ENOENT;
3921  }
3922 
3923  if (ec_copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3924  ecrt_sdo_request_data_size(req), ctx))
3925  return -EFAULT;
3926 
3927  return 0;
3928 }
3929 
3930 /****************************************************************************/
3931 
3937  ec_master_t *master,
3938  void *arg,
3939  ec_ioctl_context_t *ctx
3940  )
3941 {
3942  ec_ioctl_soe_request_t data;
3943  ec_slave_config_t *sc;
3944  ec_soe_request_t *req;
3945 
3946  if (unlikely(!ctx->requested))
3947  return -EPERM;
3948 
3949  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3950  return -EFAULT;
3951 
3952  /* no locking of master_sem needed, because neither sc nor req will not be
3953  * deleted in the meantime. */
3954 
3955  if (!(sc = ec_master_get_config(master, data.config_index))) {
3956  return -ENOENT;
3957  }
3958 
3959  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3960  return -ENOENT;
3961  }
3962 
3963  return ecrt_soe_request_idn(req, data.drive_no, data.idn);
3964 }
3965 
3966 /****************************************************************************/
3967 
3973  ec_master_t *master,
3974  void *arg,
3975  ec_ioctl_context_t *ctx
3976  )
3977 {
3978  ec_ioctl_soe_request_t data;
3979  ec_slave_config_t *sc;
3980  ec_soe_request_t *req;
3981 
3982  if (unlikely(!ctx->requested))
3983  return -EPERM;
3984 
3985  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3986  return -EFAULT;
3987 
3988  /* no locking of master_sem needed, because neither sc nor req will not be
3989  * deleted in the meantime. */
3990 
3991  if (!(sc = ec_master_get_config(master, data.config_index))) {
3992  return -ENOENT;
3993  }
3994 
3995  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3996  return -ENOENT;
3997  }
3998 
3999  return ecrt_soe_request_timeout(req, data.timeout);
4000 }
4001 
4002 /****************************************************************************/
4003 
4009  ec_master_t *master,
4010  void *arg,
4011  ec_ioctl_context_t *ctx
4012  )
4013 {
4014  ec_ioctl_soe_request_t data;
4015  ec_slave_config_t *sc;
4016  ec_soe_request_t *req;
4017 
4018  if (unlikely(!ctx->requested))
4019  return -EPERM;
4020 
4021  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4022  return -EFAULT;
4023 
4024  /* no locking of master_sem needed, because neither sc nor req will not be
4025  * deleted in the meantime. */
4026 
4027  if (!(sc = ec_master_get_config(master, data.config_index))) {
4028  return -ENOENT;
4029  }
4030 
4031  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4032  return -ENOENT;
4033  }
4034 
4035  data.state = ecrt_soe_request_state(req);
4036  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT) {
4037  data.size = ecrt_soe_request_data_size(req);
4038  }
4039  else {
4040  data.size = 0;
4041  }
4042 
4043  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
4044  return -EFAULT;
4045 
4046  return 0;
4047 }
4048 
4049 /****************************************************************************/
4050 
4056  ec_master_t *master,
4057  void *arg,
4058  ec_ioctl_context_t *ctx
4059  )
4060 {
4061  ec_ioctl_soe_request_t data;
4062  ec_slave_config_t *sc;
4063  ec_soe_request_t *req;
4064 
4065  if (unlikely(!ctx->requested))
4066  return -EPERM;
4067 
4068  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4069  return -EFAULT;
4070 
4071  /* no locking of master_sem needed, because neither sc nor req will not be
4072  * deleted in the meantime. */
4073 
4074  if (!(sc = ec_master_get_config(master, data.config_index))) {
4075  return -ENOENT;
4076  }
4077 
4078  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4079  return -ENOENT;
4080  }
4081 
4082  return ecrt_soe_request_read(req);
4083 }
4084 
4085 /****************************************************************************/
4086 
4092  ec_master_t *master,
4093  void *arg,
4094  ec_ioctl_context_t *ctx
4095  )
4096 {
4097  ec_ioctl_soe_request_t data;
4098  ec_slave_config_t *sc;
4099  ec_soe_request_t *req;
4100 
4101  if (unlikely(!ctx->requested))
4102  return -EPERM;
4103 
4104  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4105  return -EFAULT;
4106 
4107  if (!data.size) {
4108  EC_MASTER_ERR(master, "IDN write: Data size may not be zero!\n");
4109  return -EINVAL;
4110  }
4111 
4112  /* no locking of master_sem needed, because neither sc nor req will not be
4113  * deleted in the meantime. */
4114 
4115  if (!(sc = ec_master_get_config(master, data.config_index))) {
4116  return -ENOENT;
4117  }
4118 
4119  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4120  return -ENOENT;
4121  }
4122 
4123  if (data.size > req->mem_size)
4124  return -ENOBUFS;
4125 
4126  if (ec_copy_from_user(req->data, (void __user *) data.data,
4127  data.size, ctx))
4128  return -EFAULT;
4129 
4130  req->data_size = data.size;
4131  return ecrt_soe_request_write(req);
4132 }
4133 
4134 /****************************************************************************/
4135 
4141  ec_master_t *master,
4142  void *arg,
4143  ec_ioctl_context_t *ctx
4144  )
4145 {
4146  ec_ioctl_soe_request_t data;
4147  ec_slave_config_t *sc;
4148  ec_soe_request_t *req;
4149 
4150  if (unlikely(!ctx->requested))
4151  return -EPERM;
4152 
4153  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4154  return -EFAULT;
4155 
4156  /* no locking of master_sem needed, because neither sc nor req will not be
4157  * deleted in the meantime. */
4158 
4159  if (!(sc = ec_master_get_config(master, data.config_index))) {
4160  return -ENOENT;
4161  }
4162 
4163  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
4164  return -ENOENT;
4165  }
4166 
4167  if (ec_copy_to_user((void __user *) data.data, ecrt_soe_request_data(req),
4168  ecrt_soe_request_data_size(req), ctx))
4169  return -EFAULT;
4170 
4171  return 0;
4172 }
4173 
4174 /****************************************************************************/
4175 
4181  ec_master_t *master,
4182  void *arg,
4183  ec_ioctl_context_t *ctx
4184  )
4185 {
4186  ec_ioctl_reg_request_t io;
4187  ec_slave_config_t *sc;
4188  ec_reg_request_t *reg;
4189 
4190  if (unlikely(!ctx->requested)) {
4191  return -EPERM;
4192  }
4193 
4194  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4195  return -EFAULT;
4196  }
4197 
4198  if (io.mem_size <= 0) {
4199  return 0;
4200  }
4201 
4202  /* no locking of master_sem needed, because neither sc nor reg will not be
4203  * deleted in the meantime. */
4204 
4205  if (!(sc = ec_master_get_config(master, io.config_index))) {
4206  return -ENOENT;
4207  }
4208 
4209  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4210  return -ENOENT;
4211  }
4212 
4213  if (ec_copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
4214  min(reg->mem_size, io.mem_size), ctx)) {
4215  return -EFAULT;
4216  }
4217 
4218  return 0;
4219 }
4220 
4221 /****************************************************************************/
4222 
4228  ec_master_t *master,
4229  void *arg,
4230  ec_ioctl_context_t *ctx
4231  )
4232 {
4233  ec_ioctl_reg_request_t io;
4234  ec_slave_config_t *sc;
4235  ec_reg_request_t *reg;
4236 
4237  if (unlikely(!ctx->requested)) {
4238  return -EPERM;
4239  }
4240 
4241  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4242  return -EFAULT;
4243  }
4244 
4245  /* no locking of master_sem needed, because neither sc nor reg will not be
4246  * deleted in the meantime. */
4247 
4248  if (!(sc = ec_master_get_config(master, io.config_index))) {
4249  return -ENOENT;
4250  }
4251 
4252  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4253  return -ENOENT;
4254  }
4255 
4256  io.state = ecrt_reg_request_state(reg);
4257  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
4258 
4259  if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) {
4260  return -EFAULT;
4261  }
4262 
4263  return 0;
4264 }
4265 
4266 /****************************************************************************/
4267 
4273  ec_master_t *master,
4274  void *arg,
4275  ec_ioctl_context_t *ctx
4276  )
4277 {
4278  ec_ioctl_reg_request_t io;
4279  ec_slave_config_t *sc;
4280  ec_reg_request_t *reg;
4281 
4282  if (unlikely(!ctx->requested)) {
4283  return -EPERM;
4284  }
4285 
4286  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4287  return -EFAULT;
4288  }
4289 
4290  /* no locking of master_sem needed, because neither sc nor reg will not be
4291  * deleted in the meantime. */
4292 
4293  if (!(sc = ec_master_get_config(master, io.config_index))) {
4294  return -ENOENT;
4295  }
4296 
4297  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4298  return -ENOENT;
4299  }
4300 
4301  if (io.transfer_size > reg->mem_size) {
4302  return -ENOBUFS;
4303  }
4304 
4305  if (ec_copy_from_user(reg->data, (void __user *) io.data,
4306  io.transfer_size, ctx)) {
4307  return -EFAULT;
4308  }
4309 
4310  return ecrt_reg_request_write(reg, io.address, io.transfer_size);
4311 }
4312 
4313 /****************************************************************************/
4314 
4320  ec_master_t *master,
4321  void *arg,
4322  ec_ioctl_context_t *ctx
4323  )
4324 {
4325  ec_ioctl_reg_request_t io;
4326  ec_slave_config_t *sc;
4327  ec_reg_request_t *reg;
4328 
4329  if (unlikely(!ctx->requested)) {
4330  return -EPERM;
4331  }
4332 
4333  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4334  return -EFAULT;
4335  }
4336 
4337  /* no locking of master_sem needed, because neither sc nor reg will not be
4338  * deleted in the meantime. */
4339 
4340  if (!(sc = ec_master_get_config(master, io.config_index))) {
4341  return -ENOENT;
4342  }
4343 
4344  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4345  return -ENOENT;
4346  }
4347 
4348  if (io.transfer_size > reg->mem_size) {
4349  return -ENOBUFS;
4350  }
4351 
4352  return ecrt_reg_request_read(reg, io.address, io.transfer_size);
4353 }
4354 
4355 /****************************************************************************/
4356 
4362  ec_master_t *master,
4363  void *arg,
4364  ec_ioctl_context_t *ctx
4365  )
4366 {
4367  ec_ioctl_voe_t data;
4368  ec_slave_config_t *sc;
4369  ec_voe_handler_t *voe;
4370  uint32_t vendor_id;
4371  uint16_t vendor_type;
4372 
4373  if (unlikely(!ctx->requested))
4374  return -EPERM;
4375 
4376  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4377  return -EFAULT;
4378 
4379  if (ec_copy_from_user(&vendor_id, data.vendor_id, sizeof(vendor_id), ctx))
4380  return -EFAULT;
4381 
4382  if (ec_copy_from_user(&vendor_type, data.vendor_type,
4383  sizeof(vendor_type), ctx))
4384  return -EFAULT;
4385 
4386  /* no locking of master_sem needed, because neither sc nor voe will not be
4387  * deleted in the meantime. */
4388 
4389  if (!(sc = ec_master_get_config(master, data.config_index))) {
4390  return -ENOENT;
4391  }
4392 
4393  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4394  return -ENOENT;
4395  }
4396 
4397  return ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
4398 }
4399 
4400 /****************************************************************************/
4401 
4407  ec_master_t *master,
4408  void *arg,
4409  ec_ioctl_context_t *ctx
4410  )
4411 {
4412  ec_ioctl_voe_t data;
4413  ec_slave_config_t *sc;
4414  ec_voe_handler_t *voe;
4415  uint32_t vendor_id;
4416  uint16_t vendor_type;
4417  int ret;
4418 
4419  if (unlikely(!ctx->requested))
4420  return -EPERM;
4421 
4422  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4423  return -EFAULT;
4424 
4425  /* no locking of master_sem needed, because neither sc nor voe will not be
4426  * deleted in the meantime. */
4427 
4428  if (!(sc = ec_master_get_config(master, data.config_index))) {
4429  return -ENOENT;
4430  }
4431 
4432  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4433  return -ENOENT;
4434  }
4435 
4436  ret = ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
4437  if (ret)
4438  return ret;
4439 
4440  if (likely(data.vendor_id))
4441  if (ec_copy_to_user(data.vendor_id, &vendor_id,
4442  sizeof(vendor_id), ctx))
4443  return -EFAULT;
4444 
4445  if (likely(data.vendor_type))
4446  if (ec_copy_to_user(data.vendor_type, &vendor_type,
4447  sizeof(vendor_type), ctx))
4448  return -EFAULT;
4449 
4450  return 0;
4451 }
4452 
4453 /****************************************************************************/
4454 
4460  ec_master_t *master,
4461  void *arg,
4462  ec_ioctl_context_t *ctx
4463  )
4464 {
4465  ec_ioctl_voe_t data;
4466  ec_slave_config_t *sc;
4467  ec_voe_handler_t *voe;
4468 
4469  if (unlikely(!ctx->requested))
4470  return -EPERM;
4471 
4472  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4473  return -EFAULT;
4474 
4475  /* no locking of master_sem needed, because neither sc nor voe will not be
4476  * deleted in the meantime. */
4477 
4478  if (!(sc = ec_master_get_config(master, data.config_index))) {
4479  return -ENOENT;
4480  }
4481 
4482  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4483  return -ENOENT;
4484  }
4485 
4486  return ecrt_voe_handler_read(voe);
4487 }
4488 
4489 /****************************************************************************/
4490 
4496  ec_master_t *master,
4497  void *arg,
4498  ec_ioctl_context_t *ctx
4499  )
4500 {
4501  ec_ioctl_voe_t data;
4502  ec_slave_config_t *sc;
4503  ec_voe_handler_t *voe;
4504 
4505  if (unlikely(!ctx->requested))
4506  return -EPERM;
4507 
4508  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4509  return -EFAULT;
4510 
4511  /* no locking of master_sem needed, because neither sc nor voe will not be
4512  * deleted in the meantime. */
4513 
4514  if (!(sc = ec_master_get_config(master, data.config_index))) {
4515  return -ENOENT;
4516  }
4517 
4518  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4519  return -ENOENT;
4520  }
4521 
4522  return ecrt_voe_handler_read_nosync(voe);
4523 }
4524 
4525 /****************************************************************************/
4526 
4532  ec_master_t *master,
4533  void *arg,
4534  ec_ioctl_context_t *ctx
4535  )
4536 {
4537  ec_ioctl_voe_t data;
4538  ec_slave_config_t *sc;
4539  ec_voe_handler_t *voe;
4540 
4541  if (unlikely(!ctx->requested))
4542  return -EPERM;
4543 
4544  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4545  return -EFAULT;
4546 
4547  /* no locking of master_sem needed, because neither sc nor voe will not be
4548  * deleted in the meantime. */
4549 
4550  if (!(sc = ec_master_get_config(master, data.config_index))) {
4551  return -ENOENT;
4552  }
4553 
4554  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4555  return -ENOENT;
4556  }
4557 
4558  if (data.size) {
4559  if (data.size > ec_voe_handler_mem_size(voe))
4560  return -ENOBUFS;
4561 
4562  if (ec_copy_from_user(ecrt_voe_handler_data(voe),
4563  (void __user *) data.data, data.size, ctx))
4564  return -EFAULT;
4565  }
4566 
4567  return ecrt_voe_handler_write(voe, data.size);
4568 }
4569 
4570 /****************************************************************************/
4571 
4577  ec_master_t *master,
4578  void *arg,
4579  ec_ioctl_context_t *ctx
4580  )
4581 {
4582  ec_ioctl_voe_t data;
4583  ec_slave_config_t *sc;
4584  ec_voe_handler_t *voe;
4585 
4586  if (unlikely(!ctx->requested))
4587  return -EPERM;
4588 
4589  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4590  return -EFAULT;
4591 
4592  /* no locking of master_sem needed, because neither sc nor voe will not be
4593  * deleted in the meantime. */
4594 
4595  if (!(sc = ec_master_get_config(master, data.config_index))) {
4596  return -ENOENT;
4597  }
4598 
4599  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4600  return -ENOENT;
4601  }
4602 
4603  if (ec_ioctl_lock_interruptible(&master->io_mutex))
4604  return -EINTR;
4605 
4606  data.state = ecrt_voe_handler_execute(voe);
4607  ec_ioctl_unlock(&master->io_mutex);
4608  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
4609  data.size = ecrt_voe_handler_data_size(voe);
4610  else
4611  data.size = 0;
4612 
4613  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
4614  return -EFAULT;
4615 
4616  return 0;
4617 }
4618 
4619 /****************************************************************************/
4620 
4626  ec_master_t *master,
4627  void *arg,
4628  ec_ioctl_context_t *ctx
4629  )
4630 {
4631  ec_ioctl_voe_t data;
4632  ec_slave_config_t *sc;
4633  ec_voe_handler_t *voe;
4634 
4635  if (unlikely(!ctx->requested))
4636  return -EPERM;
4637 
4638  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4639  return -EFAULT;
4640 
4641  /* no locking of master_sem needed, because neither sc nor voe will not be
4642  * deleted in the meantime. */
4643 
4644  if (!(sc = ec_master_get_config(master, data.config_index))) {
4645  return -ENOENT;
4646  }
4647 
4648  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4649  return -ENOENT;
4650  }
4651 
4652  if (ec_copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
4653  ecrt_voe_handler_data_size(voe), ctx))
4654  return -EFAULT;
4655 
4656  return 0;
4657 }
4658 
4659 /****************************************************************************/
4660 
4666  ec_master_t *master,
4667  void *arg
4668  )
4669 {
4670  ec_ioctl_slave_foe_t io;
4671  ec_foe_request_t request;
4672  ec_slave_t *slave;
4673  int ret;
4674 
4675  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4676  return -EFAULT;
4677  }
4678 
4679  ec_foe_request_init(&request, io.file_name);
4680  ret = ec_foe_request_alloc(&request, 10000); // FIXME
4681  if (ret) {
4682  ec_foe_request_clear(&request);
4683  return ret;
4684  }
4685 
4686  ec_foe_request_read(&request);
4687 
4688  if (down_interruptible(&master->master_sem)) {
4689  ec_foe_request_clear(&request);
4690  return -EINTR;
4691  }
4692 
4693  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4694  up(&master->master_sem);
4695  ec_foe_request_clear(&request);
4696  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4697  io.slave_position);
4698  return -EINVAL;
4699  }
4700 
4701  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
4702 
4703  // schedule request.
4704  list_add_tail(&request.list, &slave->foe_requests);
4705 
4706  up(&master->master_sem);
4707 
4708  // wait for processing through FSM
4709  if (wait_event_interruptible(master->request_queue,
4710  request.state != EC_INT_REQUEST_QUEUED)) {
4711  // interrupted by signal
4712  down(&master->master_sem);
4713  if (request.state == EC_INT_REQUEST_QUEUED) {
4714  list_del(&request.list);
4715  up(&master->master_sem);
4716  ec_foe_request_clear(&request);
4717  return -EINTR;
4718  }
4719  // request already processing: interrupt not possible.
4720  up(&master->master_sem);
4721  }
4722 
4723  // wait until master FSM has finished processing
4724  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4725 
4726  io.result = request.result;
4727  io.error_code = request.error_code;
4728 
4729  if (request.state != EC_INT_REQUEST_SUCCESS) {
4730  io.data_size = 0;
4731  ret = -EIO;
4732  } else {
4733  if (request.data_size > io.buffer_size) {
4734  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4735  ec_foe_request_clear(&request);
4736  return -ENOBUFS;
4737  }
4738  io.data_size = request.data_size;
4739  if (copy_to_user((void __user *) io.buffer,
4740  request.buffer, io.data_size)) {
4741  ec_foe_request_clear(&request);
4742  return -EFAULT;
4743  }
4744  ret = 0;
4745  }
4746 
4747  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4748  ret = -EFAULT;
4749  }
4750 
4751  ec_foe_request_clear(&request);
4752  return ret;
4753 }
4754 
4755 /****************************************************************************/
4756 
4762  ec_master_t *master,
4763  void *arg
4764  )
4765 {
4766  ec_ioctl_slave_foe_t io;
4767  ec_foe_request_t request;
4768  ec_slave_t *slave;
4769  int ret;
4770 
4771  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4772  return -EFAULT;
4773  }
4774 
4775  ec_foe_request_init(&request, io.file_name);
4776 
4777  ret = ec_foe_request_alloc(&request, io.buffer_size);
4778  if (ret) {
4779  ec_foe_request_clear(&request);
4780  return ret;
4781  }
4782 
4783  if (copy_from_user(request.buffer,
4784  (void __user *) io.buffer, io.buffer_size)) {
4785  ec_foe_request_clear(&request);
4786  return -EFAULT;
4787  }
4788 
4789  request.data_size = io.buffer_size;
4790  ec_foe_request_write(&request);
4791 
4792  if (down_interruptible(&master->master_sem)) {
4793  ec_foe_request_clear(&request);
4794  return -EINTR;
4795  }
4796 
4797  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4798  up(&master->master_sem);
4799  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4800  io.slave_position);
4801  ec_foe_request_clear(&request);
4802  return -EINVAL;
4803  }
4804 
4805  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4806 
4807  // schedule FoE write request.
4808  list_add_tail(&request.list, &slave->foe_requests);
4809 
4810  up(&master->master_sem);
4811 
4812  // wait for processing through FSM
4813  if (wait_event_interruptible(master->request_queue,
4814  request.state != EC_INT_REQUEST_QUEUED)) {
4815  // interrupted by signal
4816  down(&master->master_sem);
4817  if (request.state == EC_INT_REQUEST_QUEUED) {
4818  // abort request
4819  list_del(&request.list);
4820  up(&master->master_sem);
4821  ec_foe_request_clear(&request);
4822  return -EINTR;
4823  }
4824  up(&master->master_sem);
4825  }
4826 
4827  // wait until master FSM has finished processing
4828  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4829 
4830  io.result = request.result;
4831  io.error_code = request.error_code;
4832 
4833  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4834 
4835  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4836  ret = -EFAULT;
4837  }
4838 
4839  ec_foe_request_clear(&request);
4840  return ret;
4841 }
4842 
4843 /****************************************************************************/
4844 
4850  ec_master_t *master,
4851  void *arg
4852  )
4853 {
4854  ec_ioctl_slave_soe_read_t ioctl;
4855  u8 *data;
4856  int retval;
4857 
4858  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4859  return -EFAULT;
4860  }
4861 
4862  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4863  if (!data) {
4864  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4865  ioctl.mem_size);
4866  return -ENOMEM;
4867  }
4868 
4869  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4870  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4871  &ioctl.error_code);
4872  if (retval) {
4873  kfree(data);
4874  return retval;
4875  }
4876 
4877  if (copy_to_user((void __user *) ioctl.data,
4878  data, ioctl.data_size)) {
4879  kfree(data);
4880  return -EFAULT;
4881  }
4882  kfree(data);
4883 
4884  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4885  retval = -EFAULT;
4886  }
4887 
4888  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4889  return retval;
4890 }
4891 
4892 /****************************************************************************/
4893 
4899  ec_master_t *master,
4900  void *arg
4901  )
4902 {
4903  ec_ioctl_slave_soe_write_t ioctl;
4904  u8 *data;
4905  int retval;
4906 
4907  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4908  return -EFAULT;
4909  }
4910 
4911  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4912  if (!data) {
4913  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4914  ioctl.data_size);
4915  return -ENOMEM;
4916  }
4917  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4918  kfree(data);
4919  return -EFAULT;
4920  }
4921 
4922  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4923  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4924  &ioctl.error_code);
4925  kfree(data);
4926  if (retval) {
4927  return retval;
4928  }
4929 
4930  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4931  retval = -EFAULT;
4932  }
4933 
4934  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4935  return retval;
4936 }
4937 
4938 /*****************************************************************************
4939  * ioctl() file operation functions
4940  ****************************************************************************/
4941 
4947 #ifndef EC_IOCTL_RTDM
4948 static long ec_ioctl_nrt(
4949  ec_master_t *master,
4950  ec_ioctl_context_t *ctx,
4951  unsigned int cmd,
4952  void *arg );
4953 #endif
4954 
4955 /****************************************************************************/
4956 
4962 static long ec_ioctl_both(
4963  ec_master_t *master,
4964  ec_ioctl_context_t *ctx,
4965  unsigned int cmd,
4966  void *arg
4967  )
4968 {
4969  int ret;
4970 
4971  switch (cmd) {
4972  case EC_IOCTL_MODULE:
4973  ret = ec_ioctl_module(arg, ctx);
4974  break;
4975  case EC_IOCTL_MASTER_RESCAN:
4976  if (!ctx->writable) {
4977  ret = -EPERM;
4978  break;
4979  }
4980  ret = ec_ioctl_master_rescan(master, arg);
4981  break;
4982  case EC_IOCTL_MASTER_STATE:
4983  ret = ec_ioctl_master_state(master, arg, ctx);
4984  break;
4985  case EC_IOCTL_MASTER_LINK_STATE:
4986  ret = ec_ioctl_master_link_state(master, arg, ctx);
4987  break;
4988  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4989  if (!ctx->writable) {
4990  ret = -EPERM;
4991  break;
4992  }
4993  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4994  break;
4995  case EC_IOCTL_SDO_REQUEST_DATA:
4996  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4997  break;
4998  case EC_IOCTL_SOE_REQUEST_TIMEOUT:
4999  if (!ctx->writable) {
5000  ret = -EPERM;
5001  break;
5002  }
5003  ret = ec_ioctl_soe_request_timeout(master, arg, ctx);
5004  break;
5005  case EC_IOCTL_SOE_REQUEST_DATA:
5006  ret = ec_ioctl_soe_request_data(master, arg, ctx);
5007  break;
5008  case EC_IOCTL_REG_REQUEST_DATA:
5009  ret = ec_ioctl_reg_request_data(master, arg, ctx);
5010  break;
5011  case EC_IOCTL_VOE_SEND_HEADER:
5012  if (!ctx->writable) {
5013  ret = -EPERM;
5014  break;
5015  }
5016  ret = ec_ioctl_voe_send_header(master, arg, ctx);
5017  break;
5018  case EC_IOCTL_VOE_DATA:
5019  ret = ec_ioctl_voe_data(master, arg, ctx);
5020  break;
5021  default:
5022 #ifdef EC_IOCTL_RTDM
5023  ret = -ENOTTY;
5024 #else
5025  /* chain non-rt commands for normal cdev */
5026  ret = ec_ioctl_nrt(master, ctx, cmd, arg);
5027 #endif
5028  break;
5029  }
5030 
5031  return ret;
5032 }
5033 
5034 /****************************************************************************/
5035 
5041 #ifdef EC_IOCTL_RTDM
5042 long ec_ioctl_rtdm_rt
5043 #else
5044 long ec_ioctl
5045 #endif
5046  (
5047  ec_master_t *master,
5048  ec_ioctl_context_t *ctx,
5049  unsigned int cmd,
5050  void *arg
5051  )
5052 {
5053 #if DEBUG_LATENCY
5054  cycles_t a = get_cycles(), b;
5055  unsigned int t;
5056 #endif
5057  long ret;
5058 
5059  switch (cmd) {
5060  case EC_IOCTL_SEND:
5061  if (!ctx->writable) {
5062  ret = -EPERM;
5063  break;
5064  }
5065  ret = ec_ioctl_send(master, arg, ctx);
5066  break;
5067  case EC_IOCTL_RECEIVE:
5068  if (!ctx->writable) {
5069  ret = -EPERM;
5070  break;
5071  }
5072  ret = ec_ioctl_receive(master, arg, ctx);
5073  break;
5074  case EC_IOCTL_APP_TIME:
5075  if (!ctx->writable) {
5076  ret = -EPERM;
5077  break;
5078  }
5079  ret = ec_ioctl_app_time(master, arg, ctx);
5080  break;
5081  case EC_IOCTL_SYNC_REF:
5082  if (!ctx->writable) {
5083  ret = -EPERM;
5084  break;
5085  }
5086  ret = ec_ioctl_sync_ref(master, arg, ctx);
5087  break;
5088  case EC_IOCTL_SYNC_REF_TO:
5089  if (!ctx->writable) {
5090  ret = -EPERM;
5091  break;
5092  }
5093  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
5094  break;
5095  case EC_IOCTL_SYNC_SLAVES:
5096  if (!ctx->writable) {
5097  ret = -EPERM;
5098  break;
5099  }
5100  ret = ec_ioctl_sync_slaves(master, arg, ctx);
5101  break;
5102  case EC_IOCTL_REF_CLOCK_TIME:
5103  if (!ctx->writable) {
5104  ret = -EPERM;
5105  break;
5106  }
5107  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
5108  break;
5109  case EC_IOCTL_SYNC_MON_QUEUE:
5110  if (!ctx->writable) {
5111  ret = -EPERM;
5112  break;
5113  }
5114  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
5115  break;
5116  case EC_IOCTL_SYNC_MON_PROCESS:
5117  if (!ctx->writable) {
5118  ret = -EPERM;
5119  break;
5120  }
5121  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
5122  break;
5123  case EC_IOCTL_RESET:
5124  if (!ctx->writable) {
5125  ret = -EPERM;
5126  break;
5127  }
5128  ret = ec_ioctl_reset(master, arg, ctx);
5129  break;
5130  case EC_IOCTL_SC_EMERG_POP:
5131  if (!ctx->writable) {
5132  ret = -EPERM;
5133  break;
5134  }
5135  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
5136  break;
5137  case EC_IOCTL_SC_EMERG_CLEAR:
5138  if (!ctx->writable) {
5139  ret = -EPERM;
5140  break;
5141  }
5142  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
5143  break;
5144  case EC_IOCTL_SC_EMERG_OVERRUNS:
5145  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
5146  break;
5147  case EC_IOCTL_SC_STATE:
5148  ret = ec_ioctl_sc_state(master, arg, ctx);
5149  break;
5150  case EC_IOCTL_DOMAIN_PROCESS:
5151  if (!ctx->writable) {
5152  ret = -EPERM;
5153  break;
5154  }
5155  ret = ec_ioctl_domain_process(master, arg, ctx);
5156  break;
5157  case EC_IOCTL_DOMAIN_QUEUE:
5158  if (!ctx->writable) {
5159  ret = -EPERM;
5160  break;
5161  }
5162  ret = ec_ioctl_domain_queue(master, arg, ctx);
5163  break;
5164  case EC_IOCTL_DOMAIN_STATE:
5165  ret = ec_ioctl_domain_state(master, arg, ctx);
5166  break;
5167  case EC_IOCTL_SDO_REQUEST_INDEX:
5168  if (!ctx->writable) {
5169  ret = -EPERM;
5170  break;
5171  }
5172  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
5173  break;
5174  case EC_IOCTL_SDO_REQUEST_STATE:
5175  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
5176  break;
5177  case EC_IOCTL_SDO_REQUEST_READ:
5178  if (!ctx->writable) {
5179  ret = -EPERM;
5180  break;
5181  }
5182  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
5183  break;
5184  case EC_IOCTL_SDO_REQUEST_WRITE:
5185  if (!ctx->writable) {
5186  ret = -EPERM;
5187  break;
5188  }
5189  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
5190  break;
5191  case EC_IOCTL_SOE_REQUEST_IDN:
5192  if (!ctx->writable) {
5193  ret = -EPERM;
5194  break;
5195  }
5196  ret = ec_ioctl_soe_request_index(master, arg, ctx);
5197  break;
5198  case EC_IOCTL_SOE_REQUEST_STATE:
5199  ret = ec_ioctl_soe_request_state(master, arg, ctx);
5200  break;
5201  case EC_IOCTL_SOE_REQUEST_READ:
5202  if (!ctx->writable) {
5203  ret = -EPERM;
5204  break;
5205  }
5206  ret = ec_ioctl_soe_request_read(master, arg, ctx);
5207  break;
5208  case EC_IOCTL_SOE_REQUEST_WRITE:
5209  if (!ctx->writable) {
5210  ret = -EPERM;
5211  break;
5212  }
5213  ret = ec_ioctl_soe_request_write(master, arg, ctx);
5214  break;
5215  case EC_IOCTL_REG_REQUEST_STATE:
5216  ret = ec_ioctl_reg_request_state(master, arg, ctx);
5217  break;
5218  case EC_IOCTL_REG_REQUEST_WRITE:
5219  if (!ctx->writable) {
5220  ret = -EPERM;
5221  break;
5222  }
5223  ret = ec_ioctl_reg_request_write(master, arg, ctx);
5224  break;
5225  case EC_IOCTL_REG_REQUEST_READ:
5226  if (!ctx->writable) {
5227  ret = -EPERM;
5228  break;
5229  }
5230  ret = ec_ioctl_reg_request_read(master, arg, ctx);
5231  break;
5232  case EC_IOCTL_VOE_REC_HEADER:
5233  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
5234  break;
5235  case EC_IOCTL_VOE_READ:
5236  if (!ctx->writable) {
5237  ret = -EPERM;
5238  break;
5239  }
5240  ret = ec_ioctl_voe_read(master, arg, ctx);
5241  break;
5242  case EC_IOCTL_VOE_READ_NOSYNC:
5243  if (!ctx->writable) {
5244  ret = -EPERM;
5245  break;
5246  }
5247  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
5248  break;
5249  case EC_IOCTL_VOE_WRITE:
5250  if (!ctx->writable) {
5251  ret = -EPERM;
5252  break;
5253  }
5254  ret = ec_ioctl_voe_write(master, arg, ctx);
5255  break;
5256  case EC_IOCTL_VOE_EXEC:
5257  if (!ctx->writable) {
5258  ret = -EPERM;
5259  break;
5260  }
5261  ret = ec_ioctl_voe_exec(master, arg, ctx);
5262  break;
5263  default:
5264  ret = ec_ioctl_both(master, ctx, cmd, arg);
5265  break;
5266  }
5267 
5268 #if DEBUG_LATENCY
5269  b = get_cycles();
5270  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5271  if (t > 50) {
5272  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5273  _IOC_NR(cmd), t);
5274  }
5275 #endif
5276 
5277  return ret;
5278 }
5279 
5280 /****************************************************************************/
5281 
5287 #ifdef EC_IOCTL_RTDM
5288 long ec_ioctl_rtdm_nrt
5289 #else
5290 static long ec_ioctl_nrt
5291 #endif
5292  (
5293  ec_master_t *master,
5294  ec_ioctl_context_t *ctx,
5295  unsigned int cmd,
5296  void *arg
5297  )
5298 {
5299 #if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM)
5300  cycles_t a = get_cycles(), b;
5301  unsigned int t;
5302 #endif
5303  int ret;
5304 
5305  switch (cmd) {
5306  case EC_IOCTL_MASTER:
5307  ret = ec_ioctl_master(master, arg);
5308  break;
5309  case EC_IOCTL_SLAVE:
5310  ret = ec_ioctl_slave(master, arg);
5311  break;
5312  case EC_IOCTL_SLAVE_SYNC:
5313  ret = ec_ioctl_slave_sync(master, arg);
5314  break;
5315  case EC_IOCTL_SLAVE_SYNC_PDO:
5316  ret = ec_ioctl_slave_sync_pdo(master, arg);
5317  break;
5318  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
5320  break;
5321  case EC_IOCTL_DOMAIN:
5322  ret = ec_ioctl_domain(master, arg);
5323  break;
5324  case EC_IOCTL_DOMAIN_FMMU:
5325  ret = ec_ioctl_domain_fmmu(master, arg);
5326  break;
5327  case EC_IOCTL_DOMAIN_DATA:
5328  ret = ec_ioctl_domain_data(master, arg);
5329  break;
5330  case EC_IOCTL_MASTER_DEBUG:
5331  if (!ctx->writable) {
5332  ret = -EPERM;
5333  break;
5334  }
5335  ret = ec_ioctl_master_debug(master, arg);
5336  break;
5337  case EC_IOCTL_SLAVE_STATE:
5338  if (!ctx->writable) {
5339  ret = -EPERM;
5340  break;
5341  }
5342  ret = ec_ioctl_slave_state(master, arg);
5343  break;
5344  case EC_IOCTL_SLAVE_SDO:
5345  ret = ec_ioctl_slave_sdo(master, arg);
5346  break;
5347  case EC_IOCTL_SLAVE_SDO_ENTRY:
5348  ret = ec_ioctl_slave_sdo_entry(master, arg);
5349  break;
5350  case EC_IOCTL_SLAVE_SDO_UPLOAD:
5351  if (!ctx->writable) {
5352  ret = -EPERM;
5353  break;
5354  }
5355  ret = ec_ioctl_slave_sdo_upload(master, arg);
5356  break;
5357  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
5358  if (!ctx->writable) {
5359  ret = -EPERM;
5360  break;
5361  }
5362  ret = ec_ioctl_slave_sdo_download(master, arg);
5363  break;
5364  case EC_IOCTL_SLAVE_SII_READ:
5365  ret = ec_ioctl_slave_sii_read(master, arg);
5366  break;
5367  case EC_IOCTL_SLAVE_SII_WRITE:
5368  if (!ctx->writable) {
5369  ret = -EPERM;
5370  break;
5371  }
5372  ret = ec_ioctl_slave_sii_write(master, arg);
5373  break;
5374  case EC_IOCTL_SLAVE_REG_READ:
5375  if (!ctx->writable) {
5376  ret = -EPERM;
5377  break;
5378  }
5379  ret = ec_ioctl_slave_reg_read(master, arg);
5380  break;
5381  case EC_IOCTL_SLAVE_REG_WRITE:
5382  if (!ctx->writable) {
5383  ret = -EPERM;
5384  break;
5385  }
5386  ret = ec_ioctl_slave_reg_write(master, arg);
5387  break;
5388  case EC_IOCTL_SLAVE_FOE_READ:
5389  if (!ctx->writable) {
5390  ret = -EPERM;
5391  break;
5392  }
5393  ret = ec_ioctl_slave_foe_read(master, arg);
5394  break;
5395  case EC_IOCTL_SLAVE_FOE_WRITE:
5396  if (!ctx->writable) {
5397  ret = -EPERM;
5398  break;
5399  }
5400  ret = ec_ioctl_slave_foe_write(master, arg);
5401  break;
5402  case EC_IOCTL_SLAVE_SOE_READ:
5403  if (!ctx->writable) {
5404  ret = -EPERM;
5405  break;
5406  }
5407  ret = ec_ioctl_slave_soe_read(master, arg);
5408  break;
5409  case EC_IOCTL_SLAVE_SOE_WRITE:
5410  if (!ctx->writable) {
5411  ret = -EPERM;
5412  break;
5413  }
5414  ret = ec_ioctl_slave_soe_write(master, arg);
5415  break;
5416 #ifdef EC_EOE
5417  case EC_IOCTL_SLAVE_EOE_IP_PARAM:
5418  if (!ctx->writable) {
5419  ret = -EPERM;
5420  break;
5421  }
5422  ret = ec_ioctl_slave_eoe_ip_param(master, arg);
5423  break;
5424 #endif
5425  case EC_IOCTL_CONFIG:
5426  ret = ec_ioctl_config(master, arg);
5427  break;
5428  case EC_IOCTL_CONFIG_PDO:
5429  ret = ec_ioctl_config_pdo(master, arg);
5430  break;
5431  case EC_IOCTL_CONFIG_PDO_ENTRY:
5432  ret = ec_ioctl_config_pdo_entry(master, arg);
5433  break;
5434  case EC_IOCTL_CONFIG_SDO:
5435  ret = ec_ioctl_config_sdo(master, arg);
5436  break;
5437  case EC_IOCTL_CONFIG_IDN:
5438  ret = ec_ioctl_config_idn(master, arg);
5439  break;
5440  case EC_IOCTL_CONFIG_FLAG:
5441  ret = ec_ioctl_config_flag(master, arg);
5442  break;
5443 #ifdef EC_EOE
5444  case EC_IOCTL_CONFIG_EOE_IP_PARAM:
5445  ret = ec_ioctl_config_ip(master, arg);
5446  break;
5447  case EC_IOCTL_EOE_HANDLER:
5448  ret = ec_ioctl_eoe_handler(master, arg);
5449  break;
5450 #endif
5451 
5452  /* Application interface */
5453 
5454  case EC_IOCTL_REQUEST:
5455  if (!ctx->writable) {
5456  ret = -EPERM;
5457  break;
5458  }
5459  ret = ec_ioctl_request(master, arg, ctx);
5460  break;
5461  case EC_IOCTL_CREATE_DOMAIN:
5462  if (!ctx->writable) {
5463  ret = -EPERM;
5464  break;
5465  }
5466  ret = ec_ioctl_create_domain(master, arg, ctx);
5467  break;
5468  case EC_IOCTL_CREATE_SLAVE_CONFIG:
5469  if (!ctx->writable) {
5470  ret = -EPERM;
5471  break;
5472  }
5473  ret = ec_ioctl_create_slave_config(master, arg, ctx);
5474  break;
5475  case EC_IOCTL_SELECT_REF_CLOCK:
5476  if (!ctx->writable) {
5477  ret = -EPERM;
5478  break;
5479  }
5480  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
5481  break;
5482  case EC_IOCTL_ACTIVATE:
5483  if (!ctx->writable) {
5484  ret = -EPERM;
5485  break;
5486  }
5487  ret = ec_ioctl_activate(master, arg, ctx);
5488  break;
5489  case EC_IOCTL_DEACTIVATE:
5490  if (!ctx->writable) {
5491  ret = -EPERM;
5492  break;
5493  }
5494  ret = ec_ioctl_deactivate(master, arg, ctx);
5495  break;
5496  case EC_IOCTL_SC_SYNC:
5497  if (!ctx->writable) {
5498  ret = -EPERM;
5499  break;
5500  }
5501  ret = ec_ioctl_sc_sync(master, arg, ctx);
5502  break;
5503  case EC_IOCTL_SC_WATCHDOG:
5504  if (!ctx->writable) {
5505  ret = -EPERM;
5506  break;
5507  }
5508  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
5509  break;
5510  case EC_IOCTL_SC_PDO_MODE:
5511  if (!ctx->writable) {
5512  ret = -EPERM;
5513  break;
5514  }
5515  ret = ec_ioctl_sc_pdo_mode(master, arg, ctx);
5516  break;
5517  case EC_IOCTL_SC_ADD_PDO:
5518  if (!ctx->writable) {
5519  ret = -EPERM;
5520  break;
5521  }
5522  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
5523  break;
5524  case EC_IOCTL_SC_CLEAR_PDOS:
5525  if (!ctx->writable) {
5526  ret = -EPERM;
5527  break;
5528  }
5529  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
5530  break;
5531  case EC_IOCTL_SC_ADD_ENTRY:
5532  if (!ctx->writable) {
5533  ret = -EPERM;
5534  break;
5535  }
5536  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
5537  break;
5538  case EC_IOCTL_SC_CLEAR_ENTRIES:
5539  if (!ctx->writable) {
5540  ret = -EPERM;
5541  break;
5542  }
5543  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
5544  break;
5545  case EC_IOCTL_SC_REG_PDO_ENTRY:
5546  if (!ctx->writable) {
5547  ret = -EPERM;
5548  break;
5549  }
5550  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
5551  break;
5552  case EC_IOCTL_SC_REG_PDO_POS:
5553  if (!ctx->writable) {
5554  ret = -EPERM;
5555  break;
5556  }
5557  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
5558  break;
5559  case EC_IOCTL_SC_DC:
5560  if (!ctx->writable) {
5561  ret = -EPERM;
5562  break;
5563  }
5564  ret = ec_ioctl_sc_dc(master, arg, ctx);
5565  break;
5566  case EC_IOCTL_SC_SDO:
5567  if (!ctx->writable) {
5568  ret = -EPERM;
5569  break;
5570  }
5571  ret = ec_ioctl_sc_sdo(master, arg, ctx);
5572  break;
5573  case EC_IOCTL_SC_EMERG_SIZE:
5574  if (!ctx->writable) {
5575  ret = -EPERM;
5576  break;
5577  }
5578  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
5579  break;
5580  case EC_IOCTL_SC_SDO_REQUEST:
5581  if (!ctx->writable) {
5582  ret = -EPERM;
5583  break;
5584  }
5585  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
5586  break;
5587  case EC_IOCTL_SC_SOE_REQUEST:
5588  if (!ctx->writable) {
5589  ret = -EPERM;
5590  break;
5591  }
5592  ret = ec_ioctl_sc_create_soe_request(master, arg, ctx);
5593  break;
5594  case EC_IOCTL_SC_REG_REQUEST:
5595  if (!ctx->writable) {
5596  ret = -EPERM;
5597  break;
5598  }
5599  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
5600  break;
5601  case EC_IOCTL_SC_VOE:
5602  if (!ctx->writable) {
5603  ret = -EPERM;
5604  break;
5605  }
5606  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
5607  break;
5608  case EC_IOCTL_SC_IDN:
5609  if (!ctx->writable) {
5610  ret = -EPERM;
5611  break;
5612  }
5613  ret = ec_ioctl_sc_idn(master, arg, ctx);
5614  break;
5615  case EC_IOCTL_SC_FLAG:
5616  if (!ctx->writable) {
5617  ret = -EPERM;
5618  break;
5619  }
5620  ret = ec_ioctl_sc_flag(master, arg, ctx);
5621  break;
5622  case EC_IOCTL_SC_STATE_TIMEOUT:
5623  if (!ctx->writable) {
5624  ret = -EPERM;
5625  break;
5626  }
5627  ret = ec_ioctl_sc_state_timeout(master, arg, ctx);
5628  break;
5629 #ifdef EC_EOE
5630  case EC_IOCTL_SC_EOE_IP_PARAM:
5631  if (!ctx->writable) {
5632  ret = -EPERM;
5633  break;
5634  }
5635  ret = ec_ioctl_sc_ip(master, arg, ctx);
5636  break;
5637 #endif
5638  case EC_IOCTL_DOMAIN_SIZE:
5639  ret = ec_ioctl_domain_size(master, arg, ctx);
5640  break;
5641  case EC_IOCTL_DOMAIN_OFFSET:
5642  ret = ec_ioctl_domain_offset(master, arg, ctx);
5643  break;
5644  case EC_IOCTL_SET_SEND_INTERVAL:
5645  if (!ctx->writable) {
5646  ret = -EPERM;
5647  break;
5648  }
5649  ret = ec_ioctl_set_send_interval(master, arg, ctx);
5650  break;
5651  case EC_IOCTL_SII_CACHING:
5652  if (!ctx->writable) {
5653  ret = -EPERM;
5654  break;
5655  }
5656  ret = ec_ioctl_sii_caching(master, arg, ctx);
5657  break;
5658  default:
5659 #ifdef EC_IOCTL_RTDM
5660  ret = ec_ioctl_both(master, ctx, cmd, arg);
5661 #else
5662  ret = -ENOTTY;
5663 #endif
5664  break;
5665  }
5666 
5667 #if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM)
5668  b = get_cycles();
5669  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5670  if (t > 50) {
5671  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5672  _IOC_NR(cmd), t);
5673  }
5674 #endif
5675 
5676  return ret;
5677 }
5678 
5679 /****************************************************************************/
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:155
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:3728
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:515
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:177
uint32_t revision_number
Revision number.
Definition: slave.h:131
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:2982
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:980
int ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2761
uint16_t boot_rx_mailbox_offset
Bootstrap rx mailbox address.
Definition: slave.h:133
#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:218
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:603
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:3699
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:3847
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:782
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:3172
int ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:172
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:2163
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:307
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:3556
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:493
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:100
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:4319
int ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2831
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:78
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:4361
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:5292
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:2115
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:119
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:181
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:97
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:537
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:581
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:715
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:186
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:3361
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:333
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: ioctl.c:3590
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:930
#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:4227
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:4272
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:2302
ec_slave_port_link_t link
Port link status.
Definition: slave.h:114
int ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3220
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:600
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:723
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:2026
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:3134
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:449
int ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:194
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:688
uint32_t serial_number
Serial number.
Definition: slave.h:132
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:154
char * order
Order number.
Definition: slave.h:151
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:2194
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:2233
uint16_t index
SDO index.
Definition: sdo_request.h:42
unsigned int scan_index
Index of slave currently scanned.
Definition: master.h:249
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:2276
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:237
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:3421
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:308
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:3164
struct list_head domains
List of domains.
Definition: master.h:234
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: ioctl.c:4849
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:225
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:156
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:2010
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:2634
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:136
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:208
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:985
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:311
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:478
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:160
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:2641
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:105
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:3525
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:138
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:4665
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:2130
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:139
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:2138
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:3015
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:693
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:3200
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:4008
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:4761
#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:135
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:3060
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:170
struct semaphore master_sem
Master semaphore.
Definition: master.h:205
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:3692
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:3233
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:3811
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:315
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:3766
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:2258
#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:215
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:52
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:2196
ec_master_phase_t phase
Master phase.
Definition: master.h:219
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:3268
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:2476
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain&#39;s process data.
Definition: domain.c:471
struct semaphore device_sem
Device semaphore.
Definition: master.h:214
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:2566
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:141
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:2179
int ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:3188
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:2800
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:70
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:2145
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:205
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:137
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:203
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:3364
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:209
struct rt_mutex io_mutex
Mutex used in IDLE and OP phase.
Definition: master.h:296
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:228
unsigned int scan_busy
Current scan state.
Definition: master.h:248
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:144
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:3601
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:2086
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:5046
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:113
#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:42
unsigned int active
Master has been activated.
Definition: master.h:220
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: ioctl.c:2054
ec_master_t * master
Master owning the slave.
Definition: slave.h:172
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:4495
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:427
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:958
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:4180
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:206
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:752
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:2423
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:376
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:2246
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:2333
#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:3021
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:2220
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:3262
uint16_t data_type
Data type.
Definition: sdo_entry.h:50
struct list_head configs
List of slave configurations.
Definition: master.h:233
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:133
unsigned int opened
net_device is opened
Definition: ethernet.h:85
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:2385
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:559
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:3111
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:4531
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3617
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:4406
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:4091
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:838
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:2112
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:936
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:2900
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:84
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:471
u64 tx_errors
Number of transmit errors.
Definition: device.h:111
uint16_t effective_alias
Effective alias address.
Definition: slave.h:179
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:2521
unsigned int sii_caching
SII caching mode.
Definition: master.h:286
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:226
ec_direction_t dir
Direction.
Definition: voe_handler.h:49
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:4459
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:3218
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2211
int ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain&#39;s datagrams.
Definition: domain.c:502
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:2600
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:4962
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:134
#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:4140
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:3282
uint8_t * ecrt_voe_handler_data(const ec_voe_handler_t *voe)
Access to the VoE handler&#39;s data.
Definition: voe_handler.c:158
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:4055
Access rights in PREOP.
Definition: globals.h:195
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:115
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:2406
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:2036
ec_sii_page_t sii_page
The SII contents, either fetched or taken from the cache.
Definition: slave.h:213
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:116
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:134
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2841
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:585
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:150
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:728
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:3936
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:2703
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1952
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:236
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:357
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:3650
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:204
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:3463
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:2687
struct work_struct sc_reset_work
Task to reset slave configuration.
Definition: master.h:313
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:149
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:165
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:206
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:3972
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:2879
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:2938
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:3522
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:3271
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:2953
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:173
unsigned int index
Index.
Definition: master.h:195
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:2082
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:4576
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:130
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:75
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:217
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:801
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:187
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:159
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:140
EtherCAT master.
Definition: master.h:194
struct list_head list
List item.
Definition: reg_request.h:41
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:228
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:2750
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:207
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:4898
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:3249
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:3148
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:4625
char * name
Slave name.
Definition: slave.h:152
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:944
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:3896
EtherCAT domain.
Definition: domain.h:46
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:83
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:2359
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:3442
uint32_t vendor_id
Vendor ID.
Definition: slave.h:129
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:118
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:246
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:625
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:3310
struct list_head list
List item.
Definition: foe_request.h:43
unsigned int has_general
General category present.
Definition: slave.h:148
unsigned int tx_queued_frames
number of frames in the queue
Definition: ethernet.h:99
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:2669
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:183
unsigned int sii_parallel_words
How many SII words the slave can read at once.
Definition: slave.h:215
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:394