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