IgH EtherCAT Master  1.6.0
rtdm-ioctl.c
Go to the documentation of this file.
1 /*****************************************************************************
2  *
3  * Copyright (C) 2006-2024 Florian Pose, Ingenieurgemeinschaft IgH
4  *
5  * This file is part of the IgH EtherCAT Master.
6  *
7  * The IgH EtherCAT Master is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License version 2, as
9  * published by the Free Software Foundation.
10  *
11  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with the IgH EtherCAT Master; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
26 /****************************************************************************/
27 
28 #include <linux/module.h>
29 #include <linux/vmalloc.h>
30 
31 #include "master.h"
32 #include "slave_config.h"
33 #include "voe_handler.h"
34 #include "ethernet.h"
35 #include "ioctl.h"
36 
41 #define DEBUG_LATENCY 0
42 
45 #if 0
46 #define ATTRIBUTES __attribute__ ((__noinline__))
47 #else
48 #define ATTRIBUTES
49 #endif
50 
51 #ifdef EC_IOCTL_RTDM
52 # include "rtdm_details.h"
53 /* RTDM does not support locking yet,
54  * therefore no send/receive callbacks are set too. */
55 # define ec_ioctl_lock(lock) do {} while(0)
56 # define ec_ioctl_unlock(lock) do {} while(0)
57 # define ec_ioctl_lock_interruptible(lock) (0)
58 # define ec_copy_to_user(to, from, n, ctx) \
59  rtdm_safe_copy_to_user(ec_ioctl_to_rtdm(ctx), to, from, n)
60 # define ec_copy_from_user(to, from, n, ctx) \
61  rtdm_safe_copy_from_user(ec_ioctl_to_rtdm(ctx), to, from, n)
62 #else
63 # define ec_ioctl_lock(lock) rt_mutex_lock(lock)
64 # define ec_ioctl_unlock(lock) rt_mutex_unlock(lock)
65 # define ec_ioctl_lock_interruptible(lock) \
66  rt_mutex_lock_interruptible(lock)
67 # define ec_copy_to_user(to, from, n, ctx) copy_to_user(to, from, n)
68 # define ec_copy_from_user(to, from, n, ctx) copy_from_user(to, from, n)
69 #endif // EC_IOCTL_RTDM
70 
71 /****************************************************************************/
72 
75 static void ec_ioctl_strcpy(
76  char *target,
77  const char *source
78  )
79 {
80  if (source) {
81  strncpy(target, source, EC_IOCTL_STRING_SIZE);
82  target[EC_IOCTL_STRING_SIZE - 1] = 0;
83  } else {
84  target[0] = 0;
85  }
86 }
87 
88 /****************************************************************************/
89 
95  void *arg,
96  ec_ioctl_context_t *ctx
97  )
98 {
99  ec_ioctl_module_t data;
100 
101  data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
102  data.master_count = ec_master_count();
103 
104  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
105  return -EFAULT;
106 
107  return 0;
108 }
109 
110 /****************************************************************************/
111 
117  ec_master_t *master,
118  void *arg
119  )
120 {
121  ec_ioctl_master_t io;
122  unsigned int dev_idx, j;
123 
124  if (down_interruptible(&master->master_sem)) {
125  return -EINTR;
126  }
127 
128  io.slave_count = master->slave_count;
129  io.scan_index = master->scan_index;
130  io.config_count = ec_master_config_count(master);
131  io.domain_count = ec_master_domain_count(master);
132 #ifdef EC_EOE
133  io.eoe_handler_count = ec_master_eoe_handler_count(master);
134 #else
135  io.eoe_handler_count = 0;
136 #endif
137  io.phase = (uint8_t) master->phase;
138  io.active = (uint8_t) master->active;
139  io.scan_busy = master->scan_busy;
140 
141  up(&master->master_sem);
142 
143  if (down_interruptible(&master->device_sem)) {
144  return -EINTR;
145  }
146 
147  for (dev_idx = EC_DEVICE_MAIN;
148  dev_idx < ec_master_num_devices(master); dev_idx++) {
149  ec_device_t *device = &master->devices[dev_idx];
150 
151  if (device->dev) {
152  memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
153  ETH_ALEN);
154  } else {
155  memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
156  ETH_ALEN);
157  }
158  io.devices[dev_idx].attached = device->dev ? 1 : 0;
159  io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
160  io.devices[dev_idx].tx_count = device->tx_count;
161  io.devices[dev_idx].rx_count = device->rx_count;
162  io.devices[dev_idx].tx_bytes = device->tx_bytes;
163  io.devices[dev_idx].rx_bytes = device->rx_bytes;
164  io.devices[dev_idx].tx_errors = device->tx_errors;
165  for (j = 0; j < EC_RATE_COUNT; j++) {
166  io.devices[dev_idx].tx_frame_rates[j] =
167  device->tx_frame_rates[j];
168  io.devices[dev_idx].rx_frame_rates[j] =
169  device->rx_frame_rates[j];
170  io.devices[dev_idx].tx_byte_rates[j] =
171  device->tx_byte_rates[j];
172  io.devices[dev_idx].rx_byte_rates[j] =
173  device->rx_byte_rates[j];
174  }
175  }
176  io.num_devices = ec_master_num_devices(master);
177 
178  io.tx_count = master->device_stats.tx_count;
179  io.rx_count = master->device_stats.rx_count;
180  io.tx_bytes = master->device_stats.tx_bytes;
181  io.rx_bytes = master->device_stats.rx_bytes;
182  for (j = 0; j < EC_RATE_COUNT; j++) {
183  io.tx_frame_rates[j] =
184  master->device_stats.tx_frame_rates[j];
185  io.rx_frame_rates[j] =
186  master->device_stats.rx_frame_rates[j];
187  io.tx_byte_rates[j] =
188  master->device_stats.tx_byte_rates[j];
189  io.rx_byte_rates[j] =
190  master->device_stats.rx_byte_rates[j];
191  io.loss_rates[j] =
192  master->device_stats.loss_rates[j];
193  }
194 
195  up(&master->device_sem);
196 
197  io.app_time = master->app_time;
198  io.dc_ref_time = master->dc_ref_time;
199  io.ref_clock =
200  master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
201 
202  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
203  return -EFAULT;
204  }
205 
206  return 0;
207 }
208 
209 /****************************************************************************/
210 
216  ec_master_t *master,
217  void *arg
218  )
219 {
220  ec_ioctl_slave_t data;
221  const ec_slave_t *slave;
222  int i;
223 
224  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
225  return -EFAULT;
226  }
227 
228  if (down_interruptible(&master->master_sem))
229  return -EINTR;
230 
231  if (!(slave = ec_master_find_slave_const(
232  master, 0, data.position))) {
233  up(&master->master_sem);
234  EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
235  return -EINVAL;
236  }
237 
238  data.device_index = slave->device_index;
239  data.vendor_id = slave->sii.vendor_id;
240  data.product_code = slave->sii.product_code;
241  data.revision_number = slave->sii.revision_number;
242  data.serial_number = slave->sii.serial_number;
243  data.alias = slave->effective_alias;
244  data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
245  data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
246  data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
247  data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
248  data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
249  data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
250  data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
251  data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
252  data.mailbox_protocols = slave->sii.mailbox_protocols;
253  data.has_general_category = slave->sii.has_general;
254  data.coe_details = slave->sii.coe_details;
255  data.general_flags = slave->sii.general_flags;
256  data.current_on_ebus = slave->sii.current_on_ebus;
257  for (i = 0; i < EC_MAX_PORTS; i++) {
258  data.ports[i].desc = slave->ports[i].desc;
259  data.ports[i].link.link_up = slave->ports[i].link.link_up;
260  data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
261  data.ports[i].link.signal_detected =
262  slave->ports[i].link.signal_detected;
263  data.ports[i].receive_time = slave->ports[i].receive_time;
264  if (slave->ports[i].next_slave) {
265  data.ports[i].next_slave =
266  slave->ports[i].next_slave->ring_position;
267  } else {
268  data.ports[i].next_slave = 0xffff;
269  }
270  data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
271  }
272  data.fmmu_bit = slave->base_fmmu_bit_operation;
273  data.dc_supported = slave->base_dc_supported;
274  data.dc_range = slave->base_dc_range;
275  data.has_dc_system_time = slave->has_dc_system_time;
276  data.transmission_delay = slave->transmission_delay;
277  data.al_state = slave->current_state;
278  data.error_flag = slave->error_flag;
279 
280  data.sync_count = slave->sii.sync_count;
281  data.sdo_count = ec_slave_sdo_count(slave);
282  data.sii_nwords = slave->sii_nwords;
283  ec_ioctl_strcpy(data.group, slave->sii.group);
284  ec_ioctl_strcpy(data.image, slave->sii.image);
285  ec_ioctl_strcpy(data.order, slave->sii.order);
286  ec_ioctl_strcpy(data.name, slave->sii.name);
287 
288  up(&master->master_sem);
289 
290  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
291  return -EFAULT;
292 
293  return 0;
294 }
295 
296 /****************************************************************************/
297 
303  ec_master_t *master,
304  void *arg
305  )
306 {
307  ec_ioctl_slave_sync_t data;
308  const ec_slave_t *slave;
309  const ec_sync_t *sync;
310 
311  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
312  return -EFAULT;
313  }
314 
315  if (down_interruptible(&master->master_sem))
316  return -EINTR;
317 
318  if (!(slave = ec_master_find_slave_const(
319  master, 0, data.slave_position))) {
320  up(&master->master_sem);
321  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
322  data.slave_position);
323  return -EINVAL;
324  }
325 
326  if (data.sync_index >= slave->sii.sync_count) {
327  up(&master->master_sem);
328  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
329  data.sync_index);
330  return -EINVAL;
331  }
332 
333  sync = &slave->sii.syncs[data.sync_index];
334 
336  data.default_size = sync->default_length;
337  data.control_register = sync->control_register;
338  data.enable = sync->enable;
339  data.pdo_count = ec_pdo_list_count(&sync->pdos);
340 
341  up(&master->master_sem);
342 
343  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
344  return -EFAULT;
345 
346  return 0;
347 }
348 
349 /****************************************************************************/
350 
356  ec_master_t *master,
357  void *arg
358  )
359 {
360  ec_ioctl_slave_sync_pdo_t data;
361  const ec_slave_t *slave;
362  const ec_sync_t *sync;
363  const ec_pdo_t *pdo;
364 
365  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
366  return -EFAULT;
367  }
368 
369  if (down_interruptible(&master->master_sem))
370  return -EINTR;
371 
372  if (!(slave = ec_master_find_slave_const(
373  master, 0, data.slave_position))) {
374  up(&master->master_sem);
375  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
376  data.slave_position);
377  return -EINVAL;
378  }
379 
380  if (data.sync_index >= slave->sii.sync_count) {
381  up(&master->master_sem);
382  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
383  data.sync_index);
384  return -EINVAL;
385  }
386 
387  sync = &slave->sii.syncs[data.sync_index];
389  &sync->pdos, data.pdo_pos))) {
390  up(&master->master_sem);
391  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
392  "position %u!\n", data.sync_index, data.pdo_pos);
393  return -EINVAL;
394  }
395 
396  data.index = pdo->index;
397  data.entry_count = ec_pdo_entry_count(pdo);
398  ec_ioctl_strcpy(data.name, pdo->name);
399 
400  up(&master->master_sem);
401 
402  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
403  return -EFAULT;
404 
405  return 0;
406 }
407 
408 /****************************************************************************/
409 
415  ec_master_t *master,
416  void *arg
417  )
418 {
419  ec_ioctl_slave_sync_pdo_entry_t data;
420  const ec_slave_t *slave;
421  const ec_sync_t *sync;
422  const ec_pdo_t *pdo;
423  const ec_pdo_entry_t *entry;
424 
425  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
426  return -EFAULT;
427  }
428 
429  if (down_interruptible(&master->master_sem))
430  return -EINTR;
431 
432  if (!(slave = ec_master_find_slave_const(
433  master, 0, data.slave_position))) {
434  up(&master->master_sem);
435  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
436  data.slave_position);
437  return -EINVAL;
438  }
439 
440  if (data.sync_index >= slave->sii.sync_count) {
441  up(&master->master_sem);
442  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
443  data.sync_index);
444  return -EINVAL;
445  }
446 
447  sync = &slave->sii.syncs[data.sync_index];
449  &sync->pdos, data.pdo_pos))) {
450  up(&master->master_sem);
451  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
452  "position %u!\n", data.sync_index, data.pdo_pos);
453  return -EINVAL;
454  }
455 
456  if (!(entry = ec_pdo_find_entry_by_pos_const(
457  pdo, data.entry_pos))) {
458  up(&master->master_sem);
459  EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
460  "position %u!\n", data.pdo_pos, data.entry_pos);
461  return -EINVAL;
462  }
463 
464  data.index = entry->index;
465  data.subindex = entry->subindex;
466  data.bit_length = entry->bit_length;
467  ec_ioctl_strcpy(data.name, entry->name);
468 
469  up(&master->master_sem);
470 
471  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
472  return -EFAULT;
473 
474  return 0;
475 }
476 
477 /****************************************************************************/
478 
484  ec_master_t *master,
485  void *arg
486  )
487 {
488  ec_ioctl_domain_t data;
489  const ec_domain_t *domain;
490  unsigned int dev_idx;
491 
492  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
493  return -EFAULT;
494  }
495 
496  if (down_interruptible(&master->master_sem))
497  return -EINTR;
498 
499  if (!(domain = ec_master_find_domain_const(master, data.index))) {
500  up(&master->master_sem);
501  EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
502  return -EINVAL;
503  }
504 
505  data.data_size = domain->data_size;
506  data.logical_base_address = domain->logical_base_address;
507  for (dev_idx = EC_DEVICE_MAIN;
508  dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
509  data.working_counter[dev_idx] = domain->working_counter[dev_idx];
510  }
511  data.expected_working_counter = domain->expected_working_counter;
512  data.fmmu_count = ec_domain_fmmu_count(domain);
513 
514  up(&master->master_sem);
515 
516  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
517  return -EFAULT;
518 
519  return 0;
520 }
521 
522 /****************************************************************************/
523 
529  ec_master_t *master,
530  void *arg
531  )
532 {
533  ec_ioctl_domain_fmmu_t data;
534  const ec_domain_t *domain;
535  const ec_fmmu_config_t *fmmu;
536 
537  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
538  return -EFAULT;
539  }
540 
541  if (down_interruptible(&master->master_sem))
542  return -EINTR;
543 
544  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
545  up(&master->master_sem);
546  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
547  data.domain_index);
548  return -EINVAL;
549  }
550 
551  if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
552  up(&master->master_sem);
553  EC_MASTER_ERR(master, "Domain %u has less than %u"
554  " fmmu configurations.\n",
555  data.domain_index, data.fmmu_index + 1);
556  return -EINVAL;
557  }
558 
559  data.slave_config_alias = fmmu->sc->alias;
560  data.slave_config_position = fmmu->sc->position;
561  data.sync_index = fmmu->sync_index;
562  data.dir = fmmu->dir;
563  data.logical_address = fmmu->logical_start_address;
564  data.data_size = fmmu->data_size;
565 
566  up(&master->master_sem);
567 
568  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
569  return -EFAULT;
570 
571  return 0;
572 }
573 
574 /****************************************************************************/
575 
581  ec_master_t *master,
582  void *arg
583  )
584 {
585  ec_ioctl_domain_data_t data;
586  const ec_domain_t *domain;
587 
588  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
589  return -EFAULT;
590  }
591 
592  if (down_interruptible(&master->master_sem))
593  return -EINTR;
594 
595  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
596  up(&master->master_sem);
597  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
598  data.domain_index);
599  return -EINVAL;
600  }
601 
602  if (domain->data_size != data.data_size) {
603  up(&master->master_sem);
604  EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
605  data.data_size, domain->data_size);
606  return -EFAULT;
607  }
608 
609  if (copy_to_user((void __user *) data.target, domain->data,
610  domain->data_size)) {
611  up(&master->master_sem);
612  return -EFAULT;
613  }
614 
615  up(&master->master_sem);
616  return 0;
617 }
618 
619 /****************************************************************************/
620 
626  ec_master_t *master,
627  void *arg
628  )
629 {
630  return ec_master_debug_level(master, (unsigned long) arg);
631 }
632 
633 /****************************************************************************/
634 
640  ec_master_t *master,
641  void *arg
642  )
643 {
644  master->fsm.rescan_required = 1;
645  return 0;
646 }
647 
648 /****************************************************************************/
649 
655  ec_master_t *master,
656  void *arg
657  )
658 {
659  ec_ioctl_slave_state_t data;
660  ec_slave_t *slave;
661 
662  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
663  return -EFAULT;
664  }
665 
666  if (down_interruptible(&master->master_sem))
667  return -EINTR;
668 
669  if (!(slave = ec_master_find_slave(
670  master, 0, data.slave_position))) {
671  up(&master->master_sem);
672  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
673  data.slave_position);
674  return -EINVAL;
675  }
676 
677  ec_slave_request_state(slave, data.al_state);
678 
679  up(&master->master_sem);
680  return 0;
681 }
682 
683 /****************************************************************************/
684 
690  ec_master_t *master,
691  void *arg
692  )
693 {
694  ec_ioctl_slave_sdo_t data;
695  const ec_slave_t *slave;
696  const ec_sdo_t *sdo;
697 
698  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
699  return -EFAULT;
700  }
701 
702  if (down_interruptible(&master->master_sem))
703  return -EINTR;
704 
705  if (!(slave = ec_master_find_slave_const(
706  master, 0, data.slave_position))) {
707  up(&master->master_sem);
708  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
709  data.slave_position);
710  return -EINVAL;
711  }
712 
713  if (!(sdo = ec_slave_get_sdo_by_pos_const(
714  slave, data.sdo_position))) {
715  up(&master->master_sem);
716  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
717  return -EINVAL;
718  }
719 
720  data.sdo_index = sdo->index;
721  data.max_subindex = sdo->max_subindex;
722  ec_ioctl_strcpy(data.name, sdo->name);
723 
724  up(&master->master_sem);
725 
726  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
727  return -EFAULT;
728 
729  return 0;
730 }
731 
732 /****************************************************************************/
733 
739  ec_master_t *master,
740  void *arg
741  )
742 {
743  ec_ioctl_slave_sdo_entry_t data;
744  const ec_slave_t *slave;
745  const ec_sdo_t *sdo;
746  const ec_sdo_entry_t *entry;
747 
748  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
749  return -EFAULT;
750  }
751 
752  if (down_interruptible(&master->master_sem))
753  return -EINTR;
754 
755  if (!(slave = ec_master_find_slave_const(
756  master, 0, data.slave_position))) {
757  up(&master->master_sem);
758  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
759  data.slave_position);
760  return -EINVAL;
761  }
762 
763  if (data.sdo_spec <= 0) {
764  if (!(sdo = ec_slave_get_sdo_by_pos_const(
765  slave, -data.sdo_spec))) {
766  up(&master->master_sem);
767  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
768  return -EINVAL;
769  }
770  } else {
771  if (!(sdo = ec_slave_get_sdo_const(
772  slave, data.sdo_spec))) {
773  up(&master->master_sem);
774  EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
775  data.sdo_spec);
776  return -EINVAL;
777  }
778  }
779 
780  if (!(entry = ec_sdo_get_entry_const(
781  sdo, data.sdo_entry_subindex))) {
782  up(&master->master_sem);
783  EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
784  sdo->index, data.sdo_entry_subindex);
785  return -EINVAL;
786  }
787 
788  data.data_type = entry->data_type;
789  data.bit_length = entry->bit_length;
790  data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
792  data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
794  data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
796  data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
798  data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
800  data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
802  ec_ioctl_strcpy(data.description, entry->description);
803 
804  up(&master->master_sem);
805 
806  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
807  return -EFAULT;
808 
809  return 0;
810 }
811 
812 /****************************************************************************/
813 
819  ec_master_t *master,
820  void *arg
821  )
822 {
823  ec_ioctl_slave_sdo_upload_t data;
824  uint8_t *target;
825  int ret;
826 
827  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
828  return -EFAULT;
829  }
830 
831  if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
832  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
833  " for SDO upload.\n", data.target_size);
834  return -ENOMEM;
835  }
836 
837  ret = ecrt_master_sdo_upload(master, data.slave_position,
838  data.sdo_index, data.sdo_entry_subindex, target,
839  data.target_size, &data.data_size, &data.abort_code);
840 
841  if (!ret) {
842  if (copy_to_user((void __user *) data.target,
843  target, data.data_size)) {
844  kfree(target);
845  return -EFAULT;
846  }
847  }
848 
849  kfree(target);
850 
851  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
852  return -EFAULT;
853  }
854 
855  return ret;
856 }
857 
858 /****************************************************************************/
859 
865  ec_master_t *master,
866  void *arg
867  )
868 {
869  ec_ioctl_slave_sdo_download_t data;
870  uint8_t *sdo_data;
871  int retval;
872 
873  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
874  return -EFAULT;
875  }
876 
877  if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
878  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
879  " for SDO download.\n", data.data_size);
880  return -ENOMEM;
881  }
882 
883  if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
884  kfree(sdo_data);
885  return -EFAULT;
886  }
887 
888  if (data.complete_access) {
889  retval = ecrt_master_sdo_download_complete(master, data.slave_position,
890  data.sdo_index, sdo_data, data.data_size, &data.abort_code);
891  } else {
892  retval = ecrt_master_sdo_download(master, data.slave_position,
893  data.sdo_index, data.sdo_entry_subindex, sdo_data,
894  data.data_size, &data.abort_code);
895  }
896 
897  kfree(sdo_data);
898 
899  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
900  retval = -EFAULT;
901  }
902 
903  return retval;
904 }
905 
906 /****************************************************************************/
907 
913  ec_master_t *master,
914  void *arg
915  )
916 {
917  ec_ioctl_slave_sii_t data;
918  const ec_slave_t *slave;
919  int retval;
920 
921  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
922  return -EFAULT;
923  }
924 
925  if (down_interruptible(&master->master_sem))
926  return -EINTR;
927 
928  if (!(slave = ec_master_find_slave_const(
929  master, 0, data.slave_position))) {
930  up(&master->master_sem);
931  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
932  data.slave_position);
933  return -EINVAL;
934  }
935 
936  if (!data.nwords
937  || data.offset + data.nwords > slave->sii_nwords) {
938  up(&master->master_sem);
939  EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
940  " size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
941  return -EINVAL;
942  }
943 
944  if (copy_to_user((void __user *) data.words,
945  slave->sii_words + data.offset, data.nwords * 2))
946  retval = -EFAULT;
947  else
948  retval = 0;
949 
950  up(&master->master_sem);
951  return retval;
952 }
953 
954 /****************************************************************************/
955 
961  ec_master_t *master,
962  void *arg
963  )
964 {
965  ec_ioctl_slave_sii_t data;
966  ec_slave_t *slave;
967  unsigned int byte_size;
968  uint16_t *words;
969  ec_sii_write_request_t request;
970 
971  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
972  return -EFAULT;
973  }
974 
975  if (!data.nwords) {
976  return 0;
977  }
978 
979  byte_size = sizeof(uint16_t) * data.nwords;
980  if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
981  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
982  " for SII contents.\n", byte_size);
983  return -ENOMEM;
984  }
985 
986  if (copy_from_user(words,
987  (void __user *) data.words, byte_size)) {
988  kfree(words);
989  return -EFAULT;
990  }
991 
992  if (down_interruptible(&master->master_sem)) {
993  kfree(words);
994  return -EINTR;
995  }
996 
997  if (!(slave = ec_master_find_slave(
998  master, 0, data.slave_position))) {
999  up(&master->master_sem);
1000  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1001  data.slave_position);
1002  kfree(words);
1003  return -EINVAL;
1004  }
1005 
1006  // init SII write request
1007  INIT_LIST_HEAD(&request.list);
1008  request.slave = slave;
1009  request.words = words;
1010  request.offset = data.offset;
1011  request.nwords = data.nwords;
1012  request.state = EC_INT_REQUEST_QUEUED;
1013 
1014  // schedule SII write request.
1015  list_add_tail(&request.list, &master->sii_requests);
1016 
1017  up(&master->master_sem);
1018 
1019  // wait for processing through FSM
1020  if (wait_event_interruptible(master->request_queue,
1021  request.state != EC_INT_REQUEST_QUEUED)) {
1022  // interrupted by signal
1023  down(&master->master_sem);
1024  if (request.state == EC_INT_REQUEST_QUEUED) {
1025  // abort request
1026  list_del(&request.list);
1027  up(&master->master_sem);
1028  kfree(words);
1029  return -EINTR;
1030  }
1031  up(&master->master_sem);
1032  }
1033 
1034  // wait until master FSM has finished processing
1035  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1036 
1037  kfree(words);
1038 
1039  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1040 }
1041 
1042 /****************************************************************************/
1043 
1049  ec_master_t *master,
1050  void *arg
1051  )
1052 {
1053  ec_ioctl_slave_reg_t io;
1054  ec_slave_t *slave;
1055  ec_reg_request_t request;
1056  int ret;
1057 
1058  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1059  return -EFAULT;
1060  }
1061 
1062  if (!io.size) {
1063  return 0;
1064  }
1065 
1066  // init register request
1067  ret = ec_reg_request_init(&request, io.size);
1068  if (ret) {
1069  return ret;
1070  }
1071 
1072  ret = ecrt_reg_request_read(&request, io.address, io.size);
1073  if (ret) {
1074  return ret;
1075  }
1076 
1077  if (down_interruptible(&master->master_sem)) {
1078  ec_reg_request_clear(&request);
1079  return -EINTR;
1080  }
1081 
1082  if (!(slave = ec_master_find_slave(
1083  master, 0, io.slave_position))) {
1084  up(&master->master_sem);
1085  ec_reg_request_clear(&request);
1086  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1087  io.slave_position);
1088  return -EINVAL;
1089  }
1090 
1091  // schedule request.
1092  list_add_tail(&request.list, &slave->reg_requests);
1093 
1094  up(&master->master_sem);
1095 
1096  // wait for processing through FSM
1097  if (wait_event_interruptible(master->request_queue,
1098  request.state != EC_INT_REQUEST_QUEUED)) {
1099  // interrupted by signal
1100  down(&master->master_sem);
1101  if (request.state == EC_INT_REQUEST_QUEUED) {
1102  // abort request
1103  list_del(&request.list);
1104  up(&master->master_sem);
1105  ec_reg_request_clear(&request);
1106  return -EINTR;
1107  }
1108  up(&master->master_sem);
1109  }
1110 
1111  // wait until master FSM has finished processing
1112  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1113 
1114  if (request.state == EC_INT_REQUEST_SUCCESS) {
1115  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1116  return -EFAULT;
1117  }
1118  }
1119  ec_reg_request_clear(&request);
1120 
1121  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1122 }
1123 
1124 /****************************************************************************/
1125 
1131  ec_master_t *master,
1132  void *arg
1133  )
1134 {
1135  ec_ioctl_slave_reg_t io;
1136  ec_slave_t *slave;
1137  ec_reg_request_t request;
1138  int ret;
1139 
1140  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1141  return -EFAULT;
1142  }
1143 
1144  if (!io.size) {
1145  return 0;
1146  }
1147 
1148  // init register request
1149  ret = ec_reg_request_init(&request, io.size);
1150  if (ret) {
1151  return ret;
1152  }
1153 
1154  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1155  ec_reg_request_clear(&request);
1156  return -EFAULT;
1157  }
1158 
1159  ret = ecrt_reg_request_write(&request, io.address, io.size);
1160  if (ret) {
1161  return ret;
1162  }
1163 
1164  if (down_interruptible(&master->master_sem)) {
1165  ec_reg_request_clear(&request);
1166  return -EINTR;
1167  }
1168 
1169  if (io.emergency) {
1170  request.ring_position = io.slave_position;
1171  // schedule request.
1172  list_add_tail(&request.list, &master->emerg_reg_requests);
1173  }
1174  else {
1175  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1176  up(&master->master_sem);
1177  ec_reg_request_clear(&request);
1178  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1179  io.slave_position);
1180  return -EINVAL;
1181  }
1182 
1183  // schedule request.
1184  list_add_tail(&request.list, &slave->reg_requests);
1185  }
1186 
1187  up(&master->master_sem);
1188 
1189  // wait for processing through FSM
1190  if (wait_event_interruptible(master->request_queue,
1191  request.state != EC_INT_REQUEST_QUEUED)) {
1192  // interrupted by signal
1193  down(&master->master_sem);
1194  if (request.state == EC_INT_REQUEST_QUEUED) {
1195  // abort request
1196  list_del(&request.list);
1197  up(&master->master_sem);
1198  ec_reg_request_clear(&request);
1199  return -EINTR;
1200  }
1201  up(&master->master_sem);
1202  }
1203 
1204  // wait until master FSM has finished processing
1205  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1206 
1207  ec_reg_request_clear(&request);
1208 
1209  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1210 }
1211 
1212 /****************************************************************************/
1213 
1219  ec_master_t *master,
1220  void *arg
1221  )
1222 {
1223  ec_ioctl_config_t data;
1224  const ec_slave_config_t *sc;
1225  uint8_t i;
1226 
1227  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1228  return -EFAULT;
1229  }
1230 
1231  if (down_interruptible(&master->master_sem))
1232  return -EINTR;
1233 
1234  if (!(sc = ec_master_get_config_const(
1235  master, data.config_index))) {
1236  up(&master->master_sem);
1237  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1238  data.config_index);
1239  return -EINVAL;
1240  }
1241 
1242  data.alias = sc->alias;
1243  data.position = sc->position;
1244  data.vendor_id = sc->vendor_id;
1245  data.product_code = sc->product_code;
1246  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1247  data.syncs[i].dir = sc->sync_configs[i].dir;
1248  data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1249  data.syncs[i].pdo_count =
1251  }
1252  data.watchdog_divider = sc->watchdog_divider;
1253  data.watchdog_intervals = sc->watchdog_intervals;
1254  data.sdo_count = ec_slave_config_sdo_count(sc);
1255  data.idn_count = ec_slave_config_idn_count(sc);
1256  data.flag_count = ec_slave_config_flag_count(sc);
1257  data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1258  data.dc_assign_activate = sc->dc_assign_activate;
1259  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1260  data.dc_sync[i] = sc->dc_sync[i];
1261  }
1262 
1263  up(&master->master_sem);
1264 
1265  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1266  return -EFAULT;
1267 
1268  return 0;
1269 }
1270 
1271 /****************************************************************************/
1272 
1278  ec_master_t *master,
1279  void *arg
1280  )
1281 {
1282  ec_ioctl_config_pdo_t data;
1283  const ec_slave_config_t *sc;
1284  const ec_pdo_t *pdo;
1285 
1286  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1287  return -EFAULT;
1288  }
1289 
1290  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1291  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1292  data.sync_index);
1293  return -EINVAL;
1294  }
1295 
1296  if (down_interruptible(&master->master_sem))
1297  return -EINTR;
1298 
1299  if (!(sc = ec_master_get_config_const(
1300  master, data.config_index))) {
1301  up(&master->master_sem);
1302  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1303  data.config_index);
1304  return -EINVAL;
1305  }
1306 
1308  &sc->sync_configs[data.sync_index].pdos,
1309  data.pdo_pos))) {
1310  up(&master->master_sem);
1311  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1312  return -EINVAL;
1313  }
1314 
1315  data.index = pdo->index;
1316  data.entry_count = ec_pdo_entry_count(pdo);
1317  ec_ioctl_strcpy(data.name, pdo->name);
1318 
1319  up(&master->master_sem);
1320 
1321  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1322  return -EFAULT;
1323 
1324  return 0;
1325 }
1326 
1327 /****************************************************************************/
1328 
1334  ec_master_t *master,
1335  void *arg
1336  )
1337 {
1338  ec_ioctl_config_pdo_entry_t data;
1339  const ec_slave_config_t *sc;
1340  const ec_pdo_t *pdo;
1341  const ec_pdo_entry_t *entry;
1342 
1343  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1344  return -EFAULT;
1345  }
1346 
1347  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1348  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1349  data.sync_index);
1350  return -EINVAL;
1351  }
1352 
1353  if (down_interruptible(&master->master_sem))
1354  return -EINTR;
1355 
1356  if (!(sc = ec_master_get_config_const(
1357  master, data.config_index))) {
1358  up(&master->master_sem);
1359  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1360  data.config_index);
1361  return -EINVAL;
1362  }
1363 
1365  &sc->sync_configs[data.sync_index].pdos,
1366  data.pdo_pos))) {
1367  up(&master->master_sem);
1368  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1369  return -EINVAL;
1370  }
1371 
1372  if (!(entry = ec_pdo_find_entry_by_pos_const(
1373  pdo, data.entry_pos))) {
1374  up(&master->master_sem);
1375  EC_MASTER_ERR(master, "Entry not found!\n");
1376  return -EINVAL;
1377  }
1378 
1379  data.index = entry->index;
1380  data.subindex = entry->subindex;
1381  data.bit_length = entry->bit_length;
1382  ec_ioctl_strcpy(data.name, entry->name);
1383 
1384  up(&master->master_sem);
1385 
1386  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1387  return -EFAULT;
1388 
1389  return 0;
1390 }
1391 
1392 /****************************************************************************/
1393 
1399  ec_master_t *master,
1400  void *arg
1401  )
1402 {
1403  ec_ioctl_config_sdo_t *ioctl;
1404  const ec_slave_config_t *sc;
1405  const ec_sdo_request_t *req;
1406 
1407  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1408  return -ENOMEM;
1409  }
1410 
1411  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1412  kfree(ioctl);
1413  return -EFAULT;
1414  }
1415 
1416  if (down_interruptible(&master->master_sem)) {
1417  kfree(ioctl);
1418  return -EINTR;
1419  }
1420 
1421  if (!(sc = ec_master_get_config_const(
1422  master, ioctl->config_index))) {
1423  up(&master->master_sem);
1424  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1425  ioctl->config_index);
1426  kfree(ioctl);
1427  return -EINVAL;
1428  }
1429 
1431  sc, ioctl->sdo_pos))) {
1432  up(&master->master_sem);
1433  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1434  kfree(ioctl);
1435  return -EINVAL;
1436  }
1437 
1438  ioctl->index = req->index;
1439  ioctl->subindex = req->subindex;
1440  ioctl->size = req->data_size;
1441  memcpy(ioctl->data, req->data,
1442  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1443  ioctl->complete_access = req->complete_access;
1444 
1445  up(&master->master_sem);
1446 
1447  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1448  kfree(ioctl);
1449  return -EFAULT;
1450  }
1451 
1452  kfree(ioctl);
1453  return 0;
1454 }
1455 
1456 /****************************************************************************/
1457 
1463  ec_master_t *master,
1464  void *arg
1465  )
1466 {
1467  ec_ioctl_config_idn_t *ioctl;
1468  const ec_slave_config_t *sc;
1469  const ec_soe_request_t *req;
1470 
1471  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1472  return -ENOMEM;
1473  }
1474 
1475  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1476  kfree(ioctl);
1477  return -EFAULT;
1478  }
1479 
1480  if (down_interruptible(&master->master_sem)) {
1481  kfree(ioctl);
1482  return -EINTR;
1483  }
1484 
1485  if (!(sc = ec_master_get_config_const(
1486  master, ioctl->config_index))) {
1487  up(&master->master_sem);
1488  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1489  ioctl->config_index);
1490  kfree(ioctl);
1491  return -EINVAL;
1492  }
1493 
1495  sc, ioctl->idn_pos))) {
1496  up(&master->master_sem);
1497  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1498  kfree(ioctl);
1499  return -EINVAL;
1500  }
1501 
1502  ioctl->drive_no = req->drive_no;
1503  ioctl->idn = req->idn;
1504  ioctl->state = req->al_state;
1505  ioctl->size = req->data_size;
1506  memcpy(ioctl->data, req->data,
1507  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1508 
1509  up(&master->master_sem);
1510 
1511  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1512  kfree(ioctl);
1513  return -EFAULT;
1514  }
1515 
1516  kfree(ioctl);
1517  return 0;
1518 }
1519 
1520 /****************************************************************************/
1521 
1527  ec_master_t *master,
1528  void *arg
1529  )
1530 {
1531  ec_ioctl_config_flag_t *ioctl;
1532  const ec_slave_config_t *sc;
1533  const ec_flag_t *flag;
1534  size_t size;
1535 
1536  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1537  return -ENOMEM;
1538  }
1539 
1540  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1541  kfree(ioctl);
1542  return -EFAULT;
1543  }
1544 
1545  if (down_interruptible(&master->master_sem)) {
1546  kfree(ioctl);
1547  return -EINTR;
1548  }
1549 
1550  if (!(sc = ec_master_get_config_const(
1551  master, ioctl->config_index))) {
1552  up(&master->master_sem);
1553  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1554  ioctl->config_index);
1555  kfree(ioctl);
1556  return -EINVAL;
1557  }
1558 
1560  sc, ioctl->flag_pos))) {
1561  up(&master->master_sem);
1562  EC_MASTER_ERR(master, "Invalid flag position!\n");
1563  kfree(ioctl);
1564  return -EINVAL;
1565  }
1566 
1567  size = min((u32) strlen(flag->key), (u32) EC_MAX_FLAG_KEY_SIZE - 1);
1568  memcpy(ioctl->key, flag->key, size);
1569  ioctl->key[size] = 0x00;
1570  ioctl->value = flag->value;
1571 
1572  up(&master->master_sem);
1573 
1574  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1575  kfree(ioctl);
1576  return -EFAULT;
1577  }
1578 
1579  kfree(ioctl);
1580  return 0;
1581 }
1582 
1583 /****************************************************************************/
1584 
1585 #ifdef EC_EOE
1586 
1592  ec_master_t *master,
1593  void *arg
1594  )
1595 {
1596  ec_ioctl_eoe_handler_t data;
1597  const ec_eoe_t *eoe;
1598 
1599  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1600  return -EFAULT;
1601  }
1602 
1603  if (down_interruptible(&master->master_sem))
1604  return -EINTR;
1605 
1606  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1607  up(&master->master_sem);
1608  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1609  data.eoe_index);
1610  return -EINVAL;
1611  }
1612 
1613  if (eoe->slave) {
1614  data.slave_position = eoe->slave->ring_position;
1615  } else {
1616  data.slave_position = 0xffff;
1617  }
1618  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1619  data.open = eoe->opened;
1620  data.rx_bytes = eoe->stats.tx_bytes;
1621  data.rx_rate = eoe->tx_rate;
1622  data.tx_bytes = eoe->stats.rx_bytes;
1623  data.tx_rate = eoe->tx_rate;
1624  data.tx_queued_frames = eoe->tx_queued_frames;
1625  data.tx_queue_size = eoe->tx_queue_size;
1626 
1627  up(&master->master_sem);
1628 
1629  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1630  return -EFAULT;
1631 
1632  return 0;
1633 }
1634 
1635 #endif
1636 
1637 /****************************************************************************/
1638 
1639 #ifdef EC_EOE
1640 
1645  ec_master_t *master,
1646  void *arg
1647  )
1648 {
1649  ec_ioctl_slave_eoe_ip_t io;
1650  ec_eoe_request_t req;
1651  ec_slave_t *slave;
1652 
1653  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1654  return -EFAULT;
1655  }
1656 
1657  // init EoE request
1658  ec_eoe_request_init(&req);
1659 
1660  req.mac_address_included = io.mac_address_included;
1661  req.ip_address_included = io.ip_address_included;
1662  req.subnet_mask_included = io.subnet_mask_included;
1663  req.gateway_included = io.gateway_included;
1664  req.dns_included = io.dns_included;
1665  req.name_included = io.name_included;
1666 
1667  memcpy(req.mac_address, io.mac_address, ETH_ALEN);
1668  req.ip_address = io.ip_address;
1669  req.subnet_mask = io.subnet_mask;
1670  req.gateway = io.gateway;
1671  req.dns = io.dns;
1672  memcpy(req.name, io.name, EC_MAX_HOSTNAME_SIZE);
1673 
1674  req.state = EC_INT_REQUEST_QUEUED;
1675 
1676  if (down_interruptible(&master->master_sem)) {
1677  return -EINTR;
1678  }
1679 
1680  if (!(slave = ec_master_find_slave(
1681  master, 0, io.slave_position))) {
1682  up(&master->master_sem);
1683  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1684  io.slave_position);
1685  return -EINVAL;
1686  }
1687 
1688  EC_MASTER_DBG(master, 1, "Scheduling EoE request.\n");
1689 
1690  // schedule request.
1691  list_add_tail(&req.list, &slave->eoe_requests);
1692 
1693  up(&master->master_sem);
1694 
1695  // wait for processing through FSM
1696  if (wait_event_interruptible(master->request_queue,
1697  req.state != EC_INT_REQUEST_QUEUED)) {
1698  // interrupted by signal
1699  down(&master->master_sem);
1700  if (req.state == EC_INT_REQUEST_QUEUED) {
1701  // abort request
1702  list_del(&req.list);
1703  up(&master->master_sem);
1704  return -EINTR;
1705  }
1706  up(&master->master_sem);
1707  }
1708 
1709  // wait until master FSM has finished processing
1710  wait_event(master->request_queue, req.state != EC_INT_REQUEST_BUSY);
1711 
1712  io.result = req.result;
1713 
1714  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
1715  return -EFAULT;
1716  }
1717 
1718  return req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1719 }
1720 #endif
1721 
1722 /*****************************************************************************/
1723 
1729  ec_master_t *master,
1730  void *arg,
1731  ec_ioctl_context_t *ctx
1732  )
1733 {
1734  ec_master_t *m;
1735  int ret = 0;
1736 
1737  m = ecrt_request_master_err(master->index);
1738  if (IS_ERR(m)) {
1739  ret = PTR_ERR(m);
1740  } else {
1741  ctx->requested = 1;
1742  }
1743 
1744  return ret;
1745 }
1746 
1747 /****************************************************************************/
1748 
1754  ec_master_t *master,
1755  void *arg,
1756  ec_ioctl_context_t *ctx
1757  )
1758 {
1759  ec_domain_t *domain;
1760 
1761  if (unlikely(!ctx->requested))
1762  return -EPERM;
1763 
1764  domain = ecrt_master_create_domain_err(master);
1765  if (IS_ERR(domain))
1766  return PTR_ERR(domain);
1767 
1768  return domain->index;
1769 }
1770 
1771 /****************************************************************************/
1772 
1778  ec_master_t *master,
1779  void *arg,
1780  ec_ioctl_context_t *ctx
1781  )
1782 {
1783  ec_ioctl_config_t data;
1784  ec_slave_config_t *sc, *entry;
1785 
1786  if (unlikely(!ctx->requested))
1787  return -EPERM;
1788 
1789  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1790  return -EFAULT;
1791  }
1792 
1793  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1794  data.vendor_id, data.product_code);
1795  if (IS_ERR(sc))
1796  return PTR_ERR(sc);
1797 
1798  data.config_index = 0;
1799 
1800  if (down_interruptible(&master->master_sem))
1801  return -EINTR;
1802 
1803  list_for_each_entry(entry, &master->configs, list) {
1804  if (entry == sc)
1805  break;
1806  data.config_index++;
1807  }
1808 
1809  up(&master->master_sem);
1810 
1811  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1812  return -EFAULT;
1813 
1814  return 0;
1815 }
1816 
1817 /****************************************************************************/
1818 
1824  ec_master_t *master,
1825  void *arg,
1826  ec_ioctl_context_t *ctx
1827  )
1828 {
1829  unsigned long config_index = (unsigned long) arg;
1830  ec_slave_config_t *sc = NULL;
1831  int ret = 0;
1832 
1833  if (unlikely(!ctx->requested)) {
1834  ret = -EPERM;
1835  goto out_return;
1836  }
1837 
1838  if (down_interruptible(&master->master_sem)) {
1839  ret = -EINTR;
1840  goto out_return;
1841  }
1842 
1843  if (config_index != 0xFFFFFFFF) {
1844  if (!(sc = ec_master_get_config(master, config_index))) {
1845  ret = -ENOENT;
1846  goto out_up;
1847  }
1848  }
1849 
1851 
1852 out_up:
1853  up(&master->master_sem);
1854 out_return:
1855  return ret;
1856 }
1857 
1858 /****************************************************************************/
1859 
1865  ec_master_t *master,
1866  void *arg,
1867  ec_ioctl_context_t *ctx
1868  )
1869 {
1870  ec_ioctl_master_activate_t io;
1871  ec_domain_t *domain;
1872  off_t offset;
1873  int ret;
1874 
1875  if (unlikely(!ctx->requested))
1876  return -EPERM;
1877 
1878  io.process_data = NULL;
1879 
1880  /* Get the sum of the domains' process data sizes. */
1881 
1882  ctx->process_data_size = 0;
1883 
1884  if (down_interruptible(&master->master_sem))
1885  return -EINTR;
1886 
1887  list_for_each_entry(domain, &master->domains, list) {
1888  ctx->process_data_size += ecrt_domain_size(domain);
1889  }
1890 
1891  up(&master->master_sem);
1892 
1893  if (ctx->process_data_size) {
1894  ctx->process_data = vmalloc(ctx->process_data_size);
1895  if (!ctx->process_data) {
1896  ctx->process_data_size = 0;
1897  return -ENOMEM;
1898  }
1899 
1900  /* Set the memory as external process data memory for the
1901  * domains.
1902  */
1903  offset = 0;
1904  list_for_each_entry(domain, &master->domains, list) {
1906  ctx->process_data + offset);
1907  offset += ecrt_domain_size(domain);
1908  }
1909 
1910 #if defined(EC_IOCTL_RTDM) && !defined(EC_RTDM_XENOMAI_V3)
1911  /* RTDM uses a different approach for memory-mapping, which has to be
1912  * initiated by the kernel.
1913  */
1914  ret = ec_rtdm_mmap(ctx, &io.process_data);
1915  if (ret < 0) {
1916  EC_MASTER_ERR(master, "Failed to map process data"
1917  " memory to user space (code %i).\n", ret);
1918  return ret;
1919  }
1920 #endif
1921  }
1922 
1923  io.process_data_size = ctx->process_data_size;
1924 
1925 #ifndef EC_IOCTL_RTDM
1926  /* RTDM does not support locking yet. */
1929 #endif
1930 
1931  ret = ecrt_master_activate(master);
1932  if (ret < 0)
1933  return ret;
1934 
1935  if (copy_to_user((void __user *) arg, &io,
1936  sizeof(ec_ioctl_master_activate_t)))
1937  return -EFAULT;
1938 
1939  return 0;
1940 }
1941 
1942 /****************************************************************************/
1943 
1949  ec_master_t *master,
1950  void *arg,
1951  ec_ioctl_context_t *ctx
1952  )
1953 {
1954  if (unlikely(!ctx->requested))
1955  return -EPERM;
1956 
1957  return ecrt_master_deactivate(master);
1958 }
1959 
1960 /****************************************************************************/
1961 
1967  ec_master_t *master,
1968  void *arg,
1969  ec_ioctl_context_t *ctx
1970  )
1971 {
1972  size_t send_interval;
1973 
1974  if (unlikely(!ctx->requested)) {
1975  return -EPERM;
1976  }
1977 
1978  if (copy_from_user(&send_interval, (void __user *) arg,
1979  sizeof(send_interval))) {
1980  return -EFAULT;
1981  }
1982 
1983  if (down_interruptible(&master->master_sem))
1984  return -EINTR;
1985 
1986  ec_master_set_send_interval(master, send_interval);
1987 
1988  up(&master->master_sem);
1989  return 0;
1990 }
1991 
1992 /****************************************************************************/
1993 
1999  ec_master_t *master,
2000  void *arg,
2001  ec_ioctl_context_t *ctx
2002  )
2003 {
2004  int ret;
2005 
2006  if (unlikely(!ctx->requested)) {
2007  return -EPERM;
2008  }
2009 
2010  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2011  return -EINTR;
2012 
2013  ret = ecrt_master_send(master);
2014  ec_ioctl_unlock(&master->io_mutex);
2015  return ret;
2016 }
2017 
2018 /****************************************************************************/
2019 
2025  ec_master_t *master,
2026  void *arg,
2027  ec_ioctl_context_t *ctx
2028  )
2029 {
2030  int ret;
2031 
2032  if (unlikely(!ctx->requested)) {
2033  return -EPERM;
2034  }
2035 
2036  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2037  return -EINTR;
2038 
2039  ret = ecrt_master_receive(master);
2040  ec_ioctl_unlock(&master->io_mutex);
2041  return ret;
2042 }
2043 
2044 /****************************************************************************/
2045 
2051  ec_master_t *master,
2052  void *arg,
2053  ec_ioctl_context_t *ctx
2054  )
2055 {
2056  ec_master_state_t data;
2057  int ret;
2058 
2059  ret = ecrt_master_state(master, &data);
2060  if (ret)
2061  return ret;
2062 
2063  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
2064  return -EFAULT;
2065 
2066  return 0;
2067 }
2068 
2069 /****************************************************************************/
2070 
2076  ec_master_t *master,
2077  void *arg,
2078  ec_ioctl_context_t *ctx
2079  )
2080 {
2081  ec_ioctl_link_state_t ioctl;
2082  ec_master_link_state_t state;
2083  int ret;
2084 
2085  if (ec_copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl), ctx)) {
2086  return -EFAULT;
2087  }
2088 
2089  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
2090  if (ret < 0) {
2091  return ret;
2092  }
2093 
2094  if (ec_copy_to_user((void __user *) ioctl.state,
2095  &state, sizeof(state), ctx)) {
2096  return -EFAULT;
2097  }
2098 
2099  return 0;
2100 }
2101 
2102 /****************************************************************************/
2103 
2109  ec_master_t *master,
2110  void *arg,
2111  ec_ioctl_context_t *ctx
2112  )
2113 {
2114  uint64_t time;
2115 
2116  if (unlikely(!ctx->requested))
2117  return -EPERM;
2118 
2119  if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) {
2120  return -EFAULT;
2121  }
2122 
2123  return ecrt_master_application_time(master, time);
2124 }
2125 
2126 /****************************************************************************/
2127 
2133  ec_master_t *master,
2134  void *arg,
2135  ec_ioctl_context_t *ctx
2136  )
2137 {
2138  int ret;
2139 
2140  if (unlikely(!ctx->requested)) {
2141  return -EPERM;
2142  }
2143 
2144  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2145  return -EINTR;
2146 
2147  ret = ecrt_master_sync_reference_clock(master);
2148  ec_ioctl_unlock(&master->io_mutex);
2149  return ret;
2150 }
2151 
2152 /****************************************************************************/
2153 
2159  ec_master_t *master,
2160  void *arg,
2161  ec_ioctl_context_t *ctx
2162  )
2163 {
2164  int ret;
2165  uint64_t time;
2166 
2167  if (unlikely(!ctx->requested))
2168  return -EPERM;
2169 
2170  if (ec_copy_from_user(&time, (void __user *) arg, sizeof(time), ctx)) {
2171  return -EFAULT;
2172  }
2173 
2174  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2175  return -EINTR;
2176 
2177  ret = ecrt_master_sync_reference_clock_to(master, time);
2178  ec_ioctl_unlock(&master->io_mutex);
2179  return ret;
2180 }
2181 
2182 /****************************************************************************/
2183 
2189  ec_master_t *master,
2190  void *arg,
2191  ec_ioctl_context_t *ctx
2192  )
2193 {
2194  int ret;
2195 
2196  if (unlikely(!ctx->requested)) {
2197  return -EPERM;
2198  }
2199 
2200  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2201  return -EINTR;
2202 
2203  ret = ecrt_master_sync_slave_clocks(master);
2204  ec_ioctl_unlock(&master->io_mutex);
2205  return ret;
2206 }
2207 
2208 /****************************************************************************/
2209 
2215  ec_master_t *master,
2216  void *arg,
2217  ec_ioctl_context_t *ctx
2218  )
2219 {
2220  uint32_t time;
2221  int ret;
2222 
2223  if (unlikely(!ctx->requested)) {
2224  return -EPERM;
2225  }
2226 
2227  ret = ecrt_master_reference_clock_time(master, &time);
2228  if (ret) {
2229  return ret;
2230  }
2231 
2232  if (ec_copy_to_user((void __user *) arg, &time, sizeof(time), ctx)) {
2233  return -EFAULT;
2234  }
2235 
2236  return 0;
2237 }
2238 
2239 /****************************************************************************/
2240 
2246  ec_master_t *master,
2247  void *arg,
2248  ec_ioctl_context_t *ctx
2249  )
2250 {
2251  int ret;
2252 
2253  if (unlikely(!ctx->requested)) {
2254  return -EPERM;
2255  }
2256 
2257  if (ec_ioctl_lock_interruptible(&master->io_mutex))
2258  return -EINTR;
2259 
2260  ret = ecrt_master_sync_monitor_queue(master);
2261  ec_ioctl_unlock(&master->io_mutex);
2262  return ret;
2263 }
2264 
2265 /****************************************************************************/
2266 
2272  ec_master_t *master,
2273  void *arg,
2274  ec_ioctl_context_t *ctx
2275  )
2276 {
2277  uint32_t time_diff;
2278 
2279  if (unlikely(!ctx->requested))
2280  return -EPERM;
2281 
2282  time_diff = ecrt_master_sync_monitor_process(master);
2283 
2284  if (ec_copy_to_user((void __user *) arg, &time_diff,
2285  sizeof(time_diff), ctx))
2286  return -EFAULT;
2287 
2288  return 0;
2289 }
2290 
2291 /****************************************************************************/
2292 
2298  ec_master_t *master,
2299  void *arg,
2300  ec_ioctl_context_t *ctx
2301  )
2302 {
2303 #ifdef EC_IOCTL_RTDM
2304  /* Xenomai/LXRT is like NMI context, so we do a two-stage schedule. */
2305  irq_work_queue(&master->sc_reset_work_kicker);
2306 #else
2307  schedule_work(&master->sc_reset_work);
2308 #endif
2309  return 0;
2310 }
2311 
2312 /****************************************************************************/
2313 
2319  ec_master_t *master,
2320  void *arg,
2321  ec_ioctl_context_t *ctx
2322  )
2323 {
2324  ec_ioctl_config_t data;
2325  ec_slave_config_t *sc;
2326  unsigned int i;
2327  int ret = 0;
2328 
2329  if (unlikely(!ctx->requested)) {
2330  ret = -EPERM;
2331  goto out_return;
2332  }
2333 
2334  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2335  ret = -EFAULT;
2336  goto out_return;
2337  }
2338 
2339  if (down_interruptible(&master->master_sem)) {
2340  ret = -EINTR;
2341  goto out_return;
2342  }
2343 
2344  if (!(sc = ec_master_get_config(master, data.config_index))) {
2345  ret = -ENOENT;
2346  goto out_up;
2347  }
2348 
2349  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2350  if (data.syncs[i].config_this) {
2351  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2352  data.syncs[i].watchdog_mode);
2353  if (ret) {
2354  goto out_up;
2355  }
2356  }
2357  }
2358 
2359 out_up:
2360  up(&master->master_sem);
2361 out_return:
2362  return ret;
2363 }
2364 
2365 /****************************************************************************/
2366 
2372  ec_master_t *master,
2373  void *arg,
2374  ec_ioctl_context_t *ctx
2375  )
2376 {
2377  ec_ioctl_config_t data;
2378  ec_slave_config_t *sc;
2379  int ret = 0;
2380 
2381  if (unlikely(!ctx->requested)) {
2382  ret = -EPERM;
2383  goto out_return;
2384  }
2385 
2386  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2387  ret = -EFAULT;
2388  goto out_return;
2389  }
2390 
2391  if (down_interruptible(&master->master_sem)) {
2392  ret = -EINTR;
2393  goto out_return;
2394  }
2395 
2396  if (!(sc = ec_master_get_config(master, data.config_index))) {
2397  ret = -ENOENT;
2398  goto out_up;
2399  }
2400 
2401  ret = ecrt_slave_config_watchdog(sc,
2402  data.watchdog_divider, data.watchdog_intervals);
2403 
2404 out_up:
2405  up(&master->master_sem);
2406 out_return:
2407  return ret;
2408 }
2409 
2410 /****************************************************************************/
2411 
2417  ec_master_t *master,
2418  void *arg,
2419  ec_ioctl_context_t *ctx
2420  )
2421 {
2422  ec_ioctl_config_pdo_t data;
2423  ec_slave_config_t *sc;
2424 
2425  if (unlikely(!ctx->requested))
2426  return -EPERM;
2427 
2428  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2429  return -EFAULT;
2430 
2431  if (down_interruptible(&master->master_sem))
2432  return -EINTR;
2433 
2434  if (!(sc = ec_master_get_config(master, data.config_index))) {
2435  up(&master->master_sem);
2436  return -ENOENT;
2437  }
2438 
2439  up(&master->master_sem);
2441  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2442 }
2443 
2444 /****************************************************************************/
2445 
2451  ec_master_t *master,
2452  void *arg,
2453  ec_ioctl_context_t *ctx
2454  )
2455 {
2456  ec_ioctl_config_pdo_t data;
2457  ec_slave_config_t *sc;
2458 
2459  if (unlikely(!ctx->requested))
2460  return -EPERM;
2461 
2462  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2463  return -EFAULT;
2464 
2465  if (down_interruptible(&master->master_sem))
2466  return -EINTR;
2467 
2468  if (!(sc = ec_master_get_config(master, data.config_index))) {
2469  up(&master->master_sem);
2470  return -ENOENT;
2471  }
2472 
2473  up(&master->master_sem);
2475  return ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2476 }
2477 
2478 /****************************************************************************/
2479 
2485  ec_master_t *master,
2486  void *arg,
2487  ec_ioctl_context_t *ctx
2488  )
2489 {
2490  ec_ioctl_add_pdo_entry_t data;
2491  ec_slave_config_t *sc;
2492 
2493  if (unlikely(!ctx->requested))
2494  return -EPERM;
2495 
2496  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2497  return -EFAULT;
2498 
2499  if (down_interruptible(&master->master_sem))
2500  return -EINTR;
2501 
2502  if (!(sc = ec_master_get_config(master, data.config_index))) {
2503  up(&master->master_sem);
2504  return -ENOENT;
2505  }
2506 
2507  up(&master->master_sem);
2509  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2510  data.entry_index, data.entry_subindex, data.entry_bit_length);
2511 }
2512 
2513 /****************************************************************************/
2514 
2520  ec_master_t *master,
2521  void *arg,
2522  ec_ioctl_context_t *ctx
2523  )
2524 {
2525  ec_ioctl_config_pdo_t data;
2526  ec_slave_config_t *sc;
2527 
2528  if (unlikely(!ctx->requested))
2529  return -EPERM;
2530 
2531  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2532  return -EFAULT;
2533 
2534  if (down_interruptible(&master->master_sem))
2535  return -EINTR;
2536 
2537  if (!(sc = ec_master_get_config(master, data.config_index))) {
2538  up(&master->master_sem);
2539  return -ENOENT;
2540  }
2541 
2542  up(&master->master_sem);
2544  return ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2545 }
2546 
2547 /****************************************************************************/
2548 
2554  ec_master_t *master,
2555  void *arg,
2556  ec_ioctl_context_t *ctx
2557  )
2558 {
2559  ec_ioctl_reg_pdo_entry_t data;
2560  ec_slave_config_t *sc;
2561  ec_domain_t *domain;
2562  int ret;
2563 
2564  if (unlikely(!ctx->requested))
2565  return -EPERM;
2566 
2567  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2568  return -EFAULT;
2569 
2570  if (down_interruptible(&master->master_sem))
2571  return -EINTR;
2572 
2573  if (!(sc = ec_master_get_config(master, data.config_index))) {
2574  up(&master->master_sem);
2575  return -ENOENT;
2576  }
2577 
2578  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2579  up(&master->master_sem);
2580  return -ENOENT;
2581  }
2582 
2583  up(&master->master_sem);
2585  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2586  data.entry_subindex, domain, &data.bit_position);
2587 
2588  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2589  return -EFAULT;
2590 
2591  return ret;
2592 }
2593 
2594 /****************************************************************************/
2595 
2601  ec_master_t *master,
2602  void *arg,
2603  ec_ioctl_context_t *ctx
2604  )
2605 {
2606  ec_ioctl_reg_pdo_pos_t io;
2607  ec_slave_config_t *sc;
2608  ec_domain_t *domain;
2609  int ret;
2610 
2611  if (unlikely(!ctx->requested)) {
2612  return -EPERM;
2613  }
2614 
2615  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2616  return -EFAULT;
2617  }
2618 
2619  if (down_interruptible(&master->master_sem)) {
2620  return -EINTR;
2621  }
2622 
2623  if (!(sc = ec_master_get_config(master, io.config_index))) {
2624  up(&master->master_sem);
2625  return -ENOENT;
2626  }
2627 
2628  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2629  up(&master->master_sem);
2630  return -ENOENT;
2631  }
2632 
2633  up(&master->master_sem);
2635  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2636  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2637 
2638  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2639  return -EFAULT;
2640 
2641  return ret;
2642 }
2643 
2644 /****************************************************************************/
2645 
2651  ec_master_t *master,
2652  void *arg,
2653  ec_ioctl_context_t *ctx
2654  )
2655 {
2656  ec_ioctl_config_t data;
2657  ec_slave_config_t *sc;
2658  int ret;
2659 
2660  if (unlikely(!ctx->requested))
2661  return -EPERM;
2662 
2663  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2664  return -EFAULT;
2665 
2666  if (down_interruptible(&master->master_sem))
2667  return -EINTR;
2668 
2669  if (!(sc = ec_master_get_config(master, data.config_index))) {
2670  up(&master->master_sem);
2671  return -ENOENT;
2672  }
2673 
2675  data.dc_sync[0].cycle_time,
2676  data.dc_sync[0].shift_time,
2677  data.dc_sync[1].cycle_time,
2678  data.dc_sync[1].shift_time);
2679 
2680  up(&master->master_sem);
2681 
2682  return ret;
2683 }
2684 
2685 /****************************************************************************/
2686 
2692  ec_master_t *master,
2693  void *arg,
2694  ec_ioctl_context_t *ctx
2695  )
2696 {
2697  ec_ioctl_sc_sdo_t data;
2698  ec_slave_config_t *sc;
2699  uint8_t *sdo_data = NULL;
2700  int ret;
2701 
2702  if (unlikely(!ctx->requested))
2703  return -EPERM;
2704 
2705  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2706  return -EFAULT;
2707 
2708  if (!data.size)
2709  return -EINVAL;
2710 
2711  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2712  return -ENOMEM;
2713  }
2714 
2715  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2716  kfree(sdo_data);
2717  return -EFAULT;
2718  }
2719 
2720  if (down_interruptible(&master->master_sem)) {
2721  kfree(sdo_data);
2722  return -EINTR;
2723  }
2724 
2725  if (!(sc = ec_master_get_config(master, data.config_index))) {
2726  up(&master->master_sem);
2727  kfree(sdo_data);
2728  return -ENOENT;
2729  }
2730 
2731  up(&master->master_sem);
2733  if (data.complete_access) {
2735  data.index, sdo_data, data.size);
2736  } else {
2737  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2738  data.size);
2739  }
2740  kfree(sdo_data);
2741  return ret;
2742 }
2743 
2744 /****************************************************************************/
2745 
2751  ec_master_t *master,
2752  void *arg,
2753  ec_ioctl_context_t *ctx
2754  )
2755 {
2756  ec_ioctl_sc_emerg_t io;
2757  ec_slave_config_t *sc;
2758  int ret;
2759 
2760  if (unlikely(!ctx->requested))
2761  return -EPERM;
2762 
2763  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2764  return -EFAULT;
2765 
2766  if (down_interruptible(&master->master_sem)) {
2767  return -EINTR;
2768  }
2769 
2770  if (!(sc = ec_master_get_config(master, io.config_index))) {
2771  up(&master->master_sem);
2772  return -ENOENT;
2773  }
2774 
2775  ret = ecrt_slave_config_emerg_size(sc, io.size);
2776 
2777  up(&master->master_sem);
2778 
2779  return ret;
2780 }
2781 
2782 /****************************************************************************/
2783 
2789  ec_master_t *master,
2790  void *arg,
2791  ec_ioctl_context_t *ctx
2792  )
2793 {
2794  ec_ioctl_sc_emerg_t io;
2795  ec_slave_config_t *sc;
2796  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
2797  int ret;
2798 
2799  if (unlikely(!ctx->requested)) {
2800  return -EPERM;
2801  }
2802 
2803  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2804  return -EFAULT;
2805  }
2806 
2807  /* no locking of master_sem needed, because configuration will not be
2808  * deleted in the meantime. */
2809 
2810  if (!(sc = ec_master_get_config(master, io.config_index))) {
2811  return -ENOENT;
2812  }
2813 
2814  ret = ecrt_slave_config_emerg_pop(sc, msg);
2815  if (ret < 0) {
2816  return ret;
2817  }
2818 
2819  if (ec_copy_to_user((void __user *) io.target, msg, sizeof(msg), ctx)) {
2820  return -EFAULT;
2821  }
2822 
2823  return ret;
2824 }
2825 
2826 /****************************************************************************/
2827 
2833  ec_master_t *master,
2834  void *arg,
2835  ec_ioctl_context_t *ctx
2836  )
2837 {
2838  ec_ioctl_sc_emerg_t io;
2839  ec_slave_config_t *sc;
2840 
2841  if (unlikely(!ctx->requested)) {
2842  return -EPERM;
2843  }
2844 
2845  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2846  return -EFAULT;
2847  }
2848 
2849  /* no locking of master_sem needed, because configuration will not be
2850  * deleted in the meantime. */
2851 
2852  if (!(sc = ec_master_get_config(master, io.config_index))) {
2853  return -ENOENT;
2854  }
2855 
2856  return ecrt_slave_config_emerg_clear(sc);
2857 }
2858 
2859 /****************************************************************************/
2860 
2866  ec_master_t *master,
2867  void *arg,
2868  ec_ioctl_context_t *ctx
2869  )
2870 {
2871  ec_ioctl_sc_emerg_t io;
2872  ec_slave_config_t *sc;
2873  int ret;
2874 
2875  if (unlikely(!ctx->requested)) {
2876  return -EPERM;
2877  }
2878 
2879  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
2880  return -EFAULT;
2881  }
2882 
2883  /* no locking of master_sem needed, because configuration will not be
2884  * deleted in the meantime. */
2885 
2886  if (!(sc = ec_master_get_config(master, io.config_index))) {
2887  return -ENOENT;
2888  }
2889 
2891  if (ret < 0) {
2892  return ret;
2893  }
2894 
2895  io.overruns = ret;
2896 
2897  if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) {
2898  return -EFAULT;
2899  }
2900 
2901  return 0;
2902 }
2903 
2904 /****************************************************************************/
2905 
2911  ec_master_t *master,
2912  void *arg,
2913  ec_ioctl_context_t *ctx
2914  )
2915 {
2916  ec_ioctl_sdo_request_t data;
2917  ec_slave_config_t *sc;
2918  ec_sdo_request_t *req;
2919 
2920  if (unlikely(!ctx->requested))
2921  return -EPERM;
2922 
2923  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2924  return -EFAULT;
2925  }
2926 
2927  data.request_index = 0;
2928 
2929  if (down_interruptible(&master->master_sem))
2930  return -EINTR;
2931 
2932  sc = ec_master_get_config(master, data.config_index);
2933  if (!sc) {
2934  up(&master->master_sem);
2935  return -ENOENT;
2936  }
2937 
2938  list_for_each_entry(req, &sc->sdo_requests, list) {
2939  data.request_index++;
2940  }
2941 
2942  up(&master->master_sem);
2944  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
2945  data.sdo_subindex, data.size);
2946  if (IS_ERR(req))
2947  return PTR_ERR(req);
2948 
2949  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2950  return -EFAULT;
2951 
2952  return 0;
2953 }
2954 
2955 /****************************************************************************/
2956 
2962  ec_master_t *master,
2963  void *arg,
2964  ec_ioctl_context_t *ctx
2965  )
2966 {
2967  ec_ioctl_soe_request_t data;
2968  ec_slave_config_t *sc;
2969  ec_soe_request_t *req;
2970 
2971  if (unlikely(!ctx->requested))
2972  return -EPERM;
2973 
2974  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2975  return -EFAULT;
2976  }
2977 
2978  data.request_index = 0;
2979 
2980  if (down_interruptible(&master->master_sem))
2981  return -EINTR;
2982 
2983  sc = ec_master_get_config(master, data.config_index);
2984  if (!sc) {
2985  up(&master->master_sem);
2986  return -ENOENT;
2987  }
2988 
2989  list_for_each_entry(req, &sc->soe_requests, list) {
2990  data.request_index++;
2991  }
2992 
2993  up(&master->master_sem);
2995  req = ecrt_slave_config_create_soe_request_err(sc, data.drive_no,
2996  data.idn, data.size);
2997  if (IS_ERR(req)) {
2998  return PTR_ERR(req);
2999  }
3000 
3001  if (copy_to_user((void __user *) arg, &data, sizeof(data))) {
3002  return -EFAULT;
3003  }
3004 
3005  return 0;
3006 }
3007 
3008 /****************************************************************************/
3009 
3015  ec_master_t *master,
3016  void *arg,
3017  ec_ioctl_context_t *ctx
3018  )
3019 {
3020  ec_ioctl_reg_request_t io;
3021  ec_slave_config_t *sc;
3022  ec_reg_request_t *reg;
3023 
3024  if (unlikely(!ctx->requested)) {
3025  return -EPERM;
3026  }
3027 
3028  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3029  return -EFAULT;
3030  }
3031 
3032  io.request_index = 0;
3033 
3034  if (down_interruptible(&master->master_sem)) {
3035  return -EINTR;
3036  }
3037 
3038  sc = ec_master_get_config(master, io.config_index);
3039  if (!sc) {
3040  up(&master->master_sem);
3041  return -ENOENT;
3042  }
3043 
3044  list_for_each_entry(reg, &sc->reg_requests, list) {
3045  io.request_index++;
3046  }
3047 
3048  up(&master->master_sem);
3050  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
3051  if (IS_ERR(reg)) {
3052  return PTR_ERR(reg);
3053  }
3054 
3055  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3056  return -EFAULT;
3057  }
3058 
3059  return 0;
3060 }
3061 
3062 /****************************************************************************/
3063 
3069  ec_master_t *master,
3070  void *arg,
3071  ec_ioctl_context_t *ctx
3072  )
3073 {
3074  ec_ioctl_voe_t data;
3075  ec_slave_config_t *sc;
3076  ec_voe_handler_t *voe;
3077 
3078  if (unlikely(!ctx->requested))
3079  return -EPERM;
3080 
3081  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3082  return -EFAULT;
3083  }
3084 
3085  data.voe_index = 0;
3086 
3087  if (down_interruptible(&master->master_sem))
3088  return -EINTR;
3089 
3090  sc = ec_master_get_config(master, data.config_index);
3091  if (!sc) {
3092  up(&master->master_sem);
3093  return -ENOENT;
3094  }
3095 
3096  list_for_each_entry(voe, &sc->voe_handlers, list) {
3097  data.voe_index++;
3098  }
3099 
3100  up(&master->master_sem);
3102  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
3103  if (IS_ERR(voe))
3104  return PTR_ERR(voe);
3105 
3106  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3107  return -EFAULT;
3108 
3109  return 0;
3110 }
3111 
3112 /****************************************************************************/
3113 
3119  ec_master_t *master,
3120  void *arg,
3121  ec_ioctl_context_t *ctx
3122  )
3123 {
3124  ec_ioctl_sc_state_t data;
3125  const ec_slave_config_t *sc;
3127  int ret;
3128 
3129  if (unlikely(!ctx->requested))
3130  return -EPERM;
3131 
3132  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) {
3133  return -EFAULT;
3134  }
3135 
3136  /* no locking of master_sem needed, because sc will not be deleted in the
3137  * meantime. */
3138 
3139  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
3140  return -ENOENT;
3141  }
3142 
3143  ret = ecrt_slave_config_state(sc, &state);
3144  if (ret)
3145  return ret;
3146 
3147  if (ec_copy_to_user((void __user *) data.state,
3148  &state, sizeof(state), ctx))
3149  return -EFAULT;
3150 
3151  return 0;
3152 }
3153 
3154 /****************************************************************************/
3155 
3161  ec_master_t *master,
3162  void *arg,
3163  ec_ioctl_context_t *ctx
3164  )
3165 {
3166  ec_ioctl_sc_idn_t ioctl;
3167  ec_slave_config_t *sc;
3168  uint8_t *data = NULL;
3169  int ret;
3170 
3171  if (unlikely(!ctx->requested))
3172  return -EPERM;
3173 
3174  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
3175  return -EFAULT;
3176 
3177  if (!ioctl.size)
3178  return -EINVAL;
3179 
3180  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
3181  return -ENOMEM;
3182  }
3183 
3184  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
3185  kfree(data);
3186  return -EFAULT;
3187  }
3188 
3189  if (down_interruptible(&master->master_sem)) {
3190  kfree(data);
3191  return -EINTR;
3192  }
3193 
3194  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3195  up(&master->master_sem);
3196  kfree(data);
3197  return -ENOENT;
3198  }
3199 
3200  up(&master->master_sem);
3202  ret = ecrt_slave_config_idn(
3203  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3204  kfree(data);
3205  return ret;
3206 }
3207 
3208 /****************************************************************************/
3209 
3215  ec_master_t *master,
3216  void *arg,
3217  ec_ioctl_context_t *ctx
3218  )
3219 {
3220  ec_ioctl_sc_flag_t ioctl;
3221  ec_slave_config_t *sc;
3222  uint8_t *key;
3223  int ret;
3224 
3225  if (unlikely(!ctx->requested)) {
3226  return -EPERM;
3227  }
3228 
3229  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3230  return -EFAULT;
3231  }
3232 
3233  if (!ioctl.key_size) {
3234  return -EINVAL;
3235  }
3236 
3237  if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3238  return -ENOMEM;
3239  }
3240 
3241  if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3242  kfree(key);
3243  return -EFAULT;
3244  }
3245  key[ioctl.key_size] = '\0';
3246 
3247  if (down_interruptible(&master->master_sem)) {
3248  kfree(key);
3249  return -EINTR;
3250  }
3251 
3252  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3253  up(&master->master_sem);
3254  kfree(key);
3255  return -ENOENT;
3256  }
3257 
3258  up(&master->master_sem);
3260  ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3261  kfree(key);
3262  return ret;
3263 }
3264 
3265 /****************************************************************************/
3266 
3272  ec_master_t *master,
3273  void *arg,
3274  ec_ioctl_context_t *ctx
3275  )
3276 {
3277  const ec_domain_t *domain;
3278 
3279  if (unlikely(!ctx->requested)) {
3280  return -EPERM;
3281  }
3282 
3283  if (down_interruptible(&master->master_sem)) {
3284  return -EINTR;
3285  }
3286 
3287  list_for_each_entry(domain, &master->domains, list) {
3288  if (domain->index == (unsigned long) arg) {
3289  size_t size = ecrt_domain_size(domain);
3290  up(&master->master_sem);
3291  return size;
3292  }
3293  }
3294 
3295  up(&master->master_sem);
3296  return -ENOENT;
3297 }
3298 
3299 /****************************************************************************/
3300 
3306  ec_master_t *master,
3307  void *arg,
3308  ec_ioctl_context_t *ctx
3309  )
3310 {
3311  int offset = 0;
3312  const ec_domain_t *domain;
3313 
3314  if (unlikely(!ctx->requested))
3315  return -EPERM;
3316 
3317  if (down_interruptible(&master->master_sem)) {
3318  return -EINTR;
3319  }
3320 
3321  list_for_each_entry(domain, &master->domains, list) {
3322  if (domain->index == (unsigned long) arg) {
3323  up(&master->master_sem);
3324  return offset;
3325  }
3326  offset += ecrt_domain_size(domain);
3327  }
3328 
3329  up(&master->master_sem);
3330  return -ENOENT;
3331 }
3332 
3333 /****************************************************************************/
3334 
3340  ec_master_t *master,
3341  void *arg,
3342  ec_ioctl_context_t *ctx
3343  )
3344 {
3345  ec_domain_t *domain;
3346 
3347  if (unlikely(!ctx->requested))
3348  return -EPERM;
3349 
3350  /* no locking of master_sem needed, because domain will not be deleted in
3351  * the meantime. */
3352 
3353  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3354  return -ENOENT;
3355  }
3356 
3357  return ecrt_domain_process(domain);
3358 }
3359 
3360 /****************************************************************************/
3361 
3367  ec_master_t *master,
3368  void *arg,
3369  ec_ioctl_context_t *ctx
3370  )
3371 {
3372  ec_domain_t *domain;
3373  int ret;
3374 
3375  if (unlikely(!ctx->requested))
3376  return -EPERM;
3377 
3378  /* no locking of master_sem needed, because domain will not be deleted in
3379  * the meantime. */
3380 
3381  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3382  return -ENOENT;
3383  }
3384 
3385  if (ec_ioctl_lock_interruptible(&master->io_mutex))
3386  return -EINTR;
3387 
3388  ret = ecrt_domain_queue(domain);
3389  ec_ioctl_unlock(&master->io_mutex);
3390  return ret;
3391 }
3392 
3393 /****************************************************************************/
3394 
3400  ec_master_t *master,
3401  void *arg,
3402  ec_ioctl_context_t *ctx
3403  )
3404 {
3405  ec_ioctl_domain_state_t data;
3406  const ec_domain_t *domain;
3407  ec_domain_state_t state;
3408  int ret;
3409 
3410  if (unlikely(!ctx->requested))
3411  return -EPERM;
3412 
3413  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx)) {
3414  return -EFAULT;
3415  }
3416 
3417  /* no locking of master_sem needed, because domain will not be deleted in
3418  * the meantime. */
3419 
3420  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3421  return -ENOENT;
3422  }
3423 
3424  ret = ecrt_domain_state(domain, &state);
3425  if (ret)
3426  return ret;
3427 
3428  if (ec_copy_to_user((void __user *) data.state, &state, sizeof(state),
3429  ctx))
3430  return -EFAULT;
3431 
3432  return 0;
3433 }
3434 
3435 /****************************************************************************/
3436 
3442  ec_master_t *master,
3443  void *arg,
3444  ec_ioctl_context_t *ctx
3445  )
3446 {
3447  ec_ioctl_sdo_request_t data;
3448  ec_slave_config_t *sc;
3449  ec_sdo_request_t *req;
3450 
3451  if (unlikely(!ctx->requested))
3452  return -EPERM;
3453 
3454  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3455  return -EFAULT;
3456 
3457  /* no locking of master_sem needed, because neither sc nor req will not be
3458  * deleted in the meantime. */
3459 
3460  if (!(sc = ec_master_get_config(master, data.config_index))) {
3461  return -ENOENT;
3462  }
3463 
3464  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3465  return -ENOENT;
3466  }
3467 
3468  return ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3469 }
3470 
3471 /****************************************************************************/
3472 
3478  ec_master_t *master,
3479  void *arg,
3480  ec_ioctl_context_t *ctx
3481  )
3482 {
3483  ec_ioctl_sdo_request_t data;
3484  ec_slave_config_t *sc;
3485  ec_sdo_request_t *req;
3486 
3487  if (unlikely(!ctx->requested))
3488  return -EPERM;
3489 
3490  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3491  return -EFAULT;
3492 
3493  /* no locking of master_sem needed, because neither sc nor req will not be
3494  * deleted in the meantime. */
3495 
3496  if (!(sc = ec_master_get_config(master, data.config_index))) {
3497  return -ENOENT;
3498  }
3499 
3500  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3501  return -ENOENT;
3502  }
3503 
3504  return ecrt_sdo_request_timeout(req, data.timeout);
3505 }
3506 
3507 /****************************************************************************/
3508 
3516  ec_master_t *master,
3517  void *arg,
3518  ec_ioctl_context_t *ctx
3519  )
3520 {
3521  ec_ioctl_sdo_request_t data;
3522  ec_slave_config_t *sc;
3523  ec_sdo_request_t *req;
3524 
3525  if (unlikely(!ctx->requested))
3526  return -EPERM;
3527 
3528  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3529  return -EFAULT;
3530 
3531  /* no locking of master_sem needed, because neither sc nor req will not be
3532  * deleted in the meantime. */
3533 
3534  if (!(sc = ec_master_get_config(master, data.config_index))) {
3535  return -ENOENT;
3536  }
3537 
3538  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3539  return -ENOENT;
3540  }
3541 
3542  data.state = ecrt_sdo_request_state(req);
3543  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3544  data.size = ecrt_sdo_request_data_size(req);
3545  else
3546  data.size = 0;
3547 
3548  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
3549  return -EFAULT;
3550 
3551  return 0;
3552 }
3553 
3554 /****************************************************************************/
3555 
3561  ec_master_t *master,
3562  void *arg,
3563  ec_ioctl_context_t *ctx
3564  )
3565 {
3566  ec_ioctl_sdo_request_t data;
3567  ec_slave_config_t *sc;
3568  ec_sdo_request_t *req;
3569 
3570  if (unlikely(!ctx->requested))
3571  return -EPERM;
3572 
3573  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3574  return -EFAULT;
3575 
3576  /* no locking of master_sem needed, because neither sc nor req will not be
3577  * deleted in the meantime. */
3578 
3579  if (!(sc = ec_master_get_config(master, data.config_index))) {
3580  return -ENOENT;
3581  }
3582 
3583  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3584  return -ENOENT;
3585  }
3586 
3587  return ecrt_sdo_request_read(req);
3588 }
3589 
3590 /****************************************************************************/
3591 
3597  ec_master_t *master,
3598  void *arg,
3599  ec_ioctl_context_t *ctx
3600  )
3601 {
3602  ec_ioctl_sdo_request_t data;
3603  ec_slave_config_t *sc;
3604  ec_sdo_request_t *req;
3605 
3606  if (unlikely(!ctx->requested))
3607  return -EPERM;
3608 
3609  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3610  return -EFAULT;
3611 
3612  if (!data.size) {
3613  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3614  return -EINVAL;
3615  }
3616 
3617  /* no locking of master_sem needed, because neither sc nor req will not be
3618  * deleted in the meantime. */
3619 
3620  if (!(sc = ec_master_get_config(master, data.config_index))) {
3621  return -ENOENT;
3622  }
3623 
3624  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3625  return -ENOENT;
3626  }
3627 
3628  if (data.size > req->mem_size)
3629  return -ENOBUFS;
3630 
3631  if (ec_copy_from_user(req->data, (void __user *) data.data,
3632  data.size, ctx))
3633  return -EFAULT;
3634 
3635  req->data_size = data.size;
3636  return ecrt_sdo_request_write(req);
3637 }
3638 
3639 /****************************************************************************/
3640 
3646  ec_master_t *master,
3647  void *arg,
3648  ec_ioctl_context_t *ctx
3649  )
3650 {
3651  ec_ioctl_sdo_request_t data;
3652  ec_slave_config_t *sc;
3653  ec_sdo_request_t *req;
3654 
3655  if (unlikely(!ctx->requested))
3656  return -EPERM;
3657 
3658  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3659  return -EFAULT;
3660 
3661  /* no locking of master_sem needed, because neither sc nor req will not be
3662  * deleted in the meantime. */
3663 
3664  if (!(sc = ec_master_get_config(master, data.config_index))) {
3665  return -ENOENT;
3666  }
3667 
3668  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3669  return -ENOENT;
3670  }
3671 
3672  if (ec_copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3673  ecrt_sdo_request_data_size(req), ctx))
3674  return -EFAULT;
3675 
3676  return 0;
3677 }
3678 
3679 /****************************************************************************/
3680 
3686  ec_master_t *master,
3687  void *arg,
3688  ec_ioctl_context_t *ctx
3689  )
3690 {
3691  ec_ioctl_soe_request_t data;
3692  ec_slave_config_t *sc;
3693  ec_soe_request_t *req;
3694 
3695  if (unlikely(!ctx->requested))
3696  return -EPERM;
3697 
3698  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3699  return -EFAULT;
3700 
3701  /* no locking of master_sem needed, because neither sc nor req will not be
3702  * deleted in the meantime. */
3703 
3704  if (!(sc = ec_master_get_config(master, data.config_index))) {
3705  return -ENOENT;
3706  }
3707 
3708  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3709  return -ENOENT;
3710  }
3711 
3712  return ecrt_soe_request_idn(req, data.drive_no, data.idn);
3713 }
3714 
3715 /****************************************************************************/
3716 
3722  ec_master_t *master,
3723  void *arg,
3724  ec_ioctl_context_t *ctx
3725  )
3726 {
3727  ec_ioctl_soe_request_t data;
3728  ec_slave_config_t *sc;
3729  ec_soe_request_t *req;
3730 
3731  if (unlikely(!ctx->requested))
3732  return -EPERM;
3733 
3734  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3735  return -EFAULT;
3736 
3737  /* no locking of master_sem needed, because neither sc nor req will not be
3738  * deleted in the meantime. */
3739 
3740  if (!(sc = ec_master_get_config(master, data.config_index))) {
3741  return -ENOENT;
3742  }
3743 
3744  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3745  return -ENOENT;
3746  }
3747 
3748  return ecrt_soe_request_timeout(req, data.timeout);
3749 }
3750 
3751 /****************************************************************************/
3752 
3758  ec_master_t *master,
3759  void *arg,
3760  ec_ioctl_context_t *ctx
3761  )
3762 {
3763  ec_ioctl_soe_request_t data;
3764  ec_slave_config_t *sc;
3765  ec_soe_request_t *req;
3766 
3767  if (unlikely(!ctx->requested))
3768  return -EPERM;
3769 
3770  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3771  return -EFAULT;
3772 
3773  /* no locking of master_sem needed, because neither sc nor req will not be
3774  * deleted in the meantime. */
3775 
3776  if (!(sc = ec_master_get_config(master, data.config_index))) {
3777  return -ENOENT;
3778  }
3779 
3780  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3781  return -ENOENT;
3782  }
3783 
3784  data.state = ecrt_soe_request_state(req);
3785  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT) {
3786  data.size = ecrt_soe_request_data_size(req);
3787  }
3788  else {
3789  data.size = 0;
3790  }
3791 
3792  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
3793  return -EFAULT;
3794 
3795  return 0;
3796 }
3797 
3798 /****************************************************************************/
3799 
3805  ec_master_t *master,
3806  void *arg,
3807  ec_ioctl_context_t *ctx
3808  )
3809 {
3810  ec_ioctl_soe_request_t data;
3811  ec_slave_config_t *sc;
3812  ec_soe_request_t *req;
3813 
3814  if (unlikely(!ctx->requested))
3815  return -EPERM;
3816 
3817  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3818  return -EFAULT;
3819 
3820  /* no locking of master_sem needed, because neither sc nor req will not be
3821  * deleted in the meantime. */
3822 
3823  if (!(sc = ec_master_get_config(master, data.config_index))) {
3824  return -ENOENT;
3825  }
3826 
3827  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3828  return -ENOENT;
3829  }
3830 
3831  return ecrt_soe_request_read(req);
3832 }
3833 
3834 /****************************************************************************/
3835 
3841  ec_master_t *master,
3842  void *arg,
3843  ec_ioctl_context_t *ctx
3844  )
3845 {
3846  ec_ioctl_soe_request_t data;
3847  ec_slave_config_t *sc;
3848  ec_soe_request_t *req;
3849 
3850  if (unlikely(!ctx->requested))
3851  return -EPERM;
3852 
3853  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3854  return -EFAULT;
3855 
3856  if (!data.size) {
3857  EC_MASTER_ERR(master, "IDN write: Data size may not be zero!\n");
3858  return -EINVAL;
3859  }
3860 
3861  /* no locking of master_sem needed, because neither sc nor req will not be
3862  * deleted in the meantime. */
3863 
3864  if (!(sc = ec_master_get_config(master, data.config_index))) {
3865  return -ENOENT;
3866  }
3867 
3868  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3869  return -ENOENT;
3870  }
3871 
3872  if (data.size > req->mem_size)
3873  return -ENOBUFS;
3874 
3875  if (ec_copy_from_user(req->data, (void __user *) data.data,
3876  data.size, ctx))
3877  return -EFAULT;
3878 
3879  req->data_size = data.size;
3880  return ecrt_soe_request_write(req);
3881 }
3882 
3883 /****************************************************************************/
3884 
3890  ec_master_t *master,
3891  void *arg,
3892  ec_ioctl_context_t *ctx
3893  )
3894 {
3895  ec_ioctl_soe_request_t data;
3896  ec_slave_config_t *sc;
3897  ec_soe_request_t *req;
3898 
3899  if (unlikely(!ctx->requested))
3900  return -EPERM;
3901 
3902  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
3903  return -EFAULT;
3904 
3905  /* no locking of master_sem needed, because neither sc nor req will not be
3906  * deleted in the meantime. */
3907 
3908  if (!(sc = ec_master_get_config(master, data.config_index))) {
3909  return -ENOENT;
3910  }
3911 
3912  if (!(req = ec_slave_config_find_soe_request(sc, data.request_index))) {
3913  return -ENOENT;
3914  }
3915 
3916  if (ec_copy_to_user((void __user *) data.data, ecrt_soe_request_data(req),
3917  ecrt_soe_request_data_size(req), ctx))
3918  return -EFAULT;
3919 
3920  return 0;
3921 }
3922 
3923 /****************************************************************************/
3924 
3930  ec_master_t *master,
3931  void *arg,
3932  ec_ioctl_context_t *ctx
3933  )
3934 {
3935  ec_ioctl_reg_request_t io;
3936  ec_slave_config_t *sc;
3937  ec_reg_request_t *reg;
3938 
3939  if (unlikely(!ctx->requested)) {
3940  return -EPERM;
3941  }
3942 
3943  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
3944  return -EFAULT;
3945  }
3946 
3947  if (io.mem_size <= 0) {
3948  return 0;
3949  }
3950 
3951  /* no locking of master_sem needed, because neither sc nor reg will not be
3952  * deleted in the meantime. */
3953 
3954  if (!(sc = ec_master_get_config(master, io.config_index))) {
3955  return -ENOENT;
3956  }
3957 
3958  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3959  return -ENOENT;
3960  }
3961 
3962  if (ec_copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3963  min(reg->mem_size, io.mem_size), ctx)) {
3964  return -EFAULT;
3965  }
3966 
3967  return 0;
3968 }
3969 
3970 /****************************************************************************/
3971 
3977  ec_master_t *master,
3978  void *arg,
3979  ec_ioctl_context_t *ctx
3980  )
3981 {
3982  ec_ioctl_reg_request_t io;
3983  ec_slave_config_t *sc;
3984  ec_reg_request_t *reg;
3985 
3986  if (unlikely(!ctx->requested)) {
3987  return -EPERM;
3988  }
3989 
3990  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
3991  return -EFAULT;
3992  }
3993 
3994  /* no locking of master_sem needed, because neither sc nor reg will not be
3995  * deleted in the meantime. */
3996 
3997  if (!(sc = ec_master_get_config(master, io.config_index))) {
3998  return -ENOENT;
3999  }
4000 
4001  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4002  return -ENOENT;
4003  }
4004 
4005  io.state = ecrt_reg_request_state(reg);
4006  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
4007 
4008  if (ec_copy_to_user((void __user *) arg, &io, sizeof(io), ctx)) {
4009  return -EFAULT;
4010  }
4011 
4012  return 0;
4013 }
4014 
4015 /****************************************************************************/
4016 
4022  ec_master_t *master,
4023  void *arg,
4024  ec_ioctl_context_t *ctx
4025  )
4026 {
4027  ec_ioctl_reg_request_t io;
4028  ec_slave_config_t *sc;
4029  ec_reg_request_t *reg;
4030 
4031  if (unlikely(!ctx->requested)) {
4032  return -EPERM;
4033  }
4034 
4035  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4036  return -EFAULT;
4037  }
4038 
4039  /* no locking of master_sem needed, because neither sc nor reg will not be
4040  * deleted in the meantime. */
4041 
4042  if (!(sc = ec_master_get_config(master, io.config_index))) {
4043  return -ENOENT;
4044  }
4045 
4046  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4047  return -ENOENT;
4048  }
4049 
4050  if (io.transfer_size > reg->mem_size) {
4051  return -ENOBUFS;
4052  }
4053 
4054  if (ec_copy_from_user(reg->data, (void __user *) io.data,
4055  io.transfer_size, ctx)) {
4056  return -EFAULT;
4057  }
4058 
4059  return ecrt_reg_request_write(reg, io.address, io.transfer_size);
4060 }
4061 
4062 /****************************************************************************/
4063 
4069  ec_master_t *master,
4070  void *arg,
4071  ec_ioctl_context_t *ctx
4072  )
4073 {
4074  ec_ioctl_reg_request_t io;
4075  ec_slave_config_t *sc;
4076  ec_reg_request_t *reg;
4077 
4078  if (unlikely(!ctx->requested)) {
4079  return -EPERM;
4080  }
4081 
4082  if (ec_copy_from_user(&io, (void __user *) arg, sizeof(io), ctx)) {
4083  return -EFAULT;
4084  }
4085 
4086  /* no locking of master_sem needed, because neither sc nor reg will not be
4087  * deleted in the meantime. */
4088 
4089  if (!(sc = ec_master_get_config(master, io.config_index))) {
4090  return -ENOENT;
4091  }
4092 
4093  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4094  return -ENOENT;
4095  }
4096 
4097  if (io.transfer_size > reg->mem_size) {
4098  return -ENOBUFS;
4099  }
4100 
4101  return ecrt_reg_request_read(reg, io.address, io.transfer_size);
4102 }
4103 
4104 /****************************************************************************/
4105 
4111  ec_master_t *master,
4112  void *arg,
4113  ec_ioctl_context_t *ctx
4114  )
4115 {
4116  ec_ioctl_voe_t data;
4117  ec_slave_config_t *sc;
4118  ec_voe_handler_t *voe;
4119  uint32_t vendor_id;
4120  uint16_t vendor_type;
4121 
4122  if (unlikely(!ctx->requested))
4123  return -EPERM;
4124 
4125  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4126  return -EFAULT;
4127 
4128  if (ec_copy_from_user(&vendor_id, data.vendor_id, sizeof(vendor_id), ctx))
4129  return -EFAULT;
4130 
4131  if (ec_copy_from_user(&vendor_type, data.vendor_type,
4132  sizeof(vendor_type), ctx))
4133  return -EFAULT;
4134 
4135  /* no locking of master_sem needed, because neither sc nor voe will not be
4136  * deleted in the meantime. */
4137 
4138  if (!(sc = ec_master_get_config(master, data.config_index))) {
4139  return -ENOENT;
4140  }
4141 
4142  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4143  return -ENOENT;
4144  }
4145 
4146  return ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
4147 }
4148 
4149 /****************************************************************************/
4150 
4156  ec_master_t *master,
4157  void *arg,
4158  ec_ioctl_context_t *ctx
4159  )
4160 {
4161  ec_ioctl_voe_t data;
4162  ec_slave_config_t *sc;
4163  ec_voe_handler_t *voe;
4164  uint32_t vendor_id;
4165  uint16_t vendor_type;
4166  int ret;
4167 
4168  if (unlikely(!ctx->requested))
4169  return -EPERM;
4170 
4171  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4172  return -EFAULT;
4173 
4174  /* no locking of master_sem needed, because neither sc nor voe will not be
4175  * deleted in the meantime. */
4176 
4177  if (!(sc = ec_master_get_config(master, data.config_index))) {
4178  return -ENOENT;
4179  }
4180 
4181  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4182  return -ENOENT;
4183  }
4184 
4185  ret = ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
4186  if (ret)
4187  return ret;
4188 
4189  if (likely(data.vendor_id))
4190  if (ec_copy_to_user(data.vendor_id, &vendor_id,
4191  sizeof(vendor_id), ctx))
4192  return -EFAULT;
4193 
4194  if (likely(data.vendor_type))
4195  if (ec_copy_to_user(data.vendor_type, &vendor_type,
4196  sizeof(vendor_type), ctx))
4197  return -EFAULT;
4198 
4199  return 0;
4200 }
4201 
4202 /****************************************************************************/
4203 
4209  ec_master_t *master,
4210  void *arg,
4211  ec_ioctl_context_t *ctx
4212  )
4213 {
4214  ec_ioctl_voe_t data;
4215  ec_slave_config_t *sc;
4216  ec_voe_handler_t *voe;
4217 
4218  if (unlikely(!ctx->requested))
4219  return -EPERM;
4220 
4221  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4222  return -EFAULT;
4223 
4224  /* no locking of master_sem needed, because neither sc nor voe will not be
4225  * deleted in the meantime. */
4226 
4227  if (!(sc = ec_master_get_config(master, data.config_index))) {
4228  return -ENOENT;
4229  }
4230 
4231  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4232  return -ENOENT;
4233  }
4234 
4235  return ecrt_voe_handler_read(voe);
4236 }
4237 
4238 /****************************************************************************/
4239 
4245  ec_master_t *master,
4246  void *arg,
4247  ec_ioctl_context_t *ctx
4248  )
4249 {
4250  ec_ioctl_voe_t data;
4251  ec_slave_config_t *sc;
4252  ec_voe_handler_t *voe;
4253 
4254  if (unlikely(!ctx->requested))
4255  return -EPERM;
4256 
4257  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4258  return -EFAULT;
4259 
4260  /* no locking of master_sem needed, because neither sc nor voe will not be
4261  * deleted in the meantime. */
4262 
4263  if (!(sc = ec_master_get_config(master, data.config_index))) {
4264  return -ENOENT;
4265  }
4266 
4267  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4268  return -ENOENT;
4269  }
4270 
4271  return ecrt_voe_handler_read_nosync(voe);
4272 }
4273 
4274 /****************************************************************************/
4275 
4281  ec_master_t *master,
4282  void *arg,
4283  ec_ioctl_context_t *ctx
4284  )
4285 {
4286  ec_ioctl_voe_t data;
4287  ec_slave_config_t *sc;
4288  ec_voe_handler_t *voe;
4289 
4290  if (unlikely(!ctx->requested))
4291  return -EPERM;
4292 
4293  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4294  return -EFAULT;
4295 
4296  /* no locking of master_sem needed, because neither sc nor voe will not be
4297  * deleted in the meantime. */
4298 
4299  if (!(sc = ec_master_get_config(master, data.config_index))) {
4300  return -ENOENT;
4301  }
4302 
4303  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4304  return -ENOENT;
4305  }
4306 
4307  if (data.size) {
4308  if (data.size > ec_voe_handler_mem_size(voe))
4309  return -ENOBUFS;
4310 
4311  if (ec_copy_from_user(ecrt_voe_handler_data(voe),
4312  (void __user *) data.data, data.size, ctx))
4313  return -EFAULT;
4314  }
4315 
4316  return ecrt_voe_handler_write(voe, data.size);
4317 }
4318 
4319 /****************************************************************************/
4320 
4326  ec_master_t *master,
4327  void *arg,
4328  ec_ioctl_context_t *ctx
4329  )
4330 {
4331  ec_ioctl_voe_t data;
4332  ec_slave_config_t *sc;
4333  ec_voe_handler_t *voe;
4334 
4335  if (unlikely(!ctx->requested))
4336  return -EPERM;
4337 
4338  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4339  return -EFAULT;
4340 
4341  /* no locking of master_sem needed, because neither sc nor voe will not be
4342  * deleted in the meantime. */
4343 
4344  if (!(sc = ec_master_get_config(master, data.config_index))) {
4345  return -ENOENT;
4346  }
4347 
4348  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4349  return -ENOENT;
4350  }
4351 
4352  if (ec_ioctl_lock_interruptible(&master->io_mutex))
4353  return -EINTR;
4354 
4355  data.state = ecrt_voe_handler_execute(voe);
4356  ec_ioctl_unlock(&master->io_mutex);
4357  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
4358  data.size = ecrt_voe_handler_data_size(voe);
4359  else
4360  data.size = 0;
4361 
4362  if (ec_copy_to_user((void __user *) arg, &data, sizeof(data), ctx))
4363  return -EFAULT;
4364 
4365  return 0;
4366 }
4367 
4368 /****************************************************************************/
4369 
4375  ec_master_t *master,
4376  void *arg,
4377  ec_ioctl_context_t *ctx
4378  )
4379 {
4380  ec_ioctl_voe_t data;
4381  ec_slave_config_t *sc;
4382  ec_voe_handler_t *voe;
4383 
4384  if (unlikely(!ctx->requested))
4385  return -EPERM;
4386 
4387  if (ec_copy_from_user(&data, (void __user *) arg, sizeof(data), ctx))
4388  return -EFAULT;
4389 
4390  /* no locking of master_sem needed, because neither sc nor voe will not be
4391  * deleted in the meantime. */
4392 
4393  if (!(sc = ec_master_get_config(master, data.config_index))) {
4394  return -ENOENT;
4395  }
4396 
4397  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4398  return -ENOENT;
4399  }
4400 
4401  if (ec_copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
4402  ecrt_voe_handler_data_size(voe), ctx))
4403  return -EFAULT;
4404 
4405  return 0;
4406 }
4407 
4408 /****************************************************************************/
4409 
4415  ec_master_t *master,
4416  void *arg
4417  )
4418 {
4419  ec_ioctl_slave_foe_t io;
4420  ec_foe_request_t request;
4421  ec_slave_t *slave;
4422  int ret;
4423 
4424  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4425  return -EFAULT;
4426  }
4427 
4428  ec_foe_request_init(&request, io.file_name);
4429  ret = ec_foe_request_alloc(&request, 10000); // FIXME
4430  if (ret) {
4431  ec_foe_request_clear(&request);
4432  return ret;
4433  }
4434 
4435  ec_foe_request_read(&request);
4436 
4437  if (down_interruptible(&master->master_sem)) {
4438  ec_foe_request_clear(&request);
4439  return -EINTR;
4440  }
4441 
4442  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4443  up(&master->master_sem);
4444  ec_foe_request_clear(&request);
4445  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4446  io.slave_position);
4447  return -EINVAL;
4448  }
4449 
4450  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
4451 
4452  // schedule request.
4453  list_add_tail(&request.list, &slave->foe_requests);
4454 
4455  up(&master->master_sem);
4456 
4457  // wait for processing through FSM
4458  if (wait_event_interruptible(master->request_queue,
4459  request.state != EC_INT_REQUEST_QUEUED)) {
4460  // interrupted by signal
4461  down(&master->master_sem);
4462  if (request.state == EC_INT_REQUEST_QUEUED) {
4463  list_del(&request.list);
4464  up(&master->master_sem);
4465  ec_foe_request_clear(&request);
4466  return -EINTR;
4467  }
4468  // request already processing: interrupt not possible.
4469  up(&master->master_sem);
4470  }
4471 
4472  // wait until master FSM has finished processing
4473  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4474 
4475  io.result = request.result;
4476  io.error_code = request.error_code;
4477 
4478  if (request.state != EC_INT_REQUEST_SUCCESS) {
4479  io.data_size = 0;
4480  ret = -EIO;
4481  } else {
4482  if (request.data_size > io.buffer_size) {
4483  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4484  ec_foe_request_clear(&request);
4485  return -ENOBUFS;
4486  }
4487  io.data_size = request.data_size;
4488  if (copy_to_user((void __user *) io.buffer,
4489  request.buffer, io.data_size)) {
4490  ec_foe_request_clear(&request);
4491  return -EFAULT;
4492  }
4493  ret = 0;
4494  }
4495 
4496  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4497  ret = -EFAULT;
4498  }
4499 
4500  ec_foe_request_clear(&request);
4501  return ret;
4502 }
4503 
4504 /****************************************************************************/
4505 
4511  ec_master_t *master,
4512  void *arg
4513  )
4514 {
4515  ec_ioctl_slave_foe_t io;
4516  ec_foe_request_t request;
4517  ec_slave_t *slave;
4518  int ret;
4519 
4520  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4521  return -EFAULT;
4522  }
4523 
4524  ec_foe_request_init(&request, io.file_name);
4525 
4526  ret = ec_foe_request_alloc(&request, io.buffer_size);
4527  if (ret) {
4528  ec_foe_request_clear(&request);
4529  return ret;
4530  }
4531 
4532  if (copy_from_user(request.buffer,
4533  (void __user *) io.buffer, io.buffer_size)) {
4534  ec_foe_request_clear(&request);
4535  return -EFAULT;
4536  }
4537 
4538  request.data_size = io.buffer_size;
4539  ec_foe_request_write(&request);
4540 
4541  if (down_interruptible(&master->master_sem)) {
4542  ec_foe_request_clear(&request);
4543  return -EINTR;
4544  }
4545 
4546  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4547  up(&master->master_sem);
4548  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4549  io.slave_position);
4550  ec_foe_request_clear(&request);
4551  return -EINVAL;
4552  }
4553 
4554  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4555 
4556  // schedule FoE write request.
4557  list_add_tail(&request.list, &slave->foe_requests);
4558 
4559  up(&master->master_sem);
4560 
4561  // wait for processing through FSM
4562  if (wait_event_interruptible(master->request_queue,
4563  request.state != EC_INT_REQUEST_QUEUED)) {
4564  // interrupted by signal
4565  down(&master->master_sem);
4566  if (request.state == EC_INT_REQUEST_QUEUED) {
4567  // abort request
4568  list_del(&request.list);
4569  up(&master->master_sem);
4570  ec_foe_request_clear(&request);
4571  return -EINTR;
4572  }
4573  up(&master->master_sem);
4574  }
4575 
4576  // wait until master FSM has finished processing
4577  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4578 
4579  io.result = request.result;
4580  io.error_code = request.error_code;
4581 
4582  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4583 
4584  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4585  ret = -EFAULT;
4586  }
4587 
4588  ec_foe_request_clear(&request);
4589  return ret;
4590 }
4591 
4592 /****************************************************************************/
4593 
4599  ec_master_t *master,
4600  void *arg
4601  )
4602 {
4603  ec_ioctl_slave_soe_read_t ioctl;
4604  u8 *data;
4605  int retval;
4606 
4607  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4608  return -EFAULT;
4609  }
4610 
4611  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4612  if (!data) {
4613  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4614  ioctl.mem_size);
4615  return -ENOMEM;
4616  }
4617 
4618  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4619  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4620  &ioctl.error_code);
4621  if (retval) {
4622  kfree(data);
4623  return retval;
4624  }
4625 
4626  if (copy_to_user((void __user *) ioctl.data,
4627  data, ioctl.data_size)) {
4628  kfree(data);
4629  return -EFAULT;
4630  }
4631  kfree(data);
4632 
4633  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4634  retval = -EFAULT;
4635  }
4636 
4637  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4638  return retval;
4639 }
4640 
4641 /****************************************************************************/
4642 
4648  ec_master_t *master,
4649  void *arg
4650  )
4651 {
4652  ec_ioctl_slave_soe_write_t ioctl;
4653  u8 *data;
4654  int retval;
4655 
4656  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4657  return -EFAULT;
4658  }
4659 
4660  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4661  if (!data) {
4662  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4663  ioctl.data_size);
4664  return -ENOMEM;
4665  }
4666  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4667  kfree(data);
4668  return -EFAULT;
4669  }
4670 
4671  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4672  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4673  &ioctl.error_code);
4674  kfree(data);
4675  if (retval) {
4676  return retval;
4677  }
4678 
4679  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4680  retval = -EFAULT;
4681  }
4682 
4683  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4684  return retval;
4685 }
4686 
4687 /*****************************************************************************
4688  * ioctl() file operation functions
4689  ****************************************************************************/
4690 
4696 #ifndef EC_IOCTL_RTDM
4697 static long ec_ioctl_nrt(
4698  ec_master_t *master,
4699  ec_ioctl_context_t *ctx,
4700  unsigned int cmd,
4701  void *arg );
4702 #endif
4703 
4704 /****************************************************************************/
4705 
4711 static long ec_ioctl_both(
4712  ec_master_t *master,
4713  ec_ioctl_context_t *ctx,
4714  unsigned int cmd,
4715  void *arg
4716  )
4717 {
4718  int ret;
4719 
4720  switch (cmd) {
4721  case EC_IOCTL_MODULE:
4722  ret = ec_ioctl_module(arg, ctx);
4723  break;
4724  case EC_IOCTL_MASTER_RESCAN:
4725  if (!ctx->writable) {
4726  ret = -EPERM;
4727  break;
4728  }
4729  ret = ec_ioctl_master_rescan(master, arg);
4730  break;
4731  case EC_IOCTL_MASTER_STATE:
4732  ret = ec_ioctl_master_state(master, arg, ctx);
4733  break;
4734  case EC_IOCTL_MASTER_LINK_STATE:
4735  ret = ec_ioctl_master_link_state(master, arg, ctx);
4736  break;
4737  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4738  if (!ctx->writable) {
4739  ret = -EPERM;
4740  break;
4741  }
4742  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4743  break;
4744  case EC_IOCTL_SDO_REQUEST_DATA:
4745  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4746  break;
4747  case EC_IOCTL_SOE_REQUEST_TIMEOUT:
4748  if (!ctx->writable) {
4749  ret = -EPERM;
4750  break;
4751  }
4752  ret = ec_ioctl_soe_request_timeout(master, arg, ctx);
4753  break;
4754  case EC_IOCTL_SOE_REQUEST_DATA:
4755  ret = ec_ioctl_soe_request_data(master, arg, ctx);
4756  break;
4757  case EC_IOCTL_REG_REQUEST_DATA:
4758  ret = ec_ioctl_reg_request_data(master, arg, ctx);
4759  break;
4760  case EC_IOCTL_VOE_SEND_HEADER:
4761  if (!ctx->writable) {
4762  ret = -EPERM;
4763  break;
4764  }
4765  ret = ec_ioctl_voe_send_header(master, arg, ctx);
4766  break;
4767  case EC_IOCTL_VOE_DATA:
4768  ret = ec_ioctl_voe_data(master, arg, ctx);
4769  break;
4770  default:
4771 #ifdef EC_IOCTL_RTDM
4772  ret = -ENOTTY;
4773 #else
4774  /* chain non-rt commands for normal cdev */
4775  ret = ec_ioctl_nrt(master, ctx, cmd, arg);
4776 #endif
4777  break;
4778  }
4779 
4780  return ret;
4781 }
4782 
4783 /****************************************************************************/
4784 
4790 #ifdef EC_IOCTL_RTDM
4791 long ec_ioctl_rtdm_rt
4792 #else
4793 long ec_ioctl
4794 #endif
4795  (
4796  ec_master_t *master,
4797  ec_ioctl_context_t *ctx,
4798  unsigned int cmd,
4799  void *arg
4800  )
4801 {
4802 #if DEBUG_LATENCY
4803  cycles_t a = get_cycles(), b;
4804  unsigned int t;
4805 #endif
4806  long ret;
4807 
4808  switch (cmd) {
4809  case EC_IOCTL_SEND:
4810  if (!ctx->writable) {
4811  ret = -EPERM;
4812  break;
4813  }
4814  ret = ec_ioctl_send(master, arg, ctx);
4815  break;
4816  case EC_IOCTL_RECEIVE:
4817  if (!ctx->writable) {
4818  ret = -EPERM;
4819  break;
4820  }
4821  ret = ec_ioctl_receive(master, arg, ctx);
4822  break;
4823  case EC_IOCTL_APP_TIME:
4824  if (!ctx->writable) {
4825  ret = -EPERM;
4826  break;
4827  }
4828  ret = ec_ioctl_app_time(master, arg, ctx);
4829  break;
4830  case EC_IOCTL_SYNC_REF:
4831  if (!ctx->writable) {
4832  ret = -EPERM;
4833  break;
4834  }
4835  ret = ec_ioctl_sync_ref(master, arg, ctx);
4836  break;
4837  case EC_IOCTL_SYNC_REF_TO:
4838  if (!ctx->writable) {
4839  ret = -EPERM;
4840  break;
4841  }
4842  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
4843  break;
4844  case EC_IOCTL_SYNC_SLAVES:
4845  if (!ctx->writable) {
4846  ret = -EPERM;
4847  break;
4848  }
4849  ret = ec_ioctl_sync_slaves(master, arg, ctx);
4850  break;
4851  case EC_IOCTL_REF_CLOCK_TIME:
4852  if (!ctx->writable) {
4853  ret = -EPERM;
4854  break;
4855  }
4856  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4857  break;
4858  case EC_IOCTL_SYNC_MON_QUEUE:
4859  if (!ctx->writable) {
4860  ret = -EPERM;
4861  break;
4862  }
4863  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4864  break;
4865  case EC_IOCTL_SYNC_MON_PROCESS:
4866  if (!ctx->writable) {
4867  ret = -EPERM;
4868  break;
4869  }
4870  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4871  break;
4872  case EC_IOCTL_RESET:
4873  if (!ctx->writable) {
4874  ret = -EPERM;
4875  break;
4876  }
4877  ret = ec_ioctl_reset(master, arg, ctx);
4878  break;
4879  case EC_IOCTL_SC_EMERG_POP:
4880  if (!ctx->writable) {
4881  ret = -EPERM;
4882  break;
4883  }
4884  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
4885  break;
4886  case EC_IOCTL_SC_EMERG_CLEAR:
4887  if (!ctx->writable) {
4888  ret = -EPERM;
4889  break;
4890  }
4891  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
4892  break;
4893  case EC_IOCTL_SC_EMERG_OVERRUNS:
4894  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
4895  break;
4896  case EC_IOCTL_SC_STATE:
4897  ret = ec_ioctl_sc_state(master, arg, ctx);
4898  break;
4899  case EC_IOCTL_DOMAIN_PROCESS:
4900  if (!ctx->writable) {
4901  ret = -EPERM;
4902  break;
4903  }
4904  ret = ec_ioctl_domain_process(master, arg, ctx);
4905  break;
4906  case EC_IOCTL_DOMAIN_QUEUE:
4907  if (!ctx->writable) {
4908  ret = -EPERM;
4909  break;
4910  }
4911  ret = ec_ioctl_domain_queue(master, arg, ctx);
4912  break;
4913  case EC_IOCTL_DOMAIN_STATE:
4914  ret = ec_ioctl_domain_state(master, arg, ctx);
4915  break;
4916  case EC_IOCTL_SDO_REQUEST_INDEX:
4917  if (!ctx->writable) {
4918  ret = -EPERM;
4919  break;
4920  }
4921  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
4922  break;
4923  case EC_IOCTL_SDO_REQUEST_STATE:
4924  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
4925  break;
4926  case EC_IOCTL_SDO_REQUEST_READ:
4927  if (!ctx->writable) {
4928  ret = -EPERM;
4929  break;
4930  }
4931  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
4932  break;
4933  case EC_IOCTL_SDO_REQUEST_WRITE:
4934  if (!ctx->writable) {
4935  ret = -EPERM;
4936  break;
4937  }
4938  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
4939  break;
4940  case EC_IOCTL_SOE_REQUEST_IDN:
4941  if (!ctx->writable) {
4942  ret = -EPERM;
4943  break;
4944  }
4945  ret = ec_ioctl_soe_request_index(master, arg, ctx);
4946  break;
4947  case EC_IOCTL_SOE_REQUEST_STATE:
4948  ret = ec_ioctl_soe_request_state(master, arg, ctx);
4949  break;
4950  case EC_IOCTL_SOE_REQUEST_READ:
4951  if (!ctx->writable) {
4952  ret = -EPERM;
4953  break;
4954  }
4955  ret = ec_ioctl_soe_request_read(master, arg, ctx);
4956  break;
4957  case EC_IOCTL_SOE_REQUEST_WRITE:
4958  if (!ctx->writable) {
4959  ret = -EPERM;
4960  break;
4961  }
4962  ret = ec_ioctl_soe_request_write(master, arg, ctx);
4963  break;
4964  case EC_IOCTL_REG_REQUEST_STATE:
4965  ret = ec_ioctl_reg_request_state(master, arg, ctx);
4966  break;
4967  case EC_IOCTL_REG_REQUEST_WRITE:
4968  if (!ctx->writable) {
4969  ret = -EPERM;
4970  break;
4971  }
4972  ret = ec_ioctl_reg_request_write(master, arg, ctx);
4973  break;
4974  case EC_IOCTL_REG_REQUEST_READ:
4975  if (!ctx->writable) {
4976  ret = -EPERM;
4977  break;
4978  }
4979  ret = ec_ioctl_reg_request_read(master, arg, ctx);
4980  break;
4981  case EC_IOCTL_VOE_REC_HEADER:
4982  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
4983  break;
4984  case EC_IOCTL_VOE_READ:
4985  if (!ctx->writable) {
4986  ret = -EPERM;
4987  break;
4988  }
4989  ret = ec_ioctl_voe_read(master, arg, ctx);
4990  break;
4991  case EC_IOCTL_VOE_READ_NOSYNC:
4992  if (!ctx->writable) {
4993  ret = -EPERM;
4994  break;
4995  }
4996  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
4997  break;
4998  case EC_IOCTL_VOE_WRITE:
4999  if (!ctx->writable) {
5000  ret = -EPERM;
5001  break;
5002  }
5003  ret = ec_ioctl_voe_write(master, arg, ctx);
5004  break;
5005  case EC_IOCTL_VOE_EXEC:
5006  if (!ctx->writable) {
5007  ret = -EPERM;
5008  break;
5009  }
5010  ret = ec_ioctl_voe_exec(master, arg, ctx);
5011  break;
5012  default:
5013  ret = ec_ioctl_both(master, ctx, cmd, arg);
5014  break;
5015  }
5016 
5017 #if DEBUG_LATENCY
5018  b = get_cycles();
5019  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5020  if (t > 50) {
5021  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5022  _IOC_NR(cmd), t);
5023  }
5024 #endif
5025 
5026  return ret;
5027 }
5028 
5029 /****************************************************************************/
5030 
5036 #ifdef EC_IOCTL_RTDM
5037 long ec_ioctl_rtdm_nrt
5038 #else
5039 static long ec_ioctl_nrt
5040 #endif
5041  (
5042  ec_master_t *master,
5043  ec_ioctl_context_t *ctx,
5044  unsigned int cmd,
5045  void *arg
5046  )
5047 {
5048 #if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM)
5049  cycles_t a = get_cycles(), b;
5050  unsigned int t;
5051 #endif
5052  int ret;
5053 
5054  switch (cmd) {
5055  case EC_IOCTL_MASTER:
5056  ret = ec_ioctl_master(master, arg);
5057  break;
5058  case EC_IOCTL_SLAVE:
5059  ret = ec_ioctl_slave(master, arg);
5060  break;
5061  case EC_IOCTL_SLAVE_SYNC:
5062  ret = ec_ioctl_slave_sync(master, arg);
5063  break;
5064  case EC_IOCTL_SLAVE_SYNC_PDO:
5065  ret = ec_ioctl_slave_sync_pdo(master, arg);
5066  break;
5067  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
5068  ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
5069  break;
5070  case EC_IOCTL_DOMAIN:
5071  ret = ec_ioctl_domain(master, arg);
5072  break;
5073  case EC_IOCTL_DOMAIN_FMMU:
5074  ret = ec_ioctl_domain_fmmu(master, arg);
5075  break;
5076  case EC_IOCTL_DOMAIN_DATA:
5077  ret = ec_ioctl_domain_data(master, arg);
5078  break;
5079  case EC_IOCTL_MASTER_DEBUG:
5080  if (!ctx->writable) {
5081  ret = -EPERM;
5082  break;
5083  }
5084  ret = ec_ioctl_master_debug(master, arg);
5085  break;
5086  case EC_IOCTL_SLAVE_STATE:
5087  if (!ctx->writable) {
5088  ret = -EPERM;
5089  break;
5090  }
5091  ret = ec_ioctl_slave_state(master, arg);
5092  break;
5093  case EC_IOCTL_SLAVE_SDO:
5094  ret = ec_ioctl_slave_sdo(master, arg);
5095  break;
5096  case EC_IOCTL_SLAVE_SDO_ENTRY:
5097  ret = ec_ioctl_slave_sdo_entry(master, arg);
5098  break;
5099  case EC_IOCTL_SLAVE_SDO_UPLOAD:
5100  if (!ctx->writable) {
5101  ret = -EPERM;
5102  break;
5103  }
5104  ret = ec_ioctl_slave_sdo_upload(master, arg);
5105  break;
5106  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
5107  if (!ctx->writable) {
5108  ret = -EPERM;
5109  break;
5110  }
5111  ret = ec_ioctl_slave_sdo_download(master, arg);
5112  break;
5113  case EC_IOCTL_SLAVE_SII_READ:
5114  ret = ec_ioctl_slave_sii_read(master, arg);
5115  break;
5116  case EC_IOCTL_SLAVE_SII_WRITE:
5117  if (!ctx->writable) {
5118  ret = -EPERM;
5119  break;
5120  }
5121  ret = ec_ioctl_slave_sii_write(master, arg);
5122  break;
5123  case EC_IOCTL_SLAVE_REG_READ:
5124  if (!ctx->writable) {
5125  ret = -EPERM;
5126  break;
5127  }
5128  ret = ec_ioctl_slave_reg_read(master, arg);
5129  break;
5130  case EC_IOCTL_SLAVE_REG_WRITE:
5131  if (!ctx->writable) {
5132  ret = -EPERM;
5133  break;
5134  }
5135  ret = ec_ioctl_slave_reg_write(master, arg);
5136  break;
5137  case EC_IOCTL_SLAVE_FOE_READ:
5138  if (!ctx->writable) {
5139  ret = -EPERM;
5140  break;
5141  }
5142  ret = ec_ioctl_slave_foe_read(master, arg);
5143  break;
5144  case EC_IOCTL_SLAVE_FOE_WRITE:
5145  if (!ctx->writable) {
5146  ret = -EPERM;
5147  break;
5148  }
5149  ret = ec_ioctl_slave_foe_write(master, arg);
5150  break;
5151  case EC_IOCTL_SLAVE_SOE_READ:
5152  if (!ctx->writable) {
5153  ret = -EPERM;
5154  break;
5155  }
5156  ret = ec_ioctl_slave_soe_read(master, arg);
5157  break;
5158  case EC_IOCTL_SLAVE_SOE_WRITE:
5159  if (!ctx->writable) {
5160  ret = -EPERM;
5161  break;
5162  }
5163  ret = ec_ioctl_slave_soe_write(master, arg);
5164  break;
5165 #ifdef EC_EOE
5166  case EC_IOCTL_SLAVE_EOE_IP_PARAM:
5167  if (!ctx->writable) {
5168  ret = -EPERM;
5169  break;
5170  }
5171  ret = ec_ioctl_slave_eoe_ip_param(master, arg);
5172  break;
5173 #endif
5174  case EC_IOCTL_CONFIG:
5175  ret = ec_ioctl_config(master, arg);
5176  break;
5177  case EC_IOCTL_CONFIG_PDO:
5178  ret = ec_ioctl_config_pdo(master, arg);
5179  break;
5180  case EC_IOCTL_CONFIG_PDO_ENTRY:
5181  ret = ec_ioctl_config_pdo_entry(master, arg);
5182  break;
5183  case EC_IOCTL_CONFIG_SDO:
5184  ret = ec_ioctl_config_sdo(master, arg);
5185  break;
5186  case EC_IOCTL_CONFIG_IDN:
5187  ret = ec_ioctl_config_idn(master, arg);
5188  break;
5189  case EC_IOCTL_CONFIG_FLAG:
5190  ret = ec_ioctl_config_flag(master, arg);
5191  break;
5192 #ifdef EC_EOE
5193  case EC_IOCTL_EOE_HANDLER:
5194  ret = ec_ioctl_eoe_handler(master, arg);
5195  break;
5196 #endif
5197 
5198  /* Application interface */
5199 
5200  case EC_IOCTL_REQUEST:
5201  if (!ctx->writable) {
5202  ret = -EPERM;
5203  break;
5204  }
5205  ret = ec_ioctl_request(master, arg, ctx);
5206  break;
5207  case EC_IOCTL_CREATE_DOMAIN:
5208  if (!ctx->writable) {
5209  ret = -EPERM;
5210  break;
5211  }
5212  ret = ec_ioctl_create_domain(master, arg, ctx);
5213  break;
5214  case EC_IOCTL_CREATE_SLAVE_CONFIG:
5215  if (!ctx->writable) {
5216  ret = -EPERM;
5217  break;
5218  }
5219  ret = ec_ioctl_create_slave_config(master, arg, ctx);
5220  break;
5221  case EC_IOCTL_SELECT_REF_CLOCK:
5222  if (!ctx->writable) {
5223  ret = -EPERM;
5224  break;
5225  }
5226  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
5227  break;
5228  case EC_IOCTL_ACTIVATE:
5229  if (!ctx->writable) {
5230  ret = -EPERM;
5231  break;
5232  }
5233  ret = ec_ioctl_activate(master, arg, ctx);
5234  break;
5235  case EC_IOCTL_DEACTIVATE:
5236  if (!ctx->writable) {
5237  ret = -EPERM;
5238  break;
5239  }
5240  ret = ec_ioctl_deactivate(master, arg, ctx);
5241  break;
5242  case EC_IOCTL_SC_SYNC:
5243  if (!ctx->writable) {
5244  ret = -EPERM;
5245  break;
5246  }
5247  ret = ec_ioctl_sc_sync(master, arg, ctx);
5248  break;
5249  case EC_IOCTL_SC_WATCHDOG:
5250  if (!ctx->writable) {
5251  ret = -EPERM;
5252  break;
5253  }
5254  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
5255  break;
5256  case EC_IOCTL_SC_ADD_PDO:
5257  if (!ctx->writable) {
5258  ret = -EPERM;
5259  break;
5260  }
5261  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
5262  break;
5263  case EC_IOCTL_SC_CLEAR_PDOS:
5264  if (!ctx->writable) {
5265  ret = -EPERM;
5266  break;
5267  }
5268  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
5269  break;
5270  case EC_IOCTL_SC_ADD_ENTRY:
5271  if (!ctx->writable) {
5272  ret = -EPERM;
5273  break;
5274  }
5275  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
5276  break;
5277  case EC_IOCTL_SC_CLEAR_ENTRIES:
5278  if (!ctx->writable) {
5279  ret = -EPERM;
5280  break;
5281  }
5282  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
5283  break;
5284  case EC_IOCTL_SC_REG_PDO_ENTRY:
5285  if (!ctx->writable) {
5286  ret = -EPERM;
5287  break;
5288  }
5289  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
5290  break;
5291  case EC_IOCTL_SC_REG_PDO_POS:
5292  if (!ctx->writable) {
5293  ret = -EPERM;
5294  break;
5295  }
5296  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
5297  break;
5298  case EC_IOCTL_SC_DC:
5299  if (!ctx->writable) {
5300  ret = -EPERM;
5301  break;
5302  }
5303  ret = ec_ioctl_sc_dc(master, arg, ctx);
5304  break;
5305  case EC_IOCTL_SC_SDO:
5306  if (!ctx->writable) {
5307  ret = -EPERM;
5308  break;
5309  }
5310  ret = ec_ioctl_sc_sdo(master, arg, ctx);
5311  break;
5312  case EC_IOCTL_SC_EMERG_SIZE:
5313  if (!ctx->writable) {
5314  ret = -EPERM;
5315  break;
5316  }
5317  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
5318  break;
5319  case EC_IOCTL_SC_SDO_REQUEST:
5320  if (!ctx->writable) {
5321  ret = -EPERM;
5322  break;
5323  }
5324  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
5325  break;
5326  case EC_IOCTL_SC_SOE_REQUEST:
5327  if (!ctx->writable) {
5328  ret = -EPERM;
5329  break;
5330  }
5331  ret = ec_ioctl_sc_create_soe_request(master, arg, ctx);
5332  break;
5333  case EC_IOCTL_SC_REG_REQUEST:
5334  if (!ctx->writable) {
5335  ret = -EPERM;
5336  break;
5337  }
5338  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
5339  break;
5340  case EC_IOCTL_SC_VOE:
5341  if (!ctx->writable) {
5342  ret = -EPERM;
5343  break;
5344  }
5345  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
5346  break;
5347  case EC_IOCTL_SC_IDN:
5348  if (!ctx->writable) {
5349  ret = -EPERM;
5350  break;
5351  }
5352  ret = ec_ioctl_sc_idn(master, arg, ctx);
5353  break;
5354  case EC_IOCTL_SC_FLAG:
5355  if (!ctx->writable) {
5356  ret = -EPERM;
5357  break;
5358  }
5359  ret = ec_ioctl_sc_flag(master, arg, ctx);
5360  break;
5361  case EC_IOCTL_DOMAIN_SIZE:
5362  ret = ec_ioctl_domain_size(master, arg, ctx);
5363  break;
5364  case EC_IOCTL_DOMAIN_OFFSET:
5365  ret = ec_ioctl_domain_offset(master, arg, ctx);
5366  break;
5367  case EC_IOCTL_SET_SEND_INTERVAL:
5368  if (!ctx->writable) {
5369  ret = -EPERM;
5370  break;
5371  }
5372  ret = ec_ioctl_set_send_interval(master, arg, ctx);
5373  break;
5374  default:
5375 #ifdef EC_IOCTL_RTDM
5376  ret = ec_ioctl_both(master, ctx, cmd, arg);
5377 #else
5378  ret = -ENOTTY;
5379 #endif
5380  break;
5381  }
5382 
5383 #if DEBUG_LATENCY && !defined(EC_IOCTL_RTDM)
5384  b = get_cycles();
5385  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5386  if (t > 50) {
5387  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5388  _IOC_NR(cmd), t);
5389  }
5390 #endif
5391 
5392  return ret;
5393 }
5394 
5395 /****************************************************************************/
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:153
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:49
const ec_slave_config_t * sc
EtherCAT slave config.
Definition: fmmu_config.h:40
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:48
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:470
uint16_t offset
SII word offset.
Definition: fsm_master.h:48
uint16_t ring_position
Ring position.
Definition: slave.h:175
uint32_t revision_number
Revision number.
Definition: slave.h:129
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave&#39;s SII.
Definition: rtdm-ioctl.c:960
const ec_sdo_entry_t * ec_sdo_get_entry_const(const ec_sdo_t *sdo, uint8_t subindex)
Get an SDO entry from an SDO via its subindex.
Definition: sdo.c:108
static ATTRIBUTES int ec_ioctl_voe_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation.
Definition: rtdm-ioctl.c:4208
static ATTRIBUTES int ec_ioctl_domain_offset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain&#39;s offset in the total process data.
Definition: rtdm-ioctl.c:3305
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: rtdm-ioctl.c:3366
static long ec_ioctl_both(ec_master_t *master, ec_ioctl_context_t *ctx, unsigned int cmd, void *arg)
Called when an ioctl() command is issued.
Definition: rtdm-ioctl.c:4711
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:710
int ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2353
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:131
static ATTRIBUTES int ec_ioctl_soe_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SoE IDN write operation.
Definition: rtdm-ioctl.c:3840
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:104
ec_sii_t sii
Extracted SII data.
Definition: slave.h:215
ec_reg_request_t * ec_slave_config_find_reg_request(ec_slave_config_t *sc, unsigned int pos)
Finds a register handler via its position in the list.
Definition: slave_config.c:558
int ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, uint8_t sync_index)
Clear a sync manager&#39;s PDO assignment.
Definition: slave_config.c:693
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:2757
FMMU configuration.
Definition: fmmu_config.h:38
static ATTRIBUTES int ec_ioctl_sdo_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO read operation.
Definition: rtdm-ioctl.c:3560
u64 tx_count
Number of frames sent.
Definition: master.h:145
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:206
int ecrt_master_sync_reference_clock_to(ec_master_t *master, uint64_t sync_time)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:2818
struct list_head sii_requests
SII write requests.
Definition: master.h:293
const ec_soe_request_t * ec_slave_config_get_idn_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an IDN configuration via its position in the list.
Definition: slave_config.c:448
ec_sdo_request_t * ecrt_slave_config_create_sdo_request_err(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size)
Same as ecrt_slave_config_create_sdo_request(), but with ERR_PTR() return value.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:98
CANopen SDO entry.
Definition: sdo_entry.h:46
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: rtdm-ioctl.c:1462
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: rtdm-ioctl.c:1277
size_t data_size
Size of the process data.
Definition: domain.h:53
int ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
Set the timeout for an SDO request.
Definition: sdo_request.c:191
int ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:77
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:162
int ecrt_reg_request_write(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule an register write operation.
Definition: reg_request.c:92
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: rtdm-ioctl.c:2691
static ATTRIBUTES int ec_ioctl_sc_emerg_overruns(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the number of emergency overruns.
Definition: rtdm-ioctl.c:2865
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:51
ec_slave_config_t * ec_master_get_config(const ec_master_t *master, unsigned int pos)
Get a slave configuration via its position in the list.
Definition: master.c:1871
int ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:173
int ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:153
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:100
int ecrt_soe_request_timeout(ec_soe_request_t *req, uint32_t timeout)
Set the timeout for an SoE request.
Definition: soe_request.c:278
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:179
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:95
const ec_flag_t * ec_slave_config_get_flag_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds a flag via its position in the list.
Definition: slave_config.c:492
static ATTRIBUTES int ec_ioctl_sc_emerg_pop(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get an emergency message from the ring.
Definition: rtdm-ioctl.c:2788
ec_soe_request_t * ec_slave_config_find_soe_request(ec_slave_config_t *sc, unsigned int pos)
Finds a SoE request via its position in the list.
Definition: slave_config.c:536
ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req)
Get the current state of the SDO request.
Definition: sdo_request.c:213
int ecrt_slave_config_watchdog(ec_slave_config_t *sc, uint16_t divider, uint16_t intervals)
Configure a slave&#39;s watchdog times.
Definition: slave_config.c:650
CANopen SDO request.
Definition: sdo_request.h:40
ec_slave_state_t current_state
Current application state.
Definition: slave.h:184
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave via complete access.
Definition: master.c:2946
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: rtdm-ioctl.c:580
int ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2424
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:319
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:842
int ecrt_reg_request_read(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule a register read operation.
Definition: reg_request.c:104
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
uint8_t * ecrt_soe_request_data(const ec_soe_request_t *req)
Access to the SoE request&#39;s data.
Definition: soe_request.c:286
size_t nwords
Number of words.
Definition: fsm_master.h:49
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:55
uint16_t address
Register address.
Definition: reg_request.h:46
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:51
Register request.
Definition: reg_request.h:40
ec_direction_t dir
Direction.
Definition: soe_request.h:50
size_t mem_size
Size of data memory.
Definition: reg_request.h:42
static ATTRIBUTES int ec_ioctl_config_flag(ec_master_t *master, void *arg)
Get slave configuration feature flag information.
Definition: rtdm-ioctl.c:1526
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:222
uint32_t product_code
Slave product code.
Definition: slave_config.h:119
ec_slave_port_link_t link
Port link status.
Definition: slave.h:112
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:545
uint16_t position
Index after alias.
Definition: slave_config.h:116
size_t mem_size
Size of SDO data memory.
Definition: sdo_request.h:45
int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, const uint8_t *data, size_t size)
Add an SDO configuration.
Definition: slave_config.c:982
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: rtdm-ioctl.c:639
static ATTRIBUTES int ec_ioctl_sc_clear_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the PDO assignment.
Definition: rtdm-ioctl.c:2450
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:1822
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:75
static ATTRIBUTES int ec_ioctl_soe_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SoE request&#39;s state.
Definition: rtdm-ioctl.c:3757
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:2719
const ec_sdo_request_t * ec_slave_config_get_sdo_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an SDO configuration via its position in the list.
Definition: slave_config.c:404
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:623
uint32_t serial_number
Serial number.
Definition: slave.h:130
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:105
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:103
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:152
char * order
Order number.
Definition: slave.h:149
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:40
const ec_domain_t * ec_master_find_domain_const(const ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:1950
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:1989
uint16_t index
SDO index.
Definition: sdo_request.h:42
unsigned int scan_index
Index of slave currently scanned.
Definition: master.h:236
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:224
static ATTRIBUTES int ec_ioctl_voe_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reads the received VoE data.
Definition: rtdm-ioctl.c:4374
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: rtdm-ioctl.c:1966
unsigned int data_size
Covered PDO size.
Definition: fmmu_config.h:45
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:294
static ATTRIBUTES int ec_ioctl_sc_clear_entries(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the mapping of a PDO.
Definition: rtdm-ioctl.c:2519
uint16_t alias
Slave alias.
Definition: slave_config.h:115
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: rtdm-ioctl.c:2024
static ATTRIBUTES int ec_ioctl_sc_add_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add an entry to a PDO&#39;s mapping.
Definition: rtdm-ioctl.c:2484
struct list_head domains
List of domains.
Definition: master.h:221
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: rtdm-ioctl.c:355
static ATTRIBUTES int ec_ioctl_sdo_request_index(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request&#39;s SDO index and subindex.
Definition: rtdm-ioctl.c:3441
struct list_head reg_requests
Register access requests.
Definition: slave.h:222
int ecrt_soe_request_idn(ec_soe_request_t *req, uint8_t drive_no, uint16_t idn)
Set the request&#39;s drive and Sercos ID numbers.
Definition: soe_request.c:268
int ecrt_slave_config_idn(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, ec_al_state_t state, const uint8_t *data, size_t size)
Add an SoE IDN configuration.
static ATTRIBUTES int ec_ioctl_sync_mon_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the sync monitoring datagram.
Definition: rtdm-ioctl.c:2245
static ATTRIBUTES int ec_ioctl_sdo_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request&#39;s timeout.
Definition: rtdm-ioctl.c:3477
CANopen SDO.
Definition: sdo.h:41
uint16_t index
SDO index.
Definition: sdo.h:44
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:44
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:154
ec_slave_t * ec_master_find_slave(ec_master_t *master, uint16_t alias, uint16_t position)
Finds a slave in the bus, given the alias and position.
Definition: master.c:1806
uint8_t link_state
device link state
Definition: device.h:80
unsigned int ec_pdo_list_count(const ec_pdo_list_t *pl)
Get the number of PDOs in the list.
Definition: pdo_list.c:303
static ATTRIBUTES int ec_ioctl_ref_clock_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the system time of the reference clock.
Definition: rtdm-ioctl.c:2214
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:535
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:134
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:197
uint32_t result
FoE request abort code.
Definition: foe_request.h:60
int ecrt_slave_config_reg_pdo_entry_pos(ec_slave_config_t *sc, uint8_t sync_index, unsigned int pdo_pos, unsigned int entry_pos, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry using its position.
Definition: slave_config.c:897
u64 rx_count
Number of frames received.
Definition: device.h:94
#define EC_MAX_HOSTNAME_SIZE
Maximum hostname size.
Definition: globals.h:110
size_t data_size
Size of SDO data.
Definition: soe_request.h:47
int ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:2834
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:297
void ec_eoe_request_init(ec_eoe_request_t *req)
EoE request constructor.
Definition: eoe_request.c:38
static ATTRIBUTES int ec_ioctl_reg_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an register request&#39;s state.
Definition: rtdm-ioctl.c:3976
void ecrt_domain_external_memory(ec_domain_t *domain, uint8_t *mem)
Provide external memory to store the domain&#39;s process data.
Definition: domain.c:426
unsigned int sync_count
Number of sync managers.
Definition: slave.h:158
struct list_head list
List head.
Definition: fsm_master.h:46
SII write request.
Definition: fsm_master.h:45
ec_domain_t * ecrt_master_create_domain_err(ec_master_t *master)
Same as ecrt_master_create_domain(), but with ERR_PTR() return value.
Definition: master.c:2232
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:103
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, const uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3110
char * key
Flag key (null-terminated ASCII string.
Definition: flag.h:40
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:136
static ATTRIBUTES int ec_ioctl_sc_create_sdo_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SDO request.
Definition: rtdm-ioctl.c:2910
static ATTRIBUTES int ec_ioctl_sc_add_pdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add a PDO to the assignment.
Definition: rtdm-ioctl.c:2416
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:1886
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave&#39;s registers.
Definition: rtdm-ioctl.c:1048
static ATTRIBUTES int ec_ioctl_sc_dc(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the DC AssignActivate word and the sync signal times.
Definition: rtdm-ioctl.c:2650
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:137
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:106
ec_al_state_t al_state
AL state (only valid for IDN config).
Definition: soe_request.h:44
int ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:2847
ec_direction_t dir
Direction.
Definition: sdo_request.h:52
PDO entry description.
Definition: pdo_entry.h:40
EtherCAT master structure.
uint8_t * data
Memory for the process data.
Definition: domain.h:54
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:134
int ecrt_master_reference_clock_time(const ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Definition: master.c:2785
static ATTRIBUTES int ec_ioctl_master_link_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the link state.
Definition: rtdm-ioctl.c:2075
uint16_t index
PDO index.
Definition: pdo.h:43
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:100
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:133
static ATTRIBUTES int ec_ioctl_sync_mon_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Processes the sync monitoring datagram.
Definition: rtdm-ioctl.c:2271
const ec_pdo_entry_t * ec_pdo_find_entry_by_pos_const(const ec_pdo_t *pdo, unsigned int pos)
Finds a PDO entry via its position in the list.
Definition: pdo.c:271
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:184
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:47
uint16_t index
PDO entry index.
Definition: pdo_entry.h:42
EtherCAT slave.
Definition: slave.h:168
struct semaphore master_sem
Master semaphore.
Definition: master.h:194
static ATTRIBUTES int ec_ioctl_voe_exec(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Executes the VoE state machine.
Definition: rtdm-ioctl.c:4325
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition: pdo.c:249
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:44
static long ec_ioctl_nrt(ec_master_t *master, ec_ioctl_context_t *ctx, unsigned int cmd, void *arg)
ioctl() function to use.
Definition: rtdm-ioctl.c:5041
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:72
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:45
struct irq_work sc_reset_work_kicker
NMI-Safe kicker to trigger reset task above.
Definition: master.h:300
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:325
uint8_t * ecrt_reg_request_data(const ec_reg_request_t *reg)
Access to the register request&#39;s data.
Definition: reg_request.c:78
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: rtdm-ioctl.c:738
char * description
Description.
Definition: sdo_entry.h:54
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2014
Slave configuration state.
Definition: ecrt.h:373
static ATTRIBUTES int ec_ioctl_reg_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register read operation.
Definition: rtdm-ioctl.c:4068
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave&#39;s registers.
Definition: rtdm-ioctl.c:1130
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:156
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:164
Ethernet over EtherCAT (EoE)
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:129
int ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex.
Definition: sdo_request.c:181
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:204
static ATTRIBUTES int ec_ioctl_sdo_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO write operation.
Definition: rtdm-ioctl.c:3596
void(* state)(ec_voe_handler_t *)
State function.
Definition: voe_handler.h:51
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:140
ec_master_phase_t phase
Master phase.
Definition: master.h:208
Domain state.
Definition: ecrt.h:491
static ATTRIBUTES int ec_ioctl_slave_eoe_ip_param(ec_master_t *master, void *arg)
Request EoE IP parameter setting.
Definition: rtdm-ioctl.c:1644
int ecrt_slave_config_emerg_overruns(const ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: rtdm-ioctl.c:625
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: rtdm-ioctl.c:2297
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:44
static ATTRIBUTES int ec_ioctl_voe_rec_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the received VoE header.
Definition: rtdm-ioctl.c:4155
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:42
Slave configutation feature flag.
Definition: flag.h:38
static ATTRIBUTES int ec_ioctl_sdo_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SDO data.
Definition: rtdm-ioctl.c:3645
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain&#39;s process data.
Definition: domain.c:419
static ATTRIBUTES int ec_ioctl_sc_flag(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures a feature flag.
Definition: rtdm-ioctl.c:3214
struct semaphore device_sem
Device semaphore.
Definition: master.h:203
PDO description.
Definition: pdo.h:41
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:111
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:137
EtherCAT device.
Definition: device.h:73
uint16_t * sii_words
Complete SII image.
Definition: slave.h:211
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:139
ec_domain_t * ec_master_find_domain(ec_master_t *master, unsigned int index)
Get a domain via its position in the list.
Definition: master.c:1935
static ATTRIBUTES int ec_ioctl_reg_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read register data.
Definition: rtdm-ioctl.c:3929
ec_reg_request_t * ecrt_slave_config_create_reg_request_err(ec_slave_config_t *sc, size_t size)
Same as ecrt_slave_config_create_reg_request(), but with ERR_PTR() return value.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:68
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: rtdm-ioctl.c:818
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:1901
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:203
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:45
Sync manager.
Definition: sync.h:39
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:135
static ATTRIBUTES int ec_ioctl_sync_ref(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: rtdm-ioctl.c:2132
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:201
static ATTRIBUTES int ec_ioctl_soe_request_index(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SoE request&#39;s drive number and IDN.
Definition: rtdm-ioctl.c:3685
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:166
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:207
struct rt_mutex io_mutex
Mutex used in IDLE and OP phase.
Definition: master.h:282
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:217
unsigned int scan_busy
Current scan state.
Definition: master.h:235
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:41
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:139
uint8_t * ecrt_sdo_request_data(const ec_sdo_request_t *req)
Access to the SDO request&#39;s data.
Definition: sdo_request.c:199
char * name
SDO name.
Definition: sdo.h:46
int ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:232
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:133
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:159
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:3186
static ATTRIBUTES int ec_ioctl_sc_create_soe_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SoE request.
Definition: rtdm-ioctl.c:2961
unsigned int index
Index (just a number).
Definition: domain.h:50
int ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master&#39;s datagram queue.
Definition: domain.c:641
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:109
Main device.
Definition: globals.h:199
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: rtdm-ioctl.c:48
int ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:2805
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:123
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: rtdm-ioctl.c:864
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:111
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:86
static ATTRIBUTES int ec_ioctl_master(ec_master_t *master, void *arg)
Get master information.
Definition: rtdm-ioctl.c:116
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_sc_emerg_clear(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clear the emergency ring.
Definition: rtdm-ioctl.c:2832
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:41
unsigned int active
Master has been activated.
Definition: master.h:209
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_pos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry by its position.
Definition: rtdm-ioctl.c:2600
struct list_head soe_requests
List of SoE requests.
Definition: slave_config.h:138
size_t ecrt_soe_request_data_size(const ec_soe_request_t *req)
Returns the current IDN data size.
Definition: soe_request.c:293
long ec_ioctl(ec_master_t *master, ec_ioctl_context_t *ctx, unsigned int cmd, void *arg)
Called when an ioctl() command is issued.
Definition: rtdm-ioctl.c:4795
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:382
const ec_sdo_t * ec_slave_get_sdo_by_pos_const(const ec_slave_t *slave, uint16_t sdo_position)
Get an SDO from the dictionary, given its position in the list.
Definition: slave.c:688
u64 rx_bytes
Number of bytes received.
Definition: device.h:99
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:204
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc, uint8_t sync_index, uint16_t pdo_index)
Add a PDO to a sync manager&#39;s PDO assignment.
Definition: slave_config.c:663
int ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
Definition: slave_config.c:962
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:51
static ATTRIBUTES int ec_ioctl_module(void *arg, ec_ioctl_context_t *ctx)
Get module information.
Definition: rtdm-ioctl.c:94
u64 tx_count
Number of frames sent.
Definition: device.h:92
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: rtdm-ioctl.c:3339
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:324
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:74
int ecrt_master_select_reference_clock(ec_master_t *master, ec_slave_config_t *sc)
Selects the reference clock for distributed clocks.
Definition: master.c:2610
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:43
static ATTRIBUTES int ec_ioctl_select_ref_clock(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Select the DC reference clock.
Definition: rtdm-ioctl.c:1823
uint8_t control_register
Control register value.
Definition: sync.h:43
static ATTRIBUTES int ec_ioctl_voe_read_nosync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation without sending a sync message first.
Definition: rtdm-ioctl.c:4244
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: rtdm-ioctl.c:1333
Values read by the master.
Definition: ecrt.h:504
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:39
int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address)
Memory-map process data to user space.
Definition: rtdm.c:238
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: rtdm-ioctl.c:528
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: rtdm-ioctl.c:483
uint16_t data_type
Data type.
Definition: sdo_entry.h:50
int ecrt_voe_handler_received_header(const ec_voe_handler_t *voe, uint32_t *vendor_id, uint16_t *vendor_type)
Reads the header data of a received VoE message.
Definition: voe_handler.c:125
static ATTRIBUTES int ec_ioctl_sc_watchdog(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a slave&#39;s watchdogs.
Definition: rtdm-ioctl.c:2371
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: rtdm-ioctl.c:1728
struct list_head configs
List of slave configurations.
Definition: master.h:220
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:126
static ATTRIBUTES int ec_ioctl_sync_ref_to(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: rtdm-ioctl.c:2158
unsigned int opened
net_device is opened
Definition: ethernet.h:83
Access rights in OP.
Definition: globals.h:192
static ATTRIBUTES int ec_ioctl_create_slave_config(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a slave configuration.
Definition: rtdm-ioctl.c:1777
int ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain&#39;s datagrams.
Definition: domain.c:450
int ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:2773
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:121
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE SDO request via its position in the list.
Definition: slave_config.c:514
static ATTRIBUTES int ec_ioctl_domain_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the domain state.
Definition: rtdm-ioctl.c:3399
int ecrt_soe_request_write(ec_soe_request_t *req)
Schedule an SoE IDN write operation.
Definition: soe_request.c:314
size_t data_size
Size of FoE data.
Definition: foe_request.h:46
static ATTRIBUTES int ec_ioctl_master_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the master state.
Definition: rtdm-ioctl.c:2050
Access rights in SAFEOP.
Definition: globals.h:191
ec_request_state_t ecrt_reg_request_state(const ec_reg_request_t *reg)
Get the current state of the register request.
Definition: reg_request.c:85
static ATTRIBUTES int ec_ioctl_sync_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the slave clocks.
Definition: rtdm-ioctl.c:2188
int ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc, uint16_t pdo_index)
Clear the mapping of a given PDO.
Definition: slave_config.c:749
static ATTRIBUTES int ec_ioctl_soe_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SoE IDN data.
Definition: rtdm-ioctl.c:3889
Ethernet-over-EtherCAT set IP parameter request.
Definition: eoe_request.h:41
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
Definition: domain.h:60
uint32_t ecrt_master_sync_monitor_process(const ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:2856
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:59
const ec_sdo_t * ec_slave_get_sdo_const(const ec_slave_t *slave, uint16_t index)
Get an SDO from the dictionary.
Definition: slave.c:666
uint32_t logical_base_address
Logical offset address of the process data.
Definition: domain.h:56
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:52
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:40
struct net_device_stats stats
device statistics
Definition: ethernet.h:82
char * name
PDO name.
Definition: pdo.h:45
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: rtdm-ioctl.c:1398
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:43
FoE request.
Definition: foe_request.h:42
static ATTRIBUTES int ec_ioctl_domain_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain&#39;s data size.
Definition: rtdm-ioctl.c:3271
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:62
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: rtdm-ioctl.c:1218
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:426
u64 tx_errors
Number of transmit errors.
Definition: device.h:102
uint16_t effective_alias
Effective alias address.
Definition: slave.h:177
char * name
entry name
Definition: pdo_entry.h:44
size_t data_size
Size of SDO data.
Definition: sdo_request.h:46
ec_internal_request_state_t state
Request state.
Definition: eoe_request.h:43
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: rtdm-ioctl.c:689
ec_soe_request_t * ecrt_slave_config_create_soe_request_err(ec_slave_config_t *sc, uint8_t drive_no, uint16_t idn, size_t size)
Same as ecrt_slave_config_create_soe_request(), but with ERR_PTR() return value.
struct list_head foe_requests
FoE requests.
Definition: slave.h:223
ec_direction_t dir
Direction.
Definition: voe_handler.h:48
u64 tx_bytes
Number of bytes sent.
Definition: master.h:150
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: rtdm-ioctl.c:215
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:1967
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: rtdm-ioctl.c:302
int ecrt_soe_request_read(ec_soe_request_t *req)
Schedule an SoE IDN read operation.
Definition: soe_request.c:307
uint8_t enable
Enable bit.
Definition: sync.h:44
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:43
Vendor specific over EtherCAT protocol handler.
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:132
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:273
static ATTRIBUTES int ec_ioctl_slave_soe_write(ec_master_t *master, void *arg)
Write an IDN to a slave via SoE.
Definition: rtdm-ioctl.c:4647
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:2867
uint8_t * ecrt_voe_handler_data(const ec_voe_handler_t *voe)
Access to the VoE handler&#39;s data.
Definition: voe_handler.c:139
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: rtdm-ioctl.c:4598
static void ec_ioctl_strcpy(char *target, const char *source)
Copies a string to an ioctl structure.
Definition: rtdm-ioctl.c:75
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.
Access rights in PREOP.
Definition: globals.h:190
static ATTRIBUTES int ec_ioctl_app_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the master DC application time.
Definition: rtdm-ioctl.c:2108
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:113
ec_direction_t dir
Direction.
Definition: reg_request.h:44
int ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:220
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: rtdm-ioctl.c:4414
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:118
uint8_t drive_no
Drive number.
Definition: soe_request.h:42
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:114
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:47
ec_request_state_t ecrt_soe_request_state(const ec_soe_request_t *req)
Get the current state of the SoE request.
Definition: soe_request.c:300
static ATTRIBUTES int ec_ioctl_sc_emerg_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the emergency ring buffer size.
Definition: rtdm-ioctl.c:2750
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:530
char * image
Image name.
Definition: slave.h:148
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:45
int32_t value
Flag value (meaning depends on key).
Definition: flag.h:41
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: rtdm-ioctl.c:3160
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:223
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:300
uint16_t physical_start_address
Physical start address.
Definition: sync.h:41
int ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:672
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:208
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:202
u64 rx_count
Number of frames received.
Definition: master.h:147
size_t sii_nwords
Size of the SII contents in words.
Definition: slave.h:212
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2279
struct work_struct sc_reset_work
Task to reset slave configuration.
Definition: master.h:299
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:205
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:65
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave&#39;s SII.
Definition: rtdm-ioctl.c:912
static ATTRIBUTES int ec_ioctl_slave_sync_pdo_entry(ec_master_t *master, void *arg)
Get slave sync manager PDO entry information.
Definition: rtdm-ioctl.c:414
char * group
Group name.
Definition: slave.h:147
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:146
static ATTRIBUTES int ec_ioctl_reg_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register write operation.
Definition: rtdm-ioctl.c:4021
static ATTRIBUTES int ec_ioctl_sc_sync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a sync manager.
Definition: rtdm-ioctl.c:2318
EtherCAT slave configuration.
Definition: slave_config.h:111
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry.
Definition: rtdm-ioctl.c:2553
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: rtdm-ioctl.c:1998
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:61
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:76
static ATTRIBUTES int ec_ioctl_sc_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the slave configuration&#39;s state.
Definition: rtdm-ioctl.c:3118
EtherCAT master character device IOCTL commands.
Request was processed successfully.
Definition: ecrt.h:604
EtherCAT slave configuration structure.
int ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2469
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:55
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:53
static ATTRIBUTES int ec_ioctl_soe_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SoE IDN read operation.
Definition: rtdm-ioctl.c:3804
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:2541
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:171
static ATTRIBUTES int ec_ioctl_voe_send_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the VoE send header.
Definition: rtdm-ioctl.c:4110
static ATTRIBUTES int ec_ioctl_voe_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE write operation.
Definition: rtdm-ioctl.c:4280
unsigned int index
Index.
Definition: master.h:184
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:1838
static ATTRIBUTES int ec_ioctl_sc_create_voe_handler(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a VoE handler.
Definition: rtdm-ioctl.c:3068
uint16_t default_length
Data length in bytes.
Definition: sync.h:42
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:128
static ATTRIBUTES int ec_ioctl_slave_foe_write(ec_master_t *master, void *arg)
Write a file to a slave via FoE.
Definition: rtdm-ioctl.c:4510
ec_direction_t dir
FMMU direction.
Definition: fmmu_config.h:43
const ec_pdo_t * ec_pdo_list_find_pdo_by_pos_const(const ec_pdo_list_t *pl, unsigned int pos)
Finds a PDO via its position in the list.
Definition: pdo_list.c:281
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:74
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: rtdm-ioctl.c:1948
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:206
u64 rx_bytes
Number of bytes received.
Definition: master.h:152
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: rtdm-ioctl.c:1591
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:290
static ATTRIBUTES int ec_ioctl_soe_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an CoE request&#39;s timeout.
Definition: rtdm-ioctl.c:3721
int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc, uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex, uint8_t entry_bit_length)
Add a PDO entry to the given PDO&#39;s mapping.
Definition: slave_config.c:712
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:185
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:157
size_t mem_size
Size of SDO data memory.
Definition: soe_request.h:46
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: rtdm-ioctl.c:1753
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:138
EtherCAT master.
Definition: master.h:183
struct list_head list
List item.
Definition: reg_request.h:41
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:225
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:43
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: rtdm-ioctl.c:654
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: rtdm-ioctl.c:1864
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:264
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:196
u64 tx_bytes
Number of bytes sent.
Definition: device.h:97
static ATTRIBUTES int ec_ioctl_sc_create_reg_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a register request.
Definition: rtdm-ioctl.c:3014
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:52
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:98
struct list_head list
List item.
Definition: eoe_request.h:42
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:50
int ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:2733
Sercos-over-EtherCAT request.
Definition: soe_request.h:40
char * name
Slave name.
Definition: slave.h:150
void ec_master_set_send_interval(ec_master_t *master, unsigned int send_interval)
Sets the expected interval between calls to ecrt_master_send and calculates the maximum amount of dat...
Definition: master.c:899
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:45
EtherCAT domain.
Definition: domain.h:46
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:81
static ATTRIBUTES int ec_ioctl_sdo_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SDO request&#39;s state.
Definition: rtdm-ioctl.c:3515
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:3027
uint32_t vendor_id
Vendor ID.
Definition: slave.h:127
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:47
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:116
int ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id, uint16_t vendor_type)
Sets the VoE header for future send operations.
Definition: voe_handler.c:115
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:233
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:580
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:49
int ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
Start a VoE read operation without querying the sync manager status.
Definition: voe_handler.c:163
struct list_head list
List item.
Definition: foe_request.h:43
unsigned int has_general
General category present.
Definition: slave.h:146
unsigned int tx_queued_frames
number of frames in the queue
Definition: ethernet.h:97
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:342