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