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 #endif
122  io.phase = (uint8_t) master->phase;
123  io.active = (uint8_t) master->active;
124  io.scan_busy = master->scan_busy;
125 
126  up(&master->master_sem);
127 
128  if (down_interruptible(&master->device_sem)) {
129  return -EINTR;
130  }
131 
132  for (dev_idx = EC_DEVICE_MAIN;
133  dev_idx < ec_master_num_devices(master); dev_idx++) {
134  ec_device_t *device = &master->devices[dev_idx];
135 
136  if (device->dev) {
137  memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
138  ETH_ALEN);
139  } else {
140  memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
141  ETH_ALEN);
142  }
143  io.devices[dev_idx].attached = device->dev ? 1 : 0;
144  io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
145  io.devices[dev_idx].tx_count = device->tx_count;
146  io.devices[dev_idx].rx_count = device->rx_count;
147  io.devices[dev_idx].tx_bytes = device->tx_bytes;
148  io.devices[dev_idx].rx_bytes = device->rx_bytes;
149  io.devices[dev_idx].tx_errors = device->tx_errors;
150  for (j = 0; j < EC_RATE_COUNT; j++) {
151  io.devices[dev_idx].tx_frame_rates[j] =
152  device->tx_frame_rates[j];
153  io.devices[dev_idx].rx_frame_rates[j] =
154  device->rx_frame_rates[j];
155  io.devices[dev_idx].tx_byte_rates[j] =
156  device->tx_byte_rates[j];
157  io.devices[dev_idx].rx_byte_rates[j] =
158  device->rx_byte_rates[j];
159  }
160  }
161  io.num_devices = ec_master_num_devices(master);
162 
163  io.tx_count = master->device_stats.tx_count;
164  io.rx_count = master->device_stats.rx_count;
165  io.tx_bytes = master->device_stats.tx_bytes;
166  io.rx_bytes = master->device_stats.rx_bytes;
167  for (j = 0; j < EC_RATE_COUNT; j++) {
168  io.tx_frame_rates[j] =
169  master->device_stats.tx_frame_rates[j];
170  io.rx_frame_rates[j] =
171  master->device_stats.rx_frame_rates[j];
172  io.tx_byte_rates[j] =
173  master->device_stats.tx_byte_rates[j];
174  io.rx_byte_rates[j] =
175  master->device_stats.rx_byte_rates[j];
176  io.loss_rates[j] =
177  master->device_stats.loss_rates[j];
178  }
179 
180  up(&master->device_sem);
181 
182  io.app_time = master->app_time;
183  io.ref_clock =
184  master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
185 
186  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
187  return -EFAULT;
188  }
189 
190  return 0;
191 }
192 
193 /*****************************************************************************/
194 
201  void *arg
202  )
203 {
204  ec_ioctl_slave_t data;
205  const ec_slave_t *slave;
206  int i;
207 
208  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
209  return -EFAULT;
210  }
211 
212  if (down_interruptible(&master->master_sem))
213  return -EINTR;
214 
215  if (!(slave = ec_master_find_slave_const(
216  master, 0, data.position))) {
217  up(&master->master_sem);
218  EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
219  return -EINVAL;
220  }
221 
222  data.device_index = slave->device_index;
223  data.vendor_id = slave->sii.vendor_id;
224  data.product_code = slave->sii.product_code;
225  data.revision_number = slave->sii.revision_number;
226  data.serial_number = slave->sii.serial_number;
227  data.alias = slave->effective_alias;
228  data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
229  data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
230  data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
231  data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
232  data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
233  data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
234  data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
235  data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
236  data.mailbox_protocols = slave->sii.mailbox_protocols;
237  data.has_general_category = slave->sii.has_general;
238  data.coe_details = slave->sii.coe_details;
239  data.general_flags = slave->sii.general_flags;
240  data.current_on_ebus = slave->sii.current_on_ebus;
241  for (i = 0; i < EC_MAX_PORTS; i++) {
242  data.ports[i].desc = slave->ports[i].desc;
243  data.ports[i].link.link_up = slave->ports[i].link.link_up;
244  data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
245  data.ports[i].link.signal_detected =
246  slave->ports[i].link.signal_detected;
247  data.ports[i].receive_time = slave->ports[i].receive_time;
248  if (slave->ports[i].next_slave) {
249  data.ports[i].next_slave =
250  slave->ports[i].next_slave->ring_position;
251  } else {
252  data.ports[i].next_slave = 0xffff;
253  }
254  data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
255  }
256  data.fmmu_bit = slave->base_fmmu_bit_operation;
257  data.dc_supported = slave->base_dc_supported;
258  data.dc_range = slave->base_dc_range;
259  data.has_dc_system_time = slave->has_dc_system_time;
260  data.transmission_delay = slave->transmission_delay;
261  data.al_state = slave->current_state;
262  data.error_flag = slave->error_flag;
263 
264  data.sync_count = slave->sii.sync_count;
265  data.sdo_count = ec_slave_sdo_count(slave);
266  data.sii_nwords = slave->sii_nwords;
267  ec_ioctl_strcpy(data.group, slave->sii.group);
268  ec_ioctl_strcpy(data.image, slave->sii.image);
269  ec_ioctl_strcpy(data.order, slave->sii.order);
270  ec_ioctl_strcpy(data.name, slave->sii.name);
271 
272  up(&master->master_sem);
273 
274  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
275  return -EFAULT;
276 
277  return 0;
278 }
279 
280 /*****************************************************************************/
281 
288  void *arg
289  )
290 {
291  ec_ioctl_slave_sync_t data;
292  const ec_slave_t *slave;
293  const ec_sync_t *sync;
294 
295  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
296  return -EFAULT;
297  }
298 
299  if (down_interruptible(&master->master_sem))
300  return -EINTR;
301 
302  if (!(slave = ec_master_find_slave_const(
303  master, 0, data.slave_position))) {
304  up(&master->master_sem);
305  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
306  data.slave_position);
307  return -EINVAL;
308  }
309 
310  if (data.sync_index >= slave->sii.sync_count) {
311  up(&master->master_sem);
312  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
313  data.sync_index);
314  return -EINVAL;
315  }
316 
317  sync = &slave->sii.syncs[data.sync_index];
318 
320  data.default_size = sync->default_length;
321  data.control_register = sync->control_register;
322  data.enable = sync->enable;
323  data.pdo_count = ec_pdo_list_count(&sync->pdos);
324 
325  up(&master->master_sem);
326 
327  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
328  return -EFAULT;
329 
330  return 0;
331 }
332 
333 /*****************************************************************************/
334 
341  void *arg
342  )
343 {
344  ec_ioctl_slave_sync_pdo_t data;
345  const ec_slave_t *slave;
346  const ec_sync_t *sync;
347  const ec_pdo_t *pdo;
348 
349  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
350  return -EFAULT;
351  }
352 
353  if (down_interruptible(&master->master_sem))
354  return -EINTR;
355 
356  if (!(slave = ec_master_find_slave_const(
357  master, 0, data.slave_position))) {
358  up(&master->master_sem);
359  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
360  data.slave_position);
361  return -EINVAL;
362  }
363 
364  if (data.sync_index >= slave->sii.sync_count) {
365  up(&master->master_sem);
366  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
367  data.sync_index);
368  return -EINVAL;
369  }
370 
371  sync = &slave->sii.syncs[data.sync_index];
373  &sync->pdos, data.pdo_pos))) {
374  up(&master->master_sem);
375  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
376  "position %u!\n", data.sync_index, data.pdo_pos);
377  return -EINVAL;
378  }
379 
380  data.index = pdo->index;
381  data.entry_count = ec_pdo_entry_count(pdo);
382  ec_ioctl_strcpy(data.name, pdo->name);
383 
384  up(&master->master_sem);
385 
386  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
387  return -EFAULT;
388 
389  return 0;
390 }
391 
392 /*****************************************************************************/
393 
400  void *arg
401  )
402 {
403  ec_ioctl_slave_sync_pdo_entry_t data;
404  const ec_slave_t *slave;
405  const ec_sync_t *sync;
406  const ec_pdo_t *pdo;
407  const ec_pdo_entry_t *entry;
408 
409  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
410  return -EFAULT;
411  }
412 
413  if (down_interruptible(&master->master_sem))
414  return -EINTR;
415 
416  if (!(slave = ec_master_find_slave_const(
417  master, 0, data.slave_position))) {
418  up(&master->master_sem);
419  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
420  data.slave_position);
421  return -EINVAL;
422  }
423 
424  if (data.sync_index >= slave->sii.sync_count) {
425  up(&master->master_sem);
426  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
427  data.sync_index);
428  return -EINVAL;
429  }
430 
431  sync = &slave->sii.syncs[data.sync_index];
433  &sync->pdos, data.pdo_pos))) {
434  up(&master->master_sem);
435  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
436  "position %u!\n", data.sync_index, data.pdo_pos);
437  return -EINVAL;
438  }
439 
440  if (!(entry = ec_pdo_find_entry_by_pos_const(
441  pdo, data.entry_pos))) {
442  up(&master->master_sem);
443  EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
444  "position %u!\n", data.pdo_pos, data.entry_pos);
445  return -EINVAL;
446  }
447 
448  data.index = entry->index;
449  data.subindex = entry->subindex;
450  data.bit_length = entry->bit_length;
451  ec_ioctl_strcpy(data.name, entry->name);
452 
453  up(&master->master_sem);
454 
455  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
456  return -EFAULT;
457 
458  return 0;
459 }
460 
461 /*****************************************************************************/
462 
469  void *arg
470  )
471 {
472  ec_ioctl_domain_t data;
473  const ec_domain_t *domain;
474  unsigned int dev_idx;
475 
476  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
477  return -EFAULT;
478  }
479 
480  if (down_interruptible(&master->master_sem))
481  return -EINTR;
482 
483  if (!(domain = ec_master_find_domain_const(master, data.index))) {
484  up(&master->master_sem);
485  EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
486  return -EINVAL;
487  }
488 
489  data.data_size = domain->data_size;
490  data.logical_base_address = domain->logical_base_address;
491  for (dev_idx = EC_DEVICE_MAIN;
492  dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
493  data.working_counter[dev_idx] = domain->working_counter[dev_idx];
494  }
495  data.expected_working_counter = domain->expected_working_counter;
496  data.fmmu_count = ec_domain_fmmu_count(domain);
497 
498  up(&master->master_sem);
499 
500  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
501  return -EFAULT;
502 
503  return 0;
504 }
505 
506 /*****************************************************************************/
507 
514  void *arg
515  )
516 {
517  ec_ioctl_domain_fmmu_t data;
518  const ec_domain_t *domain;
519  const ec_fmmu_config_t *fmmu;
520 
521  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
522  return -EFAULT;
523  }
524 
525  if (down_interruptible(&master->master_sem))
526  return -EINTR;
527 
528  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
529  up(&master->master_sem);
530  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
531  data.domain_index);
532  return -EINVAL;
533  }
534 
535  if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
536  up(&master->master_sem);
537  EC_MASTER_ERR(master, "Domain %u has less than %u"
538  " fmmu configurations.\n",
539  data.domain_index, data.fmmu_index + 1);
540  return -EINVAL;
541  }
542 
543  data.slave_config_alias = fmmu->sc->alias;
544  data.slave_config_position = fmmu->sc->position;
545  data.sync_index = fmmu->sync_index;
546  data.dir = fmmu->dir;
547  data.logical_address = fmmu->logical_start_address;
548  data.data_size = fmmu->data_size;
549 
550  up(&master->master_sem);
551 
552  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
553  return -EFAULT;
554 
555  return 0;
556 }
557 
558 /*****************************************************************************/
559 
566  void *arg
567  )
568 {
569  ec_ioctl_domain_data_t data;
570  const ec_domain_t *domain;
571 
572  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
573  return -EFAULT;
574  }
575 
576  if (down_interruptible(&master->master_sem))
577  return -EINTR;
578 
579  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
580  up(&master->master_sem);
581  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
582  data.domain_index);
583  return -EINVAL;
584  }
585 
586  if (domain->data_size != data.data_size) {
587  up(&master->master_sem);
588  EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
589  data.data_size, domain->data_size);
590  return -EFAULT;
591  }
592 
593  if (copy_to_user((void __user *) data.target, domain->data,
594  domain->data_size)) {
595  up(&master->master_sem);
596  return -EFAULT;
597  }
598 
599  up(&master->master_sem);
600  return 0;
601 }
602 
603 /*****************************************************************************/
604 
611  void *arg
612  )
613 {
614  return ec_master_debug_level(master, (unsigned long) arg);
615 }
616 
617 /*****************************************************************************/
618 
625  void *arg
626  )
627 {
628  master->fsm.rescan_required = 1;
629  return 0;
630 }
631 
632 /*****************************************************************************/
633 
640  void *arg
641  )
642 {
643  ec_ioctl_slave_state_t data;
644  ec_slave_t *slave;
645 
646  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
647  return -EFAULT;
648  }
649 
650  if (down_interruptible(&master->master_sem))
651  return -EINTR;
652 
653  if (!(slave = ec_master_find_slave(
654  master, 0, data.slave_position))) {
655  up(&master->master_sem);
656  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
657  data.slave_position);
658  return -EINVAL;
659  }
660 
661  ec_slave_request_state(slave, data.al_state);
662 
663  up(&master->master_sem);
664  return 0;
665 }
666 
667 /*****************************************************************************/
668 
675  void *arg
676  )
677 {
678  ec_ioctl_slave_sdo_t data;
679  const ec_slave_t *slave;
680  const ec_sdo_t *sdo;
681 
682  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
683  return -EFAULT;
684  }
685 
686  if (down_interruptible(&master->master_sem))
687  return -EINTR;
688 
689  if (!(slave = ec_master_find_slave_const(
690  master, 0, data.slave_position))) {
691  up(&master->master_sem);
692  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
693  data.slave_position);
694  return -EINVAL;
695  }
696 
697  if (!(sdo = ec_slave_get_sdo_by_pos_const(
698  slave, data.sdo_position))) {
699  up(&master->master_sem);
700  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
701  return -EINVAL;
702  }
703 
704  data.sdo_index = sdo->index;
705  data.max_subindex = sdo->max_subindex;
706  ec_ioctl_strcpy(data.name, sdo->name);
707 
708  up(&master->master_sem);
709 
710  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
711  return -EFAULT;
712 
713  return 0;
714 }
715 
716 /*****************************************************************************/
717 
724  void *arg
725  )
726 {
727  ec_ioctl_slave_sdo_entry_t data;
728  const ec_slave_t *slave;
729  const ec_sdo_t *sdo;
730  const ec_sdo_entry_t *entry;
731 
732  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
733  return -EFAULT;
734  }
735 
736  if (down_interruptible(&master->master_sem))
737  return -EINTR;
738 
739  if (!(slave = ec_master_find_slave_const(
740  master, 0, data.slave_position))) {
741  up(&master->master_sem);
742  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
743  data.slave_position);
744  return -EINVAL;
745  }
746 
747  if (data.sdo_spec <= 0) {
748  if (!(sdo = ec_slave_get_sdo_by_pos_const(
749  slave, -data.sdo_spec))) {
750  up(&master->master_sem);
751  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
752  return -EINVAL;
753  }
754  } else {
755  if (!(sdo = ec_slave_get_sdo_const(
756  slave, data.sdo_spec))) {
757  up(&master->master_sem);
758  EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
759  data.sdo_spec);
760  return -EINVAL;
761  }
762  }
763 
764  if (!(entry = ec_sdo_get_entry_const(
765  sdo, data.sdo_entry_subindex))) {
766  up(&master->master_sem);
767  EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
768  sdo->index, data.sdo_entry_subindex);
769  return -EINVAL;
770  }
771 
772  data.data_type = entry->data_type;
773  data.bit_length = entry->bit_length;
774  data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
776  data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
778  data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
780  data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
782  data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
784  data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
786  ec_ioctl_strcpy(data.description, entry->description);
787 
788  up(&master->master_sem);
789 
790  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
791  return -EFAULT;
792 
793  return 0;
794 }
795 
796 /*****************************************************************************/
797 
804  void *arg
805  )
806 {
807  ec_ioctl_slave_sdo_upload_t data;
808  uint8_t *target;
809  int ret;
810 
811  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
812  return -EFAULT;
813  }
814 
815  if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
816  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
817  " for SDO upload.\n", data.target_size);
818  return -ENOMEM;
819  }
820 
821  ret = ecrt_master_sdo_upload(master, data.slave_position,
822  data.sdo_index, data.sdo_entry_subindex, target,
823  data.target_size, &data.data_size, &data.abort_code);
824 
825  if (!ret) {
826  if (copy_to_user((void __user *) data.target,
827  target, data.data_size)) {
828  kfree(target);
829  return -EFAULT;
830  }
831  }
832 
833  kfree(target);
834 
835  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
836  return -EFAULT;
837  }
838 
839  return ret;
840 }
841 
842 /*****************************************************************************/
843 
850  void *arg
851  )
852 {
853  ec_ioctl_slave_sdo_download_t data;
854  uint8_t *sdo_data;
855  int retval;
856 
857  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
858  return -EFAULT;
859  }
860 
861  if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
862  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
863  " for SDO download.\n", data.data_size);
864  return -ENOMEM;
865  }
866 
867  if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
868  kfree(sdo_data);
869  return -EFAULT;
870  }
871 
872  if (data.complete_access) {
873  retval = ecrt_master_sdo_download_complete(master, data.slave_position,
874  data.sdo_index, sdo_data, data.data_size, &data.abort_code);
875  } else {
876  retval = ecrt_master_sdo_download(master, data.slave_position,
877  data.sdo_index, data.sdo_entry_subindex, sdo_data,
878  data.data_size, &data.abort_code);
879  }
880 
881  kfree(sdo_data);
882 
883  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
884  retval = -EFAULT;
885  }
886 
887  return retval;
888 }
889 
890 /*****************************************************************************/
891 
898  void *arg
899  )
900 {
901  ec_ioctl_slave_sii_t data;
902  const ec_slave_t *slave;
903  int retval;
904 
905  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
906  return -EFAULT;
907  }
908 
909  if (down_interruptible(&master->master_sem))
910  return -EINTR;
911 
912  if (!(slave = ec_master_find_slave_const(
913  master, 0, data.slave_position))) {
914  up(&master->master_sem);
915  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
916  data.slave_position);
917  return -EINVAL;
918  }
919 
920  if (!data.nwords
921  || data.offset + data.nwords > slave->sii_nwords) {
922  up(&master->master_sem);
923  EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
924  " size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
925  return -EINVAL;
926  }
927 
928  if (copy_to_user((void __user *) data.words,
929  slave->sii_words + data.offset, data.nwords * 2))
930  retval = -EFAULT;
931  else
932  retval = 0;
933 
934  up(&master->master_sem);
935  return retval;
936 }
937 
938 /*****************************************************************************/
939 
946  void *arg
947  )
948 {
949  ec_ioctl_slave_sii_t data;
950  ec_slave_t *slave;
951  unsigned int byte_size;
952  uint16_t *words;
953  ec_sii_write_request_t request;
954 
955  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
956  return -EFAULT;
957  }
958 
959  if (!data.nwords) {
960  return 0;
961  }
962 
963  byte_size = sizeof(uint16_t) * data.nwords;
964  if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
965  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
966  " for SII contents.\n", byte_size);
967  return -ENOMEM;
968  }
969 
970  if (copy_from_user(words,
971  (void __user *) data.words, byte_size)) {
972  kfree(words);
973  return -EFAULT;
974  }
975 
976  if (down_interruptible(&master->master_sem)) {
977  kfree(words);
978  return -EINTR;
979  }
980 
981  if (!(slave = ec_master_find_slave(
982  master, 0, data.slave_position))) {
983  up(&master->master_sem);
984  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
985  data.slave_position);
986  kfree(words);
987  return -EINVAL;
988  }
989 
990  // init SII write request
991  INIT_LIST_HEAD(&request.list);
992  request.slave = slave;
993  request.words = words;
994  request.offset = data.offset;
995  request.nwords = data.nwords;
996  request.state = EC_INT_REQUEST_QUEUED;
997 
998  // schedule SII write request.
999  list_add_tail(&request.list, &master->sii_requests);
1000 
1001  up(&master->master_sem);
1002 
1003  // wait for processing through FSM
1004  if (wait_event_interruptible(master->request_queue,
1005  request.state != EC_INT_REQUEST_QUEUED)) {
1006  // interrupted by signal
1007  down(&master->master_sem);
1008  if (request.state == EC_INT_REQUEST_QUEUED) {
1009  // abort request
1010  list_del(&request.list);
1011  up(&master->master_sem);
1012  kfree(words);
1013  return -EINTR;
1014  }
1015  up(&master->master_sem);
1016  }
1017 
1018  // wait until master FSM has finished processing
1019  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1020 
1021  kfree(words);
1022 
1023  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1024 }
1025 
1026 /*****************************************************************************/
1027 
1033  ec_master_t *master,
1034  void *arg
1035  )
1036 {
1037  ec_ioctl_slave_reg_t io;
1038  ec_slave_t *slave;
1039  ec_reg_request_t request;
1040  int ret;
1041 
1042  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1043  return -EFAULT;
1044  }
1045 
1046  if (!io.size) {
1047  return 0;
1048  }
1049 
1050  // init register request
1051  ret = ec_reg_request_init(&request, io.size);
1052  if (ret) {
1053  return ret;
1054  }
1055 
1056  ecrt_reg_request_read(&request, io.address, io.size);
1057 
1058  if (down_interruptible(&master->master_sem)) {
1059  ec_reg_request_clear(&request);
1060  return -EINTR;
1061  }
1062 
1063  if (!(slave = ec_master_find_slave(
1064  master, 0, io.slave_position))) {
1065  up(&master->master_sem);
1066  ec_reg_request_clear(&request);
1067  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1068  io.slave_position);
1069  return -EINVAL;
1070  }
1071 
1072  // schedule request.
1073  list_add_tail(&request.list, &slave->reg_requests);
1074 
1075  up(&master->master_sem);
1076 
1077  // wait for processing through FSM
1078  if (wait_event_interruptible(master->request_queue,
1079  request.state != EC_INT_REQUEST_QUEUED)) {
1080  // interrupted by signal
1081  down(&master->master_sem);
1082  if (request.state == EC_INT_REQUEST_QUEUED) {
1083  // abort request
1084  list_del(&request.list);
1085  up(&master->master_sem);
1086  ec_reg_request_clear(&request);
1087  return -EINTR;
1088  }
1089  up(&master->master_sem);
1090  }
1091 
1092  // wait until master FSM has finished processing
1093  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1094 
1095  if (request.state == EC_INT_REQUEST_SUCCESS) {
1096  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1097  return -EFAULT;
1098  }
1099  }
1100  ec_reg_request_clear(&request);
1101 
1102  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1103 }
1104 
1105 /*****************************************************************************/
1106 
1112  ec_master_t *master,
1113  void *arg
1114  )
1115 {
1116  ec_ioctl_slave_reg_t io;
1117  ec_slave_t *slave;
1118  ec_reg_request_t request;
1119  int ret;
1120 
1121  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1122  return -EFAULT;
1123  }
1124 
1125  if (!io.size) {
1126  return 0;
1127  }
1128 
1129  // init register request
1130  ret = ec_reg_request_init(&request, io.size);
1131  if (ret) {
1132  return ret;
1133  }
1134 
1135  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1136  ec_reg_request_clear(&request);
1137  return -EFAULT;
1138  }
1139 
1140  ecrt_reg_request_write(&request, io.address, io.size);
1141 
1142  if (down_interruptible(&master->master_sem)) {
1143  ec_reg_request_clear(&request);
1144  return -EINTR;
1145  }
1146 
1147  if (io.emergency) {
1148  request.ring_position = io.slave_position;
1149  // schedule request.
1150  list_add_tail(&request.list, &master->emerg_reg_requests);
1151  }
1152  else {
1153  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1154  up(&master->master_sem);
1155  ec_reg_request_clear(&request);
1156  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1157  io.slave_position);
1158  return -EINVAL;
1159  }
1160 
1161  // schedule request.
1162  list_add_tail(&request.list, &slave->reg_requests);
1163  }
1164 
1165  up(&master->master_sem);
1166 
1167  // wait for processing through FSM
1168  if (wait_event_interruptible(master->request_queue,
1169  request.state != EC_INT_REQUEST_QUEUED)) {
1170  // interrupted by signal
1171  down(&master->master_sem);
1172  if (request.state == EC_INT_REQUEST_QUEUED) {
1173  // abort request
1174  list_del(&request.list);
1175  up(&master->master_sem);
1176  ec_reg_request_clear(&request);
1177  return -EINTR;
1178  }
1179  up(&master->master_sem);
1180  }
1181 
1182  // wait until master FSM has finished processing
1183  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1184 
1185  ec_reg_request_clear(&request);
1186 
1187  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1188 }
1189 
1190 /*****************************************************************************/
1191 
1197  ec_master_t *master,
1198  void *arg
1199  )
1200 {
1201  ec_ioctl_config_t data;
1202  const ec_slave_config_t *sc;
1203  uint8_t i;
1204 
1205  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1206  return -EFAULT;
1207  }
1208 
1209  if (down_interruptible(&master->master_sem))
1210  return -EINTR;
1211 
1212  if (!(sc = ec_master_get_config_const(
1213  master, data.config_index))) {
1214  up(&master->master_sem);
1215  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1216  data.config_index);
1217  return -EINVAL;
1218  }
1219 
1220  data.alias = sc->alias;
1221  data.position = sc->position;
1222  data.vendor_id = sc->vendor_id;
1223  data.product_code = sc->product_code;
1224  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1225  data.syncs[i].dir = sc->sync_configs[i].dir;
1226  data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1227  data.syncs[i].pdo_count =
1229  }
1230  data.watchdog_divider = sc->watchdog_divider;
1231  data.watchdog_intervals = sc->watchdog_intervals;
1232  data.sdo_count = ec_slave_config_sdo_count(sc);
1233  data.idn_count = ec_slave_config_idn_count(sc);
1234  data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1235  data.dc_assign_activate = sc->dc_assign_activate;
1236  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1237  data.dc_sync[i] = sc->dc_sync[i];
1238  }
1239 
1240  up(&master->master_sem);
1241 
1242  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1243  return -EFAULT;
1244 
1245  return 0;
1246 }
1247 
1248 /*****************************************************************************/
1249 
1255  ec_master_t *master,
1256  void *arg
1257  )
1258 {
1259  ec_ioctl_config_pdo_t data;
1260  const ec_slave_config_t *sc;
1261  const ec_pdo_t *pdo;
1262 
1263  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1264  return -EFAULT;
1265  }
1266 
1267  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1268  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1269  data.sync_index);
1270  return -EINVAL;
1271  }
1272 
1273  if (down_interruptible(&master->master_sem))
1274  return -EINTR;
1275 
1276  if (!(sc = ec_master_get_config_const(
1277  master, data.config_index))) {
1278  up(&master->master_sem);
1279  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1280  data.config_index);
1281  return -EINVAL;
1282  }
1283 
1285  &sc->sync_configs[data.sync_index].pdos,
1286  data.pdo_pos))) {
1287  up(&master->master_sem);
1288  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1289  return -EINVAL;
1290  }
1291 
1292  data.index = pdo->index;
1293  data.entry_count = ec_pdo_entry_count(pdo);
1294  ec_ioctl_strcpy(data.name, pdo->name);
1295 
1296  up(&master->master_sem);
1297 
1298  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1299  return -EFAULT;
1300 
1301  return 0;
1302 }
1303 
1304 /*****************************************************************************/
1305 
1311  ec_master_t *master,
1312  void *arg
1313  )
1314 {
1315  ec_ioctl_config_pdo_entry_t data;
1316  const ec_slave_config_t *sc;
1317  const ec_pdo_t *pdo;
1318  const ec_pdo_entry_t *entry;
1319 
1320  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1321  return -EFAULT;
1322  }
1323 
1324  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1325  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1326  data.sync_index);
1327  return -EINVAL;
1328  }
1329 
1330  if (down_interruptible(&master->master_sem))
1331  return -EINTR;
1332 
1333  if (!(sc = ec_master_get_config_const(
1334  master, data.config_index))) {
1335  up(&master->master_sem);
1336  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1337  data.config_index);
1338  return -EINVAL;
1339  }
1340 
1342  &sc->sync_configs[data.sync_index].pdos,
1343  data.pdo_pos))) {
1344  up(&master->master_sem);
1345  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1346  return -EINVAL;
1347  }
1348 
1349  if (!(entry = ec_pdo_find_entry_by_pos_const(
1350  pdo, data.entry_pos))) {
1351  up(&master->master_sem);
1352  EC_MASTER_ERR(master, "Entry not found!\n");
1353  return -EINVAL;
1354  }
1355 
1356  data.index = entry->index;
1357  data.subindex = entry->subindex;
1358  data.bit_length = entry->bit_length;
1359  ec_ioctl_strcpy(data.name, entry->name);
1360 
1361  up(&master->master_sem);
1362 
1363  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1364  return -EFAULT;
1365 
1366  return 0;
1367 }
1368 
1369 /*****************************************************************************/
1370 
1376  ec_master_t *master,
1377  void *arg
1378  )
1379 {
1380  ec_ioctl_config_sdo_t *ioctl;
1381  const ec_slave_config_t *sc;
1382  const ec_sdo_request_t *req;
1383 
1384  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1385  return -ENOMEM;
1386  }
1387 
1388  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1389  kfree(ioctl);
1390  return -EFAULT;
1391  }
1392 
1393  if (down_interruptible(&master->master_sem)) {
1394  kfree(ioctl);
1395  return -EINTR;
1396  }
1397 
1398  if (!(sc = ec_master_get_config_const(
1399  master, ioctl->config_index))) {
1400  up(&master->master_sem);
1401  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1402  ioctl->config_index);
1403  kfree(ioctl);
1404  return -EINVAL;
1405  }
1406 
1408  sc, ioctl->sdo_pos))) {
1409  up(&master->master_sem);
1410  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1411  kfree(ioctl);
1412  return -EINVAL;
1413  }
1414 
1415  ioctl->index = req->index;
1416  ioctl->subindex = req->subindex;
1417  ioctl->size = req->data_size;
1418  memcpy(ioctl->data, req->data,
1419  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1420  ioctl->complete_access = req->complete_access;
1421 
1422  up(&master->master_sem);
1423 
1424  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1425  kfree(ioctl);
1426  return -EFAULT;
1427  }
1428 
1429  kfree(ioctl);
1430  return 0;
1431 }
1432 
1433 /*****************************************************************************/
1434 
1440  ec_master_t *master,
1441  void *arg
1442  )
1443 {
1444  ec_ioctl_config_idn_t *ioctl;
1445  const ec_slave_config_t *sc;
1446  const ec_soe_request_t *req;
1447 
1448  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1449  return -ENOMEM;
1450  }
1451 
1452  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1453  kfree(ioctl);
1454  return -EFAULT;
1455  }
1456 
1457  if (down_interruptible(&master->master_sem)) {
1458  kfree(ioctl);
1459  return -EINTR;
1460  }
1461 
1462  if (!(sc = ec_master_get_config_const(
1463  master, ioctl->config_index))) {
1464  up(&master->master_sem);
1465  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1466  ioctl->config_index);
1467  kfree(ioctl);
1468  return -EINVAL;
1469  }
1470 
1472  sc, ioctl->idn_pos))) {
1473  up(&master->master_sem);
1474  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1475  kfree(ioctl);
1476  return -EINVAL;
1477  }
1478 
1479  ioctl->drive_no = req->drive_no;
1480  ioctl->idn = req->idn;
1481  ioctl->state = req->state;
1482  ioctl->size = req->data_size;
1483  memcpy(ioctl->data, req->data,
1484  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1485 
1486  up(&master->master_sem);
1487 
1488  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1489  kfree(ioctl);
1490  return -EFAULT;
1491  }
1492 
1493  kfree(ioctl);
1494  return 0;
1495 }
1496 
1497 /*****************************************************************************/
1498 
1499 #ifdef EC_EOE
1500 
1506  ec_master_t *master,
1507  void *arg
1508  )
1509 {
1510  ec_ioctl_eoe_handler_t data;
1511  const ec_eoe_t *eoe;
1512 
1513  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1514  return -EFAULT;
1515  }
1516 
1517  if (down_interruptible(&master->master_sem))
1518  return -EINTR;
1519 
1520  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1521  up(&master->master_sem);
1522  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1523  data.eoe_index);
1524  return -EINVAL;
1525  }
1526 
1527  if (eoe->slave) {
1528  data.slave_position = eoe->slave->ring_position;
1529  } else {
1530  data.slave_position = 0xffff;
1531  }
1532  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1533  data.open = eoe->opened;
1534  data.rx_bytes = eoe->stats.tx_bytes;
1535  data.rx_rate = eoe->tx_rate;
1536  data.tx_bytes = eoe->stats.rx_bytes;
1537  data.tx_rate = eoe->tx_rate;
1538  data.tx_queued_frames = eoe->tx_queued_frames;
1539  data.tx_queue_size = eoe->tx_queue_size;
1540 
1541  up(&master->master_sem);
1542 
1543  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1544  return -EFAULT;
1545 
1546  return 0;
1547 }
1548 
1549 #endif
1550 
1551 /*****************************************************************************/
1552 
1558  ec_master_t *master,
1559  void *arg,
1560  ec_ioctl_context_t *ctx
1561  )
1562 {
1563  ec_master_t *m;
1564  int ret = 0;
1565 
1566  m = ecrt_request_master_err(master->index);
1567  if (IS_ERR(m)) {
1568  ret = PTR_ERR(m);
1569  } else {
1570  ctx->requested = 1;
1571  }
1572 
1573  return ret;
1574 }
1575 
1576 /*****************************************************************************/
1577 
1583  ec_master_t *master,
1584  void *arg,
1585  ec_ioctl_context_t *ctx
1586  )
1587 {
1588  ec_domain_t *domain;
1589 
1590  if (unlikely(!ctx->requested))
1591  return -EPERM;
1592 
1593  domain = ecrt_master_create_domain_err(master);
1594  if (IS_ERR(domain))
1595  return PTR_ERR(domain);
1596 
1597  return domain->index;
1598 }
1599 
1600 /*****************************************************************************/
1601 
1607  ec_master_t *master,
1608  void *arg,
1609  ec_ioctl_context_t *ctx
1610  )
1611 {
1612  ec_ioctl_config_t data;
1613  ec_slave_config_t *sc, *entry;
1614 
1615  if (unlikely(!ctx->requested))
1616  return -EPERM;
1617 
1618  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1619  return -EFAULT;
1620  }
1621 
1622  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1623  data.vendor_id, data.product_code);
1624  if (IS_ERR(sc))
1625  return PTR_ERR(sc);
1626 
1627  data.config_index = 0;
1628 
1629  if (down_interruptible(&master->master_sem))
1630  return -EINTR;
1631 
1632  list_for_each_entry(entry, &master->configs, list) {
1633  if (entry == sc)
1634  break;
1635  data.config_index++;
1636  }
1637 
1638  up(&master->master_sem);
1639 
1640  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1641  return -EFAULT;
1642 
1643  return 0;
1644 }
1645 
1646 /*****************************************************************************/
1647 
1653  ec_master_t *master,
1654  void *arg,
1655  ec_ioctl_context_t *ctx
1656  )
1657 {
1658  unsigned long config_index = (unsigned long) arg;
1659  ec_slave_config_t *sc = NULL;
1660  int ret = 0;
1661 
1662  if (unlikely(!ctx->requested)) {
1663  ret = -EPERM;
1664  goto out_return;
1665  }
1666 
1667  if (down_interruptible(&master->master_sem)) {
1668  ret = -EINTR;
1669  goto out_return;
1670  }
1671 
1672  if (config_index != 0xFFFFFFFF) {
1673  if (!(sc = ec_master_get_config(master, config_index))) {
1674  ret = -ENOENT;
1675  goto out_up;
1676  }
1677  }
1678 
1680 
1681 out_up:
1682  up(&master->master_sem);
1683 out_return:
1684  return ret;
1685 }
1686 
1687 /*****************************************************************************/
1688 
1694  ec_master_t *master,
1695  void *arg,
1696  ec_ioctl_context_t *ctx
1697  )
1698 {
1699  ec_ioctl_master_activate_t io;
1700  ec_domain_t *domain;
1701  off_t offset;
1702  int ret;
1703 
1704  if (unlikely(!ctx->requested))
1705  return -EPERM;
1706 
1707  io.process_data = NULL;
1708 
1709  /* Get the sum of the domains' process data sizes. */
1710 
1711  ctx->process_data_size = 0;
1712 
1713  if (down_interruptible(&master->master_sem))
1714  return -EINTR;
1715 
1716  list_for_each_entry(domain, &master->domains, list) {
1717  ctx->process_data_size += ecrt_domain_size(domain);
1718  }
1719 
1720  up(&master->master_sem);
1721 
1722  if (ctx->process_data_size) {
1723  ctx->process_data = vmalloc(ctx->process_data_size);
1724  if (!ctx->process_data) {
1725  ctx->process_data_size = 0;
1726  return -ENOMEM;
1727  }
1728 
1729  /* Set the memory as external process data memory for the
1730  * domains.
1731  */
1732  offset = 0;
1733  list_for_each_entry(domain, &master->domains, list) {
1735  ctx->process_data + offset);
1736  offset += ecrt_domain_size(domain);
1737  }
1738 
1739 #ifdef EC_IOCTL_RTDM
1740  /* RTDM uses a different approach for memory-mapping, which has to be
1741  * initiated by the kernel.
1742  */
1743  ret = ec_rtdm_mmap(ctx, &io.process_data);
1744  if (ret < 0) {
1745  EC_MASTER_ERR(master, "Failed to map process data"
1746  " memory to user space (code %i).\n", ret);
1747  return ret;
1748  }
1749 #endif
1750  }
1751 
1752  io.process_data_size = ctx->process_data_size;
1753 
1754 #ifndef EC_IOCTL_RTDM
1757 #endif
1758 
1759  ret = ecrt_master_activate(master);
1760  if (ret < 0)
1761  return ret;
1762 
1763  if (copy_to_user((void __user *) arg, &io,
1764  sizeof(ec_ioctl_master_activate_t)))
1765  return -EFAULT;
1766 
1767  return 0;
1768 }
1769 
1770 /*****************************************************************************/
1771 
1777  ec_master_t *master,
1778  void *arg,
1779  ec_ioctl_context_t *ctx
1780  )
1781 {
1782  if (unlikely(!ctx->requested))
1783  return -EPERM;
1784 
1785  ecrt_master_deactivate(master);
1786  return 0;
1787 }
1788 
1789 /*****************************************************************************/
1790 
1796  ec_master_t *master,
1797  void *arg,
1798  ec_ioctl_context_t *ctx
1799  )
1800 {
1801  size_t send_interval;
1802 
1803  if (unlikely(!ctx->requested)) {
1804  return -EPERM;
1805  }
1806 
1807  if (copy_from_user(&send_interval, (void __user *) arg,
1808  sizeof(send_interval))) {
1809  return -EFAULT;
1810  }
1811 
1812  if (down_interruptible(&master->master_sem))
1813  return -EINTR;
1814 
1815  ec_master_set_send_interval(master, send_interval);
1816 
1817  up(&master->master_sem);
1818  return 0;
1819 }
1820 
1821 /*****************************************************************************/
1822 
1828  ec_master_t *master,
1829  void *arg,
1830  ec_ioctl_context_t *ctx
1831  )
1832 {
1833  if (unlikely(!ctx->requested)) {
1834  return -EPERM;
1835  }
1836 
1837  ecrt_master_send(master);
1838  return 0;
1839 }
1840 
1841 /*****************************************************************************/
1842 
1848  ec_master_t *master,
1849  void *arg,
1850  ec_ioctl_context_t *ctx
1851  )
1852 {
1853  if (unlikely(!ctx->requested)) {
1854  return -EPERM;
1855  }
1856 
1857  ecrt_master_receive(master);
1858  return 0;
1859 }
1860 
1861 /*****************************************************************************/
1862 
1868  ec_master_t *master,
1869  void *arg,
1870  ec_ioctl_context_t *ctx
1871  )
1872 {
1873  ec_master_state_t data;
1874 
1875  ecrt_master_state(master, &data);
1876 
1877  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1878  return -EFAULT;
1879 
1880  return 0;
1881 }
1882 
1883 /*****************************************************************************/
1884 
1890  ec_master_t *master,
1891  void *arg,
1892  ec_ioctl_context_t *ctx
1893  )
1894 {
1895  ec_ioctl_link_state_t ioctl;
1896  ec_master_link_state_t state;
1897  int ret;
1898 
1899  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
1900  return -EFAULT;
1901  }
1902 
1903  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
1904  if (ret < 0) {
1905  return ret;
1906  }
1907 
1908  if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
1909  return -EFAULT;
1910  }
1911 
1912  return 0;
1913 }
1914 
1915 /*****************************************************************************/
1916 
1922  ec_master_t *master,
1923  void *arg,
1924  ec_ioctl_context_t *ctx
1925  )
1926 {
1927  ec_ioctl_app_time_t data;
1928 
1929  if (unlikely(!ctx->requested))
1930  return -EPERM;
1931 
1932  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1933  return -EFAULT;
1934  }
1935 
1936  ecrt_master_application_time(master, data.app_time);
1937  return 0;
1938 }
1939 
1940 /*****************************************************************************/
1941 
1947  ec_master_t *master,
1948  void *arg,
1949  ec_ioctl_context_t *ctx
1950  )
1951 {
1952  if (unlikely(!ctx->requested)) {
1953  return -EPERM;
1954  }
1955 
1957  return 0;
1958 }
1959 
1960 /*****************************************************************************/
1961 
1967  ec_master_t *master,
1968  void *arg,
1969  ec_ioctl_context_t *ctx
1970  )
1971 {
1972  if (unlikely(!ctx->requested)) {
1973  return -EPERM;
1974  }
1975 
1977  return 0;
1978 }
1979 
1980 /*****************************************************************************/
1981 
1987  ec_master_t *master,
1988  void *arg,
1989  ec_ioctl_context_t *ctx
1990  )
1991 {
1992  uint32_t time;
1993  int ret;
1994 
1995  if (unlikely(!ctx->requested)) {
1996  return -EPERM;
1997  }
1998 
1999  ret = ecrt_master_reference_clock_time(master, &time);
2000  if (ret) {
2001  return ret;
2002  }
2003 
2004  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2005  return -EFAULT;
2006  }
2007 
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 
2028  return 0;
2029 }
2030 
2031 /*****************************************************************************/
2032 
2038  ec_master_t *master,
2039  void *arg,
2040  ec_ioctl_context_t *ctx
2041  )
2042 {
2043  uint32_t time_diff;
2044 
2045  if (unlikely(!ctx->requested))
2046  return -EPERM;
2047 
2048  time_diff = ecrt_master_sync_monitor_process(master);
2049 
2050  if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2051  return -EFAULT;
2052 
2053  return 0;
2054 }
2055 
2056 /*****************************************************************************/
2057 
2063  ec_master_t *master,
2064  void *arg,
2065  ec_ioctl_context_t *ctx
2066  )
2067 {
2068  down(&master->master_sem);
2069  ecrt_master_reset(master);
2070  up(&master->master_sem);
2071  return 0;
2072 }
2073 
2074 /*****************************************************************************/
2075 
2081  ec_master_t *master,
2082  void *arg,
2083  ec_ioctl_context_t *ctx
2084  )
2085 {
2086  ec_ioctl_config_t data;
2087  ec_slave_config_t *sc;
2088  unsigned int i;
2089  int ret = 0;
2090 
2091  if (unlikely(!ctx->requested)) {
2092  ret = -EPERM;
2093  goto out_return;
2094  }
2095 
2096  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2097  ret = -EFAULT;
2098  goto out_return;
2099  }
2100 
2101  if (down_interruptible(&master->master_sem)) {
2102  ret = -EINTR;
2103  goto out_return;
2104  }
2105 
2106  if (!(sc = ec_master_get_config(master, data.config_index))) {
2107  ret = -ENOENT;
2108  goto out_up;
2109  }
2110 
2111  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2112  if (data.syncs[i].config_this) {
2113  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2114  data.syncs[i].watchdog_mode);
2115  if (ret) {
2116  goto out_up;
2117  }
2118  }
2119  }
2120 
2121 out_up:
2122  up(&master->master_sem);
2123 out_return:
2124  return ret;
2125 }
2126 
2127 /*****************************************************************************/
2128 
2134  ec_master_t *master,
2135  void *arg,
2136  ec_ioctl_context_t *ctx
2137  )
2138 {
2139  ec_ioctl_config_t data;
2140  ec_slave_config_t *sc;
2141  int ret = 0;
2142 
2143  if (unlikely(!ctx->requested)) {
2144  ret = -EPERM;
2145  goto out_return;
2146  }
2147 
2148  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2149  ret = -EFAULT;
2150  goto out_return;
2151  }
2152 
2153  if (down_interruptible(&master->master_sem)) {
2154  ret = -EINTR;
2155  goto out_return;
2156  }
2157 
2158  if (!(sc = ec_master_get_config(master, data.config_index))) {
2159  ret = -ENOENT;
2160  goto out_up;
2161  }
2162 
2164  data.watchdog_divider, data.watchdog_intervals);
2165 
2166 out_up:
2167  up(&master->master_sem);
2168 out_return:
2169  return ret;
2170 }
2171 
2172 /*****************************************************************************/
2173 
2179  ec_master_t *master,
2180  void *arg,
2181  ec_ioctl_context_t *ctx
2182  )
2183 {
2184  ec_ioctl_config_pdo_t data;
2185  ec_slave_config_t *sc;
2186 
2187  if (unlikely(!ctx->requested))
2188  return -EPERM;
2189 
2190  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2191  return -EFAULT;
2192 
2193  if (down_interruptible(&master->master_sem))
2194  return -EINTR;
2195 
2196  if (!(sc = ec_master_get_config(master, data.config_index))) {
2197  up(&master->master_sem);
2198  return -ENOENT;
2199  }
2200 
2201  up(&master->master_sem);
2203  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2204 }
2205 
2206 /*****************************************************************************/
2207 
2213  ec_master_t *master,
2214  void *arg,
2215  ec_ioctl_context_t *ctx
2216  )
2217 {
2218  ec_ioctl_config_pdo_t data;
2219  ec_slave_config_t *sc;
2220 
2221  if (unlikely(!ctx->requested))
2222  return -EPERM;
2223 
2224  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2225  return -EFAULT;
2226 
2227  if (down_interruptible(&master->master_sem))
2228  return -EINTR;
2229 
2230  if (!(sc = ec_master_get_config(master, data.config_index))) {
2231  up(&master->master_sem);
2232  return -ENOENT;
2233  }
2234 
2235  up(&master->master_sem);
2237  ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2238  return 0;
2239 }
2240 
2241 /*****************************************************************************/
2242 
2248  ec_master_t *master,
2249  void *arg,
2250  ec_ioctl_context_t *ctx
2251  )
2252 {
2253  ec_ioctl_add_pdo_entry_t data;
2254  ec_slave_config_t *sc;
2255 
2256  if (unlikely(!ctx->requested))
2257  return -EPERM;
2258 
2259  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2260  return -EFAULT;
2261 
2262  if (down_interruptible(&master->master_sem))
2263  return -EINTR;
2264 
2265  if (!(sc = ec_master_get_config(master, data.config_index))) {
2266  up(&master->master_sem);
2267  return -ENOENT;
2268  }
2269 
2270  up(&master->master_sem);
2272  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2273  data.entry_index, data.entry_subindex, data.entry_bit_length);
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  ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2308  return 0;
2309 }
2310 
2311 /*****************************************************************************/
2312 
2318  ec_master_t *master,
2319  void *arg,
2320  ec_ioctl_context_t *ctx
2321  )
2322 {
2323  ec_ioctl_reg_pdo_entry_t data;
2324  ec_slave_config_t *sc;
2325  ec_domain_t *domain;
2326  int ret;
2327 
2328  if (unlikely(!ctx->requested))
2329  return -EPERM;
2330 
2331  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2332  return -EFAULT;
2333 
2334  if (down_interruptible(&master->master_sem))
2335  return -EINTR;
2336 
2337  if (!(sc = ec_master_get_config(master, data.config_index))) {
2338  up(&master->master_sem);
2339  return -ENOENT;
2340  }
2341 
2342  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2343  up(&master->master_sem);
2344  return -ENOENT;
2345  }
2346 
2347  up(&master->master_sem);
2349  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2350  data.entry_subindex, domain, &data.bit_position);
2351 
2352  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2353  return -EFAULT;
2354 
2355  return ret;
2356 }
2357 
2358 /*****************************************************************************/
2359 
2365  ec_master_t *master,
2366  void *arg,
2367  ec_ioctl_context_t *ctx
2368  )
2369 {
2370  ec_ioctl_reg_pdo_pos_t io;
2371  ec_slave_config_t *sc;
2372  ec_domain_t *domain;
2373  int ret;
2374 
2375  if (unlikely(!ctx->requested)) {
2376  return -EPERM;
2377  }
2378 
2379  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2380  return -EFAULT;
2381  }
2382 
2383  if (down_interruptible(&master->master_sem)) {
2384  return -EINTR;
2385  }
2386 
2387  if (!(sc = ec_master_get_config(master, io.config_index))) {
2388  up(&master->master_sem);
2389  return -ENOENT;
2390  }
2391 
2392  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2393  up(&master->master_sem);
2394  return -ENOENT;
2395  }
2396 
2397  up(&master->master_sem);
2399  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2400  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2401 
2402  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2403  return -EFAULT;
2404 
2405  return ret;
2406 }
2407 
2408 /*****************************************************************************/
2409 
2415  ec_master_t *master,
2416  void *arg,
2417  ec_ioctl_context_t *ctx
2418  )
2419 {
2420  ec_ioctl_config_t data;
2421  ec_slave_config_t *sc;
2422 
2423  if (unlikely(!ctx->requested))
2424  return -EPERM;
2425 
2426  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2427  return -EFAULT;
2428 
2429  if (down_interruptible(&master->master_sem))
2430  return -EINTR;
2431 
2432  if (!(sc = ec_master_get_config(master, data.config_index))) {
2433  up(&master->master_sem);
2434  return -ENOENT;
2435  }
2436 
2438  data.dc_sync[0].cycle_time,
2439  data.dc_sync[0].shift_time,
2440  data.dc_sync[1].cycle_time,
2441  data.dc_sync[1].shift_time);
2442 
2443  up(&master->master_sem);
2444 
2445  return 0;
2446 }
2447 
2448 /*****************************************************************************/
2449 
2455  ec_master_t *master,
2456  void *arg,
2457  ec_ioctl_context_t *ctx
2458  )
2459 {
2460  ec_ioctl_sc_sdo_t data;
2461  ec_slave_config_t *sc;
2462  uint8_t *sdo_data = NULL;
2463  int ret;
2464 
2465  if (unlikely(!ctx->requested))
2466  return -EPERM;
2467 
2468  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2469  return -EFAULT;
2470 
2471  if (!data.size)
2472  return -EINVAL;
2473 
2474  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2475  return -ENOMEM;
2476  }
2477 
2478  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2479  kfree(sdo_data);
2480  return -EFAULT;
2481  }
2482 
2483  if (down_interruptible(&master->master_sem)) {
2484  kfree(sdo_data);
2485  return -EINTR;
2486  }
2487 
2488  if (!(sc = ec_master_get_config(master, data.config_index))) {
2489  up(&master->master_sem);
2490  kfree(sdo_data);
2491  return -ENOENT;
2492  }
2493 
2494  up(&master->master_sem);
2496  if (data.complete_access) {
2498  data.index, sdo_data, data.size);
2499  } else {
2500  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2501  data.size);
2502  }
2503  kfree(sdo_data);
2504  return ret;
2505 }
2506 
2507 /*****************************************************************************/
2508 
2514  ec_master_t *master,
2515  void *arg,
2516  ec_ioctl_context_t *ctx
2517  )
2518 {
2519  ec_ioctl_sc_emerg_t io;
2520  ec_slave_config_t *sc;
2521  int ret;
2522 
2523  if (unlikely(!ctx->requested))
2524  return -EPERM;
2525 
2526  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2527  return -EFAULT;
2528 
2529  if (down_interruptible(&master->master_sem)) {
2530  return -EINTR;
2531  }
2532 
2533  if (!(sc = ec_master_get_config(master, io.config_index))) {
2534  up(&master->master_sem);
2535  return -ENOENT;
2536  }
2537 
2538  ret = ecrt_slave_config_emerg_size(sc, io.size);
2539 
2540  up(&master->master_sem);
2541 
2542  return ret;
2543 }
2544 
2545 /*****************************************************************************/
2546 
2552  ec_master_t *master,
2553  void *arg,
2554  ec_ioctl_context_t *ctx
2555  )
2556 {
2557  ec_ioctl_sc_emerg_t io;
2558  ec_slave_config_t *sc;
2559  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
2560  int ret;
2561 
2562  if (unlikely(!ctx->requested)) {
2563  return -EPERM;
2564  }
2565 
2566  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2567  return -EFAULT;
2568  }
2569 
2570  /* no locking of master_sem needed, because configuration will not be
2571  * deleted in the meantime. */
2572 
2573  if (!(sc = ec_master_get_config(master, io.config_index))) {
2574  return -ENOENT;
2575  }
2576 
2577  ret = ecrt_slave_config_emerg_pop(sc, msg);
2578  if (ret < 0) {
2579  return ret;
2580  }
2581 
2582  if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
2583  return -EFAULT;
2584  }
2585 
2586  return ret;
2587 }
2588 
2589 /*****************************************************************************/
2590 
2596  ec_master_t *master,
2597  void *arg,
2598  ec_ioctl_context_t *ctx
2599  )
2600 {
2601  ec_ioctl_sc_emerg_t io;
2602  ec_slave_config_t *sc;
2603 
2604  if (unlikely(!ctx->requested)) {
2605  return -EPERM;
2606  }
2607 
2608  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2609  return -EFAULT;
2610  }
2611 
2612  /* no locking of master_sem needed, because configuration will not be
2613  * deleted in the meantime. */
2614 
2615  if (!(sc = ec_master_get_config(master, io.config_index))) {
2616  return -ENOENT;
2617  }
2618 
2619  return ecrt_slave_config_emerg_clear(sc);
2620 }
2621 
2622 /*****************************************************************************/
2623 
2629  ec_master_t *master,
2630  void *arg,
2631  ec_ioctl_context_t *ctx
2632  )
2633 {
2634  ec_ioctl_sc_emerg_t io;
2635  ec_slave_config_t *sc;
2636  int ret;
2637 
2638  if (unlikely(!ctx->requested)) {
2639  return -EPERM;
2640  }
2641 
2642  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2643  return -EFAULT;
2644  }
2645 
2646  /* no locking of master_sem needed, because configuration will not be
2647  * deleted in the meantime. */
2648 
2649  if (!(sc = ec_master_get_config(master, io.config_index))) {
2650  return -ENOENT;
2651  }
2652 
2654  if (ret < 0) {
2655  return ret;
2656  }
2657 
2658  io.overruns = ret;
2659 
2660  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2661  return -EFAULT;
2662  }
2663 
2664  return 0;
2665 }
2666 
2667 /*****************************************************************************/
2668 
2674  ec_master_t *master,
2675  void *arg,
2676  ec_ioctl_context_t *ctx
2677  )
2678 {
2679  ec_ioctl_sdo_request_t data;
2680  ec_slave_config_t *sc;
2681  ec_sdo_request_t *req;
2682 
2683  if (unlikely(!ctx->requested))
2684  return -EPERM;
2685 
2686  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2687  return -EFAULT;
2688  }
2689 
2690  data.request_index = 0;
2691 
2692  if (down_interruptible(&master->master_sem))
2693  return -EINTR;
2694 
2695  sc = ec_master_get_config(master, data.config_index);
2696  if (!sc) {
2697  up(&master->master_sem);
2698  return -ENOENT;
2699  }
2700 
2701  list_for_each_entry(req, &sc->sdo_requests, list) {
2702  data.request_index++;
2703  }
2704 
2705  up(&master->master_sem);
2707  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
2708  data.sdo_subindex, data.size);
2709  if (IS_ERR(req))
2710  return PTR_ERR(req);
2711 
2712  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2713  return -EFAULT;
2714 
2715  return 0;
2716 }
2717 
2718 /*****************************************************************************/
2719 
2725  ec_master_t *master,
2726  void *arg,
2727  ec_ioctl_context_t *ctx
2728  )
2729 {
2730  ec_ioctl_reg_request_t io;
2731  ec_slave_config_t *sc;
2732  ec_reg_request_t *reg;
2733 
2734  if (unlikely(!ctx->requested)) {
2735  return -EPERM;
2736  }
2737 
2738  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2739  return -EFAULT;
2740  }
2741 
2742  io.request_index = 0;
2743 
2744  if (down_interruptible(&master->master_sem)) {
2745  return -EINTR;
2746  }
2747 
2748  sc = ec_master_get_config(master, io.config_index);
2749  if (!sc) {
2750  up(&master->master_sem);
2751  return -ENOENT;
2752  }
2753 
2754  list_for_each_entry(reg, &sc->reg_requests, list) {
2755  io.request_index++;
2756  }
2757 
2758  up(&master->master_sem);
2760  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
2761  if (IS_ERR(reg)) {
2762  return PTR_ERR(reg);
2763  }
2764 
2765  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2766  return -EFAULT;
2767  }
2768 
2769  return 0;
2770 }
2771 
2772 /*****************************************************************************/
2773 
2779  ec_master_t *master,
2780  void *arg,
2781  ec_ioctl_context_t *ctx
2782  )
2783 {
2784  ec_ioctl_voe_t data;
2785  ec_slave_config_t *sc;
2786  ec_voe_handler_t *voe;
2787 
2788  if (unlikely(!ctx->requested))
2789  return -EPERM;
2790 
2791  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2792  return -EFAULT;
2793  }
2794 
2795  data.voe_index = 0;
2796 
2797  if (down_interruptible(&master->master_sem))
2798  return -EINTR;
2799 
2800  sc = ec_master_get_config(master, data.config_index);
2801  if (!sc) {
2802  up(&master->master_sem);
2803  return -ENOENT;
2804  }
2805 
2806  list_for_each_entry(voe, &sc->voe_handlers, list) {
2807  data.voe_index++;
2808  }
2809 
2810  up(&master->master_sem);
2812  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
2813  if (IS_ERR(voe))
2814  return PTR_ERR(voe);
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_sc_state_t data;
2835  const ec_slave_config_t *sc;
2837 
2838  if (unlikely(!ctx->requested))
2839  return -EPERM;
2840 
2841  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2842  return -EFAULT;
2843  }
2844 
2845  /* no locking of master_sem needed, because sc will not be deleted in the
2846  * meantime. */
2847 
2848  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
2849  return -ENOENT;
2850  }
2851 
2852  ecrt_slave_config_state(sc, &state);
2853 
2854  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
2855  return -EFAULT;
2856 
2857  return 0;
2858 }
2859 
2860 /*****************************************************************************/
2861 
2867  ec_master_t *master,
2868  void *arg,
2869  ec_ioctl_context_t *ctx
2870  )
2871 {
2872  ec_ioctl_sc_idn_t ioctl;
2873  ec_slave_config_t *sc;
2874  uint8_t *data = NULL;
2875  int ret;
2876 
2877  if (unlikely(!ctx->requested))
2878  return -EPERM;
2879 
2880  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
2881  return -EFAULT;
2882 
2883  if (!ioctl.size)
2884  return -EINVAL;
2885 
2886  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
2887  return -ENOMEM;
2888  }
2889 
2890  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
2891  kfree(data);
2892  return -EFAULT;
2893  }
2894 
2895  if (down_interruptible(&master->master_sem)) {
2896  kfree(data);
2897  return -EINTR;
2898  }
2899 
2900  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
2901  up(&master->master_sem);
2902  kfree(data);
2903  return -ENOENT;
2904  }
2905 
2906  up(&master->master_sem);
2908  ret = ecrt_slave_config_idn(
2909  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
2910  kfree(data);
2911  return ret;
2912 }
2913 
2914 /*****************************************************************************/
2915 
2921  ec_master_t *master,
2922  void *arg,
2923  ec_ioctl_context_t *ctx
2924  )
2925 {
2926  const ec_domain_t *domain;
2927 
2928  if (unlikely(!ctx->requested)) {
2929  return -EPERM;
2930  }
2931 
2932  if (down_interruptible(&master->master_sem)) {
2933  return -EINTR;
2934  }
2935 
2936  list_for_each_entry(domain, &master->domains, list) {
2937  if (domain->index == (unsigned long) arg) {
2938  size_t size = ecrt_domain_size(domain);
2939  up(&master->master_sem);
2940  return size;
2941  }
2942  }
2943 
2944  up(&master->master_sem);
2945  return -ENOENT;
2946 }
2947 
2948 /*****************************************************************************/
2949 
2955  ec_master_t *master,
2956  void *arg,
2957  ec_ioctl_context_t *ctx
2958  )
2959 {
2960  int offset = 0;
2961  const ec_domain_t *domain;
2962 
2963  if (unlikely(!ctx->requested))
2964  return -EPERM;
2965 
2966  if (down_interruptible(&master->master_sem)) {
2967  return -EINTR;
2968  }
2969 
2970  list_for_each_entry(domain, &master->domains, list) {
2971  if (domain->index == (unsigned long) arg) {
2972  up(&master->master_sem);
2973  return offset;
2974  }
2975  offset += ecrt_domain_size(domain);
2976  }
2977 
2978  up(&master->master_sem);
2979  return -ENOENT;
2980 }
2981 
2982 /*****************************************************************************/
2983 
2989  ec_master_t *master,
2990  void *arg,
2991  ec_ioctl_context_t *ctx
2992  )
2993 {
2994  ec_domain_t *domain;
2995 
2996  if (unlikely(!ctx->requested))
2997  return -EPERM;
2998 
2999  /* no locking of master_sem needed, because domain will not be deleted in
3000  * the meantime. */
3001 
3002  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3003  return -ENOENT;
3004  }
3005 
3006  ecrt_domain_process(domain);
3007  return 0;
3008 }
3009 
3010 /*****************************************************************************/
3011 
3017  ec_master_t *master,
3018  void *arg,
3019  ec_ioctl_context_t *ctx
3020  )
3021 {
3022  ec_domain_t *domain;
3023 
3024  if (unlikely(!ctx->requested))
3025  return -EPERM;
3026 
3027  /* no locking of master_sem needed, because domain will not be deleted in
3028  * the meantime. */
3029 
3030  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3031  return -ENOENT;
3032  }
3033 
3034  ecrt_domain_queue(domain);
3035  return 0;
3036 }
3037 
3038 /*****************************************************************************/
3039 
3045  ec_master_t *master,
3046  void *arg,
3047  ec_ioctl_context_t *ctx
3048  )
3049 {
3050  ec_ioctl_domain_state_t data;
3051  const ec_domain_t *domain;
3052  ec_domain_state_t state;
3053 
3054  if (unlikely(!ctx->requested))
3055  return -EPERM;
3056 
3057  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3058  return -EFAULT;
3059  }
3060 
3061  /* no locking of master_sem needed, because domain will not be deleted in
3062  * the meantime. */
3063 
3064  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3065  return -ENOENT;
3066  }
3067 
3068  ecrt_domain_state(domain, &state);
3069 
3070  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3071  return -EFAULT;
3072 
3073  return 0;
3074 }
3075 
3076 /*****************************************************************************/
3077 
3083  ec_master_t *master,
3084  void *arg,
3085  ec_ioctl_context_t *ctx
3086  )
3087 {
3088  ec_ioctl_sdo_request_t data;
3089  ec_slave_config_t *sc;
3090  ec_sdo_request_t *req;
3091 
3092  if (unlikely(!ctx->requested))
3093  return -EPERM;
3094 
3095  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3096  return -EFAULT;
3097 
3098  /* no locking of master_sem needed, because neither sc nor req will not be
3099  * deleted in the meantime. */
3100 
3101  if (!(sc = ec_master_get_config(master, data.config_index))) {
3102  return -ENOENT;
3103  }
3104 
3105  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3106  return -ENOENT;
3107  }
3108 
3109  ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3110  return 0;
3111 }
3112 
3113 /*****************************************************************************/
3114 
3120  ec_master_t *master,
3121  void *arg,
3122  ec_ioctl_context_t *ctx
3123  )
3124 {
3125  ec_ioctl_sdo_request_t data;
3126  ec_slave_config_t *sc;
3127  ec_sdo_request_t *req;
3128 
3129  if (unlikely(!ctx->requested))
3130  return -EPERM;
3131 
3132  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3133  return -EFAULT;
3134 
3135  /* no locking of master_sem needed, because neither sc nor req will not be
3136  * deleted in the meantime. */
3137 
3138  if (!(sc = ec_master_get_config(master, data.config_index))) {
3139  return -ENOENT;
3140  }
3141 
3142  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3143  return -ENOENT;
3144  }
3145 
3146  ecrt_sdo_request_timeout(req, data.timeout);
3147  return 0;
3148 }
3149 
3150 /*****************************************************************************/
3151 
3157  ec_master_t *master,
3158  void *arg,
3159  ec_ioctl_context_t *ctx
3160  )
3161 {
3162  ec_ioctl_sdo_request_t data;
3163  ec_slave_config_t *sc;
3164  ec_sdo_request_t *req;
3165 
3166  if (unlikely(!ctx->requested))
3167  return -EPERM;
3168 
3169  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3170  return -EFAULT;
3171 
3172  /* no locking of master_sem needed, because neither sc nor req will not be
3173  * deleted in the meantime. */
3174 
3175  if (!(sc = ec_master_get_config(master, data.config_index))) {
3176  return -ENOENT;
3177  }
3178 
3179  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3180  return -ENOENT;
3181  }
3182 
3183  data.state = ecrt_sdo_request_state(req);
3184  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3185  data.size = ecrt_sdo_request_data_size(req);
3186  else
3187  data.size = 0;
3188 
3189  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3190  return -EFAULT;
3191 
3192  return 0;
3193 }
3194 
3195 /*****************************************************************************/
3196 
3202  ec_master_t *master,
3203  void *arg,
3204  ec_ioctl_context_t *ctx
3205  )
3206 {
3207  ec_ioctl_sdo_request_t data;
3208  ec_slave_config_t *sc;
3209  ec_sdo_request_t *req;
3210 
3211  if (unlikely(!ctx->requested))
3212  return -EPERM;
3213 
3214  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3215  return -EFAULT;
3216 
3217  /* no locking of master_sem needed, because neither sc nor req will not be
3218  * deleted in the meantime. */
3219 
3220  if (!(sc = ec_master_get_config(master, data.config_index))) {
3221  return -ENOENT;
3222  }
3223 
3224  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3225  return -ENOENT;
3226  }
3227 
3228  ecrt_sdo_request_read(req);
3229  return 0;
3230 }
3231 
3232 /*****************************************************************************/
3233 
3239  ec_master_t *master,
3240  void *arg,
3241  ec_ioctl_context_t *ctx
3242  )
3243 {
3244  ec_ioctl_sdo_request_t data;
3245  ec_slave_config_t *sc;
3246  ec_sdo_request_t *req;
3247  int ret;
3248 
3249  if (unlikely(!ctx->requested))
3250  return -EPERM;
3251 
3252  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3253  return -EFAULT;
3254 
3255  if (!data.size) {
3256  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3257  return -EINVAL;
3258  }
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  ret = ec_sdo_request_alloc(req, data.size);
3272  if (ret)
3273  return ret;
3274 
3275  if (copy_from_user(req->data, (void __user *) data.data, data.size))
3276  return -EFAULT;
3277 
3278  req->data_size = data.size;
3280  return 0;
3281 }
3282 
3283 /*****************************************************************************/
3284 
3290  ec_master_t *master,
3291  void *arg,
3292  ec_ioctl_context_t *ctx
3293  )
3294 {
3295  ec_ioctl_sdo_request_t data;
3296  ec_slave_config_t *sc;
3297  ec_sdo_request_t *req;
3298 
3299  if (unlikely(!ctx->requested))
3300  return -EPERM;
3301 
3302  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3303  return -EFAULT;
3304 
3305  /* no locking of master_sem needed, because neither sc nor req will not be
3306  * deleted in the meantime. */
3307 
3308  if (!(sc = ec_master_get_config(master, data.config_index))) {
3309  return -ENOENT;
3310  }
3311 
3312  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3313  return -ENOENT;
3314  }
3315 
3316  if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3318  return -EFAULT;
3319 
3320  return 0;
3321 }
3322 
3323 /*****************************************************************************/
3324 
3330  ec_master_t *master,
3331  void *arg,
3332  ec_ioctl_context_t *ctx
3333  )
3334 {
3335  ec_ioctl_reg_request_t io;
3336  ec_slave_config_t *sc;
3337  ec_reg_request_t *reg;
3338 
3339  if (unlikely(!ctx->requested)) {
3340  return -EPERM;
3341  }
3342 
3343  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3344  return -EFAULT;
3345  }
3346 
3347  if (io.mem_size <= 0) {
3348  return 0;
3349  }
3350 
3351  /* no locking of master_sem needed, because neither sc nor reg will not be
3352  * deleted in the meantime. */
3353 
3354  if (!(sc = ec_master_get_config(master, io.config_index))) {
3355  return -ENOENT;
3356  }
3357 
3358  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3359  return -ENOENT;
3360  }
3361 
3362  if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3363  min(reg->mem_size, io.mem_size))) {
3364  return -EFAULT;
3365  }
3366 
3367  return 0;
3368 }
3369 
3370 /*****************************************************************************/
3371 
3377  ec_master_t *master,
3378  void *arg,
3379  ec_ioctl_context_t *ctx
3380  )
3381 {
3382  ec_ioctl_reg_request_t io;
3383  ec_slave_config_t *sc;
3384  ec_reg_request_t *reg;
3385 
3386  if (unlikely(!ctx->requested)) {
3387  return -EPERM;
3388  }
3389 
3390  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3391  return -EFAULT;
3392  }
3393 
3394  /* no locking of master_sem needed, because neither sc nor reg will not be
3395  * deleted in the meantime. */
3396 
3397  if (!(sc = ec_master_get_config(master, io.config_index))) {
3398  return -ENOENT;
3399  }
3400 
3401  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3402  return -ENOENT;
3403  }
3404 
3405  io.state = ecrt_reg_request_state(reg);
3406  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
3407 
3408  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3409  return -EFAULT;
3410  }
3411 
3412  return 0;
3413 }
3414 
3415 /*****************************************************************************/
3416 
3422  ec_master_t *master,
3423  void *arg,
3424  ec_ioctl_context_t *ctx
3425  )
3426 {
3427  ec_ioctl_reg_request_t io;
3428  ec_slave_config_t *sc;
3429  ec_reg_request_t *reg;
3430 
3431  if (unlikely(!ctx->requested)) {
3432  return -EPERM;
3433  }
3434 
3435  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3436  return -EFAULT;
3437  }
3438 
3439  /* no locking of master_sem needed, because neither sc nor reg will not be
3440  * deleted in the meantime. */
3441 
3442  if (!(sc = ec_master_get_config(master, io.config_index))) {
3443  return -ENOENT;
3444  }
3445 
3446  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3447  return -ENOENT;
3448  }
3449 
3450  if (io.transfer_size > reg->mem_size) {
3451  return -EOVERFLOW;
3452  }
3453 
3454  if (copy_from_user(reg->data, (void __user *) io.data,
3455  io.transfer_size)) {
3456  return -EFAULT;
3457  }
3458 
3459  ecrt_reg_request_write(reg, io.address, io.transfer_size);
3460  return 0;
3461 }
3462 
3463 /*****************************************************************************/
3464 
3470  ec_master_t *master,
3471  void *arg,
3472  ec_ioctl_context_t *ctx
3473  )
3474 {
3475  ec_ioctl_reg_request_t io;
3476  ec_slave_config_t *sc;
3477  ec_reg_request_t *reg;
3478 
3479  if (unlikely(!ctx->requested)) {
3480  return -EPERM;
3481  }
3482 
3483  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3484  return -EFAULT;
3485  }
3486 
3487  /* no locking of master_sem needed, because neither sc nor reg will not be
3488  * deleted in the meantime. */
3489 
3490  if (!(sc = ec_master_get_config(master, io.config_index))) {
3491  return -ENOENT;
3492  }
3493 
3494  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3495  return -ENOENT;
3496  }
3497 
3498  if (io.transfer_size > reg->mem_size) {
3499  return -EOVERFLOW;
3500  }
3501 
3502  ecrt_reg_request_read(reg, io.address, io.transfer_size);
3503  return 0;
3504 }
3505 
3506 /*****************************************************************************/
3507 
3513  ec_master_t *master,
3514  void *arg,
3515  ec_ioctl_context_t *ctx
3516  )
3517 {
3518  ec_ioctl_voe_t data;
3519  ec_slave_config_t *sc;
3520  ec_voe_handler_t *voe;
3521  uint32_t vendor_id;
3522  uint16_t vendor_type;
3523 
3524  if (unlikely(!ctx->requested))
3525  return -EPERM;
3526 
3527  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3528  return -EFAULT;
3529 
3530  if (get_user(vendor_id, data.vendor_id))
3531  return -EFAULT;
3532 
3533  if (get_user(vendor_type, data.vendor_type))
3534  return -EFAULT;
3535 
3536  /* no locking of master_sem needed, because neither sc nor voe will not be
3537  * deleted in the meantime. */
3538 
3539  if (!(sc = ec_master_get_config(master, data.config_index))) {
3540  return -ENOENT;
3541  }
3542 
3543  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3544  return -ENOENT;
3545  }
3546 
3547  ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
3548  return 0;
3549 }
3550 
3551 /*****************************************************************************/
3552 
3558  ec_master_t *master,
3559  void *arg,
3560  ec_ioctl_context_t *ctx
3561  )
3562 {
3563  ec_ioctl_voe_t data;
3564  ec_slave_config_t *sc;
3565  ec_voe_handler_t *voe;
3566  uint32_t vendor_id;
3567  uint16_t vendor_type;
3568 
3569  if (unlikely(!ctx->requested))
3570  return -EPERM;
3571 
3572  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3573  return -EFAULT;
3574 
3575  /* no locking of master_sem needed, because neither sc nor voe will not be
3576  * deleted in the meantime. */
3577 
3578  if (!(sc = ec_master_get_config(master, data.config_index))) {
3579  return -ENOENT;
3580  }
3581 
3582  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3583  return -ENOENT;
3584  }
3585 
3586  ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
3587 
3588  if (likely(data.vendor_id))
3589  if (put_user(vendor_id, data.vendor_id))
3590  return -EFAULT;
3591 
3592  if (likely(data.vendor_type))
3593  if (put_user(vendor_type, data.vendor_type))
3594  return -EFAULT;
3595 
3596  return 0;
3597 }
3598 
3599 /*****************************************************************************/
3600 
3606  ec_master_t *master,
3607  void *arg,
3608  ec_ioctl_context_t *ctx
3609  )
3610 {
3611  ec_ioctl_voe_t data;
3612  ec_slave_config_t *sc;
3613  ec_voe_handler_t *voe;
3614 
3615  if (unlikely(!ctx->requested))
3616  return -EPERM;
3617 
3618  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3619  return -EFAULT;
3620 
3621  /* no locking of master_sem needed, because neither sc nor voe will not be
3622  * deleted in the meantime. */
3623 
3624  if (!(sc = ec_master_get_config(master, data.config_index))) {
3625  return -ENOENT;
3626  }
3627 
3628  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3629  return -ENOENT;
3630  }
3631 
3632  ecrt_voe_handler_read(voe);
3633  return 0;
3634 }
3635 
3636 /*****************************************************************************/
3637 
3643  ec_master_t *master,
3644  void *arg,
3645  ec_ioctl_context_t *ctx
3646  )
3647 {
3648  ec_ioctl_voe_t data;
3649  ec_slave_config_t *sc;
3650  ec_voe_handler_t *voe;
3651 
3652  if (unlikely(!ctx->requested))
3653  return -EPERM;
3654 
3655  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3656  return -EFAULT;
3657 
3658  /* no locking of master_sem needed, because neither sc nor voe will not be
3659  * deleted in the meantime. */
3660 
3661  if (!(sc = ec_master_get_config(master, data.config_index))) {
3662  return -ENOENT;
3663  }
3664 
3665  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3666  return -ENOENT;
3667  }
3668 
3670  return 0;
3671 }
3672 
3673 /*****************************************************************************/
3674 
3680  ec_master_t *master,
3681  void *arg,
3682  ec_ioctl_context_t *ctx
3683  )
3684 {
3685  ec_ioctl_voe_t data;
3686  ec_slave_config_t *sc;
3687  ec_voe_handler_t *voe;
3688 
3689  if (unlikely(!ctx->requested))
3690  return -EPERM;
3691 
3692  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3693  return -EFAULT;
3694 
3695  /* no locking of master_sem needed, because neither sc nor voe will not be
3696  * deleted in the meantime. */
3697 
3698  if (!(sc = ec_master_get_config(master, data.config_index))) {
3699  return -ENOENT;
3700  }
3701 
3702  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3703  return -ENOENT;
3704  }
3705 
3706  if (data.size) {
3707  if (data.size > ec_voe_handler_mem_size(voe))
3708  return -EOVERFLOW;
3709 
3710  if (copy_from_user(ecrt_voe_handler_data(voe),
3711  (void __user *) data.data, data.size))
3712  return -EFAULT;
3713  }
3714 
3715  ecrt_voe_handler_write(voe, data.size);
3716  return 0;
3717 }
3718 
3719 /*****************************************************************************/
3720 
3726  ec_master_t *master,
3727  void *arg,
3728  ec_ioctl_context_t *ctx
3729  )
3730 {
3731  ec_ioctl_voe_t data;
3732  ec_slave_config_t *sc;
3733  ec_voe_handler_t *voe;
3734 
3735  if (unlikely(!ctx->requested))
3736  return -EPERM;
3737 
3738  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3739  return -EFAULT;
3740 
3741  /* no locking of master_sem needed, because neither sc nor voe will not be
3742  * deleted in the meantime. */
3743 
3744  if (!(sc = ec_master_get_config(master, data.config_index))) {
3745  return -ENOENT;
3746  }
3747 
3748  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3749  return -ENOENT;
3750  }
3751 
3752  data.state = ecrt_voe_handler_execute(voe);
3753  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
3754  data.size = ecrt_voe_handler_data_size(voe);
3755  else
3756  data.size = 0;
3757 
3758  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3759  return -EFAULT;
3760 
3761  return 0;
3762 }
3763 
3764 /*****************************************************************************/
3765 
3771  ec_master_t *master,
3772  void *arg,
3773  ec_ioctl_context_t *ctx
3774  )
3775 {
3776  ec_ioctl_voe_t data;
3777  ec_slave_config_t *sc;
3778  ec_voe_handler_t *voe;
3779 
3780  if (unlikely(!ctx->requested))
3781  return -EPERM;
3782 
3783  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3784  return -EFAULT;
3785 
3786  /* no locking of master_sem needed, because neither sc nor voe will not be
3787  * deleted in the meantime. */
3788 
3789  if (!(sc = ec_master_get_config(master, data.config_index))) {
3790  return -ENOENT;
3791  }
3792 
3793  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3794  return -ENOENT;
3795  }
3796 
3797  if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
3799  return -EFAULT;
3800 
3801  return 0;
3802 }
3803 
3804 /*****************************************************************************/
3805 
3811  ec_master_t *master,
3812  void *arg
3813  )
3814 {
3815  ec_ioctl_slave_foe_t io;
3816  ec_foe_request_t request;
3817  ec_slave_t *slave;
3818  int ret;
3819 
3820  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3821  return -EFAULT;
3822  }
3823 
3824  ec_foe_request_init(&request, io.file_name);
3825  ret = ec_foe_request_alloc(&request, 10000); // FIXME
3826  if (ret) {
3827  ec_foe_request_clear(&request);
3828  return ret;
3829  }
3830 
3831  ec_foe_request_read(&request);
3832 
3833  if (down_interruptible(&master->master_sem)) {
3834  ec_foe_request_clear(&request);
3835  return -EINTR;
3836  }
3837 
3838  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
3839  up(&master->master_sem);
3840  ec_foe_request_clear(&request);
3841  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3842  io.slave_position);
3843  return -EINVAL;
3844  }
3845 
3846  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
3847 
3848  // schedule request.
3849  list_add_tail(&request.list, &slave->foe_requests);
3850 
3851  up(&master->master_sem);
3852 
3853  // wait for processing through FSM
3854  if (wait_event_interruptible(master->request_queue,
3855  request.state != EC_INT_REQUEST_QUEUED)) {
3856  // interrupted by signal
3857  down(&master->master_sem);
3858  if (request.state == EC_INT_REQUEST_QUEUED) {
3859  list_del(&request.list);
3860  up(&master->master_sem);
3861  ec_foe_request_clear(&request);
3862  return -EINTR;
3863  }
3864  // request already processing: interrupt not possible.
3865  up(&master->master_sem);
3866  }
3867 
3868  // wait until master FSM has finished processing
3869  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3870 
3871  io.result = request.result;
3872  io.error_code = request.error_code;
3873 
3874  if (request.state != EC_INT_REQUEST_SUCCESS) {
3875  io.data_size = 0;
3876  ret = -EIO;
3877  } else {
3878  if (request.data_size > io.buffer_size) {
3879  EC_MASTER_ERR(master, "Buffer too small.\n");
3880  ec_foe_request_clear(&request);
3881  return -EOVERFLOW;
3882  }
3883  io.data_size = request.data_size;
3884  if (copy_to_user((void __user *) io.buffer,
3885  request.buffer, io.data_size)) {
3886  ec_foe_request_clear(&request);
3887  return -EFAULT;
3888  }
3889  ret = 0;
3890  }
3891 
3892  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
3893  ret = -EFAULT;
3894  }
3895 
3896  ec_foe_request_clear(&request);
3897  return ret;
3898 }
3899 
3900 /*****************************************************************************/
3901 
3907  ec_master_t *master,
3908  void *arg
3909  )
3910 {
3911  ec_ioctl_slave_foe_t io;
3912  ec_foe_request_t request;
3913  ec_slave_t *slave;
3914  int ret;
3915 
3916  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3917  return -EFAULT;
3918  }
3919 
3920  ec_foe_request_init(&request, io.file_name);
3921 
3922  ret = ec_foe_request_alloc(&request, io.buffer_size);
3923  if (ret) {
3924  ec_foe_request_clear(&request);
3925  return ret;
3926  }
3927 
3928  if (copy_from_user(request.buffer,
3929  (void __user *) io.buffer, io.buffer_size)) {
3930  ec_foe_request_clear(&request);
3931  return -EFAULT;
3932  }
3933 
3934  request.data_size = io.buffer_size;
3935  ec_foe_request_write(&request);
3936 
3937  if (down_interruptible(&master->master_sem)) {
3938  ec_foe_request_clear(&request);
3939  return -EINTR;
3940  }
3941 
3942  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
3943  up(&master->master_sem);
3944  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3945  io.slave_position);
3946  ec_foe_request_clear(&request);
3947  return -EINVAL;
3948  }
3949 
3950  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
3951 
3952  // schedule FoE write request.
3953  list_add_tail(&request.list, &slave->foe_requests);
3954 
3955  up(&master->master_sem);
3956 
3957  // wait for processing through FSM
3958  if (wait_event_interruptible(master->request_queue,
3959  request.state != EC_INT_REQUEST_QUEUED)) {
3960  // interrupted by signal
3961  down(&master->master_sem);
3962  if (request.state == EC_INT_REQUEST_QUEUED) {
3963  // abort request
3964  list_del(&request.list);
3965  up(&master->master_sem);
3966  ec_foe_request_clear(&request);
3967  return -EINTR;
3968  }
3969  up(&master->master_sem);
3970  }
3971 
3972  // wait until master FSM has finished processing
3973  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
3974 
3975  io.result = request.result;
3976  io.error_code = request.error_code;
3977 
3978  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
3979 
3980  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
3981  ret = -EFAULT;
3982  }
3983 
3984  ec_foe_request_clear(&request);
3985  return ret;
3986 }
3987 
3988 /*****************************************************************************/
3989 
3995  ec_master_t *master,
3996  void *arg
3997  )
3998 {
3999  ec_ioctl_slave_soe_read_t ioctl;
4000  u8 *data;
4001  int retval;
4002 
4003  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4004  return -EFAULT;
4005  }
4006 
4007  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4008  if (!data) {
4009  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4010  ioctl.mem_size);
4011  return -ENOMEM;
4012  }
4013 
4014  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4015  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4016  &ioctl.error_code);
4017  if (retval) {
4018  kfree(data);
4019  return retval;
4020  }
4021 
4022  if (copy_to_user((void __user *) ioctl.data,
4023  data, ioctl.data_size)) {
4024  kfree(data);
4025  return -EFAULT;
4026  }
4027  kfree(data);
4028 
4029  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4030  retval = -EFAULT;
4031  }
4032 
4033  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4034  return retval;
4035 }
4036 
4037 /*****************************************************************************/
4038 
4044  ec_master_t *master,
4045  void *arg
4046  )
4047 {
4048  ec_ioctl_slave_soe_write_t ioctl;
4049  u8 *data;
4050  int retval;
4051 
4052  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4053  return -EFAULT;
4054  }
4055 
4056  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4057  if (!data) {
4058  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4059  ioctl.data_size);
4060  return -ENOMEM;
4061  }
4062  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4063  kfree(data);
4064  return -EFAULT;
4065  }
4066 
4067  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4068  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4069  &ioctl.error_code);
4070  kfree(data);
4071  if (retval) {
4072  return retval;
4073  }
4074 
4075  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4076  retval = -EFAULT;
4077  }
4078 
4079  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4080  return retval;
4081 }
4082 
4083 /*****************************************************************************/
4084 
4087 #ifdef EC_IOCTL_RTDM
4088 #define EC_IOCTL ec_ioctl_rtdm
4089 #else
4090 #define EC_IOCTL ec_ioctl
4091 #endif
4092 
4098  ec_master_t *master,
4099  ec_ioctl_context_t *ctx,
4100  unsigned int cmd,
4101  void *arg
4102  )
4103 {
4104 #if DEBUG_LATENCY
4105  cycles_t a = get_cycles(), b;
4106  unsigned int t;
4107 #endif
4108  int ret;
4109 
4110  switch (cmd) {
4111  case EC_IOCTL_MODULE:
4112  ret = ec_ioctl_module(arg);
4113  break;
4114  case EC_IOCTL_MASTER:
4115  ret = ec_ioctl_master(master, arg);
4116  break;
4117  case EC_IOCTL_SLAVE:
4118  ret = ec_ioctl_slave(master, arg);
4119  break;
4120  case EC_IOCTL_SLAVE_SYNC:
4121  ret = ec_ioctl_slave_sync(master, arg);
4122  break;
4123  case EC_IOCTL_SLAVE_SYNC_PDO:
4124  ret = ec_ioctl_slave_sync_pdo(master, arg);
4125  break;
4126  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
4127  ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
4128  break;
4129  case EC_IOCTL_DOMAIN:
4130  ret = ec_ioctl_domain(master, arg);
4131  break;
4132  case EC_IOCTL_DOMAIN_FMMU:
4133  ret = ec_ioctl_domain_fmmu(master, arg);
4134  break;
4135  case EC_IOCTL_DOMAIN_DATA:
4136  ret = ec_ioctl_domain_data(master, arg);
4137  break;
4138  case EC_IOCTL_MASTER_DEBUG:
4139  if (!ctx->writable) {
4140  ret = -EPERM;
4141  break;
4142  }
4143  ret = ec_ioctl_master_debug(master, arg);
4144  break;
4145  case EC_IOCTL_MASTER_RESCAN:
4146  if (!ctx->writable) {
4147  ret = -EPERM;
4148  break;
4149  }
4150  ret = ec_ioctl_master_rescan(master, arg);
4151  break;
4152  case EC_IOCTL_SLAVE_STATE:
4153  if (!ctx->writable) {
4154  ret = -EPERM;
4155  break;
4156  }
4157  ret = ec_ioctl_slave_state(master, arg);
4158  break;
4159  case EC_IOCTL_SLAVE_SDO:
4160  ret = ec_ioctl_slave_sdo(master, arg);
4161  break;
4162  case EC_IOCTL_SLAVE_SDO_ENTRY:
4163  ret = ec_ioctl_slave_sdo_entry(master, arg);
4164  break;
4165  case EC_IOCTL_SLAVE_SDO_UPLOAD:
4166  ret = ec_ioctl_slave_sdo_upload(master, arg);
4167  break;
4168  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
4169  if (!ctx->writable) {
4170  ret = -EPERM;
4171  break;
4172  }
4173  ret = ec_ioctl_slave_sdo_download(master, arg);
4174  break;
4175  case EC_IOCTL_SLAVE_SII_READ:
4176  ret = ec_ioctl_slave_sii_read(master, arg);
4177  break;
4178  case EC_IOCTL_SLAVE_SII_WRITE:
4179  if (!ctx->writable) {
4180  ret = -EPERM;
4181  break;
4182  }
4183  ret = ec_ioctl_slave_sii_write(master, arg);
4184  break;
4185  case EC_IOCTL_SLAVE_REG_READ:
4186  ret = ec_ioctl_slave_reg_read(master, arg);
4187  break;
4188  case EC_IOCTL_SLAVE_REG_WRITE:
4189  if (!ctx->writable) {
4190  ret = -EPERM;
4191  break;
4192  }
4193  ret = ec_ioctl_slave_reg_write(master, arg);
4194  break;
4195  case EC_IOCTL_SLAVE_FOE_READ:
4196  ret = ec_ioctl_slave_foe_read(master, arg);
4197  break;
4198  case EC_IOCTL_SLAVE_FOE_WRITE:
4199  if (!ctx->writable) {
4200  ret = -EPERM;
4201  break;
4202  }
4203  ret = ec_ioctl_slave_foe_write(master, arg);
4204  break;
4205  case EC_IOCTL_SLAVE_SOE_READ:
4206  ret = ec_ioctl_slave_soe_read(master, arg);
4207  break;
4208  case EC_IOCTL_SLAVE_SOE_WRITE:
4209  if (!ctx->writable) {
4210  ret = -EPERM;
4211  break;
4212  }
4213  ret = ec_ioctl_slave_soe_write(master, arg);
4214  break;
4215  case EC_IOCTL_CONFIG:
4216  ret = ec_ioctl_config(master, arg);
4217  break;
4218  case EC_IOCTL_CONFIG_PDO:
4219  ret = ec_ioctl_config_pdo(master, arg);
4220  break;
4221  case EC_IOCTL_CONFIG_PDO_ENTRY:
4222  ret = ec_ioctl_config_pdo_entry(master, arg);
4223  break;
4224  case EC_IOCTL_CONFIG_SDO:
4225  ret = ec_ioctl_config_sdo(master, arg);
4226  break;
4227  case EC_IOCTL_CONFIG_IDN:
4228  ret = ec_ioctl_config_idn(master, arg);
4229  break;
4230 #ifdef EC_EOE
4231  case EC_IOCTL_EOE_HANDLER:
4232  ret = ec_ioctl_eoe_handler(master, arg);
4233  break;
4234 #endif
4235  case EC_IOCTL_REQUEST:
4236  if (!ctx->writable) {
4237  ret = -EPERM;
4238  break;
4239  }
4240  ret = ec_ioctl_request(master, arg, ctx);
4241  break;
4242  case EC_IOCTL_CREATE_DOMAIN:
4243  if (!ctx->writable) {
4244  ret = -EPERM;
4245  break;
4246  }
4247  ret = ec_ioctl_create_domain(master, arg, ctx);
4248  break;
4249  case EC_IOCTL_CREATE_SLAVE_CONFIG:
4250  if (!ctx->writable) {
4251  ret = -EPERM;
4252  break;
4253  }
4254  ret = ec_ioctl_create_slave_config(master, arg, ctx);
4255  break;
4256  case EC_IOCTL_SELECT_REF_CLOCK:
4257  if (!ctx->writable) {
4258  ret = -EPERM;
4259  break;
4260  }
4261  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
4262  break;
4263  case EC_IOCTL_ACTIVATE:
4264  if (!ctx->writable) {
4265  ret = -EPERM;
4266  break;
4267  }
4268  ret = ec_ioctl_activate(master, arg, ctx);
4269  break;
4270  case EC_IOCTL_DEACTIVATE:
4271  if (!ctx->writable) {
4272  ret = -EPERM;
4273  break;
4274  }
4275  ret = ec_ioctl_deactivate(master, arg, ctx);
4276  break;
4277  case EC_IOCTL_SEND:
4278  if (!ctx->writable) {
4279  ret = -EPERM;
4280  break;
4281  }
4282  ret = ec_ioctl_send(master, arg, ctx);
4283  break;
4284  case EC_IOCTL_RECEIVE:
4285  if (!ctx->writable) {
4286  ret = -EPERM;
4287  break;
4288  }
4289  ret = ec_ioctl_receive(master, arg, ctx);
4290  break;
4291  case EC_IOCTL_MASTER_STATE:
4292  ret = ec_ioctl_master_state(master, arg, ctx);
4293  break;
4294  case EC_IOCTL_MASTER_LINK_STATE:
4295  ret = ec_ioctl_master_link_state(master, arg, ctx);
4296  break;
4297  case EC_IOCTL_APP_TIME:
4298  if (!ctx->writable) {
4299  ret = -EPERM;
4300  break;
4301  }
4302  ret = ec_ioctl_app_time(master, arg, ctx);
4303  break;
4304  case EC_IOCTL_SYNC_REF:
4305  if (!ctx->writable) {
4306  ret = -EPERM;
4307  break;
4308  }
4309  ret = ec_ioctl_sync_ref(master, arg, ctx);
4310  break;
4311  case EC_IOCTL_SYNC_SLAVES:
4312  if (!ctx->writable) {
4313  ret = -EPERM;
4314  break;
4315  }
4316  ret = ec_ioctl_sync_slaves(master, arg, ctx);
4317  break;
4318  case EC_IOCTL_REF_CLOCK_TIME:
4319  if (!ctx->writable) {
4320  ret = -EPERM;
4321  break;
4322  }
4323  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4324  break;
4325  case EC_IOCTL_SYNC_MON_QUEUE:
4326  if (!ctx->writable) {
4327  ret = -EPERM;
4328  break;
4329  }
4330  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4331  break;
4332  case EC_IOCTL_SYNC_MON_PROCESS:
4333  if (!ctx->writable) {
4334  ret = -EPERM;
4335  break;
4336  }
4337  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4338  break;
4339  case EC_IOCTL_RESET:
4340  if (!ctx->writable) {
4341  ret = -EPERM;
4342  break;
4343  }
4344  ret = ec_ioctl_reset(master, arg, ctx);
4345  break;
4346  case EC_IOCTL_SC_SYNC:
4347  if (!ctx->writable) {
4348  ret = -EPERM;
4349  break;
4350  }
4351  ret = ec_ioctl_sc_sync(master, arg, ctx);
4352  break;
4353  case EC_IOCTL_SC_WATCHDOG:
4354  if (!ctx->writable) {
4355  ret = -EPERM;
4356  break;
4357  }
4358  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
4359  break;
4360  case EC_IOCTL_SC_ADD_PDO:
4361  if (!ctx->writable) {
4362  ret = -EPERM;
4363  break;
4364  }
4365  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
4366  break;
4367  case EC_IOCTL_SC_CLEAR_PDOS:
4368  if (!ctx->writable) {
4369  ret = -EPERM;
4370  break;
4371  }
4372  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
4373  break;
4374  case EC_IOCTL_SC_ADD_ENTRY:
4375  if (!ctx->writable) {
4376  ret = -EPERM;
4377  break;
4378  }
4379  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
4380  break;
4381  case EC_IOCTL_SC_CLEAR_ENTRIES:
4382  if (!ctx->writable) {
4383  ret = -EPERM;
4384  break;
4385  }
4386  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
4387  break;
4388  case EC_IOCTL_SC_REG_PDO_ENTRY:
4389  if (!ctx->writable) {
4390  ret = -EPERM;
4391  break;
4392  }
4393  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
4394  break;
4395  case EC_IOCTL_SC_REG_PDO_POS:
4396  if (!ctx->writable) {
4397  ret = -EPERM;
4398  break;
4399  }
4400  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
4401  break;
4402  case EC_IOCTL_SC_DC:
4403  if (!ctx->writable) {
4404  ret = -EPERM;
4405  break;
4406  }
4407  ret = ec_ioctl_sc_dc(master, arg, ctx);
4408  break;
4409  case EC_IOCTL_SC_SDO:
4410  if (!ctx->writable) {
4411  ret = -EPERM;
4412  break;
4413  }
4414  ret = ec_ioctl_sc_sdo(master, arg, ctx);
4415  break;
4416  case EC_IOCTL_SC_EMERG_SIZE:
4417  if (!ctx->writable) {
4418  ret = -EPERM;
4419  break;
4420  }
4421  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
4422  break;
4423  case EC_IOCTL_SC_EMERG_POP:
4424  if (!ctx->writable) {
4425  ret = -EPERM;
4426  break;
4427  }
4428  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
4429  break;
4430  case EC_IOCTL_SC_EMERG_CLEAR:
4431  if (!ctx->writable) {
4432  ret = -EPERM;
4433  break;
4434  }
4435  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
4436  break;
4437  case EC_IOCTL_SC_EMERG_OVERRUNS:
4438  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
4439  break;
4440  case EC_IOCTL_SC_SDO_REQUEST:
4441  if (!ctx->writable) {
4442  ret = -EPERM;
4443  break;
4444  }
4445  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
4446  break;
4447  case EC_IOCTL_SC_REG_REQUEST:
4448  if (!ctx->writable) {
4449  ret = -EPERM;
4450  break;
4451  }
4452  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
4453  break;
4454  case EC_IOCTL_SC_VOE:
4455  if (!ctx->writable) {
4456  ret = -EPERM;
4457  break;
4458  }
4459  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
4460  break;
4461  case EC_IOCTL_SC_STATE:
4462  ret = ec_ioctl_sc_state(master, arg, ctx);
4463  break;
4464  case EC_IOCTL_SC_IDN:
4465  if (!ctx->writable) {
4466  ret = -EPERM;
4467  break;
4468  }
4469  ret = ec_ioctl_sc_idn(master, arg, ctx);
4470  break;
4471  case EC_IOCTL_DOMAIN_SIZE:
4472  ret = ec_ioctl_domain_size(master, arg, ctx);
4473  break;
4474  case EC_IOCTL_DOMAIN_OFFSET:
4475  ret = ec_ioctl_domain_offset(master, arg, ctx);
4476  break;
4477  case EC_IOCTL_DOMAIN_PROCESS:
4478  if (!ctx->writable) {
4479  ret = -EPERM;
4480  break;
4481  }
4482  ret = ec_ioctl_domain_process(master, arg, ctx);
4483  break;
4484  case EC_IOCTL_DOMAIN_QUEUE:
4485  if (!ctx->writable) {
4486  ret = -EPERM;
4487  break;
4488  }
4489  ret = ec_ioctl_domain_queue(master, arg, ctx);
4490  break;
4491  case EC_IOCTL_DOMAIN_STATE:
4492  ret = ec_ioctl_domain_state(master, arg, ctx);
4493  break;
4494  case EC_IOCTL_SDO_REQUEST_INDEX:
4495  if (!ctx->writable) {
4496  ret = -EPERM;
4497  break;
4498  }
4499  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
4500  break;
4501  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4502  if (!ctx->writable) {
4503  ret = -EPERM;
4504  break;
4505  }
4506  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4507  break;
4508  case EC_IOCTL_SDO_REQUEST_STATE:
4509  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
4510  break;
4511  case EC_IOCTL_SDO_REQUEST_READ:
4512  if (!ctx->writable) {
4513  ret = -EPERM;
4514  break;
4515  }
4516  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
4517  break;
4518  case EC_IOCTL_SDO_REQUEST_WRITE:
4519  if (!ctx->writable) {
4520  ret = -EPERM;
4521  break;
4522  }
4523  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
4524  break;
4525  case EC_IOCTL_SDO_REQUEST_DATA:
4526  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4527  break;
4528  case EC_IOCTL_REG_REQUEST_DATA:
4529  ret = ec_ioctl_reg_request_data(master, arg, ctx);
4530  break;
4531  case EC_IOCTL_REG_REQUEST_STATE:
4532  ret = ec_ioctl_reg_request_state(master, arg, ctx);
4533  break;
4534  case EC_IOCTL_REG_REQUEST_WRITE:
4535  if (!ctx->writable) {
4536  ret = -EPERM;
4537  break;
4538  }
4539  ret = ec_ioctl_reg_request_write(master, arg, ctx);
4540  break;
4541  case EC_IOCTL_REG_REQUEST_READ:
4542  if (!ctx->writable) {
4543  ret = -EPERM;
4544  break;
4545  }
4546  ret = ec_ioctl_reg_request_read(master, arg, ctx);
4547  break;
4548  case EC_IOCTL_VOE_SEND_HEADER:
4549  if (!ctx->writable) {
4550  ret = -EPERM;
4551  break;
4552  }
4553  ret = ec_ioctl_voe_send_header(master, arg, ctx);
4554  break;
4555  case EC_IOCTL_VOE_REC_HEADER:
4556  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
4557  break;
4558  case EC_IOCTL_VOE_READ:
4559  if (!ctx->writable) {
4560  ret = -EPERM;
4561  break;
4562  }
4563  ret = ec_ioctl_voe_read(master, arg, ctx);
4564  break;
4565  case EC_IOCTL_VOE_READ_NOSYNC:
4566  if (!ctx->writable) {
4567  ret = -EPERM;
4568  break;
4569  }
4570  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
4571  break;
4572  case EC_IOCTL_VOE_WRITE:
4573  if (!ctx->writable) {
4574  ret = -EPERM;
4575  break;
4576  }
4577  ret = ec_ioctl_voe_write(master, arg, ctx);
4578  break;
4579  case EC_IOCTL_VOE_EXEC:
4580  if (!ctx->writable) {
4581  ret = -EPERM;
4582  break;
4583  }
4584  ret = ec_ioctl_voe_exec(master, arg, ctx);
4585  break;
4586  case EC_IOCTL_VOE_DATA:
4587  ret = ec_ioctl_voe_data(master, arg, ctx);
4588  break;
4589  case EC_IOCTL_SET_SEND_INTERVAL:
4590  if (!ctx->writable) {
4591  ret = -EPERM;
4592  break;
4593  }
4594  ret = ec_ioctl_set_send_interval(master, arg, ctx);
4595  break;
4596  default:
4597  ret = -ENOTTY;
4598  break;
4599  }
4600 
4601 #if DEBUG_LATENCY
4602  b = get_cycles();
4603  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
4604  if (t > 50) {
4605  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
4606  _IOC_NR(cmd), t);
4607  }
4608 #endif
4609 
4610  return ret;
4611 }
4612 
4613 /*****************************************************************************/
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:467
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:3119
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:2595
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:706
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:139
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:116
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:2823
ec_reg_request_t * ec_slave_config_find_reg_request(ec_slave_config_t *sc, unsigned int pos)
Finds a register handler via its position in the list.
Definition: slave_config.c:482
void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe, uint32_t *vendor_id, uint16_t *vendor_type)
Reads the header data of a received VoE message.
Definition: voe_handler.c:136
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: ioctl.c:638
void ecrt_reg_request_read(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule a register read operation.
Definition: reg_request.c:111
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:156
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:3238
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:1375
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:1889
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:1032
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:2805
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:2954
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:1606
const ec_soe_request_t * ec_slave_config_get_idn_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an IDN configuration via its position in the list.
Definition: slave_config.c:438
int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, const uint8_t *data, size_t size)
Add an SDO configuration.
Definition: slave_config.c:878
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:3469
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: ioctl.c:802
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:3512
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:1880
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:563
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:112
int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx, ec_master_link_state_t *state)
Reads the current state of a redundant link.
Definition: master.c:2748
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:2764
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:97
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:2988
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:72
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:2918
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:3376
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:3421
uint32_t product_code
Slave product code.
Definition: slave_config.h:126
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:1986
ec_slave_port_link_t link
Port link status.
Definition: slave.h:120
Access rights in PREOP.
Definition: globals.h:193
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:553
uint16_t position
Index after alias.
Definition: slave_config.h:123
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:1831
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:2711
const ec_sdo_request_t * ec_slave_config_get_sdo_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an SDO configuration via its position in the list.
Definition: slave_config.c:394
uint32_t serial_number
Serial number.
Definition: slave.h:138
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:111
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:111
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:160
char * order
Order number.
Definition: slave.h:157
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:48
const ec_domain_t * ec_master_find_domain_const(const ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:1959
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:1998
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:1966
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:122
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:2724
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:3994
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:794
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:722
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:1254
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:162
void ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:163
ec_slave_t * ec_master_find_slave(ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1815
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:2247
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:530
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:142
#define EC_IOCTL
ioctl() function to use.
Definition: ioctl.c:4090
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:2725
u64 rx_count
Number of frames received.
Definition: device.h:102
void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
Start a VoE read operation without querying the sync manager status.
Definition: voe_handler.c:172
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h: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_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:1310
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:2241
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:106
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:144
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: ioctl.c:3810
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:1895
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:859
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:1867
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:2628
EtherCAT master structure.
uint8_t * data
Memory for the process data.
Definition: domain.h:62
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:141
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:3906
#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:623
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:2673
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:3082
Access rights in SAFEOP.
Definition: globals.h:194
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition: pdo.c:257
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:52
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:78
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:224
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
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:3201
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: ioctl.c:512
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:258
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:3156
int ecrt_slave_config_complete_sdo(ec_slave_config_t *sc, uint16_t index, const uint8_t *data, size_t size)
Add configuration data for a complete SDO.
Definition: slave_config.c:963
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:2023
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: ioctl.c:57
Slave configuration state.
Definition: ecrt.h:306
void(* state)(ec_voe_handler_t *)
State function.
Definition: voe_handler.h:59
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:167
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:175
Ethernet over EtherCAT (EoE)
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:136
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:219
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: ioctl.c:1557
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:146
static ATTRIBUTES int ec_ioctl_app_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the master DC application time.
Definition: ioctl.c:1921
ec_master_phase_t phase
Master phase.
Definition: master.h:223
Domain state.
Definition: ecrt.h:407
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:2828
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: ioctl.c:564
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
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:2133
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:2178
PDO description.
Definition: pdo.h:49
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:119
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:144
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:2834
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:1944
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:2414
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:1910
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:609
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
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:2615
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:232
unsigned int scan_busy
Current scan state.
Definition: master.h:251
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:49
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:145
char * name
SDO name.
Definition: sdo.h:54
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:140
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:170
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave's SII.
Definition: ioctl.c:896
unsigned int index
Index (just a number).
Definition: domain.h:58
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:117
Main device.
Definition: globals.h:202
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: ioctl.c:1827
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: ioctl.c:199
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:130
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:1439
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: ioctl.c:1196
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:1795
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:191
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:3642
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:372
const ec_sdo_t * ec_slave_get_sdo_by_pos_const(const ec_slave_t *slave, uint16_t sdo_position)
Get an SDO from the dictionary, given its position in the list.
Definition: slave.c:684
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:3329
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:3004
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:2080
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_slave_sii_write(ec_master_t *master, void *arg)
Write a slave's SII.
Definition: ioctl.c:944
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:2017
#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:1946
Values read by the master.
Definition: ecrt.h:420
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:133
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:1582
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: ioctl.c:2062
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:128
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE handler via its position in the list.
Definition: slave_config.c:460
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:3247
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:3679
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3016
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:3557
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:2815
void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:181
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: ioctl.c:1847
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:2513
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:611
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:48
struct net_device_stats stats
device statistics
Definition: ethernet.h:84
char * name
PDO name.
Definition: pdo.h:53
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:398
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:416
u64 tx_errors
Number of transmit errors.
Definition: device.h:110
int ecrt_slave_config_reg_pdo_entry(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry for process data exchange in a domain.
Definition: slave_config.c:739
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:3163
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: ioctl.c:286
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:3605
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:2288
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:2778
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:1976
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:210
void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc, uint16_t pdo_index)
Clear the mapping of a given PDO.
Definition: slave_config.c:648
uint8_t enable
Enable bit.
Definition: sync.h:52
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:2212
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:209
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:121
ec_direction_t dir
Direction.
Definition: reg_request.h:52
Access rights in OP.
Definition: globals.h:195
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:1776
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:125
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:122
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2454
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:539
char * image
Image name.
Definition: slave.h:156
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry.
Definition: ioctl.c:2317
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1693
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:3044
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:551
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2362
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: ioctl.c:673
size_t sii_nwords
Size of the SII contents in words.
Definition: slave.h:220
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:204
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
char * group
Group name.
Definition: slave.h:155
int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index, ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
Configure a sync manager.
Definition: slave_config.c:524
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3087
EtherCAT slave configuration.
Definition: slave_config.h:118
void ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id, uint16_t vendor_type)
Sets the VoE header for future send operations.
Definition: voe_handler.c:127
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:2551
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:2920
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:520
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:2546
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:2776
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:1847
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:3725
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:593
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:136
void ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain'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:226
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:2795
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:2364
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:200
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:4043
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:339
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:1652
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:110
uint8_t * ecrt_voe_handler_data(ec_voe_handler_t *voe)
Access to the VoE handler's data.
Definition: voe_handler.c:149
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:235
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave's registers.
Definition: ioctl.c:1111
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:3770
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:900
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:3289
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:2037
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: ioctl.c:1505
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:848
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:249
ec_voe_handler_t * ec_slave_config_find_voe_handler(ec_slave_config_t *sc, unsigned int pos)
Finds a VoE handler via its position in the list.
Definition: slave_config.c:504
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:57
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: ioctl.c:2866
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:2282
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2477
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:2433
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