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