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