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