IgH EtherCAT Master  1.5.3
ioctl.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 2006-2023 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  * ---
21  *
22  * The license mentioned above concerns the source code only. Using the
23  * EtherCAT technology and brand is only permitted in compliance with the
24  * industrial property and similar rights of Beckhoff Automation GmbH.
25  *
26  *****************************************************************************/
27 
33 /*****************************************************************************/
34 
35 #include <linux/module.h>
36 #include <linux/vmalloc.h>
37 
38 #include "master.h"
39 #include "slave_config.h"
40 #include "voe_handler.h"
41 #include "ethernet.h"
42 #include "ioctl.h"
43 
48 #define DEBUG_LATENCY 0
49 
52 #if 0
53 #define ATTRIBUTES __attribute__ ((__noinline__))
54 #else
55 #define ATTRIBUTES
56 #endif
57 
58 /*****************************************************************************/
59 
62 static void ec_ioctl_strcpy(
63  char *target,
64  const char *source
65  )
66 {
67  if (source) {
68  strncpy(target, source, EC_IOCTL_STRING_SIZE);
69  target[EC_IOCTL_STRING_SIZE - 1] = 0;
70  } else {
71  target[0] = 0;
72  }
73 }
74 
75 /*****************************************************************************/
76 
82  void *arg
83  )
84 {
85  ec_ioctl_module_t data;
86 
87  data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
88  data.master_count = ec_master_count();
89 
90  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
91  return -EFAULT;
92 
93  return 0;
94 }
95 
96 /*****************************************************************************/
97 
104  void *arg
105  )
106 {
107  ec_ioctl_master_t io;
108  unsigned int dev_idx, j;
109 
110  if (down_interruptible(&master->master_sem)) {
111  return -EINTR;
112  }
113 
114  io.slave_count = master->slave_count;
115  io.config_count = ec_master_config_count(master);
116  io.domain_count = ec_master_domain_count(master);
117 #ifdef EC_EOE
118  io.eoe_handler_count = ec_master_eoe_handler_count(master);
119 #else
120  io.eoe_handler_count = 0;
121 #endif
122  io.phase = (uint8_t) master->phase;
123  io.active = (uint8_t) master->active;
124  io.scan_busy = master->scan_busy;
125 
126  up(&master->master_sem);
127 
128  if (down_interruptible(&master->device_sem)) {
129  return -EINTR;
130  }
131 
132  for (dev_idx = EC_DEVICE_MAIN;
133  dev_idx < ec_master_num_devices(master); dev_idx++) {
134  ec_device_t *device = &master->devices[dev_idx];
135 
136  if (device->dev) {
137  memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
138  ETH_ALEN);
139  } else {
140  memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
141  ETH_ALEN);
142  }
143  io.devices[dev_idx].attached = device->dev ? 1 : 0;
144  io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
145  io.devices[dev_idx].tx_count = device->tx_count;
146  io.devices[dev_idx].rx_count = device->rx_count;
147  io.devices[dev_idx].tx_bytes = device->tx_bytes;
148  io.devices[dev_idx].rx_bytes = device->rx_bytes;
149  io.devices[dev_idx].tx_errors = device->tx_errors;
150  for (j = 0; j < EC_RATE_COUNT; j++) {
151  io.devices[dev_idx].tx_frame_rates[j] =
152  device->tx_frame_rates[j];
153  io.devices[dev_idx].rx_frame_rates[j] =
154  device->rx_frame_rates[j];
155  io.devices[dev_idx].tx_byte_rates[j] =
156  device->tx_byte_rates[j];
157  io.devices[dev_idx].rx_byte_rates[j] =
158  device->rx_byte_rates[j];
159  }
160  }
161  io.num_devices = ec_master_num_devices(master);
162 
163  io.tx_count = master->device_stats.tx_count;
164  io.rx_count = master->device_stats.rx_count;
165  io.tx_bytes = master->device_stats.tx_bytes;
166  io.rx_bytes = master->device_stats.rx_bytes;
167  for (j = 0; j < EC_RATE_COUNT; j++) {
168  io.tx_frame_rates[j] =
170  io.rx_frame_rates[j] =
172  io.tx_byte_rates[j] =
174  io.rx_byte_rates[j] =
176  io.loss_rates[j] =
178  }
179 
180  up(&master->device_sem);
181 
182  io.app_time = master->app_time;
183  io.dc_ref_time = master->dc_ref_time;
184  io.ref_clock =
186 
187  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
188  return -EFAULT;
189  }
190 
191  return 0;
192 }
193 
194 /*****************************************************************************/
195 
202  void *arg
203  )
204 {
205  ec_ioctl_slave_t data;
206  const ec_slave_t *slave;
207  int i;
208 
209  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
210  return -EFAULT;
211  }
212 
213  if (down_interruptible(&master->master_sem))
214  return -EINTR;
215 
216  if (!(slave = ec_master_find_slave_const(
217  master, 0, data.position))) {
218  up(&master->master_sem);
219  EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
220  return -EINVAL;
221  }
222 
223  data.device_index = slave->device_index;
224  data.vendor_id = slave->sii.vendor_id;
225  data.product_code = slave->sii.product_code;
226  data.revision_number = slave->sii.revision_number;
227  data.serial_number = slave->sii.serial_number;
228  data.alias = slave->effective_alias;
229  data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
230  data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
231  data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
232  data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
233  data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
234  data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
235  data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
236  data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
237  data.mailbox_protocols = slave->sii.mailbox_protocols;
238  data.has_general_category = slave->sii.has_general;
239  data.coe_details = slave->sii.coe_details;
240  data.general_flags = slave->sii.general_flags;
241  data.current_on_ebus = slave->sii.current_on_ebus;
242  for (i = 0; i < EC_MAX_PORTS; i++) {
243  data.ports[i].desc = slave->ports[i].desc;
244  data.ports[i].link.link_up = slave->ports[i].link.link_up;
245  data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
246  data.ports[i].link.signal_detected =
247  slave->ports[i].link.signal_detected;
248  data.ports[i].receive_time = slave->ports[i].receive_time;
249  if (slave->ports[i].next_slave) {
250  data.ports[i].next_slave =
251  slave->ports[i].next_slave->ring_position;
252  } else {
253  data.ports[i].next_slave = 0xffff;
254  }
255  data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
256  }
257  data.fmmu_bit = slave->base_fmmu_bit_operation;
258  data.dc_supported = slave->base_dc_supported;
259  data.dc_range = slave->base_dc_range;
260  data.has_dc_system_time = slave->has_dc_system_time;
261  data.transmission_delay = slave->transmission_delay;
262  data.al_state = slave->current_state;
263  data.error_flag = slave->error_flag;
264 
265  data.sync_count = slave->sii.sync_count;
266  data.sdo_count = ec_slave_sdo_count(slave);
267  data.sii_nwords = slave->sii_nwords;
268  ec_ioctl_strcpy(data.group, slave->sii.group);
269  ec_ioctl_strcpy(data.image, slave->sii.image);
270  ec_ioctl_strcpy(data.order, slave->sii.order);
271  ec_ioctl_strcpy(data.name, slave->sii.name);
272 
273  up(&master->master_sem);
274 
275  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
276  return -EFAULT;
277 
278  return 0;
279 }
280 
281 /*****************************************************************************/
282 
289  void *arg
290  )
291 {
292  ec_ioctl_slave_sync_t data;
293  const ec_slave_t *slave;
294  const ec_sync_t *sync;
295 
296  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
297  return -EFAULT;
298  }
299 
300  if (down_interruptible(&master->master_sem))
301  return -EINTR;
302 
303  if (!(slave = ec_master_find_slave_const(
304  master, 0, data.slave_position))) {
305  up(&master->master_sem);
306  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
307  data.slave_position);
308  return -EINVAL;
309  }
310 
311  if (data.sync_index >= slave->sii.sync_count) {
312  up(&master->master_sem);
313  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
314  data.sync_index);
315  return -EINVAL;
316  }
317 
318  sync = &slave->sii.syncs[data.sync_index];
319 
321  data.default_size = sync->default_length;
322  data.control_register = sync->control_register;
323  data.enable = sync->enable;
324  data.pdo_count = ec_pdo_list_count(&sync->pdos);
325 
326  up(&master->master_sem);
327 
328  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
329  return -EFAULT;
330 
331  return 0;
332 }
333 
334 /*****************************************************************************/
335 
342  void *arg
343  )
344 {
345  ec_ioctl_slave_sync_pdo_t data;
346  const ec_slave_t *slave;
347  const ec_sync_t *sync;
348  const ec_pdo_t *pdo;
349 
350  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
351  return -EFAULT;
352  }
353 
354  if (down_interruptible(&master->master_sem))
355  return -EINTR;
356 
357  if (!(slave = ec_master_find_slave_const(
358  master, 0, data.slave_position))) {
359  up(&master->master_sem);
360  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
361  data.slave_position);
362  return -EINVAL;
363  }
364 
365  if (data.sync_index >= slave->sii.sync_count) {
366  up(&master->master_sem);
367  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
368  data.sync_index);
369  return -EINVAL;
370  }
371 
372  sync = &slave->sii.syncs[data.sync_index];
374  &sync->pdos, data.pdo_pos))) {
375  up(&master->master_sem);
376  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
377  "position %u!\n", data.sync_index, data.pdo_pos);
378  return -EINVAL;
379  }
380 
381  data.index = pdo->index;
382  data.entry_count = ec_pdo_entry_count(pdo);
383  ec_ioctl_strcpy(data.name, pdo->name);
384 
385  up(&master->master_sem);
386 
387  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
388  return -EFAULT;
389 
390  return 0;
391 }
392 
393 /*****************************************************************************/
394 
401  void *arg
402  )
403 {
404  ec_ioctl_slave_sync_pdo_entry_t data;
405  const ec_slave_t *slave;
406  const ec_sync_t *sync;
407  const ec_pdo_t *pdo;
408  const ec_pdo_entry_t *entry;
409 
410  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
411  return -EFAULT;
412  }
413 
414  if (down_interruptible(&master->master_sem))
415  return -EINTR;
416 
417  if (!(slave = ec_master_find_slave_const(
418  master, 0, data.slave_position))) {
419  up(&master->master_sem);
420  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
421  data.slave_position);
422  return -EINVAL;
423  }
424 
425  if (data.sync_index >= slave->sii.sync_count) {
426  up(&master->master_sem);
427  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
428  data.sync_index);
429  return -EINVAL;
430  }
431 
432  sync = &slave->sii.syncs[data.sync_index];
434  &sync->pdos, data.pdo_pos))) {
435  up(&master->master_sem);
436  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
437  "position %u!\n", data.sync_index, data.pdo_pos);
438  return -EINVAL;
439  }
440 
441  if (!(entry = ec_pdo_find_entry_by_pos_const(
442  pdo, data.entry_pos))) {
443  up(&master->master_sem);
444  EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
445  "position %u!\n", data.pdo_pos, data.entry_pos);
446  return -EINVAL;
447  }
448 
449  data.index = entry->index;
450  data.subindex = entry->subindex;
451  data.bit_length = entry->bit_length;
452  ec_ioctl_strcpy(data.name, entry->name);
453 
454  up(&master->master_sem);
455 
456  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
457  return -EFAULT;
458 
459  return 0;
460 }
461 
462 /*****************************************************************************/
463 
470  void *arg
471  )
472 {
473  ec_ioctl_domain_t data;
474  const ec_domain_t *domain;
475  unsigned int dev_idx;
476 
477  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
478  return -EFAULT;
479  }
480 
481  if (down_interruptible(&master->master_sem))
482  return -EINTR;
483 
484  if (!(domain = ec_master_find_domain_const(master, data.index))) {
485  up(&master->master_sem);
486  EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
487  return -EINVAL;
488  }
489 
490  data.data_size = domain->data_size;
491  data.logical_base_address = domain->logical_base_address;
492  for (dev_idx = EC_DEVICE_MAIN;
493  dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
494  data.working_counter[dev_idx] = domain->working_counter[dev_idx];
495  }
496  data.expected_working_counter = domain->expected_working_counter;
497  data.fmmu_count = ec_domain_fmmu_count(domain);
498 
499  up(&master->master_sem);
500 
501  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
502  return -EFAULT;
503 
504  return 0;
505 }
506 
507 /*****************************************************************************/
508 
515  void *arg
516  )
517 {
518  ec_ioctl_domain_fmmu_t data;
519  const ec_domain_t *domain;
520  const ec_fmmu_config_t *fmmu;
521 
522  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
523  return -EFAULT;
524  }
525 
526  if (down_interruptible(&master->master_sem))
527  return -EINTR;
528 
529  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
530  up(&master->master_sem);
531  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
532  data.domain_index);
533  return -EINVAL;
534  }
535 
536  if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
537  up(&master->master_sem);
538  EC_MASTER_ERR(master, "Domain %u has less than %u"
539  " fmmu configurations.\n",
540  data.domain_index, data.fmmu_index + 1);
541  return -EINVAL;
542  }
543 
544  data.slave_config_alias = fmmu->sc->alias;
545  data.slave_config_position = fmmu->sc->position;
546  data.sync_index = fmmu->sync_index;
547  data.dir = fmmu->dir;
548  data.logical_address = fmmu->logical_start_address;
549  data.data_size = fmmu->data_size;
550 
551  up(&master->master_sem);
552 
553  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
554  return -EFAULT;
555 
556  return 0;
557 }
558 
559 /*****************************************************************************/
560 
567  void *arg
568  )
569 {
570  ec_ioctl_domain_data_t data;
571  const ec_domain_t *domain;
572 
573  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
574  return -EFAULT;
575  }
576 
577  if (down_interruptible(&master->master_sem))
578  return -EINTR;
579 
580  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
581  up(&master->master_sem);
582  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
583  data.domain_index);
584  return -EINVAL;
585  }
586 
587  if (domain->data_size != data.data_size) {
588  up(&master->master_sem);
589  EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
590  data.data_size, domain->data_size);
591  return -EFAULT;
592  }
593 
594  if (copy_to_user((void __user *) data.target, domain->data,
595  domain->data_size)) {
596  up(&master->master_sem);
597  return -EFAULT;
598  }
599 
600  up(&master->master_sem);
601  return 0;
602 }
603 
604 /*****************************************************************************/
605 
612  void *arg
613  )
614 {
615  return ec_master_debug_level(master, (unsigned long) arg);
616 }
617 
618 /*****************************************************************************/
619 
626  void *arg
627  )
628 {
630  return 0;
631 }
632 
633 /*****************************************************************************/
634 
641  void *arg
642  )
643 {
644  ec_ioctl_slave_state_t data;
645  ec_slave_t *slave;
646 
647  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
648  return -EFAULT;
649  }
650 
651  if (down_interruptible(&master->master_sem))
652  return -EINTR;
653 
654  if (!(slave = ec_master_find_slave(
655  master, 0, data.slave_position))) {
656  up(&master->master_sem);
657  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
658  data.slave_position);
659  return -EINVAL;
660  }
661 
662  ec_slave_request_state(slave, data.al_state);
663 
664  up(&master->master_sem);
665  return 0;
666 }
667 
668 /*****************************************************************************/
669 
676  void *arg
677  )
678 {
679  ec_ioctl_slave_sdo_t data;
680  const ec_slave_t *slave;
681  const ec_sdo_t *sdo;
682 
683  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
684  return -EFAULT;
685  }
686 
687  if (down_interruptible(&master->master_sem))
688  return -EINTR;
689 
690  if (!(slave = ec_master_find_slave_const(
691  master, 0, data.slave_position))) {
692  up(&master->master_sem);
693  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
694  data.slave_position);
695  return -EINVAL;
696  }
697 
698  if (!(sdo = ec_slave_get_sdo_by_pos_const(
699  slave, data.sdo_position))) {
700  up(&master->master_sem);
701  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
702  return -EINVAL;
703  }
704 
705  data.sdo_index = sdo->index;
706  data.max_subindex = sdo->max_subindex;
707  ec_ioctl_strcpy(data.name, sdo->name);
708 
709  up(&master->master_sem);
710 
711  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
712  return -EFAULT;
713 
714  return 0;
715 }
716 
717 /*****************************************************************************/
718 
725  void *arg
726  )
727 {
728  ec_ioctl_slave_sdo_entry_t data;
729  const ec_slave_t *slave;
730  const ec_sdo_t *sdo;
731  const ec_sdo_entry_t *entry;
732 
733  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
734  return -EFAULT;
735  }
736 
737  if (down_interruptible(&master->master_sem))
738  return -EINTR;
739 
740  if (!(slave = ec_master_find_slave_const(
741  master, 0, data.slave_position))) {
742  up(&master->master_sem);
743  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
744  data.slave_position);
745  return -EINVAL;
746  }
747 
748  if (data.sdo_spec <= 0) {
749  if (!(sdo = ec_slave_get_sdo_by_pos_const(
750  slave, -data.sdo_spec))) {
751  up(&master->master_sem);
752  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
753  return -EINVAL;
754  }
755  } else {
756  if (!(sdo = ec_slave_get_sdo_const(
757  slave, data.sdo_spec))) {
758  up(&master->master_sem);
759  EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
760  data.sdo_spec);
761  return -EINVAL;
762  }
763  }
764 
765  if (!(entry = ec_sdo_get_entry_const(
766  sdo, data.sdo_entry_subindex))) {
767  up(&master->master_sem);
768  EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
769  sdo->index, data.sdo_entry_subindex);
770  return -EINVAL;
771  }
772 
773  data.data_type = entry->data_type;
774  data.bit_length = entry->bit_length;
775  data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
777  data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
779  data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
781  data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
783  data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
785  data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
787  ec_ioctl_strcpy(data.description, entry->description);
788 
789  up(&master->master_sem);
790 
791  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
792  return -EFAULT;
793 
794  return 0;
795 }
796 
797 /*****************************************************************************/
798 
805  void *arg
806  )
807 {
808  ec_ioctl_slave_sdo_upload_t data;
809  uint8_t *target;
810  int ret;
811 
812  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
813  return -EFAULT;
814  }
815 
816  if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
817  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
818  " for SDO upload.\n", data.target_size);
819  return -ENOMEM;
820  }
821 
822  ret = ecrt_master_sdo_upload(master, data.slave_position,
823  data.sdo_index, data.sdo_entry_subindex, target,
824  data.target_size, &data.data_size, &data.abort_code);
825 
826  if (!ret) {
827  if (copy_to_user((void __user *) data.target,
828  target, data.data_size)) {
829  kfree(target);
830  return -EFAULT;
831  }
832  }
833 
834  kfree(target);
835 
836  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
837  return -EFAULT;
838  }
839 
840  return ret;
841 }
842 
843 /*****************************************************************************/
844 
851  void *arg
852  )
853 {
854  ec_ioctl_slave_sdo_download_t data;
855  uint8_t *sdo_data;
856  int retval;
857 
858  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
859  return -EFAULT;
860  }
861 
862  if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
863  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
864  " for SDO download.\n", data.data_size);
865  return -ENOMEM;
866  }
867 
868  if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
869  kfree(sdo_data);
870  return -EFAULT;
871  }
872 
873  if (data.complete_access) {
874  retval = ecrt_master_sdo_download_complete(master, data.slave_position,
875  data.sdo_index, sdo_data, data.data_size, &data.abort_code);
876  } else {
877  retval = ecrt_master_sdo_download(master, data.slave_position,
878  data.sdo_index, data.sdo_entry_subindex, sdo_data,
879  data.data_size, &data.abort_code);
880  }
881 
882  kfree(sdo_data);
883 
884  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
885  retval = -EFAULT;
886  }
887 
888  return retval;
889 }
890 
891 /*****************************************************************************/
892 
899  void *arg
900  )
901 {
902  ec_ioctl_slave_sii_t data;
903  const ec_slave_t *slave;
904  int retval;
905 
906  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
907  return -EFAULT;
908  }
909 
910  if (down_interruptible(&master->master_sem))
911  return -EINTR;
912 
913  if (!(slave = ec_master_find_slave_const(
914  master, 0, data.slave_position))) {
915  up(&master->master_sem);
916  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
917  data.slave_position);
918  return -EINVAL;
919  }
920 
921  if (!data.nwords
922  || data.offset + data.nwords > slave->sii_nwords) {
923  up(&master->master_sem);
924  EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
925  " size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
926  return -EINVAL;
927  }
928 
929  if (copy_to_user((void __user *) data.words,
930  slave->sii_words + data.offset, data.nwords * 2))
931  retval = -EFAULT;
932  else
933  retval = 0;
934 
935  up(&master->master_sem);
936  return retval;
937 }
938 
939 /*****************************************************************************/
940 
947  void *arg
948  )
949 {
950  ec_ioctl_slave_sii_t data;
951  ec_slave_t *slave;
952  unsigned int byte_size;
953  uint16_t *words;
954  ec_sii_write_request_t request;
955 
956  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
957  return -EFAULT;
958  }
959 
960  if (!data.nwords) {
961  return 0;
962  }
963 
964  byte_size = sizeof(uint16_t) * data.nwords;
965  if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
966  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
967  " for SII contents.\n", byte_size);
968  return -ENOMEM;
969  }
970 
971  if (copy_from_user(words,
972  (void __user *) data.words, byte_size)) {
973  kfree(words);
974  return -EFAULT;
975  }
976 
977  if (down_interruptible(&master->master_sem)) {
978  kfree(words);
979  return -EINTR;
980  }
981 
982  if (!(slave = ec_master_find_slave(
983  master, 0, data.slave_position))) {
984  up(&master->master_sem);
985  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
986  data.slave_position);
987  kfree(words);
988  return -EINVAL;
989  }
990 
991  // init SII write request
992  INIT_LIST_HEAD(&request.list);
993  request.slave = slave;
994  request.words = words;
995  request.offset = data.offset;
996  request.nwords = data.nwords;
997  request.state = EC_INT_REQUEST_QUEUED;
998 
999  // schedule SII write request.
1000  list_add_tail(&request.list, &master->sii_requests);
1001 
1002  up(&master->master_sem);
1003 
1004  // wait for processing through FSM
1005  if (wait_event_interruptible(master->request_queue,
1006  request.state != EC_INT_REQUEST_QUEUED)) {
1007  // interrupted by signal
1008  down(&master->master_sem);
1009  if (request.state == EC_INT_REQUEST_QUEUED) {
1010  // abort request
1011  list_del(&request.list);
1012  up(&master->master_sem);
1013  kfree(words);
1014  return -EINTR;
1015  }
1016  up(&master->master_sem);
1017  }
1018 
1019  // wait until master FSM has finished processing
1020  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1021 
1022  kfree(words);
1023 
1024  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1025 }
1026 
1027 /*****************************************************************************/
1028 
1034  ec_master_t *master,
1035  void *arg
1036  )
1037 {
1038  ec_ioctl_slave_reg_t io;
1039  ec_slave_t *slave;
1040  ec_reg_request_t request;
1041  int ret;
1042 
1043  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1044  return -EFAULT;
1045  }
1046 
1047  if (!io.size) {
1048  return 0;
1049  }
1050 
1051  // init register request
1052  ret = ec_reg_request_init(&request, io.size);
1053  if (ret) {
1054  return ret;
1055  }
1056 
1057  ecrt_reg_request_read(&request, io.address, io.size);
1058 
1059  if (down_interruptible(&master->master_sem)) {
1060  ec_reg_request_clear(&request);
1061  return -EINTR;
1062  }
1063 
1064  if (!(slave = ec_master_find_slave(
1065  master, 0, io.slave_position))) {
1066  up(&master->master_sem);
1067  ec_reg_request_clear(&request);
1068  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1069  io.slave_position);
1070  return -EINVAL;
1071  }
1072 
1073  // schedule request.
1074  list_add_tail(&request.list, &slave->reg_requests);
1075 
1076  up(&master->master_sem);
1077 
1078  // wait for processing through FSM
1079  if (wait_event_interruptible(master->request_queue,
1080  request.state != EC_INT_REQUEST_QUEUED)) {
1081  // interrupted by signal
1082  down(&master->master_sem);
1083  if (request.state == EC_INT_REQUEST_QUEUED) {
1084  // abort request
1085  list_del(&request.list);
1086  up(&master->master_sem);
1087  ec_reg_request_clear(&request);
1088  return -EINTR;
1089  }
1090  up(&master->master_sem);
1091  }
1092 
1093  // wait until master FSM has finished processing
1094  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1095 
1096  if (request.state == EC_INT_REQUEST_SUCCESS) {
1097  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1098  return -EFAULT;
1099  }
1100  }
1101  ec_reg_request_clear(&request);
1102 
1103  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1104 }
1105 
1106 /*****************************************************************************/
1107 
1113  ec_master_t *master,
1114  void *arg
1115  )
1116 {
1117  ec_ioctl_slave_reg_t io;
1118  ec_slave_t *slave;
1119  ec_reg_request_t request;
1120  int ret;
1121 
1122  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1123  return -EFAULT;
1124  }
1125 
1126  if (!io.size) {
1127  return 0;
1128  }
1129 
1130  // init register request
1131  ret = ec_reg_request_init(&request, io.size);
1132  if (ret) {
1133  return ret;
1134  }
1135 
1136  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1137  ec_reg_request_clear(&request);
1138  return -EFAULT;
1139  }
1140 
1141  ecrt_reg_request_write(&request, io.address, io.size);
1142 
1143  if (down_interruptible(&master->master_sem)) {
1144  ec_reg_request_clear(&request);
1145  return -EINTR;
1146  }
1147 
1148  if (io.emergency) {
1149  request.ring_position = io.slave_position;
1150  // schedule request.
1151  list_add_tail(&request.list, &master->emerg_reg_requests);
1152  }
1153  else {
1154  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1155  up(&master->master_sem);
1156  ec_reg_request_clear(&request);
1157  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1158  io.slave_position);
1159  return -EINVAL;
1160  }
1161 
1162  // schedule request.
1163  list_add_tail(&request.list, &slave->reg_requests);
1164  }
1165 
1166  up(&master->master_sem);
1167 
1168  // wait for processing through FSM
1169  if (wait_event_interruptible(master->request_queue,
1170  request.state != EC_INT_REQUEST_QUEUED)) {
1171  // interrupted by signal
1172  down(&master->master_sem);
1173  if (request.state == EC_INT_REQUEST_QUEUED) {
1174  // abort request
1175  list_del(&request.list);
1176  up(&master->master_sem);
1177  ec_reg_request_clear(&request);
1178  return -EINTR;
1179  }
1180  up(&master->master_sem);
1181  }
1182 
1183  // wait until master FSM has finished processing
1184  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1185 
1186  ec_reg_request_clear(&request);
1187 
1188  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1189 }
1190 
1191 /*****************************************************************************/
1192 
1198  ec_master_t *master,
1199  void *arg
1200  )
1201 {
1202  ec_ioctl_config_t data;
1203  const ec_slave_config_t *sc;
1204  uint8_t i;
1205 
1206  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1207  return -EFAULT;
1208  }
1209 
1210  if (down_interruptible(&master->master_sem))
1211  return -EINTR;
1212 
1213  if (!(sc = ec_master_get_config_const(
1214  master, data.config_index))) {
1215  up(&master->master_sem);
1216  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1217  data.config_index);
1218  return -EINVAL;
1219  }
1220 
1221  data.alias = sc->alias;
1222  data.position = sc->position;
1223  data.vendor_id = sc->vendor_id;
1224  data.product_code = sc->product_code;
1225  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1226  data.syncs[i].dir = sc->sync_configs[i].dir;
1227  data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1228  data.syncs[i].pdo_count =
1230  }
1231  data.watchdog_divider = sc->watchdog_divider;
1232  data.watchdog_intervals = sc->watchdog_intervals;
1233  data.sdo_count = ec_slave_config_sdo_count(sc);
1234  data.idn_count = ec_slave_config_idn_count(sc);
1235  data.flag_count = ec_slave_config_flag_count(sc);
1236  data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1237  data.dc_assign_activate = sc->dc_assign_activate;
1238  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1239  data.dc_sync[i] = sc->dc_sync[i];
1240  }
1241 
1242  up(&master->master_sem);
1243 
1244  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1245  return -EFAULT;
1246 
1247  return 0;
1248 }
1249 
1250 /*****************************************************************************/
1251 
1257  ec_master_t *master,
1258  void *arg
1259  )
1260 {
1261  ec_ioctl_config_pdo_t data;
1262  const ec_slave_config_t *sc;
1263  const ec_pdo_t *pdo;
1264 
1265  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1266  return -EFAULT;
1267  }
1268 
1269  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1270  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1271  data.sync_index);
1272  return -EINVAL;
1273  }
1274 
1275  if (down_interruptible(&master->master_sem))
1276  return -EINTR;
1277 
1278  if (!(sc = ec_master_get_config_const(
1279  master, data.config_index))) {
1280  up(&master->master_sem);
1281  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1282  data.config_index);
1283  return -EINVAL;
1284  }
1285 
1287  &sc->sync_configs[data.sync_index].pdos,
1288  data.pdo_pos))) {
1289  up(&master->master_sem);
1290  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1291  return -EINVAL;
1292  }
1293 
1294  data.index = pdo->index;
1295  data.entry_count = ec_pdo_entry_count(pdo);
1296  ec_ioctl_strcpy(data.name, pdo->name);
1297 
1298  up(&master->master_sem);
1299 
1300  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1301  return -EFAULT;
1302 
1303  return 0;
1304 }
1305 
1306 /*****************************************************************************/
1307 
1313  ec_master_t *master,
1314  void *arg
1315  )
1316 {
1317  ec_ioctl_config_pdo_entry_t data;
1318  const ec_slave_config_t *sc;
1319  const ec_pdo_t *pdo;
1320  const ec_pdo_entry_t *entry;
1321 
1322  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1323  return -EFAULT;
1324  }
1325 
1326  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1327  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1328  data.sync_index);
1329  return -EINVAL;
1330  }
1331 
1332  if (down_interruptible(&master->master_sem))
1333  return -EINTR;
1334 
1335  if (!(sc = ec_master_get_config_const(
1336  master, data.config_index))) {
1337  up(&master->master_sem);
1338  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1339  data.config_index);
1340  return -EINVAL;
1341  }
1342 
1344  &sc->sync_configs[data.sync_index].pdos,
1345  data.pdo_pos))) {
1346  up(&master->master_sem);
1347  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1348  return -EINVAL;
1349  }
1350 
1351  if (!(entry = ec_pdo_find_entry_by_pos_const(
1352  pdo, data.entry_pos))) {
1353  up(&master->master_sem);
1354  EC_MASTER_ERR(master, "Entry not found!\n");
1355  return -EINVAL;
1356  }
1357 
1358  data.index = entry->index;
1359  data.subindex = entry->subindex;
1360  data.bit_length = entry->bit_length;
1361  ec_ioctl_strcpy(data.name, entry->name);
1362 
1363  up(&master->master_sem);
1364 
1365  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1366  return -EFAULT;
1367 
1368  return 0;
1369 }
1370 
1371 /*****************************************************************************/
1372 
1378  ec_master_t *master,
1379  void *arg
1380  )
1381 {
1382  ec_ioctl_config_sdo_t *ioctl;
1383  const ec_slave_config_t *sc;
1384  const ec_sdo_request_t *req;
1385 
1386  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1387  return -ENOMEM;
1388  }
1389 
1390  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1391  kfree(ioctl);
1392  return -EFAULT;
1393  }
1394 
1395  if (down_interruptible(&master->master_sem)) {
1396  kfree(ioctl);
1397  return -EINTR;
1398  }
1399 
1400  if (!(sc = ec_master_get_config_const(
1401  master, ioctl->config_index))) {
1402  up(&master->master_sem);
1403  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1404  ioctl->config_index);
1405  kfree(ioctl);
1406  return -EINVAL;
1407  }
1408 
1410  sc, ioctl->sdo_pos))) {
1411  up(&master->master_sem);
1412  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1413  kfree(ioctl);
1414  return -EINVAL;
1415  }
1416 
1417  ioctl->index = req->index;
1418  ioctl->subindex = req->subindex;
1419  ioctl->size = req->data_size;
1420  memcpy(ioctl->data, req->data,
1421  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1422  ioctl->complete_access = req->complete_access;
1423 
1424  up(&master->master_sem);
1425 
1426  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1427  kfree(ioctl);
1428  return -EFAULT;
1429  }
1430 
1431  kfree(ioctl);
1432  return 0;
1433 }
1434 
1435 /*****************************************************************************/
1436 
1442  ec_master_t *master,
1443  void *arg
1444  )
1445 {
1446  ec_ioctl_config_idn_t *ioctl;
1447  const ec_slave_config_t *sc;
1448  const ec_soe_request_t *req;
1449 
1450  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1451  return -ENOMEM;
1452  }
1453 
1454  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1455  kfree(ioctl);
1456  return -EFAULT;
1457  }
1458 
1459  if (down_interruptible(&master->master_sem)) {
1460  kfree(ioctl);
1461  return -EINTR;
1462  }
1463 
1464  if (!(sc = ec_master_get_config_const(
1465  master, ioctl->config_index))) {
1466  up(&master->master_sem);
1467  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1468  ioctl->config_index);
1469  kfree(ioctl);
1470  return -EINVAL;
1471  }
1472 
1474  sc, ioctl->idn_pos))) {
1475  up(&master->master_sem);
1476  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1477  kfree(ioctl);
1478  return -EINVAL;
1479  }
1480 
1481  ioctl->drive_no = req->drive_no;
1482  ioctl->idn = req->idn;
1483  ioctl->state = req->al_state;
1484  ioctl->size = req->data_size;
1485  memcpy(ioctl->data, req->data,
1486  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1487 
1488  up(&master->master_sem);
1489 
1490  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1491  kfree(ioctl);
1492  return -EFAULT;
1493  }
1494 
1495  kfree(ioctl);
1496  return 0;
1497 }
1498 
1499 /*****************************************************************************/
1500 
1506  ec_master_t *master,
1507  void *arg
1508  )
1509 {
1510  ec_ioctl_config_flag_t *ioctl;
1511  const ec_slave_config_t *sc;
1512  const ec_flag_t *flag;
1513  size_t size;
1514 
1515  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1516  return -ENOMEM;
1517  }
1518 
1519  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1520  kfree(ioctl);
1521  return -EFAULT;
1522  }
1523 
1524  if (down_interruptible(&master->master_sem)) {
1525  kfree(ioctl);
1526  return -EINTR;
1527  }
1528 
1529  if (!(sc = ec_master_get_config_const(
1530  master, ioctl->config_index))) {
1531  up(&master->master_sem);
1532  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1533  ioctl->config_index);
1534  kfree(ioctl);
1535  return -EINVAL;
1536  }
1537 
1539  sc, ioctl->flag_pos))) {
1540  up(&master->master_sem);
1541  EC_MASTER_ERR(master, "Invalid flag position!\n");
1542  kfree(ioctl);
1543  return -EINVAL;
1544  }
1545 
1546  size = min((u32) strlen(flag->key), (u32) EC_MAX_FLAG_KEY_SIZE - 1);
1547  memcpy(ioctl->key, flag->key, size);
1548  ioctl->key[size] = 0x00;
1549  ioctl->value = flag->value;
1550 
1551  up(&master->master_sem);
1552 
1553  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1554  kfree(ioctl);
1555  return -EFAULT;
1556  }
1557 
1558  kfree(ioctl);
1559  return 0;
1560 }
1561 
1562 /*****************************************************************************/
1563 
1564 #ifdef EC_EOE
1565 
1571  ec_master_t *master,
1572  void *arg
1573  )
1574 {
1575  ec_ioctl_eoe_handler_t data;
1576  const ec_eoe_t *eoe;
1577 
1578  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1579  return -EFAULT;
1580  }
1581 
1582  if (down_interruptible(&master->master_sem))
1583  return -EINTR;
1584 
1585  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1586  up(&master->master_sem);
1587  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1588  data.eoe_index);
1589  return -EINVAL;
1590  }
1591 
1592  if (eoe->slave) {
1593  data.slave_position = eoe->slave->ring_position;
1594  } else {
1595  data.slave_position = 0xffff;
1596  }
1597  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1598  data.open = eoe->opened;
1599  data.rx_bytes = eoe->stats.tx_bytes;
1600  data.rx_rate = eoe->tx_rate;
1601  data.tx_bytes = eoe->stats.rx_bytes;
1602  data.tx_rate = eoe->tx_rate;
1603  data.tx_queued_frames = eoe->tx_queued_frames;
1604  data.tx_queue_size = eoe->tx_queue_size;
1605 
1606  up(&master->master_sem);
1607 
1608  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1609  return -EFAULT;
1610 
1611  return 0;
1612 }
1613 
1614 #endif
1615 
1616 /*****************************************************************************/
1617 
1623  ec_master_t *master,
1624  void *arg,
1625  ec_ioctl_context_t *ctx
1626  )
1627 {
1628  ec_master_t *m;
1629  int ret = 0;
1630 
1632  if (IS_ERR(m)) {
1633  ret = PTR_ERR(m);
1634  } else {
1635  ctx->requested = 1;
1636  }
1637 
1638  return ret;
1639 }
1640 
1641 /*****************************************************************************/
1642 
1648  ec_master_t *master,
1649  void *arg,
1650  ec_ioctl_context_t *ctx
1651  )
1652 {
1653  ec_domain_t *domain;
1654 
1655  if (unlikely(!ctx->requested))
1656  return -EPERM;
1657 
1659  if (IS_ERR(domain))
1660  return PTR_ERR(domain);
1661 
1662  return domain->index;
1663 }
1664 
1665 /*****************************************************************************/
1666 
1672  ec_master_t *master,
1673  void *arg,
1674  ec_ioctl_context_t *ctx
1675  )
1676 {
1677  ec_ioctl_config_t data;
1678  ec_slave_config_t *sc, *entry;
1679 
1680  if (unlikely(!ctx->requested))
1681  return -EPERM;
1682 
1683  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1684  return -EFAULT;
1685  }
1686 
1687  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1688  data.vendor_id, data.product_code);
1689  if (IS_ERR(sc))
1690  return PTR_ERR(sc);
1691 
1692  data.config_index = 0;
1693 
1694  if (down_interruptible(&master->master_sem))
1695  return -EINTR;
1696 
1697  list_for_each_entry(entry, &master->configs, list) {
1698  if (entry == sc)
1699  break;
1700  data.config_index++;
1701  }
1702 
1703  up(&master->master_sem);
1704 
1705  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1706  return -EFAULT;
1707 
1708  return 0;
1709 }
1710 
1711 /*****************************************************************************/
1712 
1718  ec_master_t *master,
1719  void *arg,
1720  ec_ioctl_context_t *ctx
1721  )
1722 {
1723  unsigned long config_index = (unsigned long) arg;
1724  ec_slave_config_t *sc = NULL;
1725  int ret = 0;
1726 
1727  if (unlikely(!ctx->requested)) {
1728  ret = -EPERM;
1729  goto out_return;
1730  }
1731 
1732  if (down_interruptible(&master->master_sem)) {
1733  ret = -EINTR;
1734  goto out_return;
1735  }
1736 
1737  if (config_index != 0xFFFFFFFF) {
1738  if (!(sc = ec_master_get_config(master, config_index))) {
1739  ret = -ENOENT;
1740  goto out_up;
1741  }
1742  }
1743 
1745 
1746 out_up:
1747  up(&master->master_sem);
1748 out_return:
1749  return ret;
1750 }
1751 
1752 /*****************************************************************************/
1753 
1759  ec_master_t *master,
1760  void *arg,
1761  ec_ioctl_context_t *ctx
1762  )
1763 {
1764  ec_ioctl_master_activate_t io;
1765  ec_domain_t *domain;
1766  off_t offset;
1767  int ret;
1768 
1769  if (unlikely(!ctx->requested))
1770  return -EPERM;
1771 
1772  io.process_data = NULL;
1773 
1774  /* Get the sum of the domains' process data sizes. */
1775 
1776  ctx->process_data_size = 0;
1777 
1778  if (down_interruptible(&master->master_sem))
1779  return -EINTR;
1780 
1781  list_for_each_entry(domain, &master->domains, list) {
1782  ctx->process_data_size += ecrt_domain_size(domain);
1783  }
1784 
1785  up(&master->master_sem);
1786 
1787  if (ctx->process_data_size) {
1788  ctx->process_data = vmalloc(ctx->process_data_size);
1789  if (!ctx->process_data) {
1790  ctx->process_data_size = 0;
1791  return -ENOMEM;
1792  }
1793 
1794  /* Set the memory as external process data memory for the
1795  * domains.
1796  */
1797  offset = 0;
1798  list_for_each_entry(domain, &master->domains, list) {
1800  ctx->process_data + offset);
1801  offset += ecrt_domain_size(domain);
1802  }
1803 
1804 #ifdef EC_IOCTL_RTDM
1805  /* RTDM uses a different approach for memory-mapping, which has to be
1806  * initiated by the kernel.
1807  */
1808  ret = ec_rtdm_mmap(ctx, &io.process_data);
1809  if (ret < 0) {
1810  EC_MASTER_ERR(master, "Failed to map process data"
1811  " memory to user space (code %i).\n", ret);
1812  return ret;
1813  }
1814 #endif
1815  }
1816 
1817  io.process_data_size = ctx->process_data_size;
1818 
1819 #ifndef EC_IOCTL_RTDM
1822 #endif
1823 
1825  if (ret < 0)
1826  return ret;
1827 
1828  if (copy_to_user((void __user *) arg, &io,
1829  sizeof(ec_ioctl_master_activate_t)))
1830  return -EFAULT;
1831 
1832  return 0;
1833 }
1834 
1835 /*****************************************************************************/
1836 
1842  ec_master_t *master,
1843  void *arg,
1844  ec_ioctl_context_t *ctx
1845  )
1846 {
1847  if (unlikely(!ctx->requested))
1848  return -EPERM;
1849 
1851  return 0;
1852 }
1853 
1854 /*****************************************************************************/
1855 
1861  ec_master_t *master,
1862  void *arg,
1863  ec_ioctl_context_t *ctx
1864  )
1865 {
1866  size_t send_interval;
1867 
1868  if (unlikely(!ctx->requested)) {
1869  return -EPERM;
1870  }
1871 
1872  if (copy_from_user(&send_interval, (void __user *) arg,
1873  sizeof(send_interval))) {
1874  return -EFAULT;
1875  }
1876 
1877  if (down_interruptible(&master->master_sem))
1878  return -EINTR;
1879 
1880  ec_master_set_send_interval(master, send_interval);
1881 
1882  up(&master->master_sem);
1883  return 0;
1884 }
1885 
1886 /*****************************************************************************/
1887 
1893  ec_master_t *master,
1894  void *arg,
1895  ec_ioctl_context_t *ctx
1896  )
1897 {
1898  if (unlikely(!ctx->requested)) {
1899  return -EPERM;
1900  }
1901 
1902  down( & master->io_sem );
1904  up( & master->io_sem );
1905  return 0;
1906 }
1907 
1908 /*****************************************************************************/
1909 
1915  ec_master_t *master,
1916  void *arg,
1917  ec_ioctl_context_t *ctx
1918  )
1919 {
1920  if (unlikely(!ctx->requested)) {
1921  return -EPERM;
1922  }
1923 
1924  down( & master->io_sem );
1926  up( & master->io_sem );
1927  return 0;
1928 }
1929 
1930 /*****************************************************************************/
1931 
1937  ec_master_t *master,
1938  void *arg,
1939  ec_ioctl_context_t *ctx
1940  )
1941 {
1942  ec_master_state_t data;
1943 
1944  ecrt_master_state(master, &data);
1945 
1946  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1947  return -EFAULT;
1948 
1949  return 0;
1950 }
1951 
1952 /*****************************************************************************/
1953 
1959  ec_master_t *master,
1960  void *arg,
1961  ec_ioctl_context_t *ctx
1962  )
1963 {
1964  ec_ioctl_link_state_t ioctl;
1965  ec_master_link_state_t state;
1966  int ret;
1967 
1968  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
1969  return -EFAULT;
1970  }
1971 
1972  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
1973  if (ret < 0) {
1974  return ret;
1975  }
1976 
1977  if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
1978  return -EFAULT;
1979  }
1980 
1981  return 0;
1982 }
1983 
1984 /*****************************************************************************/
1985 
1991  ec_master_t *master,
1992  void *arg,
1993  ec_ioctl_context_t *ctx
1994  )
1995 {
1996  uint64_t time;
1997 
1998  if (unlikely(!ctx->requested))
1999  return -EPERM;
2000 
2001  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2002  return -EFAULT;
2003  }
2004 
2006  return 0;
2007 }
2008 
2009 /*****************************************************************************/
2010 
2016  ec_master_t *master,
2017  void *arg,
2018  ec_ioctl_context_t *ctx
2019  )
2020 {
2021  if (unlikely(!ctx->requested)) {
2022  return -EPERM;
2023  }
2024 
2025  down( & master->io_sem );
2027  up( & master->io_sem );
2028  return 0;
2029 }
2030 
2031 /*****************************************************************************/
2032 
2038  ec_master_t *master,
2039  void *arg,
2040  ec_ioctl_context_t *ctx
2041  )
2042 {
2043  uint64_t time;
2044 
2045  if (unlikely(!ctx->requested))
2046  return -EPERM;
2047 
2048  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2049  return -EFAULT;
2050  }
2051 
2052  down( & master->io_sem );
2054  up( & master->io_sem );
2055  return 0;
2056 }
2057 
2058 /*****************************************************************************/
2059 
2065  ec_master_t *master,
2066  void *arg,
2067  ec_ioctl_context_t *ctx
2068  )
2069 {
2070  if (unlikely(!ctx->requested)) {
2071  return -EPERM;
2072  }
2073 
2074  down( & master->io_sem );
2076  up( & master->io_sem );
2077  return 0;
2078 }
2079 
2080 /*****************************************************************************/
2081 
2087  ec_master_t *master,
2088  void *arg,
2089  ec_ioctl_context_t *ctx
2090  )
2091 {
2092  uint32_t time;
2093  int ret;
2094 
2095  if (unlikely(!ctx->requested)) {
2096  return -EPERM;
2097  }
2098 
2100  if (ret) {
2101  return ret;
2102  }
2103 
2104  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2105  return -EFAULT;
2106  }
2107 
2108  return 0;
2109 }
2110 
2111 /*****************************************************************************/
2112 
2118  ec_master_t *master,
2119  void *arg,
2120  ec_ioctl_context_t *ctx
2121  )
2122 {
2123  if (unlikely(!ctx->requested)) {
2124  return -EPERM;
2125  }
2126 
2127  down( & master->io_sem );
2129  up( & master->io_sem );
2130  return 0;
2131 }
2132 
2133 /*****************************************************************************/
2134 
2140  ec_master_t *master,
2141  void *arg,
2142  ec_ioctl_context_t *ctx
2143  )
2144 {
2145  uint32_t time_diff;
2146 
2147  if (unlikely(!ctx->requested))
2148  return -EPERM;
2149 
2151 
2152  if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2153  return -EFAULT;
2154 
2155  return 0;
2156 }
2157 
2158 /*****************************************************************************/
2159 
2165  ec_master_t *master,
2166  void *arg,
2167  ec_ioctl_context_t *ctx
2168  )
2169 {
2170  down(&master->master_sem);
2172  up(&master->master_sem);
2173  return 0;
2174 }
2175 
2176 /*****************************************************************************/
2177 
2183  ec_master_t *master,
2184  void *arg,
2185  ec_ioctl_context_t *ctx
2186  )
2187 {
2188  ec_ioctl_config_t data;
2189  ec_slave_config_t *sc;
2190  unsigned int i;
2191  int ret = 0;
2192 
2193  if (unlikely(!ctx->requested)) {
2194  ret = -EPERM;
2195  goto out_return;
2196  }
2197 
2198  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2199  ret = -EFAULT;
2200  goto out_return;
2201  }
2202 
2203  if (down_interruptible(&master->master_sem)) {
2204  ret = -EINTR;
2205  goto out_return;
2206  }
2207 
2208  if (!(sc = ec_master_get_config(master, data.config_index))) {
2209  ret = -ENOENT;
2210  goto out_up;
2211  }
2212 
2213  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2214  if (data.syncs[i].config_this) {
2215  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2216  data.syncs[i].watchdog_mode);
2217  if (ret) {
2218  goto out_up;
2219  }
2220  }
2221  }
2222 
2223 out_up:
2224  up(&master->master_sem);
2225 out_return:
2226  return ret;
2227 }
2228 
2229 /*****************************************************************************/
2230 
2236  ec_master_t *master,
2237  void *arg,
2238  ec_ioctl_context_t *ctx
2239  )
2240 {
2241  ec_ioctl_config_t data;
2242  ec_slave_config_t *sc;
2243  int ret = 0;
2244 
2245  if (unlikely(!ctx->requested)) {
2246  ret = -EPERM;
2247  goto out_return;
2248  }
2249 
2250  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2251  ret = -EFAULT;
2252  goto out_return;
2253  }
2254 
2255  if (down_interruptible(&master->master_sem)) {
2256  ret = -EINTR;
2257  goto out_return;
2258  }
2259 
2260  if (!(sc = ec_master_get_config(master, data.config_index))) {
2261  ret = -ENOENT;
2262  goto out_up;
2263  }
2264 
2266  data.watchdog_divider, data.watchdog_intervals);
2267 
2268 out_up:
2269  up(&master->master_sem);
2270 out_return:
2271  return ret;
2272 }
2273 
2274 /*****************************************************************************/
2275 
2281  ec_master_t *master,
2282  void *arg,
2283  ec_ioctl_context_t *ctx
2284  )
2285 {
2286  ec_ioctl_config_pdo_t data;
2287  ec_slave_config_t *sc;
2288 
2289  if (unlikely(!ctx->requested))
2290  return -EPERM;
2291 
2292  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2293  return -EFAULT;
2294 
2295  if (down_interruptible(&master->master_sem))
2296  return -EINTR;
2297 
2298  if (!(sc = ec_master_get_config(master, data.config_index))) {
2299  up(&master->master_sem);
2300  return -ENOENT;
2301  }
2302 
2303  up(&master->master_sem);
2305  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2306 }
2307 
2308 /*****************************************************************************/
2309 
2315  ec_master_t *master,
2316  void *arg,
2317  ec_ioctl_context_t *ctx
2318  )
2319 {
2320  ec_ioctl_config_pdo_t data;
2321  ec_slave_config_t *sc;
2322 
2323  if (unlikely(!ctx->requested))
2324  return -EPERM;
2325 
2326  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2327  return -EFAULT;
2328 
2329  if (down_interruptible(&master->master_sem))
2330  return -EINTR;
2331 
2332  if (!(sc = ec_master_get_config(master, data.config_index))) {
2333  up(&master->master_sem);
2334  return -ENOENT;
2335  }
2336 
2337  up(&master->master_sem);
2339  ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2340  return 0;
2341 }
2342 
2343 /*****************************************************************************/
2344 
2350  ec_master_t *master,
2351  void *arg,
2352  ec_ioctl_context_t *ctx
2353  )
2354 {
2355  ec_ioctl_add_pdo_entry_t data;
2356  ec_slave_config_t *sc;
2357 
2358  if (unlikely(!ctx->requested))
2359  return -EPERM;
2360 
2361  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2362  return -EFAULT;
2363 
2364  if (down_interruptible(&master->master_sem))
2365  return -EINTR;
2366 
2367  if (!(sc = ec_master_get_config(master, data.config_index))) {
2368  up(&master->master_sem);
2369  return -ENOENT;
2370  }
2371 
2372  up(&master->master_sem);
2374  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2375  data.entry_index, data.entry_subindex, data.entry_bit_length);
2376 }
2377 
2378 /*****************************************************************************/
2379 
2385  ec_master_t *master,
2386  void *arg,
2387  ec_ioctl_context_t *ctx
2388  )
2389 {
2390  ec_ioctl_config_pdo_t data;
2391  ec_slave_config_t *sc;
2392 
2393  if (unlikely(!ctx->requested))
2394  return -EPERM;
2395 
2396  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2397  return -EFAULT;
2398 
2399  if (down_interruptible(&master->master_sem))
2400  return -EINTR;
2401 
2402  if (!(sc = ec_master_get_config(master, data.config_index))) {
2403  up(&master->master_sem);
2404  return -ENOENT;
2405  }
2406 
2407  up(&master->master_sem);
2409  ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2410  return 0;
2411 }
2412 
2413 /*****************************************************************************/
2414 
2420  ec_master_t *master,
2421  void *arg,
2422  ec_ioctl_context_t *ctx
2423  )
2424 {
2425  ec_ioctl_reg_pdo_entry_t data;
2426  ec_slave_config_t *sc;
2427  ec_domain_t *domain;
2428  int ret;
2429 
2430  if (unlikely(!ctx->requested))
2431  return -EPERM;
2432 
2433  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2434  return -EFAULT;
2435 
2436  if (down_interruptible(&master->master_sem))
2437  return -EINTR;
2438 
2439  if (!(sc = ec_master_get_config(master, data.config_index))) {
2440  up(&master->master_sem);
2441  return -ENOENT;
2442  }
2443 
2444  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2445  up(&master->master_sem);
2446  return -ENOENT;
2447  }
2448 
2449  up(&master->master_sem);
2451  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2452  data.entry_subindex, domain, &data.bit_position);
2453 
2454  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2455  return -EFAULT;
2456 
2457  return ret;
2458 }
2459 
2460 /*****************************************************************************/
2461 
2467  ec_master_t *master,
2468  void *arg,
2469  ec_ioctl_context_t *ctx
2470  )
2471 {
2472  ec_ioctl_reg_pdo_pos_t io;
2473  ec_slave_config_t *sc;
2474  ec_domain_t *domain;
2475  int ret;
2476 
2477  if (unlikely(!ctx->requested)) {
2478  return -EPERM;
2479  }
2480 
2481  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2482  return -EFAULT;
2483  }
2484 
2485  if (down_interruptible(&master->master_sem)) {
2486  return -EINTR;
2487  }
2488 
2489  if (!(sc = ec_master_get_config(master, io.config_index))) {
2490  up(&master->master_sem);
2491  return -ENOENT;
2492  }
2493 
2494  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2495  up(&master->master_sem);
2496  return -ENOENT;
2497  }
2498 
2499  up(&master->master_sem);
2501  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2502  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2503 
2504  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2505  return -EFAULT;
2506 
2507  return ret;
2508 }
2509 
2510 /*****************************************************************************/
2511 
2517  ec_master_t *master,
2518  void *arg,
2519  ec_ioctl_context_t *ctx
2520  )
2521 {
2522  ec_ioctl_config_t data;
2523  ec_slave_config_t *sc;
2524 
2525  if (unlikely(!ctx->requested))
2526  return -EPERM;
2527 
2528  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2529  return -EFAULT;
2530 
2531  if (down_interruptible(&master->master_sem))
2532  return -EINTR;
2533 
2534  if (!(sc = ec_master_get_config(master, data.config_index))) {
2535  up(&master->master_sem);
2536  return -ENOENT;
2537  }
2538 
2540  data.dc_sync[0].cycle_time,
2541  data.dc_sync[0].shift_time,
2542  data.dc_sync[1].cycle_time,
2543  data.dc_sync[1].shift_time);
2544 
2545  up(&master->master_sem);
2546 
2547  return 0;
2548 }
2549 
2550 /*****************************************************************************/
2551 
2557  ec_master_t *master,
2558  void *arg,
2559  ec_ioctl_context_t *ctx
2560  )
2561 {
2562  ec_ioctl_sc_sdo_t data;
2563  ec_slave_config_t *sc;
2564  uint8_t *sdo_data = NULL;
2565  int ret;
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 (!data.size)
2574  return -EINVAL;
2575 
2576  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2577  return -ENOMEM;
2578  }
2579 
2580  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2581  kfree(sdo_data);
2582  return -EFAULT;
2583  }
2584 
2585  if (down_interruptible(&master->master_sem)) {
2586  kfree(sdo_data);
2587  return -EINTR;
2588  }
2589 
2590  if (!(sc = ec_master_get_config(master, data.config_index))) {
2591  up(&master->master_sem);
2592  kfree(sdo_data);
2593  return -ENOENT;
2594  }
2595 
2596  up(&master->master_sem);
2598  if (data.complete_access) {
2600  data.index, sdo_data, data.size);
2601  } else {
2602  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2603  data.size);
2604  }
2605  kfree(sdo_data);
2606  return ret;
2607 }
2608 
2609 /*****************************************************************************/
2610 
2616  ec_master_t *master,
2617  void *arg,
2618  ec_ioctl_context_t *ctx
2619  )
2620 {
2621  ec_ioctl_sc_emerg_t io;
2622  ec_slave_config_t *sc;
2623  int ret;
2624 
2625  if (unlikely(!ctx->requested))
2626  return -EPERM;
2627 
2628  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2629  return -EFAULT;
2630 
2631  if (down_interruptible(&master->master_sem)) {
2632  return -EINTR;
2633  }
2634 
2635  if (!(sc = ec_master_get_config(master, io.config_index))) {
2636  up(&master->master_sem);
2637  return -ENOENT;
2638  }
2639 
2640  ret = ecrt_slave_config_emerg_size(sc, io.size);
2641 
2642  up(&master->master_sem);
2643 
2644  return ret;
2645 }
2646 
2647 /*****************************************************************************/
2648 
2654  ec_master_t *master,
2655  void *arg,
2656  ec_ioctl_context_t *ctx
2657  )
2658 {
2659  ec_ioctl_sc_emerg_t io;
2660  ec_slave_config_t *sc;
2661  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
2662  int ret;
2663 
2664  if (unlikely(!ctx->requested)) {
2665  return -EPERM;
2666  }
2667 
2668  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2669  return -EFAULT;
2670  }
2671 
2672  /* no locking of master_sem needed, because configuration will not be
2673  * deleted in the meantime. */
2674 
2675  if (!(sc = ec_master_get_config(master, io.config_index))) {
2676  return -ENOENT;
2677  }
2678 
2679  ret = ecrt_slave_config_emerg_pop(sc, msg);
2680  if (ret < 0) {
2681  return ret;
2682  }
2683 
2684  if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
2685  return -EFAULT;
2686  }
2687 
2688  return ret;
2689 }
2690 
2691 /*****************************************************************************/
2692 
2698  ec_master_t *master,
2699  void *arg,
2700  ec_ioctl_context_t *ctx
2701  )
2702 {
2703  ec_ioctl_sc_emerg_t io;
2704  ec_slave_config_t *sc;
2705 
2706  if (unlikely(!ctx->requested)) {
2707  return -EPERM;
2708  }
2709 
2710  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2711  return -EFAULT;
2712  }
2713 
2714  /* no locking of master_sem needed, because configuration will not be
2715  * deleted in the meantime. */
2716 
2717  if (!(sc = ec_master_get_config(master, io.config_index))) {
2718  return -ENOENT;
2719  }
2720 
2721  return ecrt_slave_config_emerg_clear(sc);
2722 }
2723 
2724 /*****************************************************************************/
2725 
2731  ec_master_t *master,
2732  void *arg,
2733  ec_ioctl_context_t *ctx
2734  )
2735 {
2736  ec_ioctl_sc_emerg_t io;
2737  ec_slave_config_t *sc;
2738  int ret;
2739 
2740  if (unlikely(!ctx->requested)) {
2741  return -EPERM;
2742  }
2743 
2744  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2745  return -EFAULT;
2746  }
2747 
2748  /* no locking of master_sem needed, because configuration will not be
2749  * deleted in the meantime. */
2750 
2751  if (!(sc = ec_master_get_config(master, io.config_index))) {
2752  return -ENOENT;
2753  }
2754 
2756  if (ret < 0) {
2757  return ret;
2758  }
2759 
2760  io.overruns = ret;
2761 
2762  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2763  return -EFAULT;
2764  }
2765 
2766  return 0;
2767 }
2768 
2769 /*****************************************************************************/
2770 
2776  ec_master_t *master,
2777  void *arg,
2778  ec_ioctl_context_t *ctx
2779  )
2780 {
2781  ec_ioctl_sdo_request_t data;
2782  ec_slave_config_t *sc;
2783  ec_sdo_request_t *req;
2784 
2785  if (unlikely(!ctx->requested))
2786  return -EPERM;
2787 
2788  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2789  return -EFAULT;
2790  }
2791 
2792  data.request_index = 0;
2793 
2794  if (down_interruptible(&master->master_sem))
2795  return -EINTR;
2796 
2797  sc = ec_master_get_config(master, data.config_index);
2798  if (!sc) {
2799  up(&master->master_sem);
2800  return -ENOENT;
2801  }
2802 
2803  list_for_each_entry(req, &sc->sdo_requests, list) {
2804  data.request_index++;
2805  }
2806 
2807  up(&master->master_sem);
2809  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
2810  data.sdo_subindex, data.size);
2811  if (IS_ERR(req))
2812  return PTR_ERR(req);
2813 
2814  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2815  return -EFAULT;
2816 
2817  return 0;
2818 }
2819 
2820 /*****************************************************************************/
2821 
2827  ec_master_t *master,
2828  void *arg,
2829  ec_ioctl_context_t *ctx
2830  )
2831 {
2832  ec_ioctl_soe_request_t data;
2833  ec_slave_config_t *sc;
2834  ec_soe_request_t *req;
2835 
2836  if (unlikely(!ctx->requested))
2837  return -EPERM;
2838 
2839  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2840  return -EFAULT;
2841  }
2842 
2843  data.request_index = 0;
2844 
2845  if (down_interruptible(&master->master_sem))
2846  return -EINTR;
2847 
2848  sc = ec_master_get_config(master, data.config_index);
2849  if (!sc) {
2850  up(&master->master_sem);
2851  return -ENOENT;
2852  }
2853 
2854  list_for_each_entry(req, &sc->soe_requests, list) {
2855  data.request_index++;
2856  }
2857 
2858  up(&master->master_sem);
2860  req = ecrt_slave_config_create_soe_request_err(sc, data.drive_no,
2861  data.idn, data.size);
2862  if (IS_ERR(req)) {
2863  return PTR_ERR(req);
2864  }
2865 
2866  if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
2867  return -EFAULT;
2868  }
2869 
2870  return 0;
2871 }
2872 
2873 /*****************************************************************************/
2874 
2880  ec_master_t *master,
2881  void *arg,
2882  ec_ioctl_context_t *ctx
2883  )
2884 {
2885  ec_ioctl_reg_request_t io;
2886  ec_slave_config_t *sc;
2887  ec_reg_request_t *reg;
2888 
2889  if (unlikely(!ctx->requested)) {
2890  return -EPERM;
2891  }
2892 
2893  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2894  return -EFAULT;
2895  }
2896 
2897  io.request_index = 0;
2898 
2899  if (down_interruptible(&master->master_sem)) {
2900  return -EINTR;
2901  }
2902 
2903  sc = ec_master_get_config(master, io.config_index);
2904  if (!sc) {
2905  up(&master->master_sem);
2906  return -ENOENT;
2907  }
2908 
2909  list_for_each_entry(reg, &sc->reg_requests, list) {
2910  io.request_index++;
2911  }
2912 
2913  up(&master->master_sem);
2915  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
2916  if (IS_ERR(reg)) {
2917  return PTR_ERR(reg);
2918  }
2919 
2920  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2921  return -EFAULT;
2922  }
2923 
2924  return 0;
2925 }
2926 
2927 /*****************************************************************************/
2928 
2934  ec_master_t *master,
2935  void *arg,
2936  ec_ioctl_context_t *ctx
2937  )
2938 {
2939  ec_ioctl_voe_t data;
2940  ec_slave_config_t *sc;
2941  ec_voe_handler_t *voe;
2942 
2943  if (unlikely(!ctx->requested))
2944  return -EPERM;
2945 
2946  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2947  return -EFAULT;
2948  }
2949 
2950  data.voe_index = 0;
2951 
2952  if (down_interruptible(&master->master_sem))
2953  return -EINTR;
2954 
2955  sc = ec_master_get_config(master, data.config_index);
2956  if (!sc) {
2957  up(&master->master_sem);
2958  return -ENOENT;
2959  }
2960 
2961  list_for_each_entry(voe, &sc->voe_handlers, list) {
2962  data.voe_index++;
2963  }
2964 
2965  up(&master->master_sem);
2967  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
2968  if (IS_ERR(voe))
2969  return PTR_ERR(voe);
2970 
2971  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2972  return -EFAULT;
2973 
2974  return 0;
2975 }
2976 
2977 /*****************************************************************************/
2978 
2984  ec_master_t *master,
2985  void *arg,
2986  ec_ioctl_context_t *ctx
2987  )
2988 {
2989  ec_ioctl_sc_state_t data;
2990  const ec_slave_config_t *sc;
2992 
2993  if (unlikely(!ctx->requested))
2994  return -EPERM;
2995 
2996  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2997  return -EFAULT;
2998  }
2999 
3000  /* no locking of master_sem needed, because sc will not be deleted in the
3001  * meantime. */
3002 
3003  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
3004  return -ENOENT;
3005  }
3006 
3007  ecrt_slave_config_state(sc, &state);
3008 
3009  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3010  return -EFAULT;
3011 
3012  return 0;
3013 }
3014 
3015 /*****************************************************************************/
3016 
3022  ec_master_t *master,
3023  void *arg,
3024  ec_ioctl_context_t *ctx
3025  )
3026 {
3027  ec_ioctl_sc_idn_t ioctl;
3028  ec_slave_config_t *sc;
3029  uint8_t *data = NULL;
3030  int ret;
3031 
3032  if (unlikely(!ctx->requested))
3033  return -EPERM;
3034 
3035  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
3036  return -EFAULT;
3037 
3038  if (!ioctl.size)
3039  return -EINVAL;
3040 
3041  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
3042  return -ENOMEM;
3043  }
3044 
3045  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
3046  kfree(data);
3047  return -EFAULT;
3048  }
3049 
3050  if (down_interruptible(&master->master_sem)) {
3051  kfree(data);
3052  return -EINTR;
3053  }
3054 
3055  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3056  up(&master->master_sem);
3057  kfree(data);
3058  return -ENOENT;
3059  }
3060 
3061  up(&master->master_sem);
3063  ret = ecrt_slave_config_idn(
3064  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3065  kfree(data);
3066  return ret;
3067 }
3068 
3069 /*****************************************************************************/
3070 
3076  ec_master_t *master,
3077  void *arg,
3078  ec_ioctl_context_t *ctx
3079  )
3080 {
3081  ec_ioctl_sc_flag_t ioctl;
3082  ec_slave_config_t *sc;
3083  uint8_t *key;
3084  int ret;
3085 
3086  if (unlikely(!ctx->requested)) {
3087  return -EPERM;
3088  }
3089 
3090  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3091  return -EFAULT;
3092  }
3093 
3094  if (!ioctl.key_size) {
3095  return -EINVAL;
3096  }
3097 
3098  if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3099  return -ENOMEM;
3100  }
3101 
3102  if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3103  kfree(key);
3104  return -EFAULT;
3105  }
3106  key[ioctl.key_size] = '\0';
3107 
3108  if (down_interruptible(&master->master_sem)) {
3109  kfree(key);
3110  return -EINTR;
3111  }
3112 
3113  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3114  up(&master->master_sem);
3115  kfree(key);
3116  return -ENOENT;
3117  }
3118 
3119  up(&master->master_sem);
3121  ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3122  kfree(key);
3123  return ret;
3124 }
3125 
3126 /*****************************************************************************/
3127 
3133  ec_master_t *master,
3134  void *arg,
3135  ec_ioctl_context_t *ctx
3136  )
3137 {
3138  const ec_domain_t *domain;
3139 
3140  if (unlikely(!ctx->requested)) {
3141  return -EPERM;
3142  }
3143 
3144  if (down_interruptible(&master->master_sem)) {
3145  return -EINTR;
3146  }
3147 
3148  list_for_each_entry(domain, &master->domains, list) {
3149  if (domain->index == (unsigned long) arg) {
3150  size_t size = ecrt_domain_size(domain);
3151  up(&master->master_sem);
3152  return size;
3153  }
3154  }
3155 
3156  up(&master->master_sem);
3157  return -ENOENT;
3158 }
3159 
3160 /*****************************************************************************/
3161 
3167  ec_master_t *master,
3168  void *arg,
3169  ec_ioctl_context_t *ctx
3170  )
3171 {
3172  int offset = 0;
3173  const ec_domain_t *domain;
3174 
3175  if (unlikely(!ctx->requested))
3176  return -EPERM;
3177 
3178  if (down_interruptible(&master->master_sem)) {
3179  return -EINTR;
3180  }
3181 
3182  list_for_each_entry(domain, &master->domains, list) {
3183  if (domain->index == (unsigned long) arg) {
3184  up(&master->master_sem);
3185  return offset;
3186  }
3187  offset += ecrt_domain_size(domain);
3188  }
3189 
3190  up(&master->master_sem);
3191  return -ENOENT;
3192 }
3193 
3194 /*****************************************************************************/
3195 
3201  ec_master_t *master,
3202  void *arg,
3203  ec_ioctl_context_t *ctx
3204  )
3205 {
3206  ec_domain_t *domain;
3207 
3208  if (unlikely(!ctx->requested))
3209  return -EPERM;
3210 
3211  /* no locking of master_sem needed, because domain will not be deleted in
3212  * the meantime. */
3213 
3214  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3215  return -ENOENT;
3216  }
3217 
3218  ecrt_domain_process(domain);
3219  return 0;
3220 }
3221 
3222 /*****************************************************************************/
3223 
3229  ec_master_t *master,
3230  void *arg,
3231  ec_ioctl_context_t *ctx
3232  )
3233 {
3234  ec_domain_t *domain;
3235 
3236  if (unlikely(!ctx->requested))
3237  return -EPERM;
3238 
3239  /* no locking of master_sem needed, because domain will not be deleted in
3240  * the meantime. */
3241 
3242  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3243  return -ENOENT;
3244  }
3245 
3246  down( & master->io_sem );
3247  ecrt_domain_queue(domain);
3248  up( & master->io_sem );
3249  return 0;
3250 }
3251 
3252 /*****************************************************************************/
3253 
3259  ec_master_t *master,
3260  void *arg,
3261  ec_ioctl_context_t *ctx
3262  )
3263 {
3264  ec_ioctl_domain_state_t data;
3265  const ec_domain_t *domain;
3266  ec_domain_state_t state;
3267 
3268  if (unlikely(!ctx->requested))
3269  return -EPERM;
3270 
3271  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3272  return -EFAULT;
3273  }
3274 
3275  /* no locking of master_sem needed, because domain will not be deleted in
3276  * the meantime. */
3277 
3278  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3279  return -ENOENT;
3280  }
3281 
3282  ecrt_domain_state(domain, &state);
3283 
3284  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3285  return -EFAULT;
3286 
3287  return 0;
3288 }
3289 
3290 /*****************************************************************************/
3291 
3297  ec_master_t *master,
3298  void *arg,
3299  ec_ioctl_context_t *ctx
3300  )
3301 {
3302  ec_ioctl_sdo_request_t data;
3303  ec_slave_config_t *sc;
3304  ec_sdo_request_t *req;
3305 
3306  if (unlikely(!ctx->requested))
3307  return -EPERM;
3308 
3309  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3310  return -EFAULT;
3311 
3312  /* no locking of master_sem needed, because neither sc nor req will not be
3313  * deleted in the meantime. */
3314 
3315  if (!(sc = ec_master_get_config(master, data.config_index))) {
3316  return -ENOENT;
3317  }
3318 
3319  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3320  return -ENOENT;
3321  }
3322 
3323  ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3324  return 0;
3325 }
3326 
3327 /*****************************************************************************/
3328 
3334  ec_master_t *master,
3335  void *arg,
3336  ec_ioctl_context_t *ctx
3337  )
3338 {
3339  ec_ioctl_sdo_request_t data;
3340  ec_slave_config_t *sc;
3341  ec_sdo_request_t *req;
3342 
3343  if (unlikely(!ctx->requested))
3344  return -EPERM;
3345 
3346  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3347  return -EFAULT;
3348 
3349  /* no locking of master_sem needed, because neither sc nor req will not be
3350  * deleted in the meantime. */
3351 
3352  if (!(sc = ec_master_get_config(master, data.config_index))) {
3353  return -ENOENT;
3354  }
3355 
3356  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3357  return -ENOENT;
3358  }
3359 
3360  ecrt_sdo_request_timeout(req, data.timeout);
3361  return 0;
3362 }
3363 
3364 /*****************************************************************************/
3365 
3371  ec_master_t *master,
3372  void *arg,
3373  ec_ioctl_context_t *ctx
3374  )
3375 {
3376  ec_ioctl_sdo_request_t data;
3377  ec_slave_config_t *sc;
3378  ec_sdo_request_t *req;
3379 
3380  if (unlikely(!ctx->requested))
3381  return -EPERM;
3382 
3383  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3384  return -EFAULT;
3385 
3386  /* no locking of master_sem needed, because neither sc nor req will not be
3387  * deleted in the meantime. */
3388 
3389  if (!(sc = ec_master_get_config(master, data.config_index))) {
3390  return -ENOENT;
3391  }
3392 
3393  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3394  return -ENOENT;
3395  }
3396 
3397  data.state = ecrt_sdo_request_state(req);
3398  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3399  data.size = ecrt_sdo_request_data_size(req);
3400  else
3401  data.size = 0;
3402 
3403  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3404  return -EFAULT;
3405 
3406  return 0;
3407 }
3408 
3409 /*****************************************************************************/
3410 
3416  ec_master_t *master,
3417  void *arg,
3418  ec_ioctl_context_t *ctx
3419  )
3420 {
3421  ec_ioctl_sdo_request_t data;
3422  ec_slave_config_t *sc;
3423  ec_sdo_request_t *req;
3424 
3425  if (unlikely(!ctx->requested))
3426  return -EPERM;
3427 
3428  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3429  return -EFAULT;
3430 
3431  /* no locking of master_sem needed, because neither sc nor req will not be
3432  * deleted in the meantime. */
3433 
3434  if (!(sc = ec_master_get_config(master, data.config_index))) {
3435  return -ENOENT;
3436  }
3437 
3438  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3439  return -ENOENT;
3440  }
3441 
3442  ecrt_sdo_request_read(req);
3443  return 0;
3444 }
3445 
3446 /*****************************************************************************/
3447 
3453  ec_master_t *master,
3454  void *arg,
3455  ec_ioctl_context_t *ctx
3456  )
3457 {
3458  ec_ioctl_sdo_request_t data;
3459  ec_slave_config_t *sc;
3460  ec_sdo_request_t *req;
3461  int ret;
3462 
3463  if (unlikely(!ctx->requested))
3464  return -EPERM;
3465 
3466  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3467  return -EFAULT;
3468 
3469  if (!data.size) {
3470  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3471  return -EINVAL;
3472  }
3473 
3474  /* no locking of master_sem needed, because neither sc nor req will not be
3475  * deleted in the meantime. */
3476 
3477  if (!(sc = ec_master_get_config(master, data.config_index))) {
3478  return -ENOENT;
3479  }
3480 
3481  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3482  return -ENOENT;
3483  }
3484 
3485  ret = ec_sdo_request_alloc(req, data.size);
3486  if (ret)
3487  return ret;
3488 
3489  if (copy_from_user(req->data, (void __user *) data.data, data.size))
3490  return -EFAULT;
3491 
3492  req->data_size = data.size;
3494  return 0;
3495 }
3496 
3497 /*****************************************************************************/
3498 
3504  ec_master_t *master,
3505  void *arg,
3506  ec_ioctl_context_t *ctx
3507  )
3508 {
3509  ec_ioctl_sdo_request_t data;
3510  ec_slave_config_t *sc;
3511  ec_sdo_request_t *req;
3512 
3513  if (unlikely(!ctx->requested))
3514  return -EPERM;
3515 
3516  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3517  return -EFAULT;
3518 
3519  /* no locking of master_sem needed, because neither sc nor req will not be
3520  * deleted in the meantime. */
3521 
3522  if (!(sc = ec_master_get_config(master, data.config_index))) {
3523  return -ENOENT;
3524  }
3525 
3526  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3527  return -ENOENT;
3528  }
3529 
3530  if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3532  return -EFAULT;
3533 
3534  return 0;
3535 }
3536 
3537 /*****************************************************************************/
3538 
3544  ec_master_t *master,
3545  void *arg,
3546  ec_ioctl_context_t *ctx
3547  )
3548 {
3549  ec_ioctl_soe_request_t data;
3550  ec_slave_config_t *sc;
3551  ec_soe_request_t *req;
3552 
3553  if (unlikely(!ctx->requested))
3554  return -EPERM;
3555 
3556  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3557  return -EFAULT;
3558 
3559  /* no locking of master_sem needed, because neither sc nor req will not be
3560  * deleted in the meantime. */
3561 
3562  if (!(sc = ec_master_get_config(master, data.config_index))) {
3563  return -ENOENT;
3564  }
3565 
3566  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3567  return -ENOENT;
3568  }
3569 
3570  ecrt_soe_request_idn(req, data.drive_no, data.idn);
3571  return 0;
3572 }
3573 
3574 /*****************************************************************************/
3575 
3581  ec_master_t *master,
3582  void *arg,
3583  ec_ioctl_context_t *ctx
3584  )
3585 {
3586  ec_ioctl_soe_request_t data;
3587  ec_slave_config_t *sc;
3588  ec_soe_request_t *req;
3589 
3590  if (unlikely(!ctx->requested))
3591  return -EPERM;
3592 
3593  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3594  return -EFAULT;
3595 
3596  /* no locking of master_sem needed, because neither sc nor req will not be
3597  * deleted in the meantime. */
3598 
3599  if (!(sc = ec_master_get_config(master, data.config_index))) {
3600  return -ENOENT;
3601  }
3602 
3603  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3604  return -ENOENT;
3605  }
3606 
3607  ecrt_soe_request_timeout(req, data.timeout);
3608  return 0;
3609 }
3610 
3611 /*****************************************************************************/
3612 
3618  ec_master_t *master,
3619  void *arg,
3620  ec_ioctl_context_t *ctx
3621  )
3622 {
3623  ec_ioctl_soe_request_t data;
3624  ec_slave_config_t *sc;
3625  ec_soe_request_t *req;
3626 
3627  if (unlikely(!ctx->requested))
3628  return -EPERM;
3629 
3630  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3631  return -EFAULT;
3632 
3633  /* no locking of master_sem needed, because neither sc nor req will not be
3634  * deleted in the meantime. */
3635 
3636  if (!(sc = ec_master_get_config(master, data.config_index))) {
3637  return -ENOENT;
3638  }
3639 
3640  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3641  return -ENOENT;
3642  }
3643 
3644  data.state = ecrt_soe_request_state(req);
3645  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT) {
3646  data.size = ecrt_soe_request_data_size(req);
3647  }
3648  else {
3649  data.size = 0;
3650  }
3651 
3652  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3653  return -EFAULT;
3654 
3655  return 0;
3656 }
3657 
3658 /*****************************************************************************/
3659 
3665  ec_master_t *master,
3666  void *arg,
3667  ec_ioctl_context_t *ctx
3668  )
3669 {
3670  ec_ioctl_soe_request_t data;
3671  ec_slave_config_t *sc;
3672  ec_soe_request_t *req;
3673 
3674  if (unlikely(!ctx->requested))
3675  return -EPERM;
3676 
3677  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3678  return -EFAULT;
3679 
3680  /* no locking of master_sem needed, because neither sc nor req will not be
3681  * deleted in the meantime. */
3682 
3683  if (!(sc = ec_master_get_config(master, data.config_index))) {
3684  return -ENOENT;
3685  }
3686 
3687  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3688  return -ENOENT;
3689  }
3690 
3691  ecrt_soe_request_read(req);
3692  return 0;
3693 }
3694 
3695 /*****************************************************************************/
3696 
3702  ec_master_t *master,
3703  void *arg,
3704  ec_ioctl_context_t *ctx
3705  )
3706 {
3707  ec_ioctl_soe_request_t data;
3708  ec_slave_config_t *sc;
3709  ec_soe_request_t *req;
3710  int ret;
3711 
3712  if (unlikely(!ctx->requested))
3713  return -EPERM;
3714 
3715  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3716  return -EFAULT;
3717 
3718  if (!data.size) {
3719  EC_MASTER_ERR(master, "IDN write: Data size may not be zero!\n");
3720  return -EINVAL;
3721  }
3722 
3723  /* no locking of master_sem needed, because neither sc nor req will not be
3724  * deleted in the meantime. */
3725 
3726  if (!(sc = ec_master_get_config(master, data.config_index))) {
3727  return -ENOENT;
3728  }
3729 
3730  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3731  return -ENOENT;
3732  }
3733 
3734  ret = ec_soe_request_alloc(req, data.size);
3735  if (ret)
3736  return ret;
3737 
3738  if (copy_from_user(req->data, (void __user *) data.data, data.size))
3739  return -EFAULT;
3740 
3741  req->data_size = data.size;
3743  return 0;
3744 }
3745 
3746 /*****************************************************************************/
3747 
3753  ec_master_t *master,
3754  void *arg,
3755  ec_ioctl_context_t *ctx
3756  )
3757 {
3758  ec_ioctl_soe_request_t data;
3759  ec_slave_config_t *sc;
3760  ec_soe_request_t *req;
3761 
3762  if (unlikely(!ctx->requested))
3763  return -EPERM;
3764 
3765  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3766  return -EFAULT;
3767 
3768  /* no locking of master_sem needed, because neither sc nor req will not be
3769  * deleted in the meantime. */
3770 
3771  if (!(sc = ec_master_get_config(master, data.config_index))) {
3772  return -ENOENT;
3773  }
3774 
3775  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3776  return -ENOENT;
3777  }
3778 
3779  if (copy_to_user((void __user *) data.data, ecrt_soe_request_data(req),
3781  return -EFAULT;
3782 
3783  return 0;
3784 }
3785 
3786 /*****************************************************************************/
3787 
3793  ec_master_t *master,
3794  void *arg,
3795  ec_ioctl_context_t *ctx
3796  )
3797 {
3798  ec_ioctl_reg_request_t io;
3799  ec_slave_config_t *sc;
3800  ec_reg_request_t *reg;
3801 
3802  if (unlikely(!ctx->requested)) {
3803  return -EPERM;
3804  }
3805 
3806  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3807  return -EFAULT;
3808  }
3809 
3810  if (io.mem_size <= 0) {
3811  return 0;
3812  }
3813 
3814  /* no locking of master_sem needed, because neither sc nor reg will not be
3815  * deleted in the meantime. */
3816 
3817  if (!(sc = ec_master_get_config(master, io.config_index))) {
3818  return -ENOENT;
3819  }
3820 
3821  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3822  return -ENOENT;
3823  }
3824 
3825  if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3826  min(reg->mem_size, io.mem_size))) {
3827  return -EFAULT;
3828  }
3829 
3830  return 0;
3831 }
3832 
3833 /*****************************************************************************/
3834 
3840  ec_master_t *master,
3841  void *arg,
3842  ec_ioctl_context_t *ctx
3843  )
3844 {
3845  ec_ioctl_reg_request_t io;
3846  ec_slave_config_t *sc;
3847  ec_reg_request_t *reg;
3848 
3849  if (unlikely(!ctx->requested)) {
3850  return -EPERM;
3851  }
3852 
3853  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3854  return -EFAULT;
3855  }
3856 
3857  /* no locking of master_sem needed, because neither sc nor reg will not be
3858  * deleted in the meantime. */
3859 
3860  if (!(sc = ec_master_get_config(master, io.config_index))) {
3861  return -ENOENT;
3862  }
3863 
3864  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3865  return -ENOENT;
3866  }
3867 
3868  io.state = ecrt_reg_request_state(reg);
3869  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
3870 
3871  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3872  return -EFAULT;
3873  }
3874 
3875  return 0;
3876 }
3877 
3878 /*****************************************************************************/
3879 
3885  ec_master_t *master,
3886  void *arg,
3887  ec_ioctl_context_t *ctx
3888  )
3889 {
3890  ec_ioctl_reg_request_t io;
3891  ec_slave_config_t *sc;
3892  ec_reg_request_t *reg;
3893 
3894  if (unlikely(!ctx->requested)) {
3895  return -EPERM;
3896  }
3897 
3898  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3899  return -EFAULT;
3900  }
3901 
3902  /* no locking of master_sem needed, because neither sc nor reg will not be
3903  * deleted in the meantime. */
3904 
3905  if (!(sc = ec_master_get_config(master, io.config_index))) {
3906  return -ENOENT;
3907  }
3908 
3909  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3910  return -ENOENT;
3911  }
3912 
3913  if (io.transfer_size > reg->mem_size) {
3914  return -EOVERFLOW;
3915  }
3916 
3917  if (copy_from_user(reg->data, (void __user *) io.data,
3918  io.transfer_size)) {
3919  return -EFAULT;
3920  }
3921 
3922  ecrt_reg_request_write(reg, io.address, io.transfer_size);
3923  return 0;
3924 }
3925 
3926 /*****************************************************************************/
3927 
3933  ec_master_t *master,
3934  void *arg,
3935  ec_ioctl_context_t *ctx
3936  )
3937 {
3938  ec_ioctl_reg_request_t io;
3939  ec_slave_config_t *sc;
3940  ec_reg_request_t *reg;
3941 
3942  if (unlikely(!ctx->requested)) {
3943  return -EPERM;
3944  }
3945 
3946  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3947  return -EFAULT;
3948  }
3949 
3950  /* no locking of master_sem needed, because neither sc nor reg will not be
3951  * deleted in the meantime. */
3952 
3953  if (!(sc = ec_master_get_config(master, io.config_index))) {
3954  return -ENOENT;
3955  }
3956 
3957  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3958  return -ENOENT;
3959  }
3960 
3961  if (io.transfer_size > reg->mem_size) {
3962  return -EOVERFLOW;
3963  }
3964 
3965  ecrt_reg_request_read(reg, io.address, io.transfer_size);
3966  return 0;
3967 }
3968 
3969 /*****************************************************************************/
3970 
3976  ec_master_t *master,
3977  void *arg,
3978  ec_ioctl_context_t *ctx
3979  )
3980 {
3981  ec_ioctl_voe_t data;
3982  ec_slave_config_t *sc;
3983  ec_voe_handler_t *voe;
3984  uint32_t vendor_id;
3985  uint16_t vendor_type;
3986 
3987  if (unlikely(!ctx->requested))
3988  return -EPERM;
3989 
3990  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3991  return -EFAULT;
3992 
3993  if (get_user(vendor_id, data.vendor_id))
3994  return -EFAULT;
3995 
3996  if (get_user(vendor_type, data.vendor_type))
3997  return -EFAULT;
3998 
3999  /* no locking of master_sem needed, because neither sc nor voe will not be
4000  * deleted in the meantime. */
4001 
4002  if (!(sc = ec_master_get_config(master, data.config_index))) {
4003  return -ENOENT;
4004  }
4005 
4006  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4007  return -ENOENT;
4008  }
4009 
4010  ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
4011  return 0;
4012 }
4013 
4014 /*****************************************************************************/
4015 
4021  ec_master_t *master,
4022  void *arg,
4023  ec_ioctl_context_t *ctx
4024  )
4025 {
4026  ec_ioctl_voe_t data;
4027  ec_slave_config_t *sc;
4028  ec_voe_handler_t *voe;
4029  uint32_t vendor_id;
4030  uint16_t vendor_type;
4031 
4032  if (unlikely(!ctx->requested))
4033  return -EPERM;
4034 
4035  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4036  return -EFAULT;
4037 
4038  /* no locking of master_sem needed, because neither sc nor voe will not be
4039  * deleted in the meantime. */
4040 
4041  if (!(sc = ec_master_get_config(master, data.config_index))) {
4042  return -ENOENT;
4043  }
4044 
4045  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4046  return -ENOENT;
4047  }
4048 
4049  ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
4050 
4051  if (likely(data.vendor_id))
4052  if (put_user(vendor_id, data.vendor_id))
4053  return -EFAULT;
4054 
4055  if (likely(data.vendor_type))
4056  if (put_user(vendor_type, data.vendor_type))
4057  return -EFAULT;
4058 
4059  return 0;
4060 }
4061 
4062 /*****************************************************************************/
4063 
4069  ec_master_t *master,
4070  void *arg,
4071  ec_ioctl_context_t *ctx
4072  )
4073 {
4074  ec_ioctl_voe_t data;
4075  ec_slave_config_t *sc;
4076  ec_voe_handler_t *voe;
4077 
4078  if (unlikely(!ctx->requested))
4079  return -EPERM;
4080 
4081  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4082  return -EFAULT;
4083 
4084  /* no locking of master_sem needed, because neither sc nor voe will not be
4085  * deleted in the meantime. */
4086 
4087  if (!(sc = ec_master_get_config(master, data.config_index))) {
4088  return -ENOENT;
4089  }
4090 
4091  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4092  return -ENOENT;
4093  }
4094 
4095  ecrt_voe_handler_read(voe);
4096  return 0;
4097 }
4098 
4099 /*****************************************************************************/
4100 
4106  ec_master_t *master,
4107  void *arg,
4108  ec_ioctl_context_t *ctx
4109  )
4110 {
4111  ec_ioctl_voe_t data;
4112  ec_slave_config_t *sc;
4113  ec_voe_handler_t *voe;
4114 
4115  if (unlikely(!ctx->requested))
4116  return -EPERM;
4117 
4118  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4119  return -EFAULT;
4120 
4121  /* no locking of master_sem needed, because neither sc nor voe will not be
4122  * deleted in the meantime. */
4123 
4124  if (!(sc = ec_master_get_config(master, data.config_index))) {
4125  return -ENOENT;
4126  }
4127 
4128  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4129  return -ENOENT;
4130  }
4131 
4133  return 0;
4134 }
4135 
4136 /*****************************************************************************/
4137 
4143  ec_master_t *master,
4144  void *arg,
4145  ec_ioctl_context_t *ctx
4146  )
4147 {
4148  ec_ioctl_voe_t data;
4149  ec_slave_config_t *sc;
4150  ec_voe_handler_t *voe;
4151 
4152  if (unlikely(!ctx->requested))
4153  return -EPERM;
4154 
4155  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4156  return -EFAULT;
4157 
4158  /* no locking of master_sem needed, because neither sc nor voe will not be
4159  * deleted in the meantime. */
4160 
4161  if (!(sc = ec_master_get_config(master, data.config_index))) {
4162  return -ENOENT;
4163  }
4164 
4165  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4166  return -ENOENT;
4167  }
4168 
4169  if (data.size) {
4170  if (data.size > ec_voe_handler_mem_size(voe))
4171  return -EOVERFLOW;
4172 
4173  if (copy_from_user(ecrt_voe_handler_data(voe),
4174  (void __user *) data.data, data.size))
4175  return -EFAULT;
4176  }
4177 
4178  ecrt_voe_handler_write(voe, data.size);
4179  return 0;
4180 }
4181 
4182 /*****************************************************************************/
4183 
4189  ec_master_t *master,
4190  void *arg,
4191  ec_ioctl_context_t *ctx
4192  )
4193 {
4194  ec_ioctl_voe_t data;
4195  ec_slave_config_t *sc;
4196  ec_voe_handler_t *voe;
4197 
4198  if (unlikely(!ctx->requested))
4199  return -EPERM;
4200 
4201  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4202  return -EFAULT;
4203 
4204  /* no locking of master_sem needed, because neither sc nor voe will not be
4205  * deleted in the meantime. */
4206 
4207  if (!(sc = ec_master_get_config(master, data.config_index))) {
4208  return -ENOENT;
4209  }
4210 
4211  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4212  return -ENOENT;
4213  }
4214 
4215  down( & master->io_sem );
4216  data.state = ecrt_voe_handler_execute(voe);
4217  up( & master->io_sem );
4218  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
4219  data.size = ecrt_voe_handler_data_size(voe);
4220  else
4221  data.size = 0;
4222 
4223  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
4224  return -EFAULT;
4225 
4226  return 0;
4227 }
4228 
4229 /*****************************************************************************/
4230 
4236  ec_master_t *master,
4237  void *arg,
4238  ec_ioctl_context_t *ctx
4239  )
4240 {
4241  ec_ioctl_voe_t data;
4242  ec_slave_config_t *sc;
4243  ec_voe_handler_t *voe;
4244 
4245  if (unlikely(!ctx->requested))
4246  return -EPERM;
4247 
4248  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4249  return -EFAULT;
4250 
4251  /* no locking of master_sem needed, because neither sc nor voe will not be
4252  * deleted in the meantime. */
4253 
4254  if (!(sc = ec_master_get_config(master, data.config_index))) {
4255  return -ENOENT;
4256  }
4257 
4258  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4259  return -ENOENT;
4260  }
4261 
4262  if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
4264  return -EFAULT;
4265 
4266  return 0;
4267 }
4268 
4269 /*****************************************************************************/
4270 
4276  ec_master_t *master,
4277  void *arg
4278  )
4279 {
4280  ec_ioctl_slave_foe_t io;
4281  ec_foe_request_t request;
4282  ec_slave_t *slave;
4283  int ret;
4284 
4285  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4286  return -EFAULT;
4287  }
4288 
4289  ec_foe_request_init(&request, io.file_name);
4290  ret = ec_foe_request_alloc(&request, 10000); // FIXME
4291  if (ret) {
4292  ec_foe_request_clear(&request);
4293  return ret;
4294  }
4295 
4296  ec_foe_request_read(&request);
4297 
4298  if (down_interruptible(&master->master_sem)) {
4299  ec_foe_request_clear(&request);
4300  return -EINTR;
4301  }
4302 
4303  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4304  up(&master->master_sem);
4305  ec_foe_request_clear(&request);
4306  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4307  io.slave_position);
4308  return -EINVAL;
4309  }
4310 
4311  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
4312 
4313  // schedule request.
4314  list_add_tail(&request.list, &slave->foe_requests);
4315 
4316  up(&master->master_sem);
4317 
4318  // wait for processing through FSM
4319  if (wait_event_interruptible(master->request_queue,
4320  request.state != EC_INT_REQUEST_QUEUED)) {
4321  // interrupted by signal
4322  down(&master->master_sem);
4323  if (request.state == EC_INT_REQUEST_QUEUED) {
4324  list_del(&request.list);
4325  up(&master->master_sem);
4326  ec_foe_request_clear(&request);
4327  return -EINTR;
4328  }
4329  // request already processing: interrupt not possible.
4330  up(&master->master_sem);
4331  }
4332 
4333  // wait until master FSM has finished processing
4334  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4335 
4336  io.result = request.result;
4337  io.error_code = request.error_code;
4338 
4339  if (request.state != EC_INT_REQUEST_SUCCESS) {
4340  io.data_size = 0;
4341  ret = -EIO;
4342  } else {
4343  if (request.data_size > io.buffer_size) {
4344  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4345  ec_foe_request_clear(&request);
4346  return -EOVERFLOW;
4347  }
4348  io.data_size = request.data_size;
4349  if (copy_to_user((void __user *) io.buffer,
4350  request.buffer, io.data_size)) {
4351  ec_foe_request_clear(&request);
4352  return -EFAULT;
4353  }
4354  ret = 0;
4355  }
4356 
4357  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4358  ret = -EFAULT;
4359  }
4360 
4361  ec_foe_request_clear(&request);
4362  return ret;
4363 }
4364 
4365 /*****************************************************************************/
4366 
4372  ec_master_t *master,
4373  void *arg
4374  )
4375 {
4376  ec_ioctl_slave_foe_t io;
4377  ec_foe_request_t request;
4378  ec_slave_t *slave;
4379  int ret;
4380 
4381  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4382  return -EFAULT;
4383  }
4384 
4385  ec_foe_request_init(&request, io.file_name);
4386 
4387  ret = ec_foe_request_alloc(&request, io.buffer_size);
4388  if (ret) {
4389  ec_foe_request_clear(&request);
4390  return ret;
4391  }
4392 
4393  if (copy_from_user(request.buffer,
4394  (void __user *) io.buffer, io.buffer_size)) {
4395  ec_foe_request_clear(&request);
4396  return -EFAULT;
4397  }
4398 
4399  request.data_size = io.buffer_size;
4400  ec_foe_request_write(&request);
4401 
4402  if (down_interruptible(&master->master_sem)) {
4403  ec_foe_request_clear(&request);
4404  return -EINTR;
4405  }
4406 
4407  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4408  up(&master->master_sem);
4409  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4410  io.slave_position);
4411  ec_foe_request_clear(&request);
4412  return -EINVAL;
4413  }
4414 
4415  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4416 
4417  // schedule FoE write request.
4418  list_add_tail(&request.list, &slave->foe_requests);
4419 
4420  up(&master->master_sem);
4421 
4422  // wait for processing through FSM
4423  if (wait_event_interruptible(master->request_queue,
4424  request.state != EC_INT_REQUEST_QUEUED)) {
4425  // interrupted by signal
4426  down(&master->master_sem);
4427  if (request.state == EC_INT_REQUEST_QUEUED) {
4428  // abort request
4429  list_del(&request.list);
4430  up(&master->master_sem);
4431  ec_foe_request_clear(&request);
4432  return -EINTR;
4433  }
4434  up(&master->master_sem);
4435  }
4436 
4437  // wait until master FSM has finished processing
4438  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4439 
4440  io.result = request.result;
4441  io.error_code = request.error_code;
4442 
4443  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4444 
4445  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4446  ret = -EFAULT;
4447  }
4448 
4449  ec_foe_request_clear(&request);
4450  return ret;
4451 }
4452 
4453 /*****************************************************************************/
4454 
4460  ec_master_t *master,
4461  void *arg
4462  )
4463 {
4464  ec_ioctl_slave_soe_read_t ioctl;
4465  u8 *data;
4466  int retval;
4467 
4468  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4469  return -EFAULT;
4470  }
4471 
4472  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4473  if (!data) {
4474  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4475  ioctl.mem_size);
4476  return -ENOMEM;
4477  }
4478 
4479  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4480  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4481  &ioctl.error_code);
4482  if (retval) {
4483  kfree(data);
4484  return retval;
4485  }
4486 
4487  if (copy_to_user((void __user *) ioctl.data,
4488  data, ioctl.data_size)) {
4489  kfree(data);
4490  return -EFAULT;
4491  }
4492  kfree(data);
4493 
4494  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4495  retval = -EFAULT;
4496  }
4497 
4498  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4499  return retval;
4500 }
4501 
4502 /*****************************************************************************/
4503 
4509  ec_master_t *master,
4510  void *arg
4511  )
4512 {
4513  ec_ioctl_slave_soe_write_t ioctl;
4514  u8 *data;
4515  int retval;
4516 
4517  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4518  return -EFAULT;
4519  }
4520 
4521  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4522  if (!data) {
4523  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4524  ioctl.data_size);
4525  return -ENOMEM;
4526  }
4527  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4528  kfree(data);
4529  return -EFAULT;
4530  }
4531 
4532  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4533  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4534  &ioctl.error_code);
4535  kfree(data);
4536  if (retval) {
4537  return retval;
4538  }
4539 
4540  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4541  retval = -EFAULT;
4542  }
4543 
4544  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4545  return retval;
4546 }
4547 
4548 /*****************************************************************************/
4549 
4552 #ifdef EC_IOCTL_RTDM
4553 #define EC_IOCTL ec_ioctl_rtdm
4554 #else
4555 #define EC_IOCTL ec_ioctl
4556 #endif
4557 
4563  ec_master_t *master,
4564  ec_ioctl_context_t *ctx,
4565  unsigned int cmd,
4566  void *arg
4567  )
4568 {
4569 #if DEBUG_LATENCY
4570  cycles_t a = get_cycles(), b;
4571  unsigned int t;
4572 #endif
4573  int ret;
4574 
4575  switch (cmd) {
4576  case EC_IOCTL_MODULE:
4577  ret = ec_ioctl_module(arg);
4578  break;
4579  case EC_IOCTL_MASTER:
4580  ret = ec_ioctl_master(master, arg);
4581  break;
4582  case EC_IOCTL_SLAVE:
4583  ret = ec_ioctl_slave(master, arg);
4584  break;
4585  case EC_IOCTL_SLAVE_SYNC:
4586  ret = ec_ioctl_slave_sync(master, arg);
4587  break;
4588  case EC_IOCTL_SLAVE_SYNC_PDO:
4589  ret = ec_ioctl_slave_sync_pdo(master, arg);
4590  break;
4591  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
4593  break;
4594  case EC_IOCTL_DOMAIN:
4595  ret = ec_ioctl_domain(master, arg);
4596  break;
4597  case EC_IOCTL_DOMAIN_FMMU:
4598  ret = ec_ioctl_domain_fmmu(master, arg);
4599  break;
4600  case EC_IOCTL_DOMAIN_DATA:
4601  ret = ec_ioctl_domain_data(master, arg);
4602  break;
4603  case EC_IOCTL_MASTER_DEBUG:
4604  if (!ctx->writable) {
4605  ret = -EPERM;
4606  break;
4607  }
4608  ret = ec_ioctl_master_debug(master, arg);
4609  break;
4610  case EC_IOCTL_MASTER_RESCAN:
4611  if (!ctx->writable) {
4612  ret = -EPERM;
4613  break;
4614  }
4615  ret = ec_ioctl_master_rescan(master, arg);
4616  break;
4617  case EC_IOCTL_SLAVE_STATE:
4618  if (!ctx->writable) {
4619  ret = -EPERM;
4620  break;
4621  }
4622  ret = ec_ioctl_slave_state(master, arg);
4623  break;
4624  case EC_IOCTL_SLAVE_SDO:
4625  ret = ec_ioctl_slave_sdo(master, arg);
4626  break;
4627  case EC_IOCTL_SLAVE_SDO_ENTRY:
4628  ret = ec_ioctl_slave_sdo_entry(master, arg);
4629  break;
4630  case EC_IOCTL_SLAVE_SDO_UPLOAD:
4631  ret = ec_ioctl_slave_sdo_upload(master, arg);
4632  break;
4633  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
4634  if (!ctx->writable) {
4635  ret = -EPERM;
4636  break;
4637  }
4638  ret = ec_ioctl_slave_sdo_download(master, arg);
4639  break;
4640  case EC_IOCTL_SLAVE_SII_READ:
4641  ret = ec_ioctl_slave_sii_read(master, arg);
4642  break;
4643  case EC_IOCTL_SLAVE_SII_WRITE:
4644  if (!ctx->writable) {
4645  ret = -EPERM;
4646  break;
4647  }
4648  ret = ec_ioctl_slave_sii_write(master, arg);
4649  break;
4650  case EC_IOCTL_SLAVE_REG_READ:
4651  ret = ec_ioctl_slave_reg_read(master, arg);
4652  break;
4653  case EC_IOCTL_SLAVE_REG_WRITE:
4654  if (!ctx->writable) {
4655  ret = -EPERM;
4656  break;
4657  }
4658  ret = ec_ioctl_slave_reg_write(master, arg);
4659  break;
4660  case EC_IOCTL_SLAVE_FOE_READ:
4661  ret = ec_ioctl_slave_foe_read(master, arg);
4662  break;
4663  case EC_IOCTL_SLAVE_FOE_WRITE:
4664  if (!ctx->writable) {
4665  ret = -EPERM;
4666  break;
4667  }
4668  ret = ec_ioctl_slave_foe_write(master, arg);
4669  break;
4670  case EC_IOCTL_SLAVE_SOE_READ:
4671  ret = ec_ioctl_slave_soe_read(master, arg);
4672  break;
4673  case EC_IOCTL_SLAVE_SOE_WRITE:
4674  if (!ctx->writable) {
4675  ret = -EPERM;
4676  break;
4677  }
4678  ret = ec_ioctl_slave_soe_write(master, arg);
4679  break;
4680  case EC_IOCTL_CONFIG:
4681  ret = ec_ioctl_config(master, arg);
4682  break;
4683  case EC_IOCTL_CONFIG_PDO:
4684  ret = ec_ioctl_config_pdo(master, arg);
4685  break;
4686  case EC_IOCTL_CONFIG_PDO_ENTRY:
4687  ret = ec_ioctl_config_pdo_entry(master, arg);
4688  break;
4689  case EC_IOCTL_CONFIG_SDO:
4690  ret = ec_ioctl_config_sdo(master, arg);
4691  break;
4692  case EC_IOCTL_CONFIG_IDN:
4693  ret = ec_ioctl_config_idn(master, arg);
4694  break;
4695  case EC_IOCTL_CONFIG_FLAG:
4696  ret = ec_ioctl_config_flag(master, arg);
4697  break;
4698 #ifdef EC_EOE
4699  case EC_IOCTL_EOE_HANDLER:
4700  ret = ec_ioctl_eoe_handler(master, arg);
4701  break;
4702 #endif
4703  case EC_IOCTL_REQUEST:
4704  if (!ctx->writable) {
4705  ret = -EPERM;
4706  break;
4707  }
4708  ret = ec_ioctl_request(master, arg, ctx);
4709  break;
4710  case EC_IOCTL_CREATE_DOMAIN:
4711  if (!ctx->writable) {
4712  ret = -EPERM;
4713  break;
4714  }
4715  ret = ec_ioctl_create_domain(master, arg, ctx);
4716  break;
4717  case EC_IOCTL_CREATE_SLAVE_CONFIG:
4718  if (!ctx->writable) {
4719  ret = -EPERM;
4720  break;
4721  }
4722  ret = ec_ioctl_create_slave_config(master, arg, ctx);
4723  break;
4724  case EC_IOCTL_SELECT_REF_CLOCK:
4725  if (!ctx->writable) {
4726  ret = -EPERM;
4727  break;
4728  }
4729  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
4730  break;
4731  case EC_IOCTL_ACTIVATE:
4732  if (!ctx->writable) {
4733  ret = -EPERM;
4734  break;
4735  }
4736  ret = ec_ioctl_activate(master, arg, ctx);
4737  break;
4738  case EC_IOCTL_DEACTIVATE:
4739  if (!ctx->writable) {
4740  ret = -EPERM;
4741  break;
4742  }
4743  ret = ec_ioctl_deactivate(master, arg, ctx);
4744  break;
4745  case EC_IOCTL_SEND:
4746  if (!ctx->writable) {
4747  ret = -EPERM;
4748  break;
4749  }
4750  ret = ec_ioctl_send(master, arg, ctx);
4751  break;
4752  case EC_IOCTL_RECEIVE:
4753  if (!ctx->writable) {
4754  ret = -EPERM;
4755  break;
4756  }
4757  ret = ec_ioctl_receive(master, arg, ctx);
4758  break;
4759  case EC_IOCTL_MASTER_STATE:
4760  ret = ec_ioctl_master_state(master, arg, ctx);
4761  break;
4762  case EC_IOCTL_MASTER_LINK_STATE:
4763  ret = ec_ioctl_master_link_state(master, arg, ctx);
4764  break;
4765  case EC_IOCTL_APP_TIME:
4766  if (!ctx->writable) {
4767  ret = -EPERM;
4768  break;
4769  }
4770  ret = ec_ioctl_app_time(master, arg, ctx);
4771  break;
4772  case EC_IOCTL_SYNC_REF:
4773  if (!ctx->writable) {
4774  ret = -EPERM;
4775  break;
4776  }
4777  ret = ec_ioctl_sync_ref(master, arg, ctx);
4778  break;
4779  case EC_IOCTL_SYNC_REF_TO:
4780  if (!ctx->writable) {
4781  ret = -EPERM;
4782  break;
4783  }
4784  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
4785  break;
4786  case EC_IOCTL_SYNC_SLAVES:
4787  if (!ctx->writable) {
4788  ret = -EPERM;
4789  break;
4790  }
4791  ret = ec_ioctl_sync_slaves(master, arg, ctx);
4792  break;
4793  case EC_IOCTL_REF_CLOCK_TIME:
4794  if (!ctx->writable) {
4795  ret = -EPERM;
4796  break;
4797  }
4798  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4799  break;
4800  case EC_IOCTL_SYNC_MON_QUEUE:
4801  if (!ctx->writable) {
4802  ret = -EPERM;
4803  break;
4804  }
4805  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4806  break;
4807  case EC_IOCTL_SYNC_MON_PROCESS:
4808  if (!ctx->writable) {
4809  ret = -EPERM;
4810  break;
4811  }
4812  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4813  break;
4814  case EC_IOCTL_RESET:
4815  if (!ctx->writable) {
4816  ret = -EPERM;
4817  break;
4818  }
4819  ret = ec_ioctl_reset(master, arg, ctx);
4820  break;
4821  case EC_IOCTL_SC_SYNC:
4822  if (!ctx->writable) {
4823  ret = -EPERM;
4824  break;
4825  }
4826  ret = ec_ioctl_sc_sync(master, arg, ctx);
4827  break;
4828  case EC_IOCTL_SC_WATCHDOG:
4829  if (!ctx->writable) {
4830  ret = -EPERM;
4831  break;
4832  }
4833  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
4834  break;
4835  case EC_IOCTL_SC_ADD_PDO:
4836  if (!ctx->writable) {
4837  ret = -EPERM;
4838  break;
4839  }
4840  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
4841  break;
4842  case EC_IOCTL_SC_CLEAR_PDOS:
4843  if (!ctx->writable) {
4844  ret = -EPERM;
4845  break;
4846  }
4847  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
4848  break;
4849  case EC_IOCTL_SC_ADD_ENTRY:
4850  if (!ctx->writable) {
4851  ret = -EPERM;
4852  break;
4853  }
4854  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
4855  break;
4856  case EC_IOCTL_SC_CLEAR_ENTRIES:
4857  if (!ctx->writable) {
4858  ret = -EPERM;
4859  break;
4860  }
4861  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
4862  break;
4863  case EC_IOCTL_SC_REG_PDO_ENTRY:
4864  if (!ctx->writable) {
4865  ret = -EPERM;
4866  break;
4867  }
4868  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
4869  break;
4870  case EC_IOCTL_SC_REG_PDO_POS:
4871  if (!ctx->writable) {
4872  ret = -EPERM;
4873  break;
4874  }
4875  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
4876  break;
4877  case EC_IOCTL_SC_DC:
4878  if (!ctx->writable) {
4879  ret = -EPERM;
4880  break;
4881  }
4882  ret = ec_ioctl_sc_dc(master, arg, ctx);
4883  break;
4884  case EC_IOCTL_SC_SDO:
4885  if (!ctx->writable) {
4886  ret = -EPERM;
4887  break;
4888  }
4889  ret = ec_ioctl_sc_sdo(master, arg, ctx);
4890  break;
4891  case EC_IOCTL_SC_EMERG_SIZE:
4892  if (!ctx->writable) {
4893  ret = -EPERM;
4894  break;
4895  }
4896  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
4897  break;
4898  case EC_IOCTL_SC_EMERG_POP:
4899  if (!ctx->writable) {
4900  ret = -EPERM;
4901  break;
4902  }
4903  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
4904  break;
4905  case EC_IOCTL_SC_EMERG_CLEAR:
4906  if (!ctx->writable) {
4907  ret = -EPERM;
4908  break;
4909  }
4910  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
4911  break;
4912  case EC_IOCTL_SC_EMERG_OVERRUNS:
4913  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
4914  break;
4915  case EC_IOCTL_SC_SDO_REQUEST:
4916  if (!ctx->writable) {
4917  ret = -EPERM;
4918  break;
4919  }
4920  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
4921  break;
4922  case EC_IOCTL_SC_SOE_REQUEST:
4923  if (!ctx->writable) {
4924  ret = -EPERM;
4925  break;
4926  }
4927  ret = ec_ioctl_sc_create_soe_request(master, arg, ctx);
4928  break;
4929  case EC_IOCTL_SC_REG_REQUEST:
4930  if (!ctx->writable) {
4931  ret = -EPERM;
4932  break;
4933  }
4934  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
4935  break;
4936  case EC_IOCTL_SC_VOE:
4937  if (!ctx->writable) {
4938  ret = -EPERM;
4939  break;
4940  }
4941  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
4942  break;
4943  case EC_IOCTL_SC_STATE:
4944  ret = ec_ioctl_sc_state(master, arg, ctx);
4945  break;
4946  case EC_IOCTL_SC_IDN:
4947  if (!ctx->writable) {
4948  ret = -EPERM;
4949  break;
4950  }
4951  ret = ec_ioctl_sc_idn(master, arg, ctx);
4952  break;
4953  case EC_IOCTL_SC_FLAG:
4954  if (!ctx->writable) {
4955  ret = -EPERM;
4956  break;
4957  }
4958  ret = ec_ioctl_sc_flag(master, arg, ctx);
4959  break;
4960  case EC_IOCTL_DOMAIN_SIZE:
4961  ret = ec_ioctl_domain_size(master, arg, ctx);
4962  break;
4963  case EC_IOCTL_DOMAIN_OFFSET:
4964  ret = ec_ioctl_domain_offset(master, arg, ctx);
4965  break;
4966  case EC_IOCTL_DOMAIN_PROCESS:
4967  if (!ctx->writable) {
4968  ret = -EPERM;
4969  break;
4970  }
4971  ret = ec_ioctl_domain_process(master, arg, ctx);
4972  break;
4973  case EC_IOCTL_DOMAIN_QUEUE:
4974  if (!ctx->writable) {
4975  ret = -EPERM;
4976  break;
4977  }
4978  ret = ec_ioctl_domain_queue(master, arg, ctx);
4979  break;
4980  case EC_IOCTL_DOMAIN_STATE:
4981  ret = ec_ioctl_domain_state(master, arg, ctx);
4982  break;
4983  case EC_IOCTL_SDO_REQUEST_INDEX:
4984  if (!ctx->writable) {
4985  ret = -EPERM;
4986  break;
4987  }
4988  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
4989  break;
4990  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4991  if (!ctx->writable) {
4992  ret = -EPERM;
4993  break;
4994  }
4995  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4996  break;
4997  case EC_IOCTL_SDO_REQUEST_STATE:
4998  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
4999  break;
5000  case EC_IOCTL_SDO_REQUEST_READ:
5001  if (!ctx->writable) {
5002  ret = -EPERM;
5003  break;
5004  }
5005  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
5006  break;
5007  case EC_IOCTL_SDO_REQUEST_WRITE:
5008  if (!ctx->writable) {
5009  ret = -EPERM;
5010  break;
5011  }
5012  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
5013  break;
5014  case EC_IOCTL_SDO_REQUEST_DATA:
5015  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
5016  break;
5017  case EC_IOCTL_SOE_REQUEST_IDN:
5018  if (!ctx->writable) {
5019  ret = -EPERM;
5020  break;
5021  }
5022  ret = ec_ioctl_soe_request_index(master, arg, ctx);
5023  break;
5024  case EC_IOCTL_SOE_REQUEST_TIMEOUT:
5025  if (!ctx->writable) {
5026  ret = -EPERM;
5027  break;
5028  }
5029  ret = ec_ioctl_soe_request_timeout(master, arg, ctx);
5030  break;
5031  case EC_IOCTL_SOE_REQUEST_STATE:
5032  ret = ec_ioctl_soe_request_state(master, arg, ctx);
5033  break;
5034  case EC_IOCTL_SOE_REQUEST_READ:
5035  if (!ctx->writable) {
5036  ret = -EPERM;
5037  break;
5038  }
5039  ret = ec_ioctl_soe_request_read(master, arg, ctx);
5040  break;
5041  case EC_IOCTL_SOE_REQUEST_WRITE:
5042  if (!ctx->writable) {
5043  ret = -EPERM;
5044  break;
5045  }
5046  ret = ec_ioctl_soe_request_write(master, arg, ctx);
5047  break;
5048  case EC_IOCTL_SOE_REQUEST_DATA:
5049  ret = ec_ioctl_soe_request_data(master, arg, ctx);
5050  break;
5051  case EC_IOCTL_REG_REQUEST_DATA:
5052  ret = ec_ioctl_reg_request_data(master, arg, ctx);
5053  break;
5054  case EC_IOCTL_REG_REQUEST_STATE:
5055  ret = ec_ioctl_reg_request_state(master, arg, ctx);
5056  break;
5057  case EC_IOCTL_REG_REQUEST_WRITE:
5058  if (!ctx->writable) {
5059  ret = -EPERM;
5060  break;
5061  }
5062  ret = ec_ioctl_reg_request_write(master, arg, ctx);
5063  break;
5064  case EC_IOCTL_REG_REQUEST_READ:
5065  if (!ctx->writable) {
5066  ret = -EPERM;
5067  break;
5068  }
5069  ret = ec_ioctl_reg_request_read(master, arg, ctx);
5070  break;
5071  case EC_IOCTL_VOE_SEND_HEADER:
5072  if (!ctx->writable) {
5073  ret = -EPERM;
5074  break;
5075  }
5076  ret = ec_ioctl_voe_send_header(master, arg, ctx);
5077  break;
5078  case EC_IOCTL_VOE_REC_HEADER:
5079  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
5080  break;
5081  case EC_IOCTL_VOE_READ:
5082  if (!ctx->writable) {
5083  ret = -EPERM;
5084  break;
5085  }
5086  ret = ec_ioctl_voe_read(master, arg, ctx);
5087  break;
5088  case EC_IOCTL_VOE_READ_NOSYNC:
5089  if (!ctx->writable) {
5090  ret = -EPERM;
5091  break;
5092  }
5093  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
5094  break;
5095  case EC_IOCTL_VOE_WRITE:
5096  if (!ctx->writable) {
5097  ret = -EPERM;
5098  break;
5099  }
5100  ret = ec_ioctl_voe_write(master, arg, ctx);
5101  break;
5102  case EC_IOCTL_VOE_EXEC:
5103  if (!ctx->writable) {
5104  ret = -EPERM;
5105  break;
5106  }
5107  ret = ec_ioctl_voe_exec(master, arg, ctx);
5108  break;
5109  case EC_IOCTL_VOE_DATA:
5110  ret = ec_ioctl_voe_data(master, arg, ctx);
5111  break;
5112  case EC_IOCTL_SET_SEND_INTERVAL:
5113  if (!ctx->writable) {
5114  ret = -EPERM;
5115  break;
5116  }
5117  ret = ec_ioctl_set_send_interval(master, arg, ctx);
5118  break;
5119  default:
5120  ret = -ENOTTY;
5121  break;
5122  }
5123 
5124 #if DEBUG_LATENCY
5125  b = get_cycles();
5126  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5127  if (t > 50) {
5128  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5129  _IOC_NR(cmd), t);
5130  }
5131 #endif
5132 
5133  return ret;
5134 }
5135 
5136 /*****************************************************************************/
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain&#39;s process data.
Definition: domain.c:427
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:161
void ecrt_reg_request_write(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule an register write operation.
Definition: reg_request.c:100
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:57
const ec_slave_config_t * sc
EtherCAT slave config.
Definition: fmmu_config.h:48
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: ioctl.c:468
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
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:3333
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:476
uint16_t offset
SII word offset.
Definition: fsm_master.h:54
uint16_t ring_position
Ring position.
Definition: slave.h:183
uint32_t revision_number
Revision number.
Definition: slave.h:137
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:116
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:2697
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:706
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:139
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
#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:223
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:2867
struct semaphore io_sem
Semaphore used in IDLE phase.
Definition: master.h:296
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:564
void 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:132
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: ioctl.c:639
void ecrt_reg_request_read(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule a register read operation.
Definition: reg_request.c:111
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:152
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:3452
FMMU configuration.
Definition: fmmu_config.h:46
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: ioctl.c:1377
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:1958
u64 tx_count
Number of frames sent.
Definition: master.h:156
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave&#39;s registers.
Definition: ioctl.c:1033
struct list_head sii_requests
SII write requests.
Definition: master.h:307
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:2849
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:3166
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:1671
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:454
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.
Definition: slave_config.c:984
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:106
CANopen SDO entry.
Definition: sdo_entry.h:54
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:3932
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: ioctl.c:803
size_t data_size
Size of the process data.
Definition: domain.h:61
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:79
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:3975
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:173
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:57
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:1913
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:668
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:108
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:2780
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:187
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:2796
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:97
const ec_flag_t * ec_slave_config_get_flag_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds a flag via its position in the list.
Definition: slave_config.c:498
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:542
CANopen SDO request.
Definition: sdo_request.h:46
ec_slave_state_t current_state
Current application state.
Definition: slave.h:192
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:328
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: ioctl.c:3200
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
static ATTRIBUTES int ec_ioctl_module(void *arg)
Get module information.
Definition: ioctl.c:81
size_t nwords
Number of words.
Definition: fsm_master.h:55
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:61
uint16_t address
Register address.
Definition: reg_request.h:54
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, 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:2957
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:59
Register request.
Definition: reg_request.h:48
ec_direction_t dir
Direction.
Definition: soe_request.h:58
size_t mem_size
Size of data memory.
Definition: reg_request.h:50
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:228
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:3839
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:3884
uint32_t product_code
Slave product code.
Definition: slave_config.h:125
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:2086
ec_slave_port_link_t link
Port link status.
Definition: slave.h:120
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:563
uint16_t position
Index after alias.
Definition: slave_config.h:122
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:1864
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:81
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:2743
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:410
uint32_t serial_number
Serial number.
Definition: slave.h:138
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:111
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:111
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:160
char * order
Order number.
Definition: slave.h:157
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:48
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:1992
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:2031
uint16_t index
SDO index.
Definition: sdo_request.h:48
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:2064
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:239
unsigned int data_size
Covered PDO size.
Definition: fmmu_config.h:53
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:308
uint16_t alias
Slave alias.
Definition: slave_config.h:121
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:2879
struct list_head domains
List of domains.
Definition: master.h:236
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: ioctl.c:4459
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:900
struct list_head reg_requests
Register access requests.
Definition: slave.h:230
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: ioctl.c:723
CANopen SDO.
Definition: sdo.h:49
uint16_t index
SDO index.
Definition: sdo.h:52
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:50
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: ioctl.c:1256
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:162
void ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:159
uint8_t * ecrt_soe_request_data(ec_soe_request_t *req)
Access to the SoE request&#39;s data.
Definition: soe_request.c:288
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:1848
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:2349
uint8_t link_state
device link state
Definition: device.h:88
Access rights in SAFEOP.
Definition: globals.h:182
unsigned int ec_pdo_list_count(const ec_pdo_list_t *pl)
Get the number of PDOs in the list.
Definition: pdo_list.c:311
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:541
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:142
#define EC_IOCTL
ioctl() function to use.
Definition: ioctl.c:4555
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:212
uint32_t result
FoE request abort code.
Definition: foe_request.h:68
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:2757
u64 rx_count
Number of frames received.
Definition: device.h:102
void 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:168
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:311
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
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:434
void 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:2836
void 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:272
void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
Set the timeout for an SDO request.
Definition: sdo_request.c:196
Access rights in PREOP.
Definition: globals.h:181
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: ioctl.c:1312
unsigned int sync_count
Number of sync managers.
Definition: slave.h:166
struct list_head list
List head.
Definition: fsm_master.h:52
SII write request.
Definition: fsm_master.h:51
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:2274
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:106
char * key
Flag key (null-terminated ASCII string.
Definition: flag.h:40
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:144
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:4275
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:1928
void 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.
Definition: slave_config.c:965
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:145
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:114
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition: soe_request.h:52
uint8_t * ecrt_sdo_request_data(ec_sdo_request_t *req)
Access to the SDO request&#39;s data.
Definition: sdo_request.c:203
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:1936
ec_direction_t dir
Direction.
Definition: sdo_request.h:58
PDO entry description.
Definition: pdo_entry.h:48
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:2730
EtherCAT master structure.
uint8_t * data
Memory for the process data.
Definition: domain.h:62
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:140
uint16_t index
PDO index.
Definition: pdo.h:51
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:3617
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:4371
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:111
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: ioctl.c:624
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:141
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:279
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:2775
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:53
uint16_t index
PDO entry index.
Definition: pdo_entry.h:50
EtherCAT slave.
Definition: slave.h:176
struct semaphore master_sem
Master semaphore.
Definition: master.h:209
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:3296
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition: pdo.c:257
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:52
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:78
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:224
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
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:3415
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: ioctl.c:513
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:287
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:3370
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.
char * description
Description.
Definition: sdo_entry.h:62
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2056
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: ioctl.c:55
Slave configuration state.
Definition: ecrt.h:335
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:167
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:175
Ethernet over EtherCAT (EoE)
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:135
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:219
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:1622
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:146
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:1990
ec_master_phase_t phase
Master phase.
Definition: master.h:223
Domain state.
Definition: ecrt.h:436
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:2983
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: ioctl.c:565
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:50
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:2235
struct semaphore device_sem
Device semaphore.
Definition: master.h:218
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:2280
PDO description.
Definition: pdo.h:49
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:119
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:143
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, 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:2878
EtherCAT device.
Definition: device.h:81
uint16_t * sii_words
Complete SII image.
Definition: slave.h:219
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
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:1977
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:2516
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:76
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:1943
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:211
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:53
Sync manager.
Definition: sync.h:47
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: ioctl.c:610
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:143
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:209
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:3075
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:177
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:215
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:2647
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:232
unsigned int scan_busy
Current scan state.
Definition: master.h:250
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:49
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:145
char * name
SDO name.
Definition: sdo.h:54
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:139
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:170
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave&#39;s SII.
Definition: ioctl.c:897
unsigned int index
Index (just a number).
Definition: domain.h:58
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:117
Main device.
Definition: globals.h:190
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: ioctl.c:1892
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: ioctl.c:200
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:129
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:119
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:97
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: ioctl.c:1441
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: ioctl.c:1197
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:49
unsigned int active
Master has been activated.
Definition: master.h:224
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: ioctl.c:1860
ec_master_t * master
Master owning the slave.
Definition: slave.h:178
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:187
struct list_head soe_requests
List of SoE requests.
Definition: slave_config.h:144
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:4105
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:388
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:684
static ATTRIBUTES int ec_ioctl_master(ec_master_t *master, void *arg)
Get master information.
Definition: ioctl.c:102
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:3792
u64 rx_bytes
Number of bytes received.
Definition: device.h:107
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:3038
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:212
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:57
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:2182
u64 tx_count
Number of frames sent.
Definition: device.h:100
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:332
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:2037
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave&#39;s SII.
Definition: ioctl.c:945
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:2117
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:85
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:51
uint8_t control_register
Control register value.
Definition: sync.h:51
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:2015
ec_request_state_t ecrt_soe_request_state(ec_soe_request_t *req)
Get the current state of the SoE request.
Definition: soe_request.c:302
Values read by the master.
Definition: ecrt.h:449
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:47
int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address)
Memory-map process data to user space.
Definition: rtdm.c:220
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
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:217
struct list_head configs
List of slave configurations.
Definition: master.h:235
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:132
unsigned int opened
net_device is opened
Definition: ethernet.h:85
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: ioctl.c:1647
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: ioctl.c:2164
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:127
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:520
int ec_soe_request_alloc(ec_soe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: soe_request.c:150
Access rights in OP.
Definition: globals.h:183
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.
void ecrt_master_reset(ec_master_t *master)
Retry configuring slaves.
Definition: master.c:3281
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:2826
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:4142
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3228
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
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:4020
static ATTRIBUTES int ec_ioctl_config_flag(ec_master_t *master, void *arg)
Get slave configuration feature flag information.
Definition: ioctl.c:1505
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:2859
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:3701
void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:177
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: ioctl.c:1914
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
Definition: domain.h:68
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
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:662
uint32_t logical_base_address
Logical offset address of the process data.
Definition: domain.h:64
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:2615
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:60
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:716
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:48
struct net_device_stats stats
device statistics
Definition: ethernet.h:84
char * name
PDO name.
Definition: pdo.h:53
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:49
FoE request.
Definition: foe_request.h:50
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:70
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:399
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:432
u64 tx_errors
Number of transmit errors.
Definition: device.h:110
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:845
uint16_t effective_alias
Effective alias address.
Definition: slave.h:185
char * name
entry name
Definition: pdo_entry.h:52
size_t data_size
Size of SDO data.
Definition: sdo_request.h:52
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:3197
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:287
struct list_head foe_requests
FoE write requests.
Definition: slave.h:231
ec_direction_t dir
Direction.
Definition: voe_handler.h:56
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:4068
u64 tx_bytes
Number of bytes sent.
Definition: master.h:161
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2321
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:2933
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2009
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:210
void 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:753
uint8_t enable
Enable bit.
Definition: sync.h:52
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:2314
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:51
Vendor specific over EtherCAT protocol handler.
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:140
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:235
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:3752
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:3664
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:121
ec_direction_t dir
Direction.
Definition: reg_request.h:52
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:1841
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:124
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:122
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2556
void ecrt_soe_request_write(ec_soe_request_t *req)
Schedule an SoE IDN write operation.
Definition: soe_request.c:316
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:549
char * image
Image name.
Definition: slave.h:156
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
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:3543
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:2419
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1758
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:238
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:296
uint16_t physical_start_address
Physical start address.
Definition: sync.h:49
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:3258
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:214
void ecrt_soe_request_read(ec_soe_request_t *req)
Schedule an SoE IDN read operation.
Definition: soe_request.c:309
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:210
u64 rx_count
Number of frames received.
Definition: master.h:158
void 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:656
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2395
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: ioctl.c:674
size_t sii_nwords
Size of the SII contents in words.
Definition: slave.h:220
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:211
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
char * group
Group name.
Definition: slave.h:155
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:629
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:3580
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3121
EtherCAT slave configuration.
Definition: slave_config.h:117
void 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:123
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:2653
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:69
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:3132
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:84
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:62
Request was processed successfully.
Definition: ecrt.h:549
EtherCAT slave configuration structure.
void ecrt_soe_request_timeout(ec_soe_request_t *req, uint32_t timeout)
Set the timeout for an SoE request.
Definition: soe_request.c:281
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
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:2578
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:179
uint8_t * ecrt_reg_request_data(ec_reg_request_t *reg)
Access to the register request&#39;s data.
Definition: reg_request.c:86
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Definition: master.c:2807
unsigned int index
Index.
Definition: master.h:195
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:1880
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:678
uint16_t default_length
Data length in bytes.
Definition: sync.h:50
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.
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:4188
void 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:698
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:136
void ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain&#39;s datagrams.
Definition: domain.c:458
ec_direction_t dir
FMMU direction.
Definition: fmmu_config.h:51
void ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
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:289
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:76
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:221
u64 rx_bytes
Number of bytes received.
Definition: master.h:163
void ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master&#39;s datagram queue.
Definition: domain.c:648
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:252
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:193
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:165
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:146
EtherCAT master.
Definition: master.h:194
size_t ecrt_soe_request_data_size(const ec_soe_request_t *req)
Returns the current IDN data size.
Definition: soe_request.c:295
struct list_head list
List item.
Definition: reg_request.h:49
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:2826
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:2466
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:226
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:211
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:4508
u64 tx_bytes
Number of bytes sent.
Definition: device.h:105
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: ioctl.c:340
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:60
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:1717
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:98
uint8_t * ecrt_voe_handler_data(ec_voe_handler_t *voe)
Access to the VoE handler&#39;s data.
Definition: voe_handler.c:145
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:235
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave&#39;s registers.
Definition: ioctl.c:1112
int ecrt_slave_config_emerg_overruns(ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:56
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
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:4235
char * name
Slave name.
Definition: slave.h:158
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:916
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:93
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
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:3503
EtherCAT domain.
Definition: domain.h:54
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:83
static ATTRIBUTES int ec_ioctl_sync_mon_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Processes the sync monitoring datagram.
Definition: ioctl.c:2139
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: ioctl.c:1570
uint32_t vendor_id
Vendor ID.
Definition: slave.h:135
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:53
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:124
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: ioctl.c:849
void 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:187
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:248
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:586
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:57
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: ioctl.c:3021
struct list_head list
List item.
Definition: foe_request.h:51
unsigned int has_general
General category present.
Definition: slave.h:154
unsigned int tx_queued_frames
number of frames in the queue
Definition: ethernet.h:99
static ATTRIBUTES int ec_ioctl_sc_clear_entries(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the mapping of a PDO.
Definition: ioctl.c:2384
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2509
void ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2465
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:350