IgH EtherCAT Master  1.5.2
rtdm-ioctl.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
6  *
7  * This file is part of the IgH EtherCAT Master.
8  *
9  * The IgH EtherCAT Master is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version 2, as
11  * published by the Free Software Foundation.
12  *
13  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with the IgH EtherCAT Master; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * ---
23  *
24  * The license mentioned above concerns the source code only. Using the
25  * EtherCAT technology and brand is only permitted in compliance with the
26  * industrial property and similar rights of Beckhoff Automation GmbH.
27  *
28  *****************************************************************************/
29 
35 /*****************************************************************************/
36 
37 #include <linux/module.h>
38 #include <linux/vmalloc.h>
39 
40 #include "master.h"
41 #include "slave_config.h"
42 #include "voe_handler.h"
43 #include "ethernet.h"
44 #include "ioctl.h"
45 
50 #define DEBUG_LATENCY 0
51 
54 #if 0
55 #define ATTRIBUTES __attribute__ ((__noinline__))
56 #else
57 #define ATTRIBUTES
58 #endif
59 
60 /*****************************************************************************/
61 
64 static void ec_ioctl_strcpy(
65  char *target,
66  const char *source
67  )
68 {
69  if (source) {
70  strncpy(target, source, EC_IOCTL_STRING_SIZE);
71  target[EC_IOCTL_STRING_SIZE - 1] = 0;
72  } else {
73  target[0] = 0;
74  }
75 }
76 
77 /*****************************************************************************/
78 
84  void *arg
85  )
86 {
87  ec_ioctl_module_t data;
88 
89  data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
90  data.master_count = ec_master_count();
91 
92  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
93  return -EFAULT;
94 
95  return 0;
96 }
97 
98 /*****************************************************************************/
99 
105  ec_master_t *master,
106  void *arg
107  )
108 {
109  ec_ioctl_master_t io;
110  unsigned int dev_idx, j;
111 
112  if (down_interruptible(&master->master_sem)) {
113  return -EINTR;
114  }
115 
116  io.slave_count = master->slave_count;
117  io.config_count = ec_master_config_count(master);
118  io.domain_count = ec_master_domain_count(master);
119 #ifdef EC_EOE
120  io.eoe_handler_count = ec_master_eoe_handler_count(master);
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] =
169  master->device_stats.tx_frame_rates[j];
170  io.rx_frame_rates[j] =
171  master->device_stats.rx_frame_rates[j];
172  io.tx_byte_rates[j] =
173  master->device_stats.tx_byte_rates[j];
174  io.rx_byte_rates[j] =
175  master->device_stats.rx_byte_rates[j];
176  io.loss_rates[j] =
177  master->device_stats.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 =
185  master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
186 
187  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
188  return -EFAULT;
189  }
190 
191  return 0;
192 }
193 
194 /*****************************************************************************/
195 
201  ec_master_t *master,
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 
288  ec_master_t *master,
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 
341  ec_master_t *master,
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 
400  ec_master_t *master,
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 
469  ec_master_t *master,
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 
514  ec_master_t *master,
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 
566  ec_master_t *master,
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 
611  ec_master_t *master,
612  void *arg
613  )
614 {
615  return ec_master_debug_level(master, (unsigned long) arg);
616 }
617 
618 /*****************************************************************************/
619 
625  ec_master_t *master,
626  void *arg
627  )
628 {
629  master->fsm.rescan_required = 1;
630  return 0;
631 }
632 
633 /*****************************************************************************/
634 
640  ec_master_t *master,
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 
675  ec_master_t *master,
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 
724  ec_master_t *master,
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 
804  ec_master_t *master,
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 
850  ec_master_t *master,
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 
898  ec_master_t *master,
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 
946  ec_master_t *master,
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.slave_position = sc->slave ? sc->slave->ring_position : -1;
1236  data.dc_assign_activate = sc->dc_assign_activate;
1237  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1238  data.dc_sync[i] = sc->dc_sync[i];
1239  }
1240 
1241  up(&master->master_sem);
1242 
1243  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1244  return -EFAULT;
1245 
1246  return 0;
1247 }
1248 
1249 /*****************************************************************************/
1250 
1256  ec_master_t *master,
1257  void *arg
1258  )
1259 {
1260  ec_ioctl_config_pdo_t data;
1261  const ec_slave_config_t *sc;
1262  const ec_pdo_t *pdo;
1263 
1264  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1265  return -EFAULT;
1266  }
1267 
1268  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1269  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1270  data.sync_index);
1271  return -EINVAL;
1272  }
1273 
1274  if (down_interruptible(&master->master_sem))
1275  return -EINTR;
1276 
1277  if (!(sc = ec_master_get_config_const(
1278  master, data.config_index))) {
1279  up(&master->master_sem);
1280  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1281  data.config_index);
1282  return -EINVAL;
1283  }
1284 
1286  &sc->sync_configs[data.sync_index].pdos,
1287  data.pdo_pos))) {
1288  up(&master->master_sem);
1289  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1290  return -EINVAL;
1291  }
1292 
1293  data.index = pdo->index;
1294  data.entry_count = ec_pdo_entry_count(pdo);
1295  ec_ioctl_strcpy(data.name, pdo->name);
1296 
1297  up(&master->master_sem);
1298 
1299  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1300  return -EFAULT;
1301 
1302  return 0;
1303 }
1304 
1305 /*****************************************************************************/
1306 
1312  ec_master_t *master,
1313  void *arg
1314  )
1315 {
1316  ec_ioctl_config_pdo_entry_t data;
1317  const ec_slave_config_t *sc;
1318  const ec_pdo_t *pdo;
1319  const ec_pdo_entry_t *entry;
1320 
1321  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1322  return -EFAULT;
1323  }
1324 
1325  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1326  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1327  data.sync_index);
1328  return -EINVAL;
1329  }
1330 
1331  if (down_interruptible(&master->master_sem))
1332  return -EINTR;
1333 
1334  if (!(sc = ec_master_get_config_const(
1335  master, data.config_index))) {
1336  up(&master->master_sem);
1337  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1338  data.config_index);
1339  return -EINVAL;
1340  }
1341 
1343  &sc->sync_configs[data.sync_index].pdos,
1344  data.pdo_pos))) {
1345  up(&master->master_sem);
1346  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1347  return -EINVAL;
1348  }
1349 
1350  if (!(entry = ec_pdo_find_entry_by_pos_const(
1351  pdo, data.entry_pos))) {
1352  up(&master->master_sem);
1353  EC_MASTER_ERR(master, "Entry not found!\n");
1354  return -EINVAL;
1355  }
1356 
1357  data.index = entry->index;
1358  data.subindex = entry->subindex;
1359  data.bit_length = entry->bit_length;
1360  ec_ioctl_strcpy(data.name, entry->name);
1361 
1362  up(&master->master_sem);
1363 
1364  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1365  return -EFAULT;
1366 
1367  return 0;
1368 }
1369 
1370 /*****************************************************************************/
1371 
1377  ec_master_t *master,
1378  void *arg
1379  )
1380 {
1381  ec_ioctl_config_sdo_t *ioctl;
1382  const ec_slave_config_t *sc;
1383  const ec_sdo_request_t *req;
1384 
1385  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1386  return -ENOMEM;
1387  }
1388 
1389  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1390  kfree(ioctl);
1391  return -EFAULT;
1392  }
1393 
1394  if (down_interruptible(&master->master_sem)) {
1395  kfree(ioctl);
1396  return -EINTR;
1397  }
1398 
1399  if (!(sc = ec_master_get_config_const(
1400  master, ioctl->config_index))) {
1401  up(&master->master_sem);
1402  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1403  ioctl->config_index);
1404  kfree(ioctl);
1405  return -EINVAL;
1406  }
1407 
1409  sc, ioctl->sdo_pos))) {
1410  up(&master->master_sem);
1411  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1412  kfree(ioctl);
1413  return -EINVAL;
1414  }
1415 
1416  ioctl->index = req->index;
1417  ioctl->subindex = req->subindex;
1418  ioctl->size = req->data_size;
1419  memcpy(ioctl->data, req->data,
1420  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1421  ioctl->complete_access = req->complete_access;
1422 
1423  up(&master->master_sem);
1424 
1425  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1426  kfree(ioctl);
1427  return -EFAULT;
1428  }
1429 
1430  kfree(ioctl);
1431  return 0;
1432 }
1433 
1434 /*****************************************************************************/
1435 
1441  ec_master_t *master,
1442  void *arg
1443  )
1444 {
1445  ec_ioctl_config_idn_t *ioctl;
1446  const ec_slave_config_t *sc;
1447  const ec_soe_request_t *req;
1448 
1449  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1450  return -ENOMEM;
1451  }
1452 
1453  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1454  kfree(ioctl);
1455  return -EFAULT;
1456  }
1457 
1458  if (down_interruptible(&master->master_sem)) {
1459  kfree(ioctl);
1460  return -EINTR;
1461  }
1462 
1463  if (!(sc = ec_master_get_config_const(
1464  master, ioctl->config_index))) {
1465  up(&master->master_sem);
1466  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1467  ioctl->config_index);
1468  kfree(ioctl);
1469  return -EINVAL;
1470  }
1471 
1473  sc, ioctl->idn_pos))) {
1474  up(&master->master_sem);
1475  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1476  kfree(ioctl);
1477  return -EINVAL;
1478  }
1479 
1480  ioctl->drive_no = req->drive_no;
1481  ioctl->idn = req->idn;
1482  ioctl->state = req->state;
1483  ioctl->size = req->data_size;
1484  memcpy(ioctl->data, req->data,
1485  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1486 
1487  up(&master->master_sem);
1488 
1489  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1490  kfree(ioctl);
1491  return -EFAULT;
1492  }
1493 
1494  kfree(ioctl);
1495  return 0;
1496 }
1497 
1498 /*****************************************************************************/
1499 
1500 #ifdef EC_EOE
1501 
1507  ec_master_t *master,
1508  void *arg
1509  )
1510 {
1511  ec_ioctl_eoe_handler_t data;
1512  const ec_eoe_t *eoe;
1513 
1514  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1515  return -EFAULT;
1516  }
1517 
1518  if (down_interruptible(&master->master_sem))
1519  return -EINTR;
1520 
1521  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1522  up(&master->master_sem);
1523  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1524  data.eoe_index);
1525  return -EINVAL;
1526  }
1527 
1528  if (eoe->slave) {
1529  data.slave_position = eoe->slave->ring_position;
1530  } else {
1531  data.slave_position = 0xffff;
1532  }
1533  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1534  data.open = eoe->opened;
1535  data.rx_bytes = eoe->stats.tx_bytes;
1536  data.rx_rate = eoe->tx_rate;
1537  data.tx_bytes = eoe->stats.rx_bytes;
1538  data.tx_rate = eoe->tx_rate;
1539  data.tx_queued_frames = eoe->tx_queued_frames;
1540  data.tx_queue_size = eoe->tx_queue_size;
1541 
1542  up(&master->master_sem);
1543 
1544  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1545  return -EFAULT;
1546 
1547  return 0;
1548 }
1549 
1550 #endif
1551 
1552 /*****************************************************************************/
1553 
1559  ec_master_t *master,
1560  void *arg,
1561  ec_ioctl_context_t *ctx
1562  )
1563 {
1564  ec_master_t *m;
1565  int ret = 0;
1566 
1567  m = ecrt_request_master_err(master->index);
1568  if (IS_ERR(m)) {
1569  ret = PTR_ERR(m);
1570  } else {
1571  ctx->requested = 1;
1572  }
1573 
1574  return ret;
1575 }
1576 
1577 /*****************************************************************************/
1578 
1584  ec_master_t *master,
1585  void *arg,
1586  ec_ioctl_context_t *ctx
1587  )
1588 {
1589  ec_domain_t *domain;
1590 
1591  if (unlikely(!ctx->requested))
1592  return -EPERM;
1593 
1594  domain = ecrt_master_create_domain_err(master);
1595  if (IS_ERR(domain))
1596  return PTR_ERR(domain);
1597 
1598  return domain->index;
1599 }
1600 
1601 /*****************************************************************************/
1602 
1608  ec_master_t *master,
1609  void *arg,
1610  ec_ioctl_context_t *ctx
1611  )
1612 {
1613  ec_ioctl_config_t data;
1614  ec_slave_config_t *sc, *entry;
1615 
1616  if (unlikely(!ctx->requested))
1617  return -EPERM;
1618 
1619  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1620  return -EFAULT;
1621  }
1622 
1623  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1624  data.vendor_id, data.product_code);
1625  if (IS_ERR(sc))
1626  return PTR_ERR(sc);
1627 
1628  data.config_index = 0;
1629 
1630  if (down_interruptible(&master->master_sem))
1631  return -EINTR;
1632 
1633  list_for_each_entry(entry, &master->configs, list) {
1634  if (entry == sc)
1635  break;
1636  data.config_index++;
1637  }
1638 
1639  up(&master->master_sem);
1640 
1641  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1642  return -EFAULT;
1643 
1644  return 0;
1645 }
1646 
1647 /*****************************************************************************/
1648 
1654  ec_master_t *master,
1655  void *arg,
1656  ec_ioctl_context_t *ctx
1657  )
1658 {
1659  unsigned long config_index = (unsigned long) arg;
1660  ec_slave_config_t *sc = NULL;
1661  int ret = 0;
1662 
1663  if (unlikely(!ctx->requested)) {
1664  ret = -EPERM;
1665  goto out_return;
1666  }
1667 
1668  if (down_interruptible(&master->master_sem)) {
1669  ret = -EINTR;
1670  goto out_return;
1671  }
1672 
1673  if (config_index != 0xFFFFFFFF) {
1674  if (!(sc = ec_master_get_config(master, config_index))) {
1675  ret = -ENOENT;
1676  goto out_up;
1677  }
1678  }
1679 
1681 
1682 out_up:
1683  up(&master->master_sem);
1684 out_return:
1685  return ret;
1686 }
1687 
1688 /*****************************************************************************/
1689 
1695  ec_master_t *master,
1696  void *arg,
1697  ec_ioctl_context_t *ctx
1698  )
1699 {
1700  ec_ioctl_master_activate_t io;
1701  ec_domain_t *domain;
1702  off_t offset;
1703  int ret;
1704 
1705  if (unlikely(!ctx->requested))
1706  return -EPERM;
1707 
1708  io.process_data = NULL;
1709 
1710  /* Get the sum of the domains' process data sizes. */
1711 
1712  ctx->process_data_size = 0;
1713 
1714  if (down_interruptible(&master->master_sem))
1715  return -EINTR;
1716 
1717  list_for_each_entry(domain, &master->domains, list) {
1718  ctx->process_data_size += ecrt_domain_size(domain);
1719  }
1720 
1721  up(&master->master_sem);
1722 
1723  if (ctx->process_data_size) {
1724  ctx->process_data = vmalloc(ctx->process_data_size);
1725  if (!ctx->process_data) {
1726  ctx->process_data_size = 0;
1727  return -ENOMEM;
1728  }
1729 
1730  /* Set the memory as external process data memory for the
1731  * domains.
1732  */
1733  offset = 0;
1734  list_for_each_entry(domain, &master->domains, list) {
1736  ctx->process_data + offset);
1737  offset += ecrt_domain_size(domain);
1738  }
1739 
1740 #ifdef EC_IOCTL_RTDM
1741  /* RTDM uses a different approach for memory-mapping, which has to be
1742  * initiated by the kernel.
1743  */
1744  ret = ec_rtdm_mmap(ctx, &io.process_data);
1745  if (ret < 0) {
1746  EC_MASTER_ERR(master, "Failed to map process data"
1747  " memory to user space (code %i).\n", ret);
1748  return ret;
1749  }
1750 #endif
1751  }
1752 
1753  io.process_data_size = ctx->process_data_size;
1754 
1755 #ifndef EC_IOCTL_RTDM
1758 #endif
1759 
1760  ret = ecrt_master_activate(master);
1761  if (ret < 0)
1762  return ret;
1763 
1764  if (copy_to_user((void __user *) arg, &io,
1765  sizeof(ec_ioctl_master_activate_t)))
1766  return -EFAULT;
1767 
1768  return 0;
1769 }
1770 
1771 /*****************************************************************************/
1772 
1778  ec_master_t *master,
1779  void *arg,
1780  ec_ioctl_context_t *ctx
1781  )
1782 {
1783  if (unlikely(!ctx->requested))
1784  return -EPERM;
1785 
1786  ecrt_master_deactivate(master);
1787  return 0;
1788 }
1789 
1790 /*****************************************************************************/
1791 
1797  ec_master_t *master,
1798  void *arg,
1799  ec_ioctl_context_t *ctx
1800  )
1801 {
1802  size_t send_interval;
1803 
1804  if (unlikely(!ctx->requested)) {
1805  return -EPERM;
1806  }
1807 
1808  if (copy_from_user(&send_interval, (void __user *) arg,
1809  sizeof(send_interval))) {
1810  return -EFAULT;
1811  }
1812 
1813  if (down_interruptible(&master->master_sem))
1814  return -EINTR;
1815 
1816  ec_master_set_send_interval(master, send_interval);
1817 
1818  up(&master->master_sem);
1819  return 0;
1820 }
1821 
1822 /*****************************************************************************/
1823 
1829  ec_master_t *master,
1830  void *arg,
1831  ec_ioctl_context_t *ctx
1832  )
1833 {
1834  if (unlikely(!ctx->requested)) {
1835  return -EPERM;
1836  }
1837 
1838  ecrt_master_send(master);
1839  return 0;
1840 }
1841 
1842 /*****************************************************************************/
1843 
1849  ec_master_t *master,
1850  void *arg,
1851  ec_ioctl_context_t *ctx
1852  )
1853 {
1854  if (unlikely(!ctx->requested)) {
1855  return -EPERM;
1856  }
1857 
1858  ecrt_master_receive(master);
1859  return 0;
1860 }
1861 
1862 /*****************************************************************************/
1863 
1869  ec_master_t *master,
1870  void *arg,
1871  ec_ioctl_context_t *ctx
1872  )
1873 {
1874  ec_master_state_t data;
1875 
1876  ecrt_master_state(master, &data);
1877 
1878  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1879  return -EFAULT;
1880 
1881  return 0;
1882 }
1883 
1884 /*****************************************************************************/
1885 
1891  ec_master_t *master,
1892  void *arg,
1893  ec_ioctl_context_t *ctx
1894  )
1895 {
1896  ec_ioctl_link_state_t ioctl;
1897  ec_master_link_state_t state;
1898  int ret;
1899 
1900  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
1901  return -EFAULT;
1902  }
1903 
1904  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
1905  if (ret < 0) {
1906  return ret;
1907  }
1908 
1909  if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
1910  return -EFAULT;
1911  }
1912 
1913  return 0;
1914 }
1915 
1916 /*****************************************************************************/
1917 
1923  ec_master_t *master,
1924  void *arg,
1925  ec_ioctl_context_t *ctx
1926  )
1927 {
1928  uint64_t time;
1929 
1930  if (unlikely(!ctx->requested))
1931  return -EPERM;
1932 
1933  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
1934  return -EFAULT;
1935  }
1936 
1937  ecrt_master_application_time(master, time);
1938  return 0;
1939 }
1940 
1941 /*****************************************************************************/
1942 
1948  ec_master_t *master,
1949  void *arg,
1950  ec_ioctl_context_t *ctx
1951  )
1952 {
1953  if (unlikely(!ctx->requested)) {
1954  return -EPERM;
1955  }
1956 
1958  return 0;
1959 }
1960 
1961 /*****************************************************************************/
1962 
1968  ec_master_t *master,
1969  void *arg,
1970  ec_ioctl_context_t *ctx
1971  )
1972 {
1973  uint64_t time;
1974 
1975  if (unlikely(!ctx->requested))
1976  return -EPERM;
1977 
1978  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
1979  return -EFAULT;
1980  }
1981 
1983  return 0;
1984 }
1985 
1986 /*****************************************************************************/
1987 
1993  ec_master_t *master,
1994  void *arg,
1995  ec_ioctl_context_t *ctx
1996  )
1997 {
1998  if (unlikely(!ctx->requested)) {
1999  return -EPERM;
2000  }
2001 
2003  return 0;
2004 }
2005 
2006 /*****************************************************************************/
2007 
2013  ec_master_t *master,
2014  void *arg,
2015  ec_ioctl_context_t *ctx
2016  )
2017 {
2018  uint32_t time;
2019  int ret;
2020 
2021  if (unlikely(!ctx->requested)) {
2022  return -EPERM;
2023  }
2024 
2025  ret = ecrt_master_reference_clock_time(master, &time);
2026  if (ret) {
2027  return ret;
2028  }
2029 
2030  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2031  return -EFAULT;
2032  }
2033 
2034  return 0;
2035 }
2036 
2037 /*****************************************************************************/
2038 
2044  ec_master_t *master,
2045  void *arg,
2046  ec_ioctl_context_t *ctx
2047  )
2048 {
2049  if (unlikely(!ctx->requested)) {
2050  return -EPERM;
2051  }
2052 
2054  return 0;
2055 }
2056 
2057 /*****************************************************************************/
2058 
2064  ec_master_t *master,
2065  void *arg,
2066  ec_ioctl_context_t *ctx
2067  )
2068 {
2069  uint32_t time_diff;
2070 
2071  if (unlikely(!ctx->requested))
2072  return -EPERM;
2073 
2074  time_diff = ecrt_master_sync_monitor_process(master);
2075 
2076  if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2077  return -EFAULT;
2078 
2079  return 0;
2080 }
2081 
2082 /*****************************************************************************/
2083 
2089  ec_master_t *master,
2090  void *arg,
2091  ec_ioctl_context_t *ctx
2092  )
2093 {
2094  down(&master->master_sem);
2095  ecrt_master_reset(master);
2096  up(&master->master_sem);
2097  return 0;
2098 }
2099 
2100 /*****************************************************************************/
2101 
2107  ec_master_t *master,
2108  void *arg,
2109  ec_ioctl_context_t *ctx
2110  )
2111 {
2112  ec_ioctl_config_t data;
2113  ec_slave_config_t *sc;
2114  unsigned int i;
2115  int ret = 0;
2116 
2117  if (unlikely(!ctx->requested)) {
2118  ret = -EPERM;
2119  goto out_return;
2120  }
2121 
2122  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2123  ret = -EFAULT;
2124  goto out_return;
2125  }
2126 
2127  if (down_interruptible(&master->master_sem)) {
2128  ret = -EINTR;
2129  goto out_return;
2130  }
2131 
2132  if (!(sc = ec_master_get_config(master, data.config_index))) {
2133  ret = -ENOENT;
2134  goto out_up;
2135  }
2136 
2137  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2138  if (data.syncs[i].config_this) {
2139  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2140  data.syncs[i].watchdog_mode);
2141  if (ret) {
2142  goto out_up;
2143  }
2144  }
2145  }
2146 
2147 out_up:
2148  up(&master->master_sem);
2149 out_return:
2150  return ret;
2151 }
2152 
2153 /*****************************************************************************/
2154 
2160  ec_master_t *master,
2161  void *arg,
2162  ec_ioctl_context_t *ctx
2163  )
2164 {
2165  ec_ioctl_config_t data;
2166  ec_slave_config_t *sc;
2167  int ret = 0;
2168 
2169  if (unlikely(!ctx->requested)) {
2170  ret = -EPERM;
2171  goto out_return;
2172  }
2173 
2174  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2175  ret = -EFAULT;
2176  goto out_return;
2177  }
2178 
2179  if (down_interruptible(&master->master_sem)) {
2180  ret = -EINTR;
2181  goto out_return;
2182  }
2183 
2184  if (!(sc = ec_master_get_config(master, data.config_index))) {
2185  ret = -ENOENT;
2186  goto out_up;
2187  }
2188 
2190  data.watchdog_divider, data.watchdog_intervals);
2191 
2192 out_up:
2193  up(&master->master_sem);
2194 out_return:
2195  return ret;
2196 }
2197 
2198 /*****************************************************************************/
2199 
2205  ec_master_t *master,
2206  void *arg,
2207  ec_ioctl_context_t *ctx
2208  )
2209 {
2210  ec_ioctl_config_pdo_t data;
2211  ec_slave_config_t *sc;
2212 
2213  if (unlikely(!ctx->requested))
2214  return -EPERM;
2215 
2216  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2217  return -EFAULT;
2218 
2219  if (down_interruptible(&master->master_sem))
2220  return -EINTR;
2221 
2222  if (!(sc = ec_master_get_config(master, data.config_index))) {
2223  up(&master->master_sem);
2224  return -ENOENT;
2225  }
2226 
2227  up(&master->master_sem);
2229  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2230 }
2231 
2232 /*****************************************************************************/
2233 
2239  ec_master_t *master,
2240  void *arg,
2241  ec_ioctl_context_t *ctx
2242  )
2243 {
2244  ec_ioctl_config_pdo_t data;
2245  ec_slave_config_t *sc;
2246 
2247  if (unlikely(!ctx->requested))
2248  return -EPERM;
2249 
2250  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2251  return -EFAULT;
2252 
2253  if (down_interruptible(&master->master_sem))
2254  return -EINTR;
2255 
2256  if (!(sc = ec_master_get_config(master, data.config_index))) {
2257  up(&master->master_sem);
2258  return -ENOENT;
2259  }
2260 
2261  up(&master->master_sem);
2263  ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2264  return 0;
2265 }
2266 
2267 /*****************************************************************************/
2268 
2274  ec_master_t *master,
2275  void *arg,
2276  ec_ioctl_context_t *ctx
2277  )
2278 {
2279  ec_ioctl_add_pdo_entry_t data;
2280  ec_slave_config_t *sc;
2281 
2282  if (unlikely(!ctx->requested))
2283  return -EPERM;
2284 
2285  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2286  return -EFAULT;
2287 
2288  if (down_interruptible(&master->master_sem))
2289  return -EINTR;
2290 
2291  if (!(sc = ec_master_get_config(master, data.config_index))) {
2292  up(&master->master_sem);
2293  return -ENOENT;
2294  }
2295 
2296  up(&master->master_sem);
2298  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2299  data.entry_index, data.entry_subindex, data.entry_bit_length);
2300 }
2301 
2302 /*****************************************************************************/
2303 
2309  ec_master_t *master,
2310  void *arg,
2311  ec_ioctl_context_t *ctx
2312  )
2313 {
2314  ec_ioctl_config_pdo_t data;
2315  ec_slave_config_t *sc;
2316 
2317  if (unlikely(!ctx->requested))
2318  return -EPERM;
2319 
2320  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2321  return -EFAULT;
2322 
2323  if (down_interruptible(&master->master_sem))
2324  return -EINTR;
2325 
2326  if (!(sc = ec_master_get_config(master, data.config_index))) {
2327  up(&master->master_sem);
2328  return -ENOENT;
2329  }
2330 
2331  up(&master->master_sem);
2333  ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2334  return 0;
2335 }
2336 
2337 /*****************************************************************************/
2338 
2344  ec_master_t *master,
2345  void *arg,
2346  ec_ioctl_context_t *ctx
2347  )
2348 {
2349  ec_ioctl_reg_pdo_entry_t data;
2350  ec_slave_config_t *sc;
2351  ec_domain_t *domain;
2352  int ret;
2353 
2354  if (unlikely(!ctx->requested))
2355  return -EPERM;
2356 
2357  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2358  return -EFAULT;
2359 
2360  if (down_interruptible(&master->master_sem))
2361  return -EINTR;
2362 
2363  if (!(sc = ec_master_get_config(master, data.config_index))) {
2364  up(&master->master_sem);
2365  return -ENOENT;
2366  }
2367 
2368  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2369  up(&master->master_sem);
2370  return -ENOENT;
2371  }
2372 
2373  up(&master->master_sem);
2375  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2376  data.entry_subindex, domain, &data.bit_position);
2377 
2378  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2379  return -EFAULT;
2380 
2381  return ret;
2382 }
2383 
2384 /*****************************************************************************/
2385 
2391  ec_master_t *master,
2392  void *arg,
2393  ec_ioctl_context_t *ctx
2394  )
2395 {
2396  ec_ioctl_reg_pdo_pos_t io;
2397  ec_slave_config_t *sc;
2398  ec_domain_t *domain;
2399  int ret;
2400 
2401  if (unlikely(!ctx->requested)) {
2402  return -EPERM;
2403  }
2404 
2405  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2406  return -EFAULT;
2407  }
2408 
2409  if (down_interruptible(&master->master_sem)) {
2410  return -EINTR;
2411  }
2412 
2413  if (!(sc = ec_master_get_config(master, io.config_index))) {
2414  up(&master->master_sem);
2415  return -ENOENT;
2416  }
2417 
2418  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2419  up(&master->master_sem);
2420  return -ENOENT;
2421  }
2422 
2423  up(&master->master_sem);
2425  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2426  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2427 
2428  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2429  return -EFAULT;
2430 
2431  return ret;
2432 }
2433 
2434 /*****************************************************************************/
2435 
2441  ec_master_t *master,
2442  void *arg,
2443  ec_ioctl_context_t *ctx
2444  )
2445 {
2446  ec_ioctl_config_t data;
2447  ec_slave_config_t *sc;
2448 
2449  if (unlikely(!ctx->requested))
2450  return -EPERM;
2451 
2452  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2453  return -EFAULT;
2454 
2455  if (down_interruptible(&master->master_sem))
2456  return -EINTR;
2457 
2458  if (!(sc = ec_master_get_config(master, data.config_index))) {
2459  up(&master->master_sem);
2460  return -ENOENT;
2461  }
2462 
2464  data.dc_sync[0].cycle_time,
2465  data.dc_sync[0].shift_time,
2466  data.dc_sync[1].cycle_time,
2467  data.dc_sync[1].shift_time);
2468 
2469  up(&master->master_sem);
2470 
2471  return 0;
2472 }
2473 
2474 /*****************************************************************************/
2475 
2481  ec_master_t *master,
2482  void *arg,
2483  ec_ioctl_context_t *ctx
2484  )
2485 {
2486  ec_ioctl_sc_sdo_t data;
2487  ec_slave_config_t *sc;
2488  uint8_t *sdo_data = NULL;
2489  int ret;
2490 
2491  if (unlikely(!ctx->requested))
2492  return -EPERM;
2493 
2494  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2495  return -EFAULT;
2496 
2497  if (!data.size)
2498  return -EINVAL;
2499 
2500  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2501  return -ENOMEM;
2502  }
2503 
2504  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2505  kfree(sdo_data);
2506  return -EFAULT;
2507  }
2508 
2509  if (down_interruptible(&master->master_sem)) {
2510  kfree(sdo_data);
2511  return -EINTR;
2512  }
2513 
2514  if (!(sc = ec_master_get_config(master, data.config_index))) {
2515  up(&master->master_sem);
2516  kfree(sdo_data);
2517  return -ENOENT;
2518  }
2519 
2520  up(&master->master_sem);
2522  if (data.complete_access) {
2524  data.index, sdo_data, data.size);
2525  } else {
2526  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2527  data.size);
2528  }
2529  kfree(sdo_data);
2530  return ret;
2531 }
2532 
2533 /*****************************************************************************/
2534 
2540  ec_master_t *master,
2541  void *arg,
2542  ec_ioctl_context_t *ctx
2543  )
2544 {
2545  ec_ioctl_sc_emerg_t io;
2546  ec_slave_config_t *sc;
2547  int ret;
2548 
2549  if (unlikely(!ctx->requested))
2550  return -EPERM;
2551 
2552  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2553  return -EFAULT;
2554 
2555  if (down_interruptible(&master->master_sem)) {
2556  return -EINTR;
2557  }
2558 
2559  if (!(sc = ec_master_get_config(master, io.config_index))) {
2560  up(&master->master_sem);
2561  return -ENOENT;
2562  }
2563 
2564  ret = ecrt_slave_config_emerg_size(sc, io.size);
2565 
2566  up(&master->master_sem);
2567 
2568  return ret;
2569 }
2570 
2571 /*****************************************************************************/
2572 
2578  ec_master_t *master,
2579  void *arg,
2580  ec_ioctl_context_t *ctx
2581  )
2582 {
2583  ec_ioctl_sc_emerg_t io;
2584  ec_slave_config_t *sc;
2585  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
2586  int ret;
2587 
2588  if (unlikely(!ctx->requested)) {
2589  return -EPERM;
2590  }
2591 
2592  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2593  return -EFAULT;
2594  }
2595 
2596  /* no locking of master_sem needed, because configuration will not be
2597  * deleted in the meantime. */
2598 
2599  if (!(sc = ec_master_get_config(master, io.config_index))) {
2600  return -ENOENT;
2601  }
2602 
2603  ret = ecrt_slave_config_emerg_pop(sc, msg);
2604  if (ret < 0) {
2605  return ret;
2606  }
2607 
2608  if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
2609  return -EFAULT;
2610  }
2611 
2612  return ret;
2613 }
2614 
2615 /*****************************************************************************/
2616 
2622  ec_master_t *master,
2623  void *arg,
2624  ec_ioctl_context_t *ctx
2625  )
2626 {
2627  ec_ioctl_sc_emerg_t io;
2628  ec_slave_config_t *sc;
2629 
2630  if (unlikely(!ctx->requested)) {
2631  return -EPERM;
2632  }
2633 
2634  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2635  return -EFAULT;
2636  }
2637 
2638  /* no locking of master_sem needed, because configuration will not be
2639  * deleted in the meantime. */
2640 
2641  if (!(sc = ec_master_get_config(master, io.config_index))) {
2642  return -ENOENT;
2643  }
2644 
2645  return ecrt_slave_config_emerg_clear(sc);
2646 }
2647 
2648 /*****************************************************************************/
2649 
2655  ec_master_t *master,
2656  void *arg,
2657  ec_ioctl_context_t *ctx
2658  )
2659 {
2660  ec_ioctl_sc_emerg_t io;
2661  ec_slave_config_t *sc;
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 
2680  if (ret < 0) {
2681  return ret;
2682  }
2683 
2684  io.overruns = ret;
2685 
2686  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2687  return -EFAULT;
2688  }
2689 
2690  return 0;
2691 }
2692 
2693 /*****************************************************************************/
2694 
2700  ec_master_t *master,
2701  void *arg,
2702  ec_ioctl_context_t *ctx
2703  )
2704 {
2705  ec_ioctl_sdo_request_t data;
2706  ec_slave_config_t *sc;
2707  ec_sdo_request_t *req;
2708 
2709  if (unlikely(!ctx->requested))
2710  return -EPERM;
2711 
2712  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2713  return -EFAULT;
2714  }
2715 
2716  data.request_index = 0;
2717 
2718  if (down_interruptible(&master->master_sem))
2719  return -EINTR;
2720 
2721  sc = ec_master_get_config(master, data.config_index);
2722  if (!sc) {
2723  up(&master->master_sem);
2724  return -ENOENT;
2725  }
2726 
2727  list_for_each_entry(req, &sc->sdo_requests, list) {
2728  data.request_index++;
2729  }
2730 
2731  up(&master->master_sem);
2733  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
2734  data.sdo_subindex, data.size);
2735  if (IS_ERR(req))
2736  return PTR_ERR(req);
2737 
2738  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2739  return -EFAULT;
2740 
2741  return 0;
2742 }
2743 
2744 /*****************************************************************************/
2745 
2751  ec_master_t *master,
2752  void *arg,
2753  ec_ioctl_context_t *ctx
2754  )
2755 {
2756  ec_ioctl_reg_request_t io;
2757  ec_slave_config_t *sc;
2758  ec_reg_request_t *reg;
2759 
2760  if (unlikely(!ctx->requested)) {
2761  return -EPERM;
2762  }
2763 
2764  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2765  return -EFAULT;
2766  }
2767 
2768  io.request_index = 0;
2769 
2770  if (down_interruptible(&master->master_sem)) {
2771  return -EINTR;
2772  }
2773 
2774  sc = ec_master_get_config(master, io.config_index);
2775  if (!sc) {
2776  up(&master->master_sem);
2777  return -ENOENT;
2778  }
2779 
2780  list_for_each_entry(reg, &sc->reg_requests, list) {
2781  io.request_index++;
2782  }
2783 
2784  up(&master->master_sem);
2786  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
2787  if (IS_ERR(reg)) {
2788  return PTR_ERR(reg);
2789  }
2790 
2791  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2792  return -EFAULT;
2793  }
2794 
2795  return 0;
2796 }
2797 
2798 /*****************************************************************************/
2799 
2805  ec_master_t *master,
2806  void *arg,
2807  ec_ioctl_context_t *ctx
2808  )
2809 {
2810  ec_ioctl_voe_t data;
2811  ec_slave_config_t *sc;
2812  ec_voe_handler_t *voe;
2813 
2814  if (unlikely(!ctx->requested))
2815  return -EPERM;
2816 
2817  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2818  return -EFAULT;
2819  }
2820 
2821  data.voe_index = 0;
2822 
2823  if (down_interruptible(&master->master_sem))
2824  return -EINTR;
2825 
2826  sc = ec_master_get_config(master, data.config_index);
2827  if (!sc) {
2828  up(&master->master_sem);
2829  return -ENOENT;
2830  }
2831 
2832  list_for_each_entry(voe, &sc->voe_handlers, list) {
2833  data.voe_index++;
2834  }
2835 
2836  up(&master->master_sem);
2838  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
2839  if (IS_ERR(voe))
2840  return PTR_ERR(voe);
2841 
2842  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2843  return -EFAULT;
2844 
2845  return 0;
2846 }
2847 
2848 /*****************************************************************************/
2849 
2855  ec_master_t *master,
2856  void *arg,
2857  ec_ioctl_context_t *ctx
2858  )
2859 {
2860  ec_ioctl_sc_state_t data;
2861  const ec_slave_config_t *sc;
2863 
2864  if (unlikely(!ctx->requested))
2865  return -EPERM;
2866 
2867  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2868  return -EFAULT;
2869  }
2870 
2871  /* no locking of master_sem needed, because sc will not be deleted in the
2872  * meantime. */
2873 
2874  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
2875  return -ENOENT;
2876  }
2877 
2878  ecrt_slave_config_state(sc, &state);
2879 
2880  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
2881  return -EFAULT;
2882 
2883  return 0;
2884 }
2885 
2886 /*****************************************************************************/
2887 
2893  ec_master_t *master,
2894  void *arg,
2895  ec_ioctl_context_t *ctx
2896  )
2897 {
2898  ec_ioctl_sc_idn_t ioctl;
2899  ec_slave_config_t *sc;
2900  uint8_t *data = NULL;
2901  int ret;
2902 
2903  if (unlikely(!ctx->requested))
2904  return -EPERM;
2905 
2906  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
2907  return -EFAULT;
2908 
2909  if (!ioctl.size)
2910  return -EINVAL;
2911 
2912  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
2913  return -ENOMEM;
2914  }
2915 
2916  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
2917  kfree(data);
2918  return -EFAULT;
2919  }
2920 
2921  if (down_interruptible(&master->master_sem)) {
2922  kfree(data);
2923  return -EINTR;
2924  }
2925 
2926  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
2927  up(&master->master_sem);
2928  kfree(data);
2929  return -ENOENT;
2930  }
2931 
2932  up(&master->master_sem);
2934  ret = ecrt_slave_config_idn(
2935  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
2936  kfree(data);
2937  return ret;
2938 }
2939 
2940 /*****************************************************************************/
2941 
2947  ec_master_t *master,
2948  void *arg,
2949  ec_ioctl_context_t *ctx
2950  )
2951 {
2952  const ec_domain_t *domain;
2953 
2954  if (unlikely(!ctx->requested)) {
2955  return -EPERM;
2956  }
2957 
2958  if (down_interruptible(&master->master_sem)) {
2959  return -EINTR;
2960  }
2961 
2962  list_for_each_entry(domain, &master->domains, list) {
2963  if (domain->index == (unsigned long) arg) {
2964  size_t size = ecrt_domain_size(domain);
2965  up(&master->master_sem);
2966  return size;
2967  }
2968  }
2969 
2970  up(&master->master_sem);
2971  return -ENOENT;
2972 }
2973 
2974 /*****************************************************************************/
2975 
2981  ec_master_t *master,
2982  void *arg,
2983  ec_ioctl_context_t *ctx
2984  )
2985 {
2986  int offset = 0;
2987  const ec_domain_t *domain;
2988 
2989  if (unlikely(!ctx->requested))
2990  return -EPERM;
2991 
2992  if (down_interruptible(&master->master_sem)) {
2993  return -EINTR;
2994  }
2995 
2996  list_for_each_entry(domain, &master->domains, list) {
2997  if (domain->index == (unsigned long) arg) {
2998  up(&master->master_sem);
2999  return offset;
3000  }
3001  offset += ecrt_domain_size(domain);
3002  }
3003 
3004  up(&master->master_sem);
3005  return -ENOENT;
3006 }
3007 
3008 /*****************************************************************************/
3009 
3015  ec_master_t *master,
3016  void *arg,
3017  ec_ioctl_context_t *ctx
3018  )
3019 {
3020  ec_domain_t *domain;
3021 
3022  if (unlikely(!ctx->requested))
3023  return -EPERM;
3024 
3025  /* no locking of master_sem needed, because domain will not be deleted in
3026  * the meantime. */
3027 
3028  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3029  return -ENOENT;
3030  }
3031 
3032  ecrt_domain_process(domain);
3033  return 0;
3034 }
3035 
3036 /*****************************************************************************/
3037 
3043  ec_master_t *master,
3044  void *arg,
3045  ec_ioctl_context_t *ctx
3046  )
3047 {
3048  ec_domain_t *domain;
3049 
3050  if (unlikely(!ctx->requested))
3051  return -EPERM;
3052 
3053  /* no locking of master_sem needed, because domain will not be deleted in
3054  * the meantime. */
3055 
3056  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3057  return -ENOENT;
3058  }
3059 
3060  ecrt_domain_queue(domain);
3061  return 0;
3062 }
3063 
3064 /*****************************************************************************/
3065 
3071  ec_master_t *master,
3072  void *arg,
3073  ec_ioctl_context_t *ctx
3074  )
3075 {
3076  ec_ioctl_domain_state_t data;
3077  const ec_domain_t *domain;
3078  ec_domain_state_t state;
3079 
3080  if (unlikely(!ctx->requested))
3081  return -EPERM;
3082 
3083  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3084  return -EFAULT;
3085  }
3086 
3087  /* no locking of master_sem needed, because domain will not be deleted in
3088  * the meantime. */
3089 
3090  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3091  return -ENOENT;
3092  }
3093 
3094  ecrt_domain_state(domain, &state);
3095 
3096  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3097  return -EFAULT;
3098 
3099  return 0;
3100 }
3101 
3102 /*****************************************************************************/
3103 
3109  ec_master_t *master,
3110  void *arg,
3111  ec_ioctl_context_t *ctx
3112  )
3113 {
3114  ec_ioctl_sdo_request_t data;
3115  ec_slave_config_t *sc;
3116  ec_sdo_request_t *req;
3117 
3118  if (unlikely(!ctx->requested))
3119  return -EPERM;
3120 
3121  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3122  return -EFAULT;
3123 
3124  /* no locking of master_sem needed, because neither sc nor req will not be
3125  * deleted in the meantime. */
3126 
3127  if (!(sc = ec_master_get_config(master, data.config_index))) {
3128  return -ENOENT;
3129  }
3130 
3131  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3132  return -ENOENT;
3133  }
3134 
3135  ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3136  return 0;
3137 }
3138 
3139 /*****************************************************************************/
3140 
3146  ec_master_t *master,
3147  void *arg,
3148  ec_ioctl_context_t *ctx
3149  )
3150 {
3151  ec_ioctl_sdo_request_t data;
3152  ec_slave_config_t *sc;
3153  ec_sdo_request_t *req;
3154 
3155  if (unlikely(!ctx->requested))
3156  return -EPERM;
3157 
3158  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3159  return -EFAULT;
3160 
3161  /* no locking of master_sem needed, because neither sc nor req will not be
3162  * deleted in the meantime. */
3163 
3164  if (!(sc = ec_master_get_config(master, data.config_index))) {
3165  return -ENOENT;
3166  }
3167 
3168  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3169  return -ENOENT;
3170  }
3171 
3172  ecrt_sdo_request_timeout(req, data.timeout);
3173  return 0;
3174 }
3175 
3176 /*****************************************************************************/
3177 
3183  ec_master_t *master,
3184  void *arg,
3185  ec_ioctl_context_t *ctx
3186  )
3187 {
3188  ec_ioctl_sdo_request_t data;
3189  ec_slave_config_t *sc;
3190  ec_sdo_request_t *req;
3191 
3192  if (unlikely(!ctx->requested))
3193  return -EPERM;
3194 
3195  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3196  return -EFAULT;
3197 
3198  /* no locking of master_sem needed, because neither sc nor req will not be
3199  * deleted in the meantime. */
3200 
3201  if (!(sc = ec_master_get_config(master, data.config_index))) {
3202  return -ENOENT;
3203  }
3204 
3205  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3206  return -ENOENT;
3207  }
3208 
3209  data.state = ecrt_sdo_request_state(req);
3210  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3211  data.size = ecrt_sdo_request_data_size(req);
3212  else
3213  data.size = 0;
3214 
3215  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3216  return -EFAULT;
3217 
3218  return 0;
3219 }
3220 
3221 /*****************************************************************************/
3222 
3228  ec_master_t *master,
3229  void *arg,
3230  ec_ioctl_context_t *ctx
3231  )
3232 {
3233  ec_ioctl_sdo_request_t data;
3234  ec_slave_config_t *sc;
3235  ec_sdo_request_t *req;
3236 
3237  if (unlikely(!ctx->requested))
3238  return -EPERM;
3239 
3240  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3241  return -EFAULT;
3242 
3243  /* no locking of master_sem needed, because neither sc nor req will not be
3244  * deleted in the meantime. */
3245 
3246  if (!(sc = ec_master_get_config(master, data.config_index))) {
3247  return -ENOENT;
3248  }
3249 
3250  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3251  return -ENOENT;
3252  }
3253 
3254  ecrt_sdo_request_read(req);
3255  return 0;
3256 }
3257 
3258 /*****************************************************************************/
3259 
3265  ec_master_t *master,
3266  void *arg,
3267  ec_ioctl_context_t *ctx
3268  )
3269 {
3270  ec_ioctl_sdo_request_t data;
3271  ec_slave_config_t *sc;
3272  ec_sdo_request_t *req;
3273  int ret;
3274 
3275  if (unlikely(!ctx->requested))
3276  return -EPERM;
3277 
3278  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3279  return -EFAULT;
3280 
3281  if (!data.size) {
3282  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3283  return -EINVAL;
3284  }
3285 
3286  /* no locking of master_sem needed, because neither sc nor req will not be
3287  * deleted in the meantime. */
3288 
3289  if (!(sc = ec_master_get_config(master, data.config_index))) {
3290  return -ENOENT;
3291  }
3292 
3293  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3294  return -ENOENT;
3295  }
3296 
3297  ret = ec_sdo_request_alloc(req, data.size);
3298  if (ret)
3299  return ret;
3300 
3301  if (copy_from_user(req->data, (void __user *) data.data, data.size))
3302  return -EFAULT;
3303 
3304  req->data_size = data.size;
3306  return 0;
3307 }
3308 
3309 /*****************************************************************************/
3310 
3316  ec_master_t *master,
3317  void *arg,
3318  ec_ioctl_context_t *ctx
3319  )
3320 {
3321  ec_ioctl_sdo_request_t data;
3322  ec_slave_config_t *sc;
3323  ec_sdo_request_t *req;
3324 
3325  if (unlikely(!ctx->requested))
3326  return -EPERM;
3327 
3328  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3329  return -EFAULT;
3330 
3331  /* no locking of master_sem needed, because neither sc nor req will not be
3332  * deleted in the meantime. */
3333 
3334  if (!(sc = ec_master_get_config(master, data.config_index))) {
3335  return -ENOENT;
3336  }
3337 
3338  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3339  return -ENOENT;
3340  }
3341 
3342  if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3344  return -EFAULT;
3345 
3346  return 0;
3347 }
3348 
3349 /*****************************************************************************/
3350 
3356  ec_master_t *master,
3357  void *arg,
3358  ec_ioctl_context_t *ctx
3359  )
3360 {
3361  ec_ioctl_reg_request_t io;
3362  ec_slave_config_t *sc;
3363  ec_reg_request_t *reg;
3364 
3365  if (unlikely(!ctx->requested)) {
3366  return -EPERM;
3367  }
3368 
3369  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3370  return -EFAULT;
3371  }
3372 
3373  if (io.mem_size <= 0) {
3374  return 0;
3375  }
3376 
3377  /* no locking of master_sem needed, because neither sc nor reg will not be
3378  * deleted in the meantime. */
3379 
3380  if (!(sc = ec_master_get_config(master, io.config_index))) {
3381  return -ENOENT;
3382  }
3383 
3384  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3385  return -ENOENT;
3386  }
3387 
3388  if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3389  min(reg->mem_size, io.mem_size))) {
3390  return -EFAULT;
3391  }
3392 
3393  return 0;
3394 }
3395 
3396 /*****************************************************************************/
3397 
3403  ec_master_t *master,
3404  void *arg,
3405  ec_ioctl_context_t *ctx
3406  )
3407 {
3408  ec_ioctl_reg_request_t io;
3409  ec_slave_config_t *sc;
3410  ec_reg_request_t *reg;
3411 
3412  if (unlikely(!ctx->requested)) {
3413  return -EPERM;
3414  }
3415 
3416  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3417  return -EFAULT;
3418  }
3419 
3420  /* no locking of master_sem needed, because neither sc nor reg will not be
3421  * deleted in the meantime. */
3422 
3423  if (!(sc = ec_master_get_config(master, io.config_index))) {
3424  return -ENOENT;
3425  }
3426 
3427  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3428  return -ENOENT;
3429  }
3430 
3431  io.state = ecrt_reg_request_state(reg);
3432  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
3433 
3434  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3435  return -EFAULT;
3436  }
3437 
3438  return 0;
3439 }
3440 
3441 /*****************************************************************************/
3442 
3448  ec_master_t *master,
3449  void *arg,
3450  ec_ioctl_context_t *ctx
3451  )
3452 {
3453  ec_ioctl_reg_request_t io;
3454  ec_slave_config_t *sc;
3455  ec_reg_request_t *reg;
3456 
3457  if (unlikely(!ctx->requested)) {
3458  return -EPERM;
3459  }
3460 
3461  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3462  return -EFAULT;
3463  }
3464 
3465  /* no locking of master_sem needed, because neither sc nor reg will not be
3466  * deleted in the meantime. */
3467 
3468  if (!(sc = ec_master_get_config(master, io.config_index))) {
3469  return -ENOENT;
3470  }
3471 
3472  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3473  return -ENOENT;
3474  }
3475 
3476  if (io.transfer_size > reg->mem_size) {
3477  return -EOVERFLOW;
3478  }
3479 
3480  if (copy_from_user(reg->data, (void __user *) io.data,
3481  io.transfer_size)) {
3482  return -EFAULT;
3483  }
3484 
3485  ecrt_reg_request_write(reg, io.address, io.transfer_size);
3486  return 0;
3487 }
3488 
3489 /*****************************************************************************/
3490 
3496  ec_master_t *master,
3497  void *arg,
3498  ec_ioctl_context_t *ctx
3499  )
3500 {
3501  ec_ioctl_reg_request_t io;
3502  ec_slave_config_t *sc;
3503  ec_reg_request_t *reg;
3504 
3505  if (unlikely(!ctx->requested)) {
3506  return -EPERM;
3507  }
3508 
3509  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3510  return -EFAULT;
3511  }
3512 
3513  /* no locking of master_sem needed, because neither sc nor reg will not be
3514  * deleted in the meantime. */
3515 
3516  if (!(sc = ec_master_get_config(master, io.config_index))) {
3517  return -ENOENT;
3518  }
3519 
3520  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3521  return -ENOENT;
3522  }
3523 
3524  if (io.transfer_size > reg->mem_size) {
3525  return -EOVERFLOW;
3526  }
3527 
3528  ecrt_reg_request_read(reg, io.address, io.transfer_size);
3529  return 0;
3530 }
3531 
3532 /*****************************************************************************/
3533 
3539  ec_master_t *master,
3540  void *arg,
3541  ec_ioctl_context_t *ctx
3542  )
3543 {
3544  ec_ioctl_voe_t data;
3545  ec_slave_config_t *sc;
3546  ec_voe_handler_t *voe;
3547  uint32_t vendor_id;
3548  uint16_t vendor_type;
3549 
3550  if (unlikely(!ctx->requested))
3551  return -EPERM;
3552 
3553  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3554  return -EFAULT;
3555 
3556  if (get_user(vendor_id, data.vendor_id))
3557  return -EFAULT;
3558 
3559  if (get_user(vendor_type, data.vendor_type))
3560  return -EFAULT;
3561 
3562  /* no locking of master_sem needed, because neither sc nor voe will not be
3563  * deleted in the meantime. */
3564 
3565  if (!(sc = ec_master_get_config(master, data.config_index))) {
3566  return -ENOENT;
3567  }
3568 
3569  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3570  return -ENOENT;
3571  }
3572 
3573  ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
3574  return 0;
3575 }
3576 
3577 /*****************************************************************************/
3578 
3584  ec_master_t *master,
3585  void *arg,
3586  ec_ioctl_context_t *ctx
3587  )
3588 {
3589  ec_ioctl_voe_t data;
3590  ec_slave_config_t *sc;
3591  ec_voe_handler_t *voe;
3592  uint32_t vendor_id;
3593  uint16_t vendor_type;
3594 
3595  if (unlikely(!ctx->requested))
3596  return -EPERM;
3597 
3598  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3599  return -EFAULT;
3600 
3601  /* no locking of master_sem needed, because neither sc nor voe will not be
3602  * deleted in the meantime. */
3603 
3604  if (!(sc = ec_master_get_config(master, data.config_index))) {
3605  return -ENOENT;
3606  }
3607 
3608  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3609  return -ENOENT;
3610  }
3611 
3612  ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
3613 
3614  if (likely(data.vendor_id))
3615  if (put_user(vendor_id, data.vendor_id))
3616  return -EFAULT;
3617 
3618  if (likely(data.vendor_type))
3619  if (put_user(vendor_type, data.vendor_type))
3620  return -EFAULT;
3621 
3622  return 0;
3623 }
3624 
3625 /*****************************************************************************/
3626 
3632  ec_master_t *master,
3633  void *arg,
3634  ec_ioctl_context_t *ctx
3635  )
3636 {
3637  ec_ioctl_voe_t data;
3638  ec_slave_config_t *sc;
3639  ec_voe_handler_t *voe;
3640 
3641  if (unlikely(!ctx->requested))
3642  return -EPERM;
3643 
3644  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3645  return -EFAULT;
3646 
3647  /* no locking of master_sem needed, because neither sc nor voe will not be
3648  * deleted in the meantime. */
3649 
3650  if (!(sc = ec_master_get_config(master, data.config_index))) {
3651  return -ENOENT;
3652  }
3653 
3654  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3655  return -ENOENT;
3656  }
3657 
3658  ecrt_voe_handler_read(voe);
3659  return 0;
3660 }
3661 
3662 /*****************************************************************************/
3663 
3669  ec_master_t *master,
3670  void *arg,
3671  ec_ioctl_context_t *ctx
3672  )
3673 {
3674  ec_ioctl_voe_t data;
3675  ec_slave_config_t *sc;
3676  ec_voe_handler_t *voe;
3677 
3678  if (unlikely(!ctx->requested))
3679  return -EPERM;
3680 
3681  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3682  return -EFAULT;
3683 
3684  /* no locking of master_sem needed, because neither sc nor voe will not be
3685  * deleted in the meantime. */
3686 
3687  if (!(sc = ec_master_get_config(master, data.config_index))) {
3688  return -ENOENT;
3689  }
3690 
3691  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3692  return -ENOENT;
3693  }
3694 
3696  return 0;
3697 }
3698 
3699 /*****************************************************************************/
3700 
3706  ec_master_t *master,
3707  void *arg,
3708  ec_ioctl_context_t *ctx
3709  )
3710 {
3711  ec_ioctl_voe_t data;
3712  ec_slave_config_t *sc;
3713  ec_voe_handler_t *voe;
3714 
3715  if (unlikely(!ctx->requested))
3716  return -EPERM;
3717 
3718  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3719  return -EFAULT;
3720 
3721  /* no locking of master_sem needed, because neither sc nor voe will not be
3722  * deleted in the meantime. */
3723 
3724  if (!(sc = ec_master_get_config(master, data.config_index))) {
3725  return -ENOENT;
3726  }
3727 
3728  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3729  return -ENOENT;
3730  }
3731 
3732  if (data.size) {
3733  if (data.size > ec_voe_handler_mem_size(voe))
3734  return -EOVERFLOW;
3735 
3736  if (copy_from_user(ecrt_voe_handler_data(voe),
3737  (void __user *) data.data, data.size))
3738  return -EFAULT;
3739  }
3740 
3741  ecrt_voe_handler_write(voe, data.size);
3742  return 0;
3743 }
3744 
3745 /*****************************************************************************/
3746 
3752  ec_master_t *master,
3753  void *arg,
3754  ec_ioctl_context_t *ctx
3755  )
3756 {
3757  ec_ioctl_voe_t data;
3758  ec_slave_config_t *sc;
3759  ec_voe_handler_t *voe;
3760 
3761  if (unlikely(!ctx->requested))
3762  return -EPERM;
3763 
3764  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3765  return -EFAULT;
3766 
3767  /* no locking of master_sem needed, because neither sc nor voe will not be
3768  * deleted in the meantime. */
3769 
3770  if (!(sc = ec_master_get_config(master, data.config_index))) {
3771  return -ENOENT;
3772  }
3773 
3774  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3775  return -ENOENT;
3776  }
3777 
3778  data.state = ecrt_voe_handler_execute(voe);
3779  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
3780  data.size = ecrt_voe_handler_data_size(voe);
3781  else
3782  data.size = 0;
3783 
3784  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3785  return -EFAULT;
3786 
3787  return 0;
3788 }
3789 
3790 /*****************************************************************************/
3791 
3797  ec_master_t *master,
3798  void *arg,
3799  ec_ioctl_context_t *ctx
3800  )
3801 {
3802  ec_ioctl_voe_t data;
3803  ec_slave_config_t *sc;
3804  ec_voe_handler_t *voe;
3805 
3806  if (unlikely(!ctx->requested))
3807  return -EPERM;
3808 
3809  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3810  return -EFAULT;
3811 
3812  /* no locking of master_sem needed, because neither sc nor voe will not be
3813  * deleted in the meantime. */
3814 
3815  if (!(sc = ec_master_get_config(master, data.config_index))) {
3816  return -ENOENT;
3817  }
3818 
3819  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3820  return -ENOENT;
3821  }
3822 
3823  if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
3825  return -EFAULT;
3826 
3827  return 0;
3828 }
3829 
3830 /*****************************************************************************/
3831 
3837  ec_master_t *master,
3838  void *arg
3839  )
3840 {
3841  ec_ioctl_slave_foe_t io;
3842  ec_foe_request_t request;
3843  ec_slave_t *slave;
3844  int ret;
3845 
3846  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3847  return -EFAULT;
3848  }
3849 
3850  ec_foe_request_init(&request, io.file_name);
3851  ret = ec_foe_request_alloc(&request, 10000); // FIXME
3852  if (ret) {
3853  ec_foe_request_clear(&request);
3854  return ret;
3855  }
3856 
3857  ec_foe_request_read(&request);
3858 
3859  if (down_interruptible(&master->master_sem)) {
3860  ec_foe_request_clear(&request);
3861  return -EINTR;
3862  }
3863 
3864  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
3865  up(&master->master_sem);
3866  ec_foe_request_clear(&request);
3867  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3868  io.slave_position);
3869  return -EINVAL;
3870  }
3871 
3872  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
3873 
3874  // schedule request.
3875  list_add_tail(&request.list, &slave->foe_requests);
3876 
3877  up(&master->master_sem);
3878 
3879  // wait for processing through FSM
3880  if (wait_event_interruptible(master->request_queue,
3881  request.state != EC_INT_REQUEST_QUEUED)) {
3882  // interrupted by signal
3883  down(&master->master_sem);
3884  if (request.state == EC_INT_REQUEST_QUEUED) {
3885  list_del(&request.list);
3886  up(&master->master_sem);
3887  ec_foe_request_clear(&request);
3888  return -EINTR;
3889  }
3890  // request already processing: interrupt not possible.
3891  up(&master->master_sem);
3892  }
3893 
3894  // wait until master FSM has finished processing
3895  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3896 
3897  io.result = request.result;
3898  io.error_code = request.error_code;
3899 
3900  if (request.state != EC_INT_REQUEST_SUCCESS) {
3901  io.data_size = 0;
3902  ret = -EIO;
3903  } else {
3904  if (request.data_size > io.buffer_size) {
3905  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
3906  ec_foe_request_clear(&request);
3907  return -EOVERFLOW;
3908  }
3909  io.data_size = request.data_size;
3910  if (copy_to_user((void __user *) io.buffer,
3911  request.buffer, io.data_size)) {
3912  ec_foe_request_clear(&request);
3913  return -EFAULT;
3914  }
3915  ret = 0;
3916  }
3917 
3918  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
3919  ret = -EFAULT;
3920  }
3921 
3922  ec_foe_request_clear(&request);
3923  return ret;
3924 }
3925 
3926 /*****************************************************************************/
3927 
3933  ec_master_t *master,
3934  void *arg
3935  )
3936 {
3937  ec_ioctl_slave_foe_t io;
3938  ec_foe_request_t request;
3939  ec_slave_t *slave;
3940  int ret;
3941 
3942  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3943  return -EFAULT;
3944  }
3945 
3946  ec_foe_request_init(&request, io.file_name);
3947 
3948  ret = ec_foe_request_alloc(&request, io.buffer_size);
3949  if (ret) {
3950  ec_foe_request_clear(&request);
3951  return ret;
3952  }
3953 
3954  if (copy_from_user(request.buffer,
3955  (void __user *) io.buffer, io.buffer_size)) {
3956  ec_foe_request_clear(&request);
3957  return -EFAULT;
3958  }
3959 
3960  request.data_size = io.buffer_size;
3961  ec_foe_request_write(&request);
3962 
3963  if (down_interruptible(&master->master_sem)) {
3964  ec_foe_request_clear(&request);
3965  return -EINTR;
3966  }
3967 
3968  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
3969  up(&master->master_sem);
3970  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3971  io.slave_position);
3972  ec_foe_request_clear(&request);
3973  return -EINVAL;
3974  }
3975 
3976  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
3977 
3978  // schedule FoE write request.
3979  list_add_tail(&request.list, &slave->foe_requests);
3980 
3981  up(&master->master_sem);
3982 
3983  // wait for processing through FSM
3984  if (wait_event_interruptible(master->request_queue,
3985  request.state != EC_INT_REQUEST_QUEUED)) {
3986  // interrupted by signal
3987  down(&master->master_sem);
3988  if (request.state == EC_INT_REQUEST_QUEUED) {
3989  // abort request
3990  list_del(&request.list);
3991  up(&master->master_sem);
3992  ec_foe_request_clear(&request);
3993  return -EINTR;
3994  }
3995  up(&master->master_sem);
3996  }
3997 
3998  // wait until master FSM has finished processing
3999  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4000 
4001  io.result = request.result;
4002  io.error_code = request.error_code;
4003 
4004  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4005 
4006  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4007  ret = -EFAULT;
4008  }
4009 
4010  ec_foe_request_clear(&request);
4011  return ret;
4012 }
4013 
4014 /*****************************************************************************/
4015 
4021  ec_master_t *master,
4022  void *arg
4023  )
4024 {
4025  ec_ioctl_slave_soe_read_t ioctl;
4026  u8 *data;
4027  int retval;
4028 
4029  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4030  return -EFAULT;
4031  }
4032 
4033  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4034  if (!data) {
4035  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4036  ioctl.mem_size);
4037  return -ENOMEM;
4038  }
4039 
4040  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4041  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4042  &ioctl.error_code);
4043  if (retval) {
4044  kfree(data);
4045  return retval;
4046  }
4047 
4048  if (copy_to_user((void __user *) ioctl.data,
4049  data, ioctl.data_size)) {
4050  kfree(data);
4051  return -EFAULT;
4052  }
4053  kfree(data);
4054 
4055  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4056  retval = -EFAULT;
4057  }
4058 
4059  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4060  return retval;
4061 }
4062 
4063 /*****************************************************************************/
4064 
4070  ec_master_t *master,
4071  void *arg
4072  )
4073 {
4074  ec_ioctl_slave_soe_write_t ioctl;
4075  u8 *data;
4076  int retval;
4077 
4078  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4079  return -EFAULT;
4080  }
4081 
4082  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4083  if (!data) {
4084  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4085  ioctl.data_size);
4086  return -ENOMEM;
4087  }
4088  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4089  kfree(data);
4090  return -EFAULT;
4091  }
4092 
4093  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4094  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4095  &ioctl.error_code);
4096  kfree(data);
4097  if (retval) {
4098  return retval;
4099  }
4100 
4101  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4102  retval = -EFAULT;
4103  }
4104 
4105  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4106  return retval;
4107 }
4108 
4109 /*****************************************************************************/
4110 
4113 #ifdef EC_IOCTL_RTDM
4114 #define EC_IOCTL ec_ioctl_rtdm
4115 #else
4116 #define EC_IOCTL ec_ioctl
4117 #endif
4118 
4124  ec_master_t *master,
4125  ec_ioctl_context_t *ctx,
4126  unsigned int cmd,
4127  void *arg
4128  )
4129 {
4130 #if DEBUG_LATENCY
4131  cycles_t a = get_cycles(), b;
4132  unsigned int t;
4133 #endif
4134  int ret;
4135 
4136  switch (cmd) {
4137  case EC_IOCTL_MODULE:
4138  ret = ec_ioctl_module(arg);
4139  break;
4140  case EC_IOCTL_MASTER:
4141  ret = ec_ioctl_master(master, arg);
4142  break;
4143  case EC_IOCTL_SLAVE:
4144  ret = ec_ioctl_slave(master, arg);
4145  break;
4146  case EC_IOCTL_SLAVE_SYNC:
4147  ret = ec_ioctl_slave_sync(master, arg);
4148  break;
4149  case EC_IOCTL_SLAVE_SYNC_PDO:
4150  ret = ec_ioctl_slave_sync_pdo(master, arg);
4151  break;
4152  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
4153  ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
4154  break;
4155  case EC_IOCTL_DOMAIN:
4156  ret = ec_ioctl_domain(master, arg);
4157  break;
4158  case EC_IOCTL_DOMAIN_FMMU:
4159  ret = ec_ioctl_domain_fmmu(master, arg);
4160  break;
4161  case EC_IOCTL_DOMAIN_DATA:
4162  ret = ec_ioctl_domain_data(master, arg);
4163  break;
4164  case EC_IOCTL_MASTER_DEBUG:
4165  if (!ctx->writable) {
4166  ret = -EPERM;
4167  break;
4168  }
4169  ret = ec_ioctl_master_debug(master, arg);
4170  break;
4171  case EC_IOCTL_MASTER_RESCAN:
4172  if (!ctx->writable) {
4173  ret = -EPERM;
4174  break;
4175  }
4176  ret = ec_ioctl_master_rescan(master, arg);
4177  break;
4178  case EC_IOCTL_SLAVE_STATE:
4179  if (!ctx->writable) {
4180  ret = -EPERM;
4181  break;
4182  }
4183  ret = ec_ioctl_slave_state(master, arg);
4184  break;
4185  case EC_IOCTL_SLAVE_SDO:
4186  ret = ec_ioctl_slave_sdo(master, arg);
4187  break;
4188  case EC_IOCTL_SLAVE_SDO_ENTRY:
4189  ret = ec_ioctl_slave_sdo_entry(master, arg);
4190  break;
4191  case EC_IOCTL_SLAVE_SDO_UPLOAD:
4192  ret = ec_ioctl_slave_sdo_upload(master, arg);
4193  break;
4194  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
4195  if (!ctx->writable) {
4196  ret = -EPERM;
4197  break;
4198  }
4199  ret = ec_ioctl_slave_sdo_download(master, arg);
4200  break;
4201  case EC_IOCTL_SLAVE_SII_READ:
4202  ret = ec_ioctl_slave_sii_read(master, arg);
4203  break;
4204  case EC_IOCTL_SLAVE_SII_WRITE:
4205  if (!ctx->writable) {
4206  ret = -EPERM;
4207  break;
4208  }
4209  ret = ec_ioctl_slave_sii_write(master, arg);
4210  break;
4211  case EC_IOCTL_SLAVE_REG_READ:
4212  ret = ec_ioctl_slave_reg_read(master, arg);
4213  break;
4214  case EC_IOCTL_SLAVE_REG_WRITE:
4215  if (!ctx->writable) {
4216  ret = -EPERM;
4217  break;
4218  }
4219  ret = ec_ioctl_slave_reg_write(master, arg);
4220  break;
4221  case EC_IOCTL_SLAVE_FOE_READ:
4222  ret = ec_ioctl_slave_foe_read(master, arg);
4223  break;
4224  case EC_IOCTL_SLAVE_FOE_WRITE:
4225  if (!ctx->writable) {
4226  ret = -EPERM;
4227  break;
4228  }
4229  ret = ec_ioctl_slave_foe_write(master, arg);
4230  break;
4231  case EC_IOCTL_SLAVE_SOE_READ:
4232  ret = ec_ioctl_slave_soe_read(master, arg);
4233  break;
4234  case EC_IOCTL_SLAVE_SOE_WRITE:
4235  if (!ctx->writable) {
4236  ret = -EPERM;
4237  break;
4238  }
4239  ret = ec_ioctl_slave_soe_write(master, arg);
4240  break;
4241  case EC_IOCTL_CONFIG:
4242  ret = ec_ioctl_config(master, arg);
4243  break;
4244  case EC_IOCTL_CONFIG_PDO:
4245  ret = ec_ioctl_config_pdo(master, arg);
4246  break;
4247  case EC_IOCTL_CONFIG_PDO_ENTRY:
4248  ret = ec_ioctl_config_pdo_entry(master, arg);
4249  break;
4250  case EC_IOCTL_CONFIG_SDO:
4251  ret = ec_ioctl_config_sdo(master, arg);
4252  break;
4253  case EC_IOCTL_CONFIG_IDN:
4254  ret = ec_ioctl_config_idn(master, arg);
4255  break;
4256 #ifdef EC_EOE
4257  case EC_IOCTL_EOE_HANDLER:
4258  ret = ec_ioctl_eoe_handler(master, arg);
4259  break;
4260 #endif
4261  case EC_IOCTL_REQUEST:
4262  if (!ctx->writable) {
4263  ret = -EPERM;
4264  break;
4265  }
4266  ret = ec_ioctl_request(master, arg, ctx);
4267  break;
4268  case EC_IOCTL_CREATE_DOMAIN:
4269  if (!ctx->writable) {
4270  ret = -EPERM;
4271  break;
4272  }
4273  ret = ec_ioctl_create_domain(master, arg, ctx);
4274  break;
4275  case EC_IOCTL_CREATE_SLAVE_CONFIG:
4276  if (!ctx->writable) {
4277  ret = -EPERM;
4278  break;
4279  }
4280  ret = ec_ioctl_create_slave_config(master, arg, ctx);
4281  break;
4282  case EC_IOCTL_SELECT_REF_CLOCK:
4283  if (!ctx->writable) {
4284  ret = -EPERM;
4285  break;
4286  }
4287  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
4288  break;
4289  case EC_IOCTL_ACTIVATE:
4290  if (!ctx->writable) {
4291  ret = -EPERM;
4292  break;
4293  }
4294  ret = ec_ioctl_activate(master, arg, ctx);
4295  break;
4296  case EC_IOCTL_DEACTIVATE:
4297  if (!ctx->writable) {
4298  ret = -EPERM;
4299  break;
4300  }
4301  ret = ec_ioctl_deactivate(master, arg, ctx);
4302  break;
4303  case EC_IOCTL_SEND:
4304  if (!ctx->writable) {
4305  ret = -EPERM;
4306  break;
4307  }
4308  ret = ec_ioctl_send(master, arg, ctx);
4309  break;
4310  case EC_IOCTL_RECEIVE:
4311  if (!ctx->writable) {
4312  ret = -EPERM;
4313  break;
4314  }
4315  ret = ec_ioctl_receive(master, arg, ctx);
4316  break;
4317  case EC_IOCTL_MASTER_STATE:
4318  ret = ec_ioctl_master_state(master, arg, ctx);
4319  break;
4320  case EC_IOCTL_MASTER_LINK_STATE:
4321  ret = ec_ioctl_master_link_state(master, arg, ctx);
4322  break;
4323  case EC_IOCTL_APP_TIME:
4324  if (!ctx->writable) {
4325  ret = -EPERM;
4326  break;
4327  }
4328  ret = ec_ioctl_app_time(master, arg, ctx);
4329  break;
4330  case EC_IOCTL_SYNC_REF:
4331  if (!ctx->writable) {
4332  ret = -EPERM;
4333  break;
4334  }
4335  ret = ec_ioctl_sync_ref(master, arg, ctx);
4336  break;
4337  case EC_IOCTL_SYNC_REF_TO:
4338  if (!ctx->writable) {
4339  ret = -EPERM;
4340  break;
4341  }
4342  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
4343  break;
4344  case EC_IOCTL_SYNC_SLAVES:
4345  if (!ctx->writable) {
4346  ret = -EPERM;
4347  break;
4348  }
4349  ret = ec_ioctl_sync_slaves(master, arg, ctx);
4350  break;
4351  case EC_IOCTL_REF_CLOCK_TIME:
4352  if (!ctx->writable) {
4353  ret = -EPERM;
4354  break;
4355  }
4356  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4357  break;
4358  case EC_IOCTL_SYNC_MON_QUEUE:
4359  if (!ctx->writable) {
4360  ret = -EPERM;
4361  break;
4362  }
4363  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4364  break;
4365  case EC_IOCTL_SYNC_MON_PROCESS:
4366  if (!ctx->writable) {
4367  ret = -EPERM;
4368  break;
4369  }
4370  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4371  break;
4372  case EC_IOCTL_RESET:
4373  if (!ctx->writable) {
4374  ret = -EPERM;
4375  break;
4376  }
4377  ret = ec_ioctl_reset(master, arg, ctx);
4378  break;
4379  case EC_IOCTL_SC_SYNC:
4380  if (!ctx->writable) {
4381  ret = -EPERM;
4382  break;
4383  }
4384  ret = ec_ioctl_sc_sync(master, arg, ctx);
4385  break;
4386  case EC_IOCTL_SC_WATCHDOG:
4387  if (!ctx->writable) {
4388  ret = -EPERM;
4389  break;
4390  }
4391  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
4392  break;
4393  case EC_IOCTL_SC_ADD_PDO:
4394  if (!ctx->writable) {
4395  ret = -EPERM;
4396  break;
4397  }
4398  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
4399  break;
4400  case EC_IOCTL_SC_CLEAR_PDOS:
4401  if (!ctx->writable) {
4402  ret = -EPERM;
4403  break;
4404  }
4405  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
4406  break;
4407  case EC_IOCTL_SC_ADD_ENTRY:
4408  if (!ctx->writable) {
4409  ret = -EPERM;
4410  break;
4411  }
4412  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
4413  break;
4414  case EC_IOCTL_SC_CLEAR_ENTRIES:
4415  if (!ctx->writable) {
4416  ret = -EPERM;
4417  break;
4418  }
4419  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
4420  break;
4421  case EC_IOCTL_SC_REG_PDO_ENTRY:
4422  if (!ctx->writable) {
4423  ret = -EPERM;
4424  break;
4425  }
4426  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
4427  break;
4428  case EC_IOCTL_SC_REG_PDO_POS:
4429  if (!ctx->writable) {
4430  ret = -EPERM;
4431  break;
4432  }
4433  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
4434  break;
4435  case EC_IOCTL_SC_DC:
4436  if (!ctx->writable) {
4437  ret = -EPERM;
4438  break;
4439  }
4440  ret = ec_ioctl_sc_dc(master, arg, ctx);
4441  break;
4442  case EC_IOCTL_SC_SDO:
4443  if (!ctx->writable) {
4444  ret = -EPERM;
4445  break;
4446  }
4447  ret = ec_ioctl_sc_sdo(master, arg, ctx);
4448  break;
4449  case EC_IOCTL_SC_EMERG_SIZE:
4450  if (!ctx->writable) {
4451  ret = -EPERM;
4452  break;
4453  }
4454  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
4455  break;
4456  case EC_IOCTL_SC_EMERG_POP:
4457  if (!ctx->writable) {
4458  ret = -EPERM;
4459  break;
4460  }
4461  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
4462  break;
4463  case EC_IOCTL_SC_EMERG_CLEAR:
4464  if (!ctx->writable) {
4465  ret = -EPERM;
4466  break;
4467  }
4468  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
4469  break;
4470  case EC_IOCTL_SC_EMERG_OVERRUNS:
4471  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
4472  break;
4473  case EC_IOCTL_SC_SDO_REQUEST:
4474  if (!ctx->writable) {
4475  ret = -EPERM;
4476  break;
4477  }
4478  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
4479  break;
4480  case EC_IOCTL_SC_REG_REQUEST:
4481  if (!ctx->writable) {
4482  ret = -EPERM;
4483  break;
4484  }
4485  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
4486  break;
4487  case EC_IOCTL_SC_VOE:
4488  if (!ctx->writable) {
4489  ret = -EPERM;
4490  break;
4491  }
4492  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
4493  break;
4494  case EC_IOCTL_SC_STATE:
4495  ret = ec_ioctl_sc_state(master, arg, ctx);
4496  break;
4497  case EC_IOCTL_SC_IDN:
4498  if (!ctx->writable) {
4499  ret = -EPERM;
4500  break;
4501  }
4502  ret = ec_ioctl_sc_idn(master, arg, ctx);
4503  break;
4504  case EC_IOCTL_DOMAIN_SIZE:
4505  ret = ec_ioctl_domain_size(master, arg, ctx);
4506  break;
4507  case EC_IOCTL_DOMAIN_OFFSET:
4508  ret = ec_ioctl_domain_offset(master, arg, ctx);
4509  break;
4510  case EC_IOCTL_DOMAIN_PROCESS:
4511  if (!ctx->writable) {
4512  ret = -EPERM;
4513  break;
4514  }
4515  ret = ec_ioctl_domain_process(master, arg, ctx);
4516  break;
4517  case EC_IOCTL_DOMAIN_QUEUE:
4518  if (!ctx->writable) {
4519  ret = -EPERM;
4520  break;
4521  }
4522  ret = ec_ioctl_domain_queue(master, arg, ctx);
4523  break;
4524  case EC_IOCTL_DOMAIN_STATE:
4525  ret = ec_ioctl_domain_state(master, arg, ctx);
4526  break;
4527  case EC_IOCTL_SDO_REQUEST_INDEX:
4528  if (!ctx->writable) {
4529  ret = -EPERM;
4530  break;
4531  }
4532  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
4533  break;
4534  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4535  if (!ctx->writable) {
4536  ret = -EPERM;
4537  break;
4538  }
4539  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4540  break;
4541  case EC_IOCTL_SDO_REQUEST_STATE:
4542  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
4543  break;
4544  case EC_IOCTL_SDO_REQUEST_READ:
4545  if (!ctx->writable) {
4546  ret = -EPERM;
4547  break;
4548  }
4549  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
4550  break;
4551  case EC_IOCTL_SDO_REQUEST_WRITE:
4552  if (!ctx->writable) {
4553  ret = -EPERM;
4554  break;
4555  }
4556  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
4557  break;
4558  case EC_IOCTL_SDO_REQUEST_DATA:
4559  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4560  break;
4561  case EC_IOCTL_REG_REQUEST_DATA:
4562  ret = ec_ioctl_reg_request_data(master, arg, ctx);
4563  break;
4564  case EC_IOCTL_REG_REQUEST_STATE:
4565  ret = ec_ioctl_reg_request_state(master, arg, ctx);
4566  break;
4567  case EC_IOCTL_REG_REQUEST_WRITE:
4568  if (!ctx->writable) {
4569  ret = -EPERM;
4570  break;
4571  }
4572  ret = ec_ioctl_reg_request_write(master, arg, ctx);
4573  break;
4574  case EC_IOCTL_REG_REQUEST_READ:
4575  if (!ctx->writable) {
4576  ret = -EPERM;
4577  break;
4578  }
4579  ret = ec_ioctl_reg_request_read(master, arg, ctx);
4580  break;
4581  case EC_IOCTL_VOE_SEND_HEADER:
4582  if (!ctx->writable) {
4583  ret = -EPERM;
4584  break;
4585  }
4586  ret = ec_ioctl_voe_send_header(master, arg, ctx);
4587  break;
4588  case EC_IOCTL_VOE_REC_HEADER:
4589  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
4590  break;
4591  case EC_IOCTL_VOE_READ:
4592  if (!ctx->writable) {
4593  ret = -EPERM;
4594  break;
4595  }
4596  ret = ec_ioctl_voe_read(master, arg, ctx);
4597  break;
4598  case EC_IOCTL_VOE_READ_NOSYNC:
4599  if (!ctx->writable) {
4600  ret = -EPERM;
4601  break;
4602  }
4603  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
4604  break;
4605  case EC_IOCTL_VOE_WRITE:
4606  if (!ctx->writable) {
4607  ret = -EPERM;
4608  break;
4609  }
4610  ret = ec_ioctl_voe_write(master, arg, ctx);
4611  break;
4612  case EC_IOCTL_VOE_EXEC:
4613  if (!ctx->writable) {
4614  ret = -EPERM;
4615  break;
4616  }
4617  ret = ec_ioctl_voe_exec(master, arg, ctx);
4618  break;
4619  case EC_IOCTL_VOE_DATA:
4620  ret = ec_ioctl_voe_data(master, arg, ctx);
4621  break;
4622  case EC_IOCTL_SET_SEND_INTERVAL:
4623  if (!ctx->writable) {
4624  ret = -EPERM;
4625  break;
4626  }
4627  ret = ec_ioctl_set_send_interval(master, arg, ctx);
4628  break;
4629  default:
4630  ret = -ENOTTY;
4631  break;
4632  }
4633 
4634 #if DEBUG_LATENCY
4635  b = get_cycles();
4636  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
4637  if (t > 50) {
4638  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
4639  _IOC_NR(cmd), t);
4640  }
4641 #endif
4642 
4643  return ret;
4644 }
4645 
4646 /*****************************************************************************/
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
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
uint16_t offset
SII word offset.
Definition: fsm_master.h:56
uint16_t ring_position
Ring position.
Definition: slave.h:183
uint32_t revision_number
Revision number.
Definition: slave.h:137
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave&#39;s SII.
Definition: rtdm-ioctl.c:945
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_voe_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation.
Definition: rtdm-ioctl.c:3631
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: rtdm-ioctl.c:2980
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: rtdm-ioctl.c:3042
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:116
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:2853
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:482
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:136
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
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:156
FMMU configuration.
Definition: fmmu_config.h:46
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: rtdm-ioctl.c:3227
u64 tx_count
Number of frames sent.
Definition: master.h:156
struct list_head sii_requests
SII write requests.
Definition: master.h:306
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:2835
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:438
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:879
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_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: rtdm-ioctl.c:1440
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: rtdm-ioctl.c:1255
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
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:173
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: rtdm-ioctl.c:2480
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: rtdm-ioctl.c:2654
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:59
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:1899
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:563
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:112
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:2766
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:2782
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:97
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: rtdm-ioctl.c:2577
CANopen SDO request.
Definition: sdo_request.h:48
ec_slave_state_t current_state
Current application state.
Definition: slave.h:192
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: rtdm-ioctl.c:565
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:329
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:72
size_t nwords
Number of words.
Definition: fsm_master.h:57
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
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:2948
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:59
Register request.
Definition: reg_request.h:48
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
uint32_t product_code
Slave product code.
Definition: slave_config.h:126
ec_slave_port_link_t link
Port link status.
Definition: slave.h:120
Access rights in PREOP.
Definition: globals.h:193
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:557
uint16_t position
Index after alias.
Definition: slave_config.h:123
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: rtdm-ioctl.c:624
static ATTRIBUTES int ec_ioctl_sc_clear_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the PDO assignment.
Definition: rtdm-ioctl.c:2238
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:1850
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:83
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:2729
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:394
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:1978
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:2017
uint16_t index
SDO index.
Definition: sdo_request.h:50
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:239
static ATTRIBUTES int ec_ioctl_voe_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reads the received VoE data.
Definition: rtdm-ioctl.c:3796
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: rtdm-ioctl.c:1796
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:307
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
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: rtdm-ioctl.c:2308
uint16_t alias
Slave alias.
Definition: slave_config.h:122
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: rtdm-ioctl.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: rtdm-ioctl.c:2273
struct list_head domains
List of domains.
Definition: master.h:236
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: rtdm-ioctl.c:340
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: rtdm-ioctl.c:3108
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:795
struct list_head reg_requests
Register access requests.
Definition: slave.h:230
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: rtdm-ioctl.c:2043
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
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: rtdm-ioctl.c:3145
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:52
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:163
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:1834
uint8_t link_state
device link state
Definition: device.h:88
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
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: rtdm-ioctl.c:2012
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:530
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:142
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:2743
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:172
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:310
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
static ATTRIBUTES int ec_ioctl_reg_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an register request&#39;s state.
Definition: rtdm-ioctl.c:3402
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:2822
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
unsigned int sync_count
Number of sync managers.
Definition: slave.h:166
struct list_head list
List head.
Definition: fsm_master.h:54
SII write request.
Definition: fsm_master.h:53
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:2260
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:106
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:144
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: rtdm-ioctl.c:2699
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: rtdm-ioctl.c:2204
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:1914
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:860
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave&#39;s registers.
Definition: rtdm-ioctl.c:1033
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: rtdm-ioctl.c:2440
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
uint8_t * ecrt_sdo_request_data(ec_sdo_request_t *req)
Access to the SDO request&#39;s data.
Definition: sdo_request.c:203
ec_direction_t dir
Direction.
Definition: sdo_request.h:60
PDO entry description.
Definition: pdo_entry.h:48
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:141
static ATTRIBUTES int ec_ioctl_master_link_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the link state.
Definition: rtdm-ioctl.c:1890
uint16_t index
PDO index.
Definition: pdo.h:51
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:111
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:141
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: rtdm-ioctl.c:2063
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
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:55
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_voe_exec(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Executes the VoE state machine.
Definition: rtdm-ioctl.c:3751
Access rights in SAFEOP.
Definition: globals.h:194
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
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:262
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: rtdm-ioctl.c:723
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.
Definition: slave_config.c:964
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:2042
Slave configuration state.
Definition: ecrt.h:310
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: rtdm-ioctl.c:3495
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave&#39;s registers.
Definition: rtdm-ioctl.c:1112
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:136
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:219
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: rtdm-ioctl.c:3264
void(* state)(ec_voe_handler_t *)
State function.
Definition: voe_handler.h:59
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:146
ec_master_phase_t phase
Master phase.
Definition: master.h:223
Domain state.
Definition: ecrt.h:411
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: rtdm-ioctl.c:610
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: rtdm-ioctl.c:2088
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
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: rtdm-ioctl.c:3583
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:50
static ATTRIBUTES int ec_ioctl_sdo_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SDO data.
Definition: rtdm-ioctl.c:3315
struct semaphore device_sem
Device semaphore.
Definition: master.h:218
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:144
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:2864
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:1963
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
static ATTRIBUTES int ec_ioctl_reg_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read register data.
Definition: rtdm-ioctl.c:3355
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
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: rtdm-ioctl.c:803
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:1929
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
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:143
static ATTRIBUTES int ec_ioctl_sync_ref(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: rtdm-ioctl.c:1947
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:209
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:177
static ATTRIBUTES int ec_ioctl_module(void *arg)
Get module information.
Definition: rtdm-ioctl.c:83
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:2633
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:140
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:170
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:202
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: rtdm-ioctl.c:57
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:130
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: rtdm-ioctl.c:849
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_master(ec_master_t *master, void *arg)
Get master information.
Definition: rtdm-ioctl.c:104
static ATTRIBUTES int ec_ioctl_sc_emerg_clear(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clear the emergency ring.
Definition: rtdm-ioctl.c:2621
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:49
unsigned int active
Master has been activated.
Definition: master.h:224
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:191
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: rtdm-ioctl.c:2390
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:372
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
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:3034
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:212
#define EC_IOCTL
ioctl() function to use.
Definition: rtdm-ioctl.c:4116
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:57
u64 tx_count
Number of frames sent.
Definition: device.h:100
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: rtdm-ioctl.c:3014
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:332
#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
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: rtdm-ioctl.c:1653
uint8_t control_register
Control register value.
Definition: sync.h:51
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: rtdm-ioctl.c:3668
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: rtdm-ioctl.c:1311
Values read by the master.
Definition: ecrt.h:424
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
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: rtdm-ioctl.c:513
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: rtdm-ioctl.c:468
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
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: rtdm-ioctl.c:2159
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: rtdm-ioctl.c:1558
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:133
static ATTRIBUTES int ec_ioctl_sync_ref_to(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: rtdm-ioctl.c:1967
unsigned int opened
net_device is opened
Definition: ethernet.h:85
static ATTRIBUTES int ec_ioctl_create_slave_config(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a slave configuration.
Definition: rtdm-ioctl.c:1607
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:128
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE handler via its position in the list.
Definition: slave_config.c:460
static ATTRIBUTES int ec_ioctl_domain_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the domain state.
Definition: rtdm-ioctl.c:3070
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:3277
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
static ATTRIBUTES int ec_ioctl_master_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the master state.
Definition: rtdm-ioctl.c:1868
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:2845
static ATTRIBUTES int ec_ioctl_sync_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the slave clocks.
Definition: rtdm-ioctl.c:1992
void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:181
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
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:611
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
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: rtdm-ioctl.c:1376
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:51
FoE request.
Definition: foe_request.h:50
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: rtdm-ioctl.c:2946
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:70
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: rtdm-ioctl.c:1197
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:416
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:740
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:54
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: rtdm-ioctl.c:674
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:3193
struct list_head foe_requests
FoE write requests.
Definition: slave.h:231
ec_direction_t dir
Direction.
Definition: voe_handler.h:56
u64 tx_bytes
Number of bytes sent.
Definition: master.h:161
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: rtdm-ioctl.c:200
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2307
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:1995
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: rtdm-ioctl.c:287
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:648
uint8_t enable
Enable bit.
Definition: sync.h:52
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:213
static ATTRIBUTES int ec_ioctl_slave_soe_write(ec_master_t *master, void *arg)
Write an IDN to a slave via SoE.
Definition: rtdm-ioctl.c:4069
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: rtdm-ioctl.c:4020
static void ec_ioctl_strcpy(char *target, const char *source)
Copies a string to an ioctl structure.
Definition: rtdm-ioctl.c:64
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: rtdm-ioctl.c:1922
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:121
ec_direction_t dir
Direction.
Definition: reg_request.h:52
Access rights in OP.
Definition: globals.h:195
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: rtdm-ioctl.c:3836
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:125
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_emerg_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the emergency ring buffer size.
Definition: rtdm-ioctl.c:2539
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:543
char * image
Image name.
Definition: slave.h:156
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: rtdm-ioctl.c:2892
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
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:214
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:551
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2381
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:204
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave&#39;s SII.
Definition: rtdm-ioctl.c:897
static ATTRIBUTES int ec_ioctl_slave_sync_pdo_entry(ec_master_t *master, void *arg)
Get slave sync manager PDO entry information.
Definition: rtdm-ioctl.c:399
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:524
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:3117
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: rtdm-ioctl.c:3447
static ATTRIBUTES int ec_ioctl_sc_sync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a sync manager.
Definition: rtdm-ioctl.c:2106
EtherCAT slave configuration.
Definition: slave_config.h:118
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: rtdm-ioctl.c:2343
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: rtdm-ioctl.c:1828
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:127
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:69
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:84
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: rtdm-ioctl.c:2854
EtherCAT master character device IOCTL commands.
Request was processed successfully.
Definition: ecrt.h:524
EtherCAT slave configuration structure.
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
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:2564
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
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: rtdm-ioctl.c:3538
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:2793
static ATTRIBUTES int ec_ioctl_voe_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE write operation.
Definition: rtdm-ioctl.c:3705
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:1866
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:678
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: rtdm-ioctl.c:2804
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.
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:593
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
static ATTRIBUTES int ec_ioctl_slave_foe_write(ec_master_t *master, void *arg)
Write a file to a slave via FoE.
Definition: rtdm-ioctl.c:3932
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
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: rtdm-ioctl.c:1777
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
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: rtdm-ioctl.c:1506
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:230
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:193
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:165
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: rtdm-ioctl.c:1583
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:146
EtherCAT master.
Definition: master.h:194
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:2812
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: rtdm-ioctl.c:639
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: rtdm-ioctl.c:1694
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:204
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:211
u64 tx_bytes
Number of bytes sent.
Definition: device.h:105
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: rtdm-ioctl.c:2750
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:110
uint8_t * ecrt_voe_handler_data(ec_voe_handler_t *voe)
Access to the VoE handler&#39;s data.
Definition: voe_handler.c:149
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:235
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:58
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:904
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
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_sdo_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SDO request&#39;s state.
Definition: rtdm-ioctl.c:3182
uint32_t vendor_id
Vendor ID.
Definition: slave.h:135
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:55
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:124
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:504
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:57
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
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2495
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
void ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2451
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