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