IgH EtherCAT Master 1.5.2
ioctl.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
6 *
7 * This file is part of the IgH EtherCAT Master.
8 *
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License version 2, as
11 * published by the Free Software Foundation.
12 *
13 * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with the IgH EtherCAT Master; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 * ---
23 *
24 * The license mentioned above concerns the source code only. Using the
25 * EtherCAT technology and brand is only permitted in compliance with the
26 * industrial property and similar rights of Beckhoff Automation GmbH.
27 *
28 *****************************************************************************/
29
35/*****************************************************************************/
36
37#include <linux/module.h>
38#include <linux/vmalloc.h>
39
40#include "master.h"
41#include "slave_config.h"
42#include "voe_handler.h"
43#include "ethernet.h"
44#include "ioctl.h"
45
50#define DEBUG_LATENCY 0
51
54#if 0
55#define ATTRIBUTES __attribute__ ((__noinline__))
56#else
57#define ATTRIBUTES
58#endif
59
60/*****************************************************************************/
61
64static void ec_ioctl_strcpy(
65 char *target,
66 const char *source
67 )
68{
69 if (source) {
70 strncpy(target, source, EC_IOCTL_STRING_SIZE);
71 target[EC_IOCTL_STRING_SIZE - 1] = 0;
72 } else {
73 target[0] = 0;
74 }
75}
76
77/*****************************************************************************/
78
84 void *arg
85 )
86{
87 ec_ioctl_module_t data;
88
89 data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
90 data.master_count = ec_master_count();
91
92 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
93 return -EFAULT;
94
95 return 0;
96}
97
98/*****************************************************************************/
99
105 ec_master_t *master,
106 void *arg
107 )
108{
109 ec_ioctl_master_t io;
110 unsigned int dev_idx, j;
111
112 if (down_interruptible(&master->master_sem)) {
113 return -EINTR;
114 }
115
116 io.slave_count = master->slave_count;
117 io.config_count = ec_master_config_count(master);
118 io.domain_count = ec_master_domain_count(master);
119#ifdef EC_EOE
120 io.eoe_handler_count = ec_master_eoe_handler_count(master);
121#endif
122 io.phase = (uint8_t) master->phase;
123 io.active = (uint8_t) master->active;
124 io.scan_busy = master->scan_busy;
125
126 up(&master->master_sem);
127
128 if (down_interruptible(&master->device_sem)) {
129 return -EINTR;
130 }
131
132 for (dev_idx = EC_DEVICE_MAIN;
133 dev_idx < ec_master_num_devices(master); dev_idx++) {
134 ec_device_t *device = &master->devices[dev_idx];
135
136 if (device->dev) {
137 memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
138 ETH_ALEN);
139 } else {
140 memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
141 ETH_ALEN);
142 }
143 io.devices[dev_idx].attached = device->dev ? 1 : 0;
144 io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
145 io.devices[dev_idx].tx_count = device->tx_count;
146 io.devices[dev_idx].rx_count = device->rx_count;
147 io.devices[dev_idx].tx_bytes = device->tx_bytes;
148 io.devices[dev_idx].rx_bytes = device->rx_bytes;
149 io.devices[dev_idx].tx_errors = device->tx_errors;
150 for (j = 0; j < EC_RATE_COUNT; j++) {
151 io.devices[dev_idx].tx_frame_rates[j] =
152 device->tx_frame_rates[j];
153 io.devices[dev_idx].rx_frame_rates[j] =
154 device->rx_frame_rates[j];
155 io.devices[dev_idx].tx_byte_rates[j] =
156 device->tx_byte_rates[j];
157 io.devices[dev_idx].rx_byte_rates[j] =
158 device->rx_byte_rates[j];
159 }
160 }
161 io.num_devices = ec_master_num_devices(master);
162
163 io.tx_count = master->device_stats.tx_count;
164 io.rx_count = master->device_stats.rx_count;
165 io.tx_bytes = master->device_stats.tx_bytes;
166 io.rx_bytes = master->device_stats.rx_bytes;
167 for (j = 0; j < EC_RATE_COUNT; j++) {
168 io.tx_frame_rates[j] =
169 master->device_stats.tx_frame_rates[j];
170 io.rx_frame_rates[j] =
171 master->device_stats.rx_frame_rates[j];
172 io.tx_byte_rates[j] =
173 master->device_stats.tx_byte_rates[j];
174 io.rx_byte_rates[j] =
175 master->device_stats.rx_byte_rates[j];
176 io.loss_rates[j] =
177 master->device_stats.loss_rates[j];
178 }
179
180 up(&master->device_sem);
181
182 io.app_time = master->app_time;
183 io.dc_ref_time = master->dc_ref_time;
184 io.ref_clock =
185 master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
186
187 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
188 return -EFAULT;
189 }
190
191 return 0;
192}
193
194/*****************************************************************************/
195
201 ec_master_t *master,
202 void *arg
203 )
204{
205 ec_ioctl_slave_t data;
206 const ec_slave_t *slave;
207 int i;
208
209 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
210 return -EFAULT;
211 }
212
213 if (down_interruptible(&master->master_sem))
214 return -EINTR;
215
216 if (!(slave = ec_master_find_slave_const(
217 master, 0, data.position))) {
218 up(&master->master_sem);
219 EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
220 return -EINVAL;
221 }
222
223 data.device_index = slave->device_index;
224 data.vendor_id = slave->sii.vendor_id;
225 data.product_code = slave->sii.product_code;
226 data.revision_number = slave->sii.revision_number;
227 data.serial_number = slave->sii.serial_number;
228 data.alias = slave->effective_alias;
229 data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
230 data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
231 data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
232 data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
233 data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
234 data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
235 data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
236 data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
237 data.mailbox_protocols = slave->sii.mailbox_protocols;
238 data.has_general_category = slave->sii.has_general;
239 data.coe_details = slave->sii.coe_details;
240 data.general_flags = slave->sii.general_flags;
241 data.current_on_ebus = slave->sii.current_on_ebus;
242 for (i = 0; i < EC_MAX_PORTS; i++) {
243 data.ports[i].desc = slave->ports[i].desc;
244 data.ports[i].link.link_up = slave->ports[i].link.link_up;
245 data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
246 data.ports[i].link.signal_detected =
247 slave->ports[i].link.signal_detected;
248 data.ports[i].receive_time = slave->ports[i].receive_time;
249 if (slave->ports[i].next_slave) {
250 data.ports[i].next_slave =
251 slave->ports[i].next_slave->ring_position;
252 } else {
253 data.ports[i].next_slave = 0xffff;
254 }
255 data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
256 }
257 data.fmmu_bit = slave->base_fmmu_bit_operation;
258 data.dc_supported = slave->base_dc_supported;
259 data.dc_range = slave->base_dc_range;
260 data.has_dc_system_time = slave->has_dc_system_time;
261 data.transmission_delay = slave->transmission_delay;
262 data.al_state = slave->current_state;
263 data.error_flag = slave->error_flag;
264
265 data.sync_count = slave->sii.sync_count;
266 data.sdo_count = ec_slave_sdo_count(slave);
267 data.sii_nwords = slave->sii_nwords;
268 ec_ioctl_strcpy(data.group, slave->sii.group);
269 ec_ioctl_strcpy(data.image, slave->sii.image);
270 ec_ioctl_strcpy(data.order, slave->sii.order);
271 ec_ioctl_strcpy(data.name, slave->sii.name);
272
273 up(&master->master_sem);
274
275 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
276 return -EFAULT;
277
278 return 0;
279}
280
281/*****************************************************************************/
282
288 ec_master_t *master,
289 void *arg
290 )
291{
292 ec_ioctl_slave_sync_t data;
293 const ec_slave_t *slave;
294 const ec_sync_t *sync;
295
296 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
297 return -EFAULT;
298 }
299
300 if (down_interruptible(&master->master_sem))
301 return -EINTR;
302
303 if (!(slave = ec_master_find_slave_const(
304 master, 0, data.slave_position))) {
305 up(&master->master_sem);
306 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
307 data.slave_position);
308 return -EINVAL;
309 }
310
311 if (data.sync_index >= slave->sii.sync_count) {
312 up(&master->master_sem);
313 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
314 data.sync_index);
315 return -EINVAL;
316 }
317
318 sync = &slave->sii.syncs[data.sync_index];
319
321 data.default_size = sync->default_length;
322 data.control_register = sync->control_register;
323 data.enable = sync->enable;
324 data.pdo_count = ec_pdo_list_count(&sync->pdos);
325
326 up(&master->master_sem);
327
328 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
329 return -EFAULT;
330
331 return 0;
332}
333
334/*****************************************************************************/
335
341 ec_master_t *master,
342 void *arg
343 )
344{
345 ec_ioctl_slave_sync_pdo_t data;
346 const ec_slave_t *slave;
347 const ec_sync_t *sync;
348 const ec_pdo_t *pdo;
349
350 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
351 return -EFAULT;
352 }
353
354 if (down_interruptible(&master->master_sem))
355 return -EINTR;
356
357 if (!(slave = ec_master_find_slave_const(
358 master, 0, data.slave_position))) {
359 up(&master->master_sem);
360 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
361 data.slave_position);
362 return -EINVAL;
363 }
364
365 if (data.sync_index >= slave->sii.sync_count) {
366 up(&master->master_sem);
367 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
368 data.sync_index);
369 return -EINVAL;
370 }
371
372 sync = &slave->sii.syncs[data.sync_index];
374 &sync->pdos, data.pdo_pos))) {
375 up(&master->master_sem);
376 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
377 "position %u!\n", data.sync_index, data.pdo_pos);
378 return -EINVAL;
379 }
380
381 data.index = pdo->index;
382 data.entry_count = ec_pdo_entry_count(pdo);
383 ec_ioctl_strcpy(data.name, pdo->name);
384
385 up(&master->master_sem);
386
387 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
388 return -EFAULT;
389
390 return 0;
391}
392
393/*****************************************************************************/
394
400 ec_master_t *master,
401 void *arg
402 )
403{
404 ec_ioctl_slave_sync_pdo_entry_t data;
405 const ec_slave_t *slave;
406 const ec_sync_t *sync;
407 const ec_pdo_t *pdo;
408 const ec_pdo_entry_t *entry;
409
410 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
411 return -EFAULT;
412 }
413
414 if (down_interruptible(&master->master_sem))
415 return -EINTR;
416
417 if (!(slave = ec_master_find_slave_const(
418 master, 0, data.slave_position))) {
419 up(&master->master_sem);
420 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
421 data.slave_position);
422 return -EINVAL;
423 }
424
425 if (data.sync_index >= slave->sii.sync_count) {
426 up(&master->master_sem);
427 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
428 data.sync_index);
429 return -EINVAL;
430 }
431
432 sync = &slave->sii.syncs[data.sync_index];
434 &sync->pdos, data.pdo_pos))) {
435 up(&master->master_sem);
436 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
437 "position %u!\n", data.sync_index, data.pdo_pos);
438 return -EINVAL;
439 }
440
441 if (!(entry = ec_pdo_find_entry_by_pos_const(
442 pdo, data.entry_pos))) {
443 up(&master->master_sem);
444 EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
445 "position %u!\n", data.pdo_pos, data.entry_pos);
446 return -EINVAL;
447 }
448
449 data.index = entry->index;
450 data.subindex = entry->subindex;
451 data.bit_length = entry->bit_length;
452 ec_ioctl_strcpy(data.name, entry->name);
453
454 up(&master->master_sem);
455
456 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
457 return -EFAULT;
458
459 return 0;
460}
461
462/*****************************************************************************/
463
469 ec_master_t *master,
470 void *arg
471 )
472{
473 ec_ioctl_domain_t data;
474 const ec_domain_t *domain;
475 unsigned int dev_idx;
476
477 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
478 return -EFAULT;
479 }
480
481 if (down_interruptible(&master->master_sem))
482 return -EINTR;
483
484 if (!(domain = ec_master_find_domain_const(master, data.index))) {
485 up(&master->master_sem);
486 EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
487 return -EINVAL;
488 }
489
490 data.data_size = domain->data_size;
491 data.logical_base_address = domain->logical_base_address;
492 for (dev_idx = EC_DEVICE_MAIN;
493 dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
494 data.working_counter[dev_idx] = domain->working_counter[dev_idx];
495 }
496 data.expected_working_counter = domain->expected_working_counter;
497 data.fmmu_count = ec_domain_fmmu_count(domain);
498
499 up(&master->master_sem);
500
501 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
502 return -EFAULT;
503
504 return 0;
505}
506
507/*****************************************************************************/
508
514 ec_master_t *master,
515 void *arg
516 )
517{
518 ec_ioctl_domain_fmmu_t data;
519 const ec_domain_t *domain;
520 const ec_fmmu_config_t *fmmu;
521
522 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
523 return -EFAULT;
524 }
525
526 if (down_interruptible(&master->master_sem))
527 return -EINTR;
528
529 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
530 up(&master->master_sem);
531 EC_MASTER_ERR(master, "Domain %u does not exist!\n",
532 data.domain_index);
533 return -EINVAL;
534 }
535
536 if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
537 up(&master->master_sem);
538 EC_MASTER_ERR(master, "Domain %u has less than %u"
539 " fmmu configurations.\n",
540 data.domain_index, data.fmmu_index + 1);
541 return -EINVAL;
542 }
543
544 data.slave_config_alias = fmmu->sc->alias;
545 data.slave_config_position = fmmu->sc->position;
546 data.sync_index = fmmu->sync_index;
547 data.dir = fmmu->dir;
548 data.logical_address = fmmu->logical_start_address;
549 data.data_size = fmmu->data_size;
550
551 up(&master->master_sem);
552
553 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
554 return -EFAULT;
555
556 return 0;
557}
558
559/*****************************************************************************/
560
566 ec_master_t *master,
567 void *arg
568 )
569{
570 ec_ioctl_domain_data_t data;
571 const ec_domain_t *domain;
572
573 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
574 return -EFAULT;
575 }
576
577 if (down_interruptible(&master->master_sem))
578 return -EINTR;
579
580 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
581 up(&master->master_sem);
582 EC_MASTER_ERR(master, "Domain %u does not exist!\n",
583 data.domain_index);
584 return -EINVAL;
585 }
586
587 if (domain->data_size != data.data_size) {
588 up(&master->master_sem);
589 EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
590 data.data_size, domain->data_size);
591 return -EFAULT;
592 }
593
594 if (copy_to_user((void __user *) data.target, domain->data,
595 domain->data_size)) {
596 up(&master->master_sem);
597 return -EFAULT;
598 }
599
600 up(&master->master_sem);
601 return 0;
602}
603
604/*****************************************************************************/
605
611 ec_master_t *master,
612 void *arg
613 )
614{
615 return ec_master_debug_level(master, (unsigned long) arg);
616}
617
618/*****************************************************************************/
619
625 ec_master_t *master,
626 void *arg
627 )
628{
629 master->fsm.rescan_required = 1;
630 return 0;
631}
632
633/*****************************************************************************/
634
640 ec_master_t *master,
641 void *arg
642 )
643{
644 ec_ioctl_slave_state_t data;
645 ec_slave_t *slave;
646
647 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
648 return -EFAULT;
649 }
650
651 if (down_interruptible(&master->master_sem))
652 return -EINTR;
653
654 if (!(slave = ec_master_find_slave(
655 master, 0, data.slave_position))) {
656 up(&master->master_sem);
657 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
658 data.slave_position);
659 return -EINVAL;
660 }
661
662 ec_slave_request_state(slave, data.al_state);
663
664 up(&master->master_sem);
665 return 0;
666}
667
668/*****************************************************************************/
669
675 ec_master_t *master,
676 void *arg
677 )
678{
679 ec_ioctl_slave_sdo_t data;
680 const ec_slave_t *slave;
681 const ec_sdo_t *sdo;
682
683 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
684 return -EFAULT;
685 }
686
687 if (down_interruptible(&master->master_sem))
688 return -EINTR;
689
690 if (!(slave = ec_master_find_slave_const(
691 master, 0, data.slave_position))) {
692 up(&master->master_sem);
693 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
694 data.slave_position);
695 return -EINVAL;
696 }
697
699 slave, data.sdo_position))) {
700 up(&master->master_sem);
701 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
702 return -EINVAL;
703 }
704
705 data.sdo_index = sdo->index;
706 data.max_subindex = sdo->max_subindex;
707 ec_ioctl_strcpy(data.name, sdo->name);
708
709 up(&master->master_sem);
710
711 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
712 return -EFAULT;
713
714 return 0;
715}
716
717/*****************************************************************************/
718
724 ec_master_t *master,
725 void *arg
726 )
727{
728 ec_ioctl_slave_sdo_entry_t data;
729 const ec_slave_t *slave;
730 const ec_sdo_t *sdo;
731 const ec_sdo_entry_t *entry;
732
733 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
734 return -EFAULT;
735 }
736
737 if (down_interruptible(&master->master_sem))
738 return -EINTR;
739
740 if (!(slave = ec_master_find_slave_const(
741 master, 0, data.slave_position))) {
742 up(&master->master_sem);
743 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
744 data.slave_position);
745 return -EINVAL;
746 }
747
748 if (data.sdo_spec <= 0) {
750 slave, -data.sdo_spec))) {
751 up(&master->master_sem);
752 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
753 return -EINVAL;
754 }
755 } else {
756 if (!(sdo = ec_slave_get_sdo_const(
757 slave, data.sdo_spec))) {
758 up(&master->master_sem);
759 EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
760 data.sdo_spec);
761 return -EINVAL;
762 }
763 }
764
765 if (!(entry = ec_sdo_get_entry_const(
766 sdo, data.sdo_entry_subindex))) {
767 up(&master->master_sem);
768 EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
769 sdo->index, data.sdo_entry_subindex);
770 return -EINVAL;
771 }
772
773 data.data_type = entry->data_type;
774 data.bit_length = entry->bit_length;
775 data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
777 data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
779 data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
781 data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
783 data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
785 data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
787 ec_ioctl_strcpy(data.description, entry->description);
788
789 up(&master->master_sem);
790
791 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
792 return -EFAULT;
793
794 return 0;
795}
796
797/*****************************************************************************/
798
804 ec_master_t *master,
805 void *arg
806 )
807{
808 ec_ioctl_slave_sdo_upload_t data;
809 uint8_t *target;
810 int ret;
811
812 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
813 return -EFAULT;
814 }
815
816 if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
817 EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
818 " for SDO upload.\n", data.target_size);
819 return -ENOMEM;
820 }
821
822 ret = ecrt_master_sdo_upload(master, data.slave_position,
823 data.sdo_index, data.sdo_entry_subindex, target,
824 data.target_size, &data.data_size, &data.abort_code);
825
826 if (!ret) {
827 if (copy_to_user((void __user *) data.target,
828 target, data.data_size)) {
829 kfree(target);
830 return -EFAULT;
831 }
832 }
833
834 kfree(target);
835
836 if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
837 return -EFAULT;
838 }
839
840 return ret;
841}
842
843/*****************************************************************************/
844
850 ec_master_t *master,
851 void *arg
852 )
853{
854 ec_ioctl_slave_sdo_download_t data;
855 uint8_t *sdo_data;
856 int retval;
857
858 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
859 return -EFAULT;
860 }
861
862 if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
863 EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
864 " for SDO download.\n", data.data_size);
865 return -ENOMEM;
866 }
867
868 if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
869 kfree(sdo_data);
870 return -EFAULT;
871 }
872
873 if (data.complete_access) {
874 retval = ecrt_master_sdo_download_complete(master, data.slave_position,
875 data.sdo_index, sdo_data, data.data_size, &data.abort_code);
876 } else {
877 retval = ecrt_master_sdo_download(master, data.slave_position,
878 data.sdo_index, data.sdo_entry_subindex, sdo_data,
879 data.data_size, &data.abort_code);
880 }
881
882 kfree(sdo_data);
883
884 if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
885 retval = -EFAULT;
886 }
887
888 return retval;
889}
890
891/*****************************************************************************/
892
898 ec_master_t *master,
899 void *arg
900 )
901{
902 ec_ioctl_slave_sii_t data;
903 const ec_slave_t *slave;
904 int retval;
905
906 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
907 return -EFAULT;
908 }
909
910 if (down_interruptible(&master->master_sem))
911 return -EINTR;
912
913 if (!(slave = ec_master_find_slave_const(
914 master, 0, data.slave_position))) {
915 up(&master->master_sem);
916 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
917 data.slave_position);
918 return -EINVAL;
919 }
920
921 if (!data.nwords
922 || data.offset + data.nwords > slave->sii_nwords) {
923 up(&master->master_sem);
924 EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
925 " size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
926 return -EINVAL;
927 }
928
929 if (copy_to_user((void __user *) data.words,
930 slave->sii_words + data.offset, data.nwords * 2))
931 retval = -EFAULT;
932 else
933 retval = 0;
934
935 up(&master->master_sem);
936 return retval;
937}
938
939/*****************************************************************************/
940
946 ec_master_t *master,
947 void *arg
948 )
949{
950 ec_ioctl_slave_sii_t data;
951 ec_slave_t *slave;
952 unsigned int byte_size;
953 uint16_t *words;
955
956 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
957 return -EFAULT;
958 }
959
960 if (!data.nwords) {
961 return 0;
962 }
963
964 byte_size = sizeof(uint16_t) * data.nwords;
965 if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
966 EC_MASTER_ERR(master, "Failed to allocate %u bytes"
967 " for SII contents.\n", byte_size);
968 return -ENOMEM;
969 }
970
971 if (copy_from_user(words,
972 (void __user *) data.words, byte_size)) {
973 kfree(words);
974 return -EFAULT;
975 }
976
977 if (down_interruptible(&master->master_sem)) {
978 kfree(words);
979 return -EINTR;
980 }
981
982 if (!(slave = ec_master_find_slave(
983 master, 0, data.slave_position))) {
984 up(&master->master_sem);
985 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
986 data.slave_position);
987 kfree(words);
988 return -EINVAL;
989 }
990
991 // init SII write request
992 INIT_LIST_HEAD(&request.list);
993 request.slave = slave;
994 request.words = words;
995 request.offset = data.offset;
996 request.nwords = data.nwords;
997 request.state = EC_INT_REQUEST_QUEUED;
998
999 // schedule SII write request.
1000 list_add_tail(&request.list, &master->sii_requests);
1001
1002 up(&master->master_sem);
1003
1004 // wait for processing through FSM
1005 if (wait_event_interruptible(master->request_queue,
1006 request.state != EC_INT_REQUEST_QUEUED)) {
1007 // interrupted by signal
1008 down(&master->master_sem);
1009 if (request.state == EC_INT_REQUEST_QUEUED) {
1010 // abort request
1011 list_del(&request.list);
1012 up(&master->master_sem);
1013 kfree(words);
1014 return -EINTR;
1015 }
1016 up(&master->master_sem);
1017 }
1018
1019 // wait until master FSM has finished processing
1020 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1021
1022 kfree(words);
1023
1024 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1025}
1026
1027/*****************************************************************************/
1028
1034 ec_master_t *master,
1035 void *arg
1036 )
1037{
1038 ec_ioctl_slave_reg_t io;
1039 ec_slave_t *slave;
1040 ec_reg_request_t request;
1041 int ret;
1042
1043 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1044 return -EFAULT;
1045 }
1046
1047 if (!io.size) {
1048 return 0;
1049 }
1050
1051 // init register request
1052 ret = ec_reg_request_init(&request, io.size);
1053 if (ret) {
1054 return ret;
1055 }
1056
1057 ecrt_reg_request_read(&request, io.address, io.size);
1058
1059 if (down_interruptible(&master->master_sem)) {
1060 ec_reg_request_clear(&request);
1061 return -EINTR;
1062 }
1063
1064 if (!(slave = ec_master_find_slave(
1065 master, 0, io.slave_position))) {
1066 up(&master->master_sem);
1067 ec_reg_request_clear(&request);
1068 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1069 io.slave_position);
1070 return -EINVAL;
1071 }
1072
1073 // schedule request.
1074 list_add_tail(&request.list, &slave->reg_requests);
1075
1076 up(&master->master_sem);
1077
1078 // wait for processing through FSM
1079 if (wait_event_interruptible(master->request_queue,
1080 request.state != EC_INT_REQUEST_QUEUED)) {
1081 // interrupted by signal
1082 down(&master->master_sem);
1083 if (request.state == EC_INT_REQUEST_QUEUED) {
1084 // abort request
1085 list_del(&request.list);
1086 up(&master->master_sem);
1087 ec_reg_request_clear(&request);
1088 return -EINTR;
1089 }
1090 up(&master->master_sem);
1091 }
1092
1093 // wait until master FSM has finished processing
1094 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1095
1096 if (request.state == EC_INT_REQUEST_SUCCESS) {
1097 if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1098 return -EFAULT;
1099 }
1100 }
1101 ec_reg_request_clear(&request);
1102
1103 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1104}
1105
1106/*****************************************************************************/
1107
1113 ec_master_t *master,
1114 void *arg
1115 )
1116{
1117 ec_ioctl_slave_reg_t io;
1118 ec_slave_t *slave;
1119 ec_reg_request_t request;
1120 int ret;
1121
1122 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1123 return -EFAULT;
1124 }
1125
1126 if (!io.size) {
1127 return 0;
1128 }
1129
1130 // init register request
1131 ret = ec_reg_request_init(&request, io.size);
1132 if (ret) {
1133 return ret;
1134 }
1135
1136 if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1137 ec_reg_request_clear(&request);
1138 return -EFAULT;
1139 }
1140
1141 ecrt_reg_request_write(&request, io.address, io.size);
1142
1143 if (down_interruptible(&master->master_sem)) {
1144 ec_reg_request_clear(&request);
1145 return -EINTR;
1146 }
1147
1148 if (io.emergency) {
1149 request.ring_position = io.slave_position;
1150 // schedule request.
1151 list_add_tail(&request.list, &master->emerg_reg_requests);
1152 }
1153 else {
1154 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1155 up(&master->master_sem);
1156 ec_reg_request_clear(&request);
1157 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1158 io.slave_position);
1159 return -EINVAL;
1160 }
1161
1162 // schedule request.
1163 list_add_tail(&request.list, &slave->reg_requests);
1164 }
1165
1166 up(&master->master_sem);
1167
1168 // wait for processing through FSM
1169 if (wait_event_interruptible(master->request_queue,
1170 request.state != EC_INT_REQUEST_QUEUED)) {
1171 // interrupted by signal
1172 down(&master->master_sem);
1173 if (request.state == EC_INT_REQUEST_QUEUED) {
1174 // abort request
1175 list_del(&request.list);
1176 up(&master->master_sem);
1177 ec_reg_request_clear(&request);
1178 return -EINTR;
1179 }
1180 up(&master->master_sem);
1181 }
1182
1183 // wait until master FSM has finished processing
1184 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1185
1186 ec_reg_request_clear(&request);
1187
1188 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1189}
1190
1191/*****************************************************************************/
1192
1198 ec_master_t *master,
1199 void *arg
1200 )
1201{
1202 ec_ioctl_config_t data;
1203 const ec_slave_config_t *sc;
1204 uint8_t i;
1205
1206 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1207 return -EFAULT;
1208 }
1209
1210 if (down_interruptible(&master->master_sem))
1211 return -EINTR;
1212
1213 if (!(sc = ec_master_get_config_const(
1214 master, data.config_index))) {
1215 up(&master->master_sem);
1216 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1217 data.config_index);
1218 return -EINVAL;
1219 }
1220
1221 data.alias = sc->alias;
1222 data.position = sc->position;
1223 data.vendor_id = sc->vendor_id;
1224 data.product_code = sc->product_code;
1225 for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1226 data.syncs[i].dir = sc->sync_configs[i].dir;
1227 data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1228 data.syncs[i].pdo_count =
1230 }
1231 data.watchdog_divider = sc->watchdog_divider;
1232 data.watchdog_intervals = sc->watchdog_intervals;
1233 data.sdo_count = ec_slave_config_sdo_count(sc);
1234 data.idn_count = ec_slave_config_idn_count(sc);
1235 data.flag_count = ec_slave_config_flag_count(sc);
1236 data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1237 data.dc_assign_activate = sc->dc_assign_activate;
1238 for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1239 data.dc_sync[i] = sc->dc_sync[i];
1240 }
1241
1242 up(&master->master_sem);
1243
1244 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1245 return -EFAULT;
1246
1247 return 0;
1248}
1249
1250/*****************************************************************************/
1251
1257 ec_master_t *master,
1258 void *arg
1259 )
1260{
1261 ec_ioctl_config_pdo_t data;
1262 const ec_slave_config_t *sc;
1263 const ec_pdo_t *pdo;
1264
1265 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1266 return -EFAULT;
1267 }
1268
1269 if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1270 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1271 data.sync_index);
1272 return -EINVAL;
1273 }
1274
1275 if (down_interruptible(&master->master_sem))
1276 return -EINTR;
1277
1278 if (!(sc = ec_master_get_config_const(
1279 master, data.config_index))) {
1280 up(&master->master_sem);
1281 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1282 data.config_index);
1283 return -EINVAL;
1284 }
1285
1287 &sc->sync_configs[data.sync_index].pdos,
1288 data.pdo_pos))) {
1289 up(&master->master_sem);
1290 EC_MASTER_ERR(master, "Invalid PDO position!\n");
1291 return -EINVAL;
1292 }
1293
1294 data.index = pdo->index;
1295 data.entry_count = ec_pdo_entry_count(pdo);
1296 ec_ioctl_strcpy(data.name, pdo->name);
1297
1298 up(&master->master_sem);
1299
1300 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1301 return -EFAULT;
1302
1303 return 0;
1304}
1305
1306/*****************************************************************************/
1307
1313 ec_master_t *master,
1314 void *arg
1315 )
1316{
1317 ec_ioctl_config_pdo_entry_t data;
1318 const ec_slave_config_t *sc;
1319 const ec_pdo_t *pdo;
1320 const ec_pdo_entry_t *entry;
1321
1322 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1323 return -EFAULT;
1324 }
1325
1326 if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1327 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1328 data.sync_index);
1329 return -EINVAL;
1330 }
1331
1332 if (down_interruptible(&master->master_sem))
1333 return -EINTR;
1334
1335 if (!(sc = ec_master_get_config_const(
1336 master, data.config_index))) {
1337 up(&master->master_sem);
1338 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1339 data.config_index);
1340 return -EINVAL;
1341 }
1342
1344 &sc->sync_configs[data.sync_index].pdos,
1345 data.pdo_pos))) {
1346 up(&master->master_sem);
1347 EC_MASTER_ERR(master, "Invalid PDO position!\n");
1348 return -EINVAL;
1349 }
1350
1351 if (!(entry = ec_pdo_find_entry_by_pos_const(
1352 pdo, data.entry_pos))) {
1353 up(&master->master_sem);
1354 EC_MASTER_ERR(master, "Entry not found!\n");
1355 return -EINVAL;
1356 }
1357
1358 data.index = entry->index;
1359 data.subindex = entry->subindex;
1360 data.bit_length = entry->bit_length;
1361 ec_ioctl_strcpy(data.name, entry->name);
1362
1363 up(&master->master_sem);
1364
1365 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1366 return -EFAULT;
1367
1368 return 0;
1369}
1370
1371/*****************************************************************************/
1372
1378 ec_master_t *master,
1379 void *arg
1380 )
1381{
1382 ec_ioctl_config_sdo_t *ioctl;
1383 const ec_slave_config_t *sc;
1384 const ec_sdo_request_t *req;
1385
1386 if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1387 return -ENOMEM;
1388 }
1389
1390 if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1391 kfree(ioctl);
1392 return -EFAULT;
1393 }
1394
1395 if (down_interruptible(&master->master_sem)) {
1396 kfree(ioctl);
1397 return -EINTR;
1398 }
1399
1400 if (!(sc = ec_master_get_config_const(
1401 master, ioctl->config_index))) {
1402 up(&master->master_sem);
1403 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1404 ioctl->config_index);
1405 kfree(ioctl);
1406 return -EINVAL;
1407 }
1408
1410 sc, ioctl->sdo_pos))) {
1411 up(&master->master_sem);
1412 EC_MASTER_ERR(master, "Invalid SDO position!\n");
1413 kfree(ioctl);
1414 return -EINVAL;
1415 }
1416
1417 ioctl->index = req->index;
1418 ioctl->subindex = req->subindex;
1419 ioctl->size = req->data_size;
1420 memcpy(ioctl->data, req->data,
1421 min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1422 ioctl->complete_access = req->complete_access;
1423
1424 up(&master->master_sem);
1425
1426 if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1427 kfree(ioctl);
1428 return -EFAULT;
1429 }
1430
1431 kfree(ioctl);
1432 return 0;
1433}
1434
1435/*****************************************************************************/
1436
1442 ec_master_t *master,
1443 void *arg
1444 )
1445{
1446 ec_ioctl_config_idn_t *ioctl;
1447 const ec_slave_config_t *sc;
1448 const ec_soe_request_t *req;
1449
1450 if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1451 return -ENOMEM;
1452 }
1453
1454 if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1455 kfree(ioctl);
1456 return -EFAULT;
1457 }
1458
1459 if (down_interruptible(&master->master_sem)) {
1460 kfree(ioctl);
1461 return -EINTR;
1462 }
1463
1464 if (!(sc = ec_master_get_config_const(
1465 master, ioctl->config_index))) {
1466 up(&master->master_sem);
1467 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1468 ioctl->config_index);
1469 kfree(ioctl);
1470 return -EINVAL;
1471 }
1472
1474 sc, ioctl->idn_pos))) {
1475 up(&master->master_sem);
1476 EC_MASTER_ERR(master, "Invalid IDN position!\n");
1477 kfree(ioctl);
1478 return -EINVAL;
1479 }
1480
1481 ioctl->drive_no = req->drive_no;
1482 ioctl->idn = req->idn;
1483 ioctl->state = req->state;
1484 ioctl->size = req->data_size;
1485 memcpy(ioctl->data, req->data,
1486 min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1487
1488 up(&master->master_sem);
1489
1490 if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1491 kfree(ioctl);
1492 return -EFAULT;
1493 }
1494
1495 kfree(ioctl);
1496 return 0;
1497}
1498
1499/*****************************************************************************/
1500
1506 ec_master_t *master,
1507 void *arg
1508 )
1509{
1510 ec_ioctl_config_flag_t *ioctl;
1511 const ec_slave_config_t *sc;
1512 const ec_flag_t *flag;
1513 size_t size;
1514
1515 if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1516 return -ENOMEM;
1517 }
1518
1519 if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1520 kfree(ioctl);
1521 return -EFAULT;
1522 }
1523
1524 if (down_interruptible(&master->master_sem)) {
1525 kfree(ioctl);
1526 return -EINTR;
1527 }
1528
1529 if (!(sc = ec_master_get_config_const(
1530 master, ioctl->config_index))) {
1531 up(&master->master_sem);
1532 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1533 ioctl->config_index);
1534 kfree(ioctl);
1535 return -EINVAL;
1536 }
1537
1539 sc, ioctl->flag_pos))) {
1540 up(&master->master_sem);
1541 EC_MASTER_ERR(master, "Invalid flag position!\n");
1542 kfree(ioctl);
1543 return -EINVAL;
1544 }
1545
1546 size = min((u32) strlen(flag->key), (u32) EC_MAX_FLAG_KEY_SIZE - 1);
1547 memcpy(ioctl->key, flag->key, size);
1548 ioctl->key[size] = 0x00;
1549 ioctl->value = flag->value;
1550
1551 up(&master->master_sem);
1552
1553 if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1554 kfree(ioctl);
1555 return -EFAULT;
1556 }
1557
1558 kfree(ioctl);
1559 return 0;
1560}
1561
1562/*****************************************************************************/
1563
1564#ifdef EC_EOE
1565
1571 ec_master_t *master,
1572 void *arg
1573 )
1574{
1575 ec_ioctl_eoe_handler_t data;
1576 const ec_eoe_t *eoe;
1577
1578 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1579 return -EFAULT;
1580 }
1581
1582 if (down_interruptible(&master->master_sem))
1583 return -EINTR;
1584
1585 if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1586 up(&master->master_sem);
1587 EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1588 data.eoe_index);
1589 return -EINVAL;
1590 }
1591
1592 if (eoe->slave) {
1593 data.slave_position = eoe->slave->ring_position;
1594 } else {
1595 data.slave_position = 0xffff;
1596 }
1597 snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1598 data.open = eoe->opened;
1599 data.rx_bytes = eoe->stats.tx_bytes;
1600 data.rx_rate = eoe->tx_rate;
1601 data.tx_bytes = eoe->stats.rx_bytes;
1602 data.tx_rate = eoe->tx_rate;
1603 data.tx_queued_frames = eoe->tx_queued_frames;
1604 data.tx_queue_size = eoe->tx_queue_size;
1605
1606 up(&master->master_sem);
1607
1608 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1609 return -EFAULT;
1610
1611 return 0;
1612}
1613
1614#endif
1615
1616/*****************************************************************************/
1617
1623 ec_master_t *master,
1624 void *arg,
1625 ec_ioctl_context_t *ctx
1626 )
1627{
1628 ec_master_t *m;
1629 int ret = 0;
1630
1631 m = ecrt_request_master_err(master->index);
1632 if (IS_ERR(m)) {
1633 ret = PTR_ERR(m);
1634 } else {
1635 ctx->requested = 1;
1636 }
1637
1638 return ret;
1639}
1640
1641/*****************************************************************************/
1642
1648 ec_master_t *master,
1649 void *arg,
1650 ec_ioctl_context_t *ctx
1651 )
1652{
1653 ec_domain_t *domain;
1654
1655 if (unlikely(!ctx->requested))
1656 return -EPERM;
1657
1658 domain = ecrt_master_create_domain_err(master);
1659 if (IS_ERR(domain))
1660 return PTR_ERR(domain);
1661
1662 return domain->index;
1663}
1664
1665/*****************************************************************************/
1666
1672 ec_master_t *master,
1673 void *arg,
1674 ec_ioctl_context_t *ctx
1675 )
1676{
1677 ec_ioctl_config_t data;
1678 ec_slave_config_t *sc, *entry;
1679
1680 if (unlikely(!ctx->requested))
1681 return -EPERM;
1682
1683 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1684 return -EFAULT;
1685 }
1686
1687 sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1688 data.vendor_id, data.product_code);
1689 if (IS_ERR(sc))
1690 return PTR_ERR(sc);
1691
1692 data.config_index = 0;
1693
1694 if (down_interruptible(&master->master_sem))
1695 return -EINTR;
1696
1697 list_for_each_entry(entry, &master->configs, list) {
1698 if (entry == sc)
1699 break;
1700 data.config_index++;
1701 }
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/*****************************************************************************/
1712
1718 ec_master_t *master,
1719 void *arg,
1720 ec_ioctl_context_t *ctx
1721 )
1722{
1723 unsigned long config_index = (unsigned long) arg;
1724 ec_slave_config_t *sc = NULL;
1725 int ret = 0;
1726
1727 if (unlikely(!ctx->requested)) {
1728 ret = -EPERM;
1729 goto out_return;
1730 }
1731
1732 if (down_interruptible(&master->master_sem)) {
1733 ret = -EINTR;
1734 goto out_return;
1735 }
1736
1737 if (config_index != 0xFFFFFFFF) {
1738 if (!(sc = ec_master_get_config(master, config_index))) {
1739 ret = -ENOENT;
1740 goto out_up;
1741 }
1742 }
1743
1745
1746out_up:
1747 up(&master->master_sem);
1748out_return:
1749 return ret;
1750}
1751
1752/*****************************************************************************/
1753
1759 ec_master_t *master,
1760 void *arg,
1761 ec_ioctl_context_t *ctx
1762 )
1763{
1764 ec_ioctl_master_activate_t io;
1765 ec_domain_t *domain;
1766 off_t offset;
1767 int ret;
1768
1769 if (unlikely(!ctx->requested))
1770 return -EPERM;
1771
1772 io.process_data = NULL;
1773
1774 /* Get the sum of the domains' process data sizes. */
1775
1776 ctx->process_data_size = 0;
1777
1778 if (down_interruptible(&master->master_sem))
1779 return -EINTR;
1780
1781 list_for_each_entry(domain, &master->domains, list) {
1782 ctx->process_data_size += ecrt_domain_size(domain);
1783 }
1784
1785 up(&master->master_sem);
1786
1787 if (ctx->process_data_size) {
1788 ctx->process_data = vmalloc(ctx->process_data_size);
1789 if (!ctx->process_data) {
1790 ctx->process_data_size = 0;
1791 return -ENOMEM;
1792 }
1793
1794 /* Set the memory as external process data memory for the
1795 * domains.
1796 */
1797 offset = 0;
1798 list_for_each_entry(domain, &master->domains, list) {
1800 ctx->process_data + offset);
1801 offset += ecrt_domain_size(domain);
1802 }
1803
1804#ifdef EC_IOCTL_RTDM
1805 /* RTDM uses a different approach for memory-mapping, which has to be
1806 * initiated by the kernel.
1807 */
1808 ret = ec_rtdm_mmap(ctx, &io.process_data);
1809 if (ret < 0) {
1810 EC_MASTER_ERR(master, "Failed to map process data"
1811 " memory to user space (code %i).\n", ret);
1812 return ret;
1813 }
1814#endif
1815 }
1816
1817 io.process_data_size = ctx->process_data_size;
1818
1819#ifndef EC_IOCTL_RTDM
1822#endif
1823
1824 ret = ecrt_master_activate(master);
1825 if (ret < 0)
1826 return ret;
1827
1828 if (copy_to_user((void __user *) arg, &io,
1829 sizeof(ec_ioctl_master_activate_t)))
1830 return -EFAULT;
1831
1832 return 0;
1833}
1834
1835/*****************************************************************************/
1836
1842 ec_master_t *master,
1843 void *arg,
1844 ec_ioctl_context_t *ctx
1845 )
1846{
1847 if (unlikely(!ctx->requested))
1848 return -EPERM;
1849
1850 ecrt_master_deactivate(master);
1851 return 0;
1852}
1853
1854/*****************************************************************************/
1855
1861 ec_master_t *master,
1862 void *arg,
1863 ec_ioctl_context_t *ctx
1864 )
1865{
1866 size_t send_interval;
1867
1868 if (unlikely(!ctx->requested)) {
1869 return -EPERM;
1870 }
1871
1872 if (copy_from_user(&send_interval, (void __user *) arg,
1873 sizeof(send_interval))) {
1874 return -EFAULT;
1875 }
1876
1877 if (down_interruptible(&master->master_sem))
1878 return -EINTR;
1879
1880 ec_master_set_send_interval(master, send_interval);
1881
1882 up(&master->master_sem);
1883 return 0;
1884}
1885
1886/*****************************************************************************/
1887
1893 ec_master_t *master,
1894 void *arg,
1895 ec_ioctl_context_t *ctx
1896 )
1897{
1898 if (unlikely(!ctx->requested)) {
1899 return -EPERM;
1900 }
1901
1902 ecrt_master_send(master);
1903 return 0;
1904}
1905
1906/*****************************************************************************/
1907
1913 ec_master_t *master,
1914 void *arg,
1915 ec_ioctl_context_t *ctx
1916 )
1917{
1918 if (unlikely(!ctx->requested)) {
1919 return -EPERM;
1920 }
1921
1922 ecrt_master_receive(master);
1923 return 0;
1924}
1925
1926/*****************************************************************************/
1927
1933 ec_master_t *master,
1934 void *arg,
1935 ec_ioctl_context_t *ctx
1936 )
1937{
1938 ec_master_state_t data;
1939
1940 ecrt_master_state(master, &data);
1941
1942 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1943 return -EFAULT;
1944
1945 return 0;
1946}
1947
1948/*****************************************************************************/
1949
1955 ec_master_t *master,
1956 void *arg,
1957 ec_ioctl_context_t *ctx
1958 )
1959{
1960 ec_ioctl_link_state_t ioctl;
1962 int ret;
1963
1964 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
1965 return -EFAULT;
1966 }
1967
1968 ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
1969 if (ret < 0) {
1970 return ret;
1971 }
1972
1973 if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
1974 return -EFAULT;
1975 }
1976
1977 return 0;
1978}
1979
1980/*****************************************************************************/
1981
1987 ec_master_t *master,
1988 void *arg,
1989 ec_ioctl_context_t *ctx
1990 )
1991{
1992 uint64_t time;
1993
1994 if (unlikely(!ctx->requested))
1995 return -EPERM;
1996
1997 if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
1998 return -EFAULT;
1999 }
2000
2001 ecrt_master_application_time(master, time);
2002 return 0;
2003}
2004
2005/*****************************************************************************/
2006
2012 ec_master_t *master,
2013 void *arg,
2014 ec_ioctl_context_t *ctx
2015 )
2016{
2017 if (unlikely(!ctx->requested)) {
2018 return -EPERM;
2019 }
2020
2022 return 0;
2023}
2024
2025/*****************************************************************************/
2026
2032 ec_master_t *master,
2033 void *arg,
2034 ec_ioctl_context_t *ctx
2035 )
2036{
2037 uint64_t time;
2038
2039 if (unlikely(!ctx->requested))
2040 return -EPERM;
2041
2042 if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2043 return -EFAULT;
2044 }
2045
2047 return 0;
2048}
2049
2050/*****************************************************************************/
2051
2057 ec_master_t *master,
2058 void *arg,
2059 ec_ioctl_context_t *ctx
2060 )
2061{
2062 if (unlikely(!ctx->requested)) {
2063 return -EPERM;
2064 }
2065
2067 return 0;
2068}
2069
2070/*****************************************************************************/
2071
2077 ec_master_t *master,
2078 void *arg,
2079 ec_ioctl_context_t *ctx
2080 )
2081{
2082 uint32_t time;
2083 int ret;
2084
2085 if (unlikely(!ctx->requested)) {
2086 return -EPERM;
2087 }
2088
2089 ret = ecrt_master_reference_clock_time(master, &time);
2090 if (ret) {
2091 return ret;
2092 }
2093
2094 if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2095 return -EFAULT;
2096 }
2097
2098 return 0;
2099}
2100
2101/*****************************************************************************/
2102
2108 ec_master_t *master,
2109 void *arg,
2110 ec_ioctl_context_t *ctx
2111 )
2112{
2113 if (unlikely(!ctx->requested)) {
2114 return -EPERM;
2115 }
2116
2118 return 0;
2119}
2120
2121/*****************************************************************************/
2122
2128 ec_master_t *master,
2129 void *arg,
2130 ec_ioctl_context_t *ctx
2131 )
2132{
2133 uint32_t time_diff;
2134
2135 if (unlikely(!ctx->requested))
2136 return -EPERM;
2137
2138 time_diff = ecrt_master_sync_monitor_process(master);
2139
2140 if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2141 return -EFAULT;
2142
2143 return 0;
2144}
2145
2146/*****************************************************************************/
2147
2153 ec_master_t *master,
2154 void *arg,
2155 ec_ioctl_context_t *ctx
2156 )
2157{
2158 down(&master->master_sem);
2159 ecrt_master_reset(master);
2160 up(&master->master_sem);
2161 return 0;
2162}
2163
2164/*****************************************************************************/
2165
2171 ec_master_t *master,
2172 void *arg,
2173 ec_ioctl_context_t *ctx
2174 )
2175{
2176 ec_ioctl_config_t data;
2178 unsigned int i;
2179 int ret = 0;
2180
2181 if (unlikely(!ctx->requested)) {
2182 ret = -EPERM;
2183 goto out_return;
2184 }
2185
2186 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2187 ret = -EFAULT;
2188 goto out_return;
2189 }
2190
2191 if (down_interruptible(&master->master_sem)) {
2192 ret = -EINTR;
2193 goto out_return;
2194 }
2195
2196 if (!(sc = ec_master_get_config(master, data.config_index))) {
2197 ret = -ENOENT;
2198 goto out_up;
2199 }
2200
2201 for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2202 if (data.syncs[i].config_this) {
2203 ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2204 data.syncs[i].watchdog_mode);
2205 if (ret) {
2206 goto out_up;
2207 }
2208 }
2209 }
2210
2211out_up:
2212 up(&master->master_sem);
2213out_return:
2214 return ret;
2215}
2216
2217/*****************************************************************************/
2218
2224 ec_master_t *master,
2225 void *arg,
2226 ec_ioctl_context_t *ctx
2227 )
2228{
2229 ec_ioctl_config_t data;
2231 int ret = 0;
2232
2233 if (unlikely(!ctx->requested)) {
2234 ret = -EPERM;
2235 goto out_return;
2236 }
2237
2238 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2239 ret = -EFAULT;
2240 goto out_return;
2241 }
2242
2243 if (down_interruptible(&master->master_sem)) {
2244 ret = -EINTR;
2245 goto out_return;
2246 }
2247
2248 if (!(sc = ec_master_get_config(master, data.config_index))) {
2249 ret = -ENOENT;
2250 goto out_up;
2251 }
2252
2254 data.watchdog_divider, data.watchdog_intervals);
2255
2256out_up:
2257 up(&master->master_sem);
2258out_return:
2259 return ret;
2260}
2261
2262/*****************************************************************************/
2263
2269 ec_master_t *master,
2270 void *arg,
2271 ec_ioctl_context_t *ctx
2272 )
2273{
2274 ec_ioctl_config_pdo_t data;
2276
2277 if (unlikely(!ctx->requested))
2278 return -EPERM;
2279
2280 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2281 return -EFAULT;
2282
2283 if (down_interruptible(&master->master_sem))
2284 return -EINTR;
2285
2286 if (!(sc = ec_master_get_config(master, data.config_index))) {
2287 up(&master->master_sem);
2288 return -ENOENT;
2289 }
2290
2291 up(&master->master_sem);
2293 return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2294}
2295
2296/*****************************************************************************/
2297
2303 ec_master_t *master,
2304 void *arg,
2305 ec_ioctl_context_t *ctx
2306 )
2307{
2308 ec_ioctl_config_pdo_t data;
2310
2311 if (unlikely(!ctx->requested))
2312 return -EPERM;
2313
2314 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2315 return -EFAULT;
2316
2317 if (down_interruptible(&master->master_sem))
2318 return -EINTR;
2319
2320 if (!(sc = ec_master_get_config(master, data.config_index))) {
2321 up(&master->master_sem);
2322 return -ENOENT;
2323 }
2324
2325 up(&master->master_sem);
2327 ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2328 return 0;
2329}
2330
2331/*****************************************************************************/
2332
2338 ec_master_t *master,
2339 void *arg,
2340 ec_ioctl_context_t *ctx
2341 )
2342{
2343 ec_ioctl_add_pdo_entry_t data;
2345
2346 if (unlikely(!ctx->requested))
2347 return -EPERM;
2348
2349 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2350 return -EFAULT;
2351
2352 if (down_interruptible(&master->master_sem))
2353 return -EINTR;
2354
2355 if (!(sc = ec_master_get_config(master, data.config_index))) {
2356 up(&master->master_sem);
2357 return -ENOENT;
2358 }
2359
2360 up(&master->master_sem);
2362 return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2363 data.entry_index, data.entry_subindex, data.entry_bit_length);
2364}
2365
2366/*****************************************************************************/
2367
2373 ec_master_t *master,
2374 void *arg,
2375 ec_ioctl_context_t *ctx
2376 )
2377{
2378 ec_ioctl_config_pdo_t data;
2380
2381 if (unlikely(!ctx->requested))
2382 return -EPERM;
2383
2384 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2385 return -EFAULT;
2386
2387 if (down_interruptible(&master->master_sem))
2388 return -EINTR;
2389
2390 if (!(sc = ec_master_get_config(master, data.config_index))) {
2391 up(&master->master_sem);
2392 return -ENOENT;
2393 }
2394
2395 up(&master->master_sem);
2398 return 0;
2399}
2400
2401/*****************************************************************************/
2402
2408 ec_master_t *master,
2409 void *arg,
2410 ec_ioctl_context_t *ctx
2411 )
2412{
2413 ec_ioctl_reg_pdo_entry_t data;
2415 ec_domain_t *domain;
2416 int ret;
2417
2418 if (unlikely(!ctx->requested))
2419 return -EPERM;
2420
2421 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2422 return -EFAULT;
2423
2424 if (down_interruptible(&master->master_sem))
2425 return -EINTR;
2426
2427 if (!(sc = ec_master_get_config(master, data.config_index))) {
2428 up(&master->master_sem);
2429 return -ENOENT;
2430 }
2431
2432 if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2433 up(&master->master_sem);
2434 return -ENOENT;
2435 }
2436
2437 up(&master->master_sem);
2439 ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2440 data.entry_subindex, domain, &data.bit_position);
2441
2442 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2443 return -EFAULT;
2444
2445 return ret;
2446}
2447
2448/*****************************************************************************/
2449
2455 ec_master_t *master,
2456 void *arg,
2457 ec_ioctl_context_t *ctx
2458 )
2459{
2460 ec_ioctl_reg_pdo_pos_t io;
2462 ec_domain_t *domain;
2463 int ret;
2464
2465 if (unlikely(!ctx->requested)) {
2466 return -EPERM;
2467 }
2468
2469 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2470 return -EFAULT;
2471 }
2472
2473 if (down_interruptible(&master->master_sem)) {
2474 return -EINTR;
2475 }
2476
2477 if (!(sc = ec_master_get_config(master, io.config_index))) {
2478 up(&master->master_sem);
2479 return -ENOENT;
2480 }
2481
2482 if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2483 up(&master->master_sem);
2484 return -ENOENT;
2485 }
2486
2487 up(&master->master_sem);
2489 ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2490 io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2491
2492 if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2493 return -EFAULT;
2494
2495 return ret;
2496}
2497
2498/*****************************************************************************/
2499
2505 ec_master_t *master,
2506 void *arg,
2507 ec_ioctl_context_t *ctx
2508 )
2509{
2510 ec_ioctl_config_t data;
2512
2513 if (unlikely(!ctx->requested))
2514 return -EPERM;
2515
2516 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2517 return -EFAULT;
2518
2519 if (down_interruptible(&master->master_sem))
2520 return -EINTR;
2521
2522 if (!(sc = ec_master_get_config(master, data.config_index))) {
2523 up(&master->master_sem);
2524 return -ENOENT;
2525 }
2526
2528 data.dc_sync[0].cycle_time,
2529 data.dc_sync[0].shift_time,
2530 data.dc_sync[1].cycle_time,
2531 data.dc_sync[1].shift_time);
2532
2533 up(&master->master_sem);
2534
2535 return 0;
2536}
2537
2538/*****************************************************************************/
2539
2545 ec_master_t *master,
2546 void *arg,
2547 ec_ioctl_context_t *ctx
2548 )
2549{
2550 ec_ioctl_sc_sdo_t data;
2552 uint8_t *sdo_data = NULL;
2553 int ret;
2554
2555 if (unlikely(!ctx->requested))
2556 return -EPERM;
2557
2558 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2559 return -EFAULT;
2560
2561 if (!data.size)
2562 return -EINVAL;
2563
2564 if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2565 return -ENOMEM;
2566 }
2567
2568 if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2569 kfree(sdo_data);
2570 return -EFAULT;
2571 }
2572
2573 if (down_interruptible(&master->master_sem)) {
2574 kfree(sdo_data);
2575 return -EINTR;
2576 }
2577
2578 if (!(sc = ec_master_get_config(master, data.config_index))) {
2579 up(&master->master_sem);
2580 kfree(sdo_data);
2581 return -ENOENT;
2582 }
2583
2584 up(&master->master_sem);
2586 if (data.complete_access) {
2588 data.index, sdo_data, data.size);
2589 } else {
2590 ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2591 data.size);
2592 }
2593 kfree(sdo_data);
2594 return ret;
2595}
2596
2597/*****************************************************************************/
2598
2604 ec_master_t *master,
2605 void *arg,
2606 ec_ioctl_context_t *ctx
2607 )
2608{
2609 ec_ioctl_sc_emerg_t io;
2611 int ret;
2612
2613 if (unlikely(!ctx->requested))
2614 return -EPERM;
2615
2616 if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2617 return -EFAULT;
2618
2619 if (down_interruptible(&master->master_sem)) {
2620 return -EINTR;
2621 }
2622
2623 if (!(sc = ec_master_get_config(master, io.config_index))) {
2624 up(&master->master_sem);
2625 return -ENOENT;
2626 }
2627
2628 ret = ecrt_slave_config_emerg_size(sc, io.size);
2629
2630 up(&master->master_sem);
2631
2632 return ret;
2633}
2634
2635/*****************************************************************************/
2636
2642 ec_master_t *master,
2643 void *arg,
2644 ec_ioctl_context_t *ctx
2645 )
2646{
2647 ec_ioctl_sc_emerg_t io;
2650 int ret;
2651
2652 if (unlikely(!ctx->requested)) {
2653 return -EPERM;
2654 }
2655
2656 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2657 return -EFAULT;
2658 }
2659
2660 /* no locking of master_sem needed, because configuration will not be
2661 * deleted in the meantime. */
2662
2663 if (!(sc = ec_master_get_config(master, io.config_index))) {
2664 return -ENOENT;
2665 }
2666
2667 ret = ecrt_slave_config_emerg_pop(sc, msg);
2668 if (ret < 0) {
2669 return ret;
2670 }
2671
2672 if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
2673 return -EFAULT;
2674 }
2675
2676 return ret;
2677}
2678
2679/*****************************************************************************/
2680
2686 ec_master_t *master,
2687 void *arg,
2688 ec_ioctl_context_t *ctx
2689 )
2690{
2691 ec_ioctl_sc_emerg_t io;
2693
2694 if (unlikely(!ctx->requested)) {
2695 return -EPERM;
2696 }
2697
2698 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2699 return -EFAULT;
2700 }
2701
2702 /* no locking of master_sem needed, because configuration will not be
2703 * deleted in the meantime. */
2704
2705 if (!(sc = ec_master_get_config(master, io.config_index))) {
2706 return -ENOENT;
2707 }
2708
2710}
2711
2712/*****************************************************************************/
2713
2719 ec_master_t *master,
2720 void *arg,
2721 ec_ioctl_context_t *ctx
2722 )
2723{
2724 ec_ioctl_sc_emerg_t io;
2726 int ret;
2727
2728 if (unlikely(!ctx->requested)) {
2729 return -EPERM;
2730 }
2731
2732 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2733 return -EFAULT;
2734 }
2735
2736 /* no locking of master_sem needed, because configuration will not be
2737 * deleted in the meantime. */
2738
2739 if (!(sc = ec_master_get_config(master, io.config_index))) {
2740 return -ENOENT;
2741 }
2742
2744 if (ret < 0) {
2745 return ret;
2746 }
2747
2748 io.overruns = ret;
2749
2750 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2751 return -EFAULT;
2752 }
2753
2754 return 0;
2755}
2756
2757/*****************************************************************************/
2758
2764 ec_master_t *master,
2765 void *arg,
2766 ec_ioctl_context_t *ctx
2767 )
2768{
2769 ec_ioctl_sdo_request_t data;
2771 ec_sdo_request_t *req;
2772
2773 if (unlikely(!ctx->requested))
2774 return -EPERM;
2775
2776 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2777 return -EFAULT;
2778 }
2779
2780 data.request_index = 0;
2781
2782 if (down_interruptible(&master->master_sem))
2783 return -EINTR;
2784
2785 sc = ec_master_get_config(master, data.config_index);
2786 if (!sc) {
2787 up(&master->master_sem);
2788 return -ENOENT;
2789 }
2790
2791 list_for_each_entry(req, &sc->sdo_requests, list) {
2792 data.request_index++;
2793 }
2794
2795 up(&master->master_sem);
2797 req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
2798 data.sdo_subindex, data.size);
2799 if (IS_ERR(req))
2800 return PTR_ERR(req);
2801
2802 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2803 return -EFAULT;
2804
2805 return 0;
2806}
2807
2808/*****************************************************************************/
2809
2815 ec_master_t *master,
2816 void *arg,
2817 ec_ioctl_context_t *ctx
2818 )
2819{
2820 ec_ioctl_reg_request_t io;
2822 ec_reg_request_t *reg;
2823
2824 if (unlikely(!ctx->requested)) {
2825 return -EPERM;
2826 }
2827
2828 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2829 return -EFAULT;
2830 }
2831
2832 io.request_index = 0;
2833
2834 if (down_interruptible(&master->master_sem)) {
2835 return -EINTR;
2836 }
2837
2838 sc = ec_master_get_config(master, io.config_index);
2839 if (!sc) {
2840 up(&master->master_sem);
2841 return -ENOENT;
2842 }
2843
2844 list_for_each_entry(reg, &sc->reg_requests, list) {
2845 io.request_index++;
2846 }
2847
2848 up(&master->master_sem);
2850 reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
2851 if (IS_ERR(reg)) {
2852 return PTR_ERR(reg);
2853 }
2854
2855 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2856 return -EFAULT;
2857 }
2858
2859 return 0;
2860}
2861
2862/*****************************************************************************/
2863
2869 ec_master_t *master,
2870 void *arg,
2871 ec_ioctl_context_t *ctx
2872 )
2873{
2874 ec_ioctl_voe_t data;
2876 ec_voe_handler_t *voe;
2877
2878 if (unlikely(!ctx->requested))
2879 return -EPERM;
2880
2881 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2882 return -EFAULT;
2883 }
2884
2885 data.voe_index = 0;
2886
2887 if (down_interruptible(&master->master_sem))
2888 return -EINTR;
2889
2890 sc = ec_master_get_config(master, data.config_index);
2891 if (!sc) {
2892 up(&master->master_sem);
2893 return -ENOENT;
2894 }
2895
2896 list_for_each_entry(voe, &sc->voe_handlers, list) {
2897 data.voe_index++;
2898 }
2899
2900 up(&master->master_sem);
2902 voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
2903 if (IS_ERR(voe))
2904 return PTR_ERR(voe);
2905
2906 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2907 return -EFAULT;
2908
2909 return 0;
2910}
2911
2912/*****************************************************************************/
2913
2919 ec_master_t *master,
2920 void *arg,
2921 ec_ioctl_context_t *ctx
2922 )
2923{
2924 ec_ioctl_sc_state_t data;
2925 const ec_slave_config_t *sc;
2927
2928 if (unlikely(!ctx->requested))
2929 return -EPERM;
2930
2931 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2932 return -EFAULT;
2933 }
2934
2935 /* no locking of master_sem needed, because sc will not be deleted in the
2936 * meantime. */
2937
2938 if (!(sc = ec_master_get_config_const(master, data.config_index))) {
2939 return -ENOENT;
2940 }
2941
2942 ecrt_slave_config_state(sc, &state);
2943
2944 if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
2945 return -EFAULT;
2946
2947 return 0;
2948}
2949
2950/*****************************************************************************/
2951
2957 ec_master_t *master,
2958 void *arg,
2959 ec_ioctl_context_t *ctx
2960 )
2961{
2962 ec_ioctl_sc_idn_t ioctl;
2964 uint8_t *data = NULL;
2965 int ret;
2966
2967 if (unlikely(!ctx->requested))
2968 return -EPERM;
2969
2970 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
2971 return -EFAULT;
2972
2973 if (!ioctl.size)
2974 return -EINVAL;
2975
2976 if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
2977 return -ENOMEM;
2978 }
2979
2980 if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
2981 kfree(data);
2982 return -EFAULT;
2983 }
2984
2985 if (down_interruptible(&master->master_sem)) {
2986 kfree(data);
2987 return -EINTR;
2988 }
2989
2990 if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
2991 up(&master->master_sem);
2992 kfree(data);
2993 return -ENOENT;
2994 }
2995
2996 up(&master->master_sem);
2999 sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3000 kfree(data);
3001 return ret;
3002}
3003
3004/*****************************************************************************/
3005
3011 ec_master_t *master,
3012 void *arg,
3013 ec_ioctl_context_t *ctx
3014 )
3015{
3016 ec_ioctl_sc_flag_t ioctl;
3018 uint8_t *key;
3019 int ret;
3020
3021 if (unlikely(!ctx->requested)) {
3022 return -EPERM;
3023 }
3024
3025 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3026 return -EFAULT;
3027 }
3028
3029 if (!ioctl.key_size) {
3030 return -EINVAL;
3031 }
3032
3033 if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3034 return -ENOMEM;
3035 }
3036
3037 if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3038 kfree(key);
3039 return -EFAULT;
3040 }
3041
3042 if (down_interruptible(&master->master_sem)) {
3043 kfree(key);
3044 return -EINTR;
3045 }
3046
3047 if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3048 up(&master->master_sem);
3049 kfree(key);
3050 return -ENOENT;
3051 }
3052
3053 up(&master->master_sem);
3055 ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3056 kfree(key);
3057 return ret;
3058}
3059
3060/*****************************************************************************/
3061
3067 ec_master_t *master,
3068 void *arg,
3069 ec_ioctl_context_t *ctx
3070 )
3071{
3072 const ec_domain_t *domain;
3073
3074 if (unlikely(!ctx->requested)) {
3075 return -EPERM;
3076 }
3077
3078 if (down_interruptible(&master->master_sem)) {
3079 return -EINTR;
3080 }
3081
3082 list_for_each_entry(domain, &master->domains, list) {
3083 if (domain->index == (unsigned long) arg) {
3084 size_t size = ecrt_domain_size(domain);
3085 up(&master->master_sem);
3086 return size;
3087 }
3088 }
3089
3090 up(&master->master_sem);
3091 return -ENOENT;
3092}
3093
3094/*****************************************************************************/
3095
3101 ec_master_t *master,
3102 void *arg,
3103 ec_ioctl_context_t *ctx
3104 )
3105{
3106 int offset = 0;
3107 const ec_domain_t *domain;
3108
3109 if (unlikely(!ctx->requested))
3110 return -EPERM;
3111
3112 if (down_interruptible(&master->master_sem)) {
3113 return -EINTR;
3114 }
3115
3116 list_for_each_entry(domain, &master->domains, list) {
3117 if (domain->index == (unsigned long) arg) {
3118 up(&master->master_sem);
3119 return offset;
3120 }
3121 offset += ecrt_domain_size(domain);
3122 }
3123
3124 up(&master->master_sem);
3125 return -ENOENT;
3126}
3127
3128/*****************************************************************************/
3129
3135 ec_master_t *master,
3136 void *arg,
3137 ec_ioctl_context_t *ctx
3138 )
3139{
3140 ec_domain_t *domain;
3141
3142 if (unlikely(!ctx->requested))
3143 return -EPERM;
3144
3145 /* no locking of master_sem needed, because domain will not be deleted in
3146 * the meantime. */
3147
3148 if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3149 return -ENOENT;
3150 }
3151
3152 ecrt_domain_process(domain);
3153 return 0;
3154}
3155
3156/*****************************************************************************/
3157
3163 ec_master_t *master,
3164 void *arg,
3165 ec_ioctl_context_t *ctx
3166 )
3167{
3168 ec_domain_t *domain;
3169
3170 if (unlikely(!ctx->requested))
3171 return -EPERM;
3172
3173 /* no locking of master_sem needed, because domain will not be deleted in
3174 * the meantime. */
3175
3176 if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3177 return -ENOENT;
3178 }
3179
3180 ecrt_domain_queue(domain);
3181 return 0;
3182}
3183
3184/*****************************************************************************/
3185
3191 ec_master_t *master,
3192 void *arg,
3193 ec_ioctl_context_t *ctx
3194 )
3195{
3196 ec_ioctl_domain_state_t data;
3197 const ec_domain_t *domain;
3198 ec_domain_state_t state;
3199
3200 if (unlikely(!ctx->requested))
3201 return -EPERM;
3202
3203 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3204 return -EFAULT;
3205 }
3206
3207 /* no locking of master_sem needed, because domain will not be deleted in
3208 * the meantime. */
3209
3210 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3211 return -ENOENT;
3212 }
3213
3214 ecrt_domain_state(domain, &state);
3215
3216 if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3217 return -EFAULT;
3218
3219 return 0;
3220}
3221
3222/*****************************************************************************/
3223
3229 ec_master_t *master,
3230 void *arg,
3231 ec_ioctl_context_t *ctx
3232 )
3233{
3234 ec_ioctl_sdo_request_t data;
3236 ec_sdo_request_t *req;
3237
3238 if (unlikely(!ctx->requested))
3239 return -EPERM;
3240
3241 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3242 return -EFAULT;
3243
3244 /* no locking of master_sem needed, because neither sc nor req will not be
3245 * deleted in the meantime. */
3246
3247 if (!(sc = ec_master_get_config(master, data.config_index))) {
3248 return -ENOENT;
3249 }
3250
3251 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3252 return -ENOENT;
3253 }
3254
3255 ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3256 return 0;
3257}
3258
3259/*****************************************************************************/
3260
3266 ec_master_t *master,
3267 void *arg,
3268 ec_ioctl_context_t *ctx
3269 )
3270{
3271 ec_ioctl_sdo_request_t data;
3273 ec_sdo_request_t *req;
3274
3275 if (unlikely(!ctx->requested))
3276 return -EPERM;
3277
3278 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3279 return -EFAULT;
3280
3281 /* no locking of master_sem needed, because neither sc nor req will not be
3282 * deleted in the meantime. */
3283
3284 if (!(sc = ec_master_get_config(master, data.config_index))) {
3285 return -ENOENT;
3286 }
3287
3288 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3289 return -ENOENT;
3290 }
3291
3292 ecrt_sdo_request_timeout(req, data.timeout);
3293 return 0;
3294}
3295
3296/*****************************************************************************/
3297
3303 ec_master_t *master,
3304 void *arg,
3305 ec_ioctl_context_t *ctx
3306 )
3307{
3308 ec_ioctl_sdo_request_t data;
3310 ec_sdo_request_t *req;
3311
3312 if (unlikely(!ctx->requested))
3313 return -EPERM;
3314
3315 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3316 return -EFAULT;
3317
3318 /* no locking of master_sem needed, because neither sc nor req will not be
3319 * deleted in the meantime. */
3320
3321 if (!(sc = ec_master_get_config(master, data.config_index))) {
3322 return -ENOENT;
3323 }
3324
3325 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3326 return -ENOENT;
3327 }
3328
3329 data.state = ecrt_sdo_request_state(req);
3330 if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3331 data.size = ecrt_sdo_request_data_size(req);
3332 else
3333 data.size = 0;
3334
3335 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3336 return -EFAULT;
3337
3338 return 0;
3339}
3340
3341/*****************************************************************************/
3342
3348 ec_master_t *master,
3349 void *arg,
3350 ec_ioctl_context_t *ctx
3351 )
3352{
3353 ec_ioctl_sdo_request_t data;
3355 ec_sdo_request_t *req;
3356
3357 if (unlikely(!ctx->requested))
3358 return -EPERM;
3359
3360 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3361 return -EFAULT;
3362
3363 /* no locking of master_sem needed, because neither sc nor req will not be
3364 * deleted in the meantime. */
3365
3366 if (!(sc = ec_master_get_config(master, data.config_index))) {
3367 return -ENOENT;
3368 }
3369
3370 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3371 return -ENOENT;
3372 }
3373
3375 return 0;
3376}
3377
3378/*****************************************************************************/
3379
3385 ec_master_t *master,
3386 void *arg,
3387 ec_ioctl_context_t *ctx
3388 )
3389{
3390 ec_ioctl_sdo_request_t data;
3392 ec_sdo_request_t *req;
3393 int ret;
3394
3395 if (unlikely(!ctx->requested))
3396 return -EPERM;
3397
3398 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3399 return -EFAULT;
3400
3401 if (!data.size) {
3402 EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3403 return -EINVAL;
3404 }
3405
3406 /* no locking of master_sem needed, because neither sc nor req will not be
3407 * deleted in the meantime. */
3408
3409 if (!(sc = ec_master_get_config(master, data.config_index))) {
3410 return -ENOENT;
3411 }
3412
3413 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3414 return -ENOENT;
3415 }
3416
3417 ret = ec_sdo_request_alloc(req, data.size);
3418 if (ret)
3419 return ret;
3420
3421 if (copy_from_user(req->data, (void __user *) data.data, data.size))
3422 return -EFAULT;
3423
3424 req->data_size = data.size;
3426 return 0;
3427}
3428
3429/*****************************************************************************/
3430
3436 ec_master_t *master,
3437 void *arg,
3438 ec_ioctl_context_t *ctx
3439 )
3440{
3441 ec_ioctl_sdo_request_t data;
3443 ec_sdo_request_t *req;
3444
3445 if (unlikely(!ctx->requested))
3446 return -EPERM;
3447
3448 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3449 return -EFAULT;
3450
3451 /* no locking of master_sem needed, because neither sc nor req will not be
3452 * deleted in the meantime. */
3453
3454 if (!(sc = ec_master_get_config(master, data.config_index))) {
3455 return -ENOENT;
3456 }
3457
3458 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3459 return -ENOENT;
3460 }
3461
3462 if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3464 return -EFAULT;
3465
3466 return 0;
3467}
3468
3469/*****************************************************************************/
3470
3476 ec_master_t *master,
3477 void *arg,
3478 ec_ioctl_context_t *ctx
3479 )
3480{
3481 ec_ioctl_reg_request_t io;
3483 ec_reg_request_t *reg;
3484
3485 if (unlikely(!ctx->requested)) {
3486 return -EPERM;
3487 }
3488
3489 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3490 return -EFAULT;
3491 }
3492
3493 if (io.mem_size <= 0) {
3494 return 0;
3495 }
3496
3497 /* no locking of master_sem needed, because neither sc nor reg will not be
3498 * deleted in the meantime. */
3499
3500 if (!(sc = ec_master_get_config(master, io.config_index))) {
3501 return -ENOENT;
3502 }
3503
3504 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3505 return -ENOENT;
3506 }
3507
3508 if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3509 min(reg->mem_size, io.mem_size))) {
3510 return -EFAULT;
3511 }
3512
3513 return 0;
3514}
3515
3516/*****************************************************************************/
3517
3523 ec_master_t *master,
3524 void *arg,
3525 ec_ioctl_context_t *ctx
3526 )
3527{
3528 ec_ioctl_reg_request_t io;
3530 ec_reg_request_t *reg;
3531
3532 if (unlikely(!ctx->requested)) {
3533 return -EPERM;
3534 }
3535
3536 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3537 return -EFAULT;
3538 }
3539
3540 /* no locking of master_sem needed, because neither sc nor reg will not be
3541 * deleted in the meantime. */
3542
3543 if (!(sc = ec_master_get_config(master, io.config_index))) {
3544 return -ENOENT;
3545 }
3546
3547 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3548 return -ENOENT;
3549 }
3550
3551 io.state = ecrt_reg_request_state(reg);
3552 io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
3553
3554 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3555 return -EFAULT;
3556 }
3557
3558 return 0;
3559}
3560
3561/*****************************************************************************/
3562
3568 ec_master_t *master,
3569 void *arg,
3570 ec_ioctl_context_t *ctx
3571 )
3572{
3573 ec_ioctl_reg_request_t io;
3575 ec_reg_request_t *reg;
3576
3577 if (unlikely(!ctx->requested)) {
3578 return -EPERM;
3579 }
3580
3581 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3582 return -EFAULT;
3583 }
3584
3585 /* no locking of master_sem needed, because neither sc nor reg will not be
3586 * deleted in the meantime. */
3587
3588 if (!(sc = ec_master_get_config(master, io.config_index))) {
3589 return -ENOENT;
3590 }
3591
3592 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3593 return -ENOENT;
3594 }
3595
3596 if (io.transfer_size > reg->mem_size) {
3597 return -EOVERFLOW;
3598 }
3599
3600 if (copy_from_user(reg->data, (void __user *) io.data,
3601 io.transfer_size)) {
3602 return -EFAULT;
3603 }
3604
3605 ecrt_reg_request_write(reg, io.address, io.transfer_size);
3606 return 0;
3607}
3608
3609/*****************************************************************************/
3610
3616 ec_master_t *master,
3617 void *arg,
3618 ec_ioctl_context_t *ctx
3619 )
3620{
3621 ec_ioctl_reg_request_t io;
3623 ec_reg_request_t *reg;
3624
3625 if (unlikely(!ctx->requested)) {
3626 return -EPERM;
3627 }
3628
3629 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3630 return -EFAULT;
3631 }
3632
3633 /* no locking of master_sem needed, because neither sc nor reg will not be
3634 * deleted in the meantime. */
3635
3636 if (!(sc = ec_master_get_config(master, io.config_index))) {
3637 return -ENOENT;
3638 }
3639
3640 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3641 return -ENOENT;
3642 }
3643
3644 if (io.transfer_size > reg->mem_size) {
3645 return -EOVERFLOW;
3646 }
3647
3648 ecrt_reg_request_read(reg, io.address, io.transfer_size);
3649 return 0;
3650}
3651
3652/*****************************************************************************/
3653
3659 ec_master_t *master,
3660 void *arg,
3661 ec_ioctl_context_t *ctx
3662 )
3663{
3664 ec_ioctl_voe_t data;
3666 ec_voe_handler_t *voe;
3667 uint32_t vendor_id;
3668 uint16_t vendor_type;
3669
3670 if (unlikely(!ctx->requested))
3671 return -EPERM;
3672
3673 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3674 return -EFAULT;
3675
3676 if (get_user(vendor_id, data.vendor_id))
3677 return -EFAULT;
3678
3679 if (get_user(vendor_type, data.vendor_type))
3680 return -EFAULT;
3681
3682 /* no locking of master_sem needed, because neither sc nor voe will not be
3683 * deleted in the meantime. */
3684
3685 if (!(sc = ec_master_get_config(master, data.config_index))) {
3686 return -ENOENT;
3687 }
3688
3689 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3690 return -ENOENT;
3691 }
3692
3693 ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
3694 return 0;
3695}
3696
3697/*****************************************************************************/
3698
3704 ec_master_t *master,
3705 void *arg,
3706 ec_ioctl_context_t *ctx
3707 )
3708{
3709 ec_ioctl_voe_t data;
3711 ec_voe_handler_t *voe;
3712 uint32_t vendor_id;
3713 uint16_t vendor_type;
3714
3715 if (unlikely(!ctx->requested))
3716 return -EPERM;
3717
3718 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3719 return -EFAULT;
3720
3721 /* no locking of master_sem needed, because neither sc nor voe will not be
3722 * deleted in the meantime. */
3723
3724 if (!(sc = ec_master_get_config(master, data.config_index))) {
3725 return -ENOENT;
3726 }
3727
3728 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3729 return -ENOENT;
3730 }
3731
3732 ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
3733
3734 if (likely(data.vendor_id))
3735 if (put_user(vendor_id, data.vendor_id))
3736 return -EFAULT;
3737
3738 if (likely(data.vendor_type))
3739 if (put_user(vendor_type, data.vendor_type))
3740 return -EFAULT;
3741
3742 return 0;
3743}
3744
3745/*****************************************************************************/
3746
3752 ec_master_t *master,
3753 void *arg,
3754 ec_ioctl_context_t *ctx
3755 )
3756{
3757 ec_ioctl_voe_t data;
3759 ec_voe_handler_t *voe;
3760
3761 if (unlikely(!ctx->requested))
3762 return -EPERM;
3763
3764 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3765 return -EFAULT;
3766
3767 /* no locking of master_sem needed, because neither sc nor voe will not be
3768 * deleted in the meantime. */
3769
3770 if (!(sc = ec_master_get_config(master, data.config_index))) {
3771 return -ENOENT;
3772 }
3773
3774 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3775 return -ENOENT;
3776 }
3777
3779 return 0;
3780}
3781
3782/*****************************************************************************/
3783
3789 ec_master_t *master,
3790 void *arg,
3791 ec_ioctl_context_t *ctx
3792 )
3793{
3794 ec_ioctl_voe_t data;
3796 ec_voe_handler_t *voe;
3797
3798 if (unlikely(!ctx->requested))
3799 return -EPERM;
3800
3801 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3802 return -EFAULT;
3803
3804 /* no locking of master_sem needed, because neither sc nor voe will not be
3805 * deleted in the meantime. */
3806
3807 if (!(sc = ec_master_get_config(master, data.config_index))) {
3808 return -ENOENT;
3809 }
3810
3811 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3812 return -ENOENT;
3813 }
3814
3816 return 0;
3817}
3818
3819/*****************************************************************************/
3820
3826 ec_master_t *master,
3827 void *arg,
3828 ec_ioctl_context_t *ctx
3829 )
3830{
3831 ec_ioctl_voe_t data;
3833 ec_voe_handler_t *voe;
3834
3835 if (unlikely(!ctx->requested))
3836 return -EPERM;
3837
3838 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3839 return -EFAULT;
3840
3841 /* no locking of master_sem needed, because neither sc nor voe will not be
3842 * deleted in the meantime. */
3843
3844 if (!(sc = ec_master_get_config(master, data.config_index))) {
3845 return -ENOENT;
3846 }
3847
3848 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3849 return -ENOENT;
3850 }
3851
3852 if (data.size) {
3853 if (data.size > ec_voe_handler_mem_size(voe))
3854 return -EOVERFLOW;
3855
3856 if (copy_from_user(ecrt_voe_handler_data(voe),
3857 (void __user *) data.data, data.size))
3858 return -EFAULT;
3859 }
3860
3861 ecrt_voe_handler_write(voe, data.size);
3862 return 0;
3863}
3864
3865/*****************************************************************************/
3866
3872 ec_master_t *master,
3873 void *arg,
3874 ec_ioctl_context_t *ctx
3875 )
3876{
3877 ec_ioctl_voe_t data;
3879 ec_voe_handler_t *voe;
3880
3881 if (unlikely(!ctx->requested))
3882 return -EPERM;
3883
3884 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3885 return -EFAULT;
3886
3887 /* no locking of master_sem needed, because neither sc nor voe will not be
3888 * deleted in the meantime. */
3889
3890 if (!(sc = ec_master_get_config(master, data.config_index))) {
3891 return -ENOENT;
3892 }
3893
3894 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3895 return -ENOENT;
3896 }
3897
3898 data.state = ecrt_voe_handler_execute(voe);
3899 if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
3900 data.size = ecrt_voe_handler_data_size(voe);
3901 else
3902 data.size = 0;
3903
3904 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3905 return -EFAULT;
3906
3907 return 0;
3908}
3909
3910/*****************************************************************************/
3911
3917 ec_master_t *master,
3918 void *arg,
3919 ec_ioctl_context_t *ctx
3920 )
3921{
3922 ec_ioctl_voe_t data;
3924 ec_voe_handler_t *voe;
3925
3926 if (unlikely(!ctx->requested))
3927 return -EPERM;
3928
3929 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3930 return -EFAULT;
3931
3932 /* no locking of master_sem needed, because neither sc nor voe will not be
3933 * deleted in the meantime. */
3934
3935 if (!(sc = ec_master_get_config(master, data.config_index))) {
3936 return -ENOENT;
3937 }
3938
3939 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3940 return -ENOENT;
3941 }
3942
3943 if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
3945 return -EFAULT;
3946
3947 return 0;
3948}
3949
3950/*****************************************************************************/
3951
3957 ec_master_t *master,
3958 void *arg
3959 )
3960{
3961 ec_ioctl_slave_foe_t io;
3962 ec_foe_request_t request;
3963 ec_slave_t *slave;
3964 int ret;
3965
3966 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3967 return -EFAULT;
3968 }
3969
3970 ec_foe_request_init(&request, io.file_name);
3971 ret = ec_foe_request_alloc(&request, 10000); // FIXME
3972 if (ret) {
3973 ec_foe_request_clear(&request);
3974 return ret;
3975 }
3976
3977 ec_foe_request_read(&request);
3978
3979 if (down_interruptible(&master->master_sem)) {
3980 ec_foe_request_clear(&request);
3981 return -EINTR;
3982 }
3983
3984 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
3985 up(&master->master_sem);
3986 ec_foe_request_clear(&request);
3987 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
3988 io.slave_position);
3989 return -EINVAL;
3990 }
3991
3992 EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
3993
3994 // schedule request.
3995 list_add_tail(&request.list, &slave->foe_requests);
3996
3997 up(&master->master_sem);
3998
3999 // wait for processing through FSM
4000 if (wait_event_interruptible(master->request_queue,
4001 request.state != EC_INT_REQUEST_QUEUED)) {
4002 // interrupted by signal
4003 down(&master->master_sem);
4004 if (request.state == EC_INT_REQUEST_QUEUED) {
4005 list_del(&request.list);
4006 up(&master->master_sem);
4007 ec_foe_request_clear(&request);
4008 return -EINTR;
4009 }
4010 // request already processing: interrupt not possible.
4011 up(&master->master_sem);
4012 }
4013
4014 // wait until master FSM has finished processing
4015 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4016
4017 io.result = request.result;
4018 io.error_code = request.error_code;
4019
4020 if (request.state != EC_INT_REQUEST_SUCCESS) {
4021 io.data_size = 0;
4022 ret = -EIO;
4023 } else {
4024 if (request.data_size > io.buffer_size) {
4025 EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4026 ec_foe_request_clear(&request);
4027 return -EOVERFLOW;
4028 }
4029 io.data_size = request.data_size;
4030 if (copy_to_user((void __user *) io.buffer,
4031 request.buffer, io.data_size)) {
4032 ec_foe_request_clear(&request);
4033 return -EFAULT;
4034 }
4035 ret = 0;
4036 }
4037
4038 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4039 ret = -EFAULT;
4040 }
4041
4042 ec_foe_request_clear(&request);
4043 return ret;
4044}
4045
4046/*****************************************************************************/
4047
4053 ec_master_t *master,
4054 void *arg
4055 )
4056{
4057 ec_ioctl_slave_foe_t io;
4058 ec_foe_request_t request;
4059 ec_slave_t *slave;
4060 int ret;
4061
4062 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4063 return -EFAULT;
4064 }
4065
4066 ec_foe_request_init(&request, io.file_name);
4067
4068 ret = ec_foe_request_alloc(&request, io.buffer_size);
4069 if (ret) {
4070 ec_foe_request_clear(&request);
4071 return ret;
4072 }
4073
4074 if (copy_from_user(request.buffer,
4075 (void __user *) io.buffer, io.buffer_size)) {
4076 ec_foe_request_clear(&request);
4077 return -EFAULT;
4078 }
4079
4080 request.data_size = io.buffer_size;
4081 ec_foe_request_write(&request);
4082
4083 if (down_interruptible(&master->master_sem)) {
4084 ec_foe_request_clear(&request);
4085 return -EINTR;
4086 }
4087
4088 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4089 up(&master->master_sem);
4090 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4091 io.slave_position);
4092 ec_foe_request_clear(&request);
4093 return -EINVAL;
4094 }
4095
4096 EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4097
4098 // schedule FoE write request.
4099 list_add_tail(&request.list, &slave->foe_requests);
4100
4101 up(&master->master_sem);
4102
4103 // wait for processing through FSM
4104 if (wait_event_interruptible(master->request_queue,
4105 request.state != EC_INT_REQUEST_QUEUED)) {
4106 // interrupted by signal
4107 down(&master->master_sem);
4108 if (request.state == EC_INT_REQUEST_QUEUED) {
4109 // abort request
4110 list_del(&request.list);
4111 up(&master->master_sem);
4112 ec_foe_request_clear(&request);
4113 return -EINTR;
4114 }
4115 up(&master->master_sem);
4116 }
4117
4118 // wait until master FSM has finished processing
4119 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4120
4121 io.result = request.result;
4122 io.error_code = request.error_code;
4123
4124 ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4125
4126 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4127 ret = -EFAULT;
4128 }
4129
4130 ec_foe_request_clear(&request);
4131 return ret;
4132}
4133
4134/*****************************************************************************/
4135
4141 ec_master_t *master,
4142 void *arg
4143 )
4144{
4145 ec_ioctl_slave_soe_read_t ioctl;
4146 u8 *data;
4147 int retval;
4148
4149 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4150 return -EFAULT;
4151 }
4152
4153 data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4154 if (!data) {
4155 EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4156 ioctl.mem_size);
4157 return -ENOMEM;
4158 }
4159
4160 retval = ecrt_master_read_idn(master, ioctl.slave_position,
4161 ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4162 &ioctl.error_code);
4163 if (retval) {
4164 kfree(data);
4165 return retval;
4166 }
4167
4168 if (copy_to_user((void __user *) ioctl.data,
4169 data, ioctl.data_size)) {
4170 kfree(data);
4171 return -EFAULT;
4172 }
4173 kfree(data);
4174
4175 if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4176 retval = -EFAULT;
4177 }
4178
4179 EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4180 return retval;
4181}
4182
4183/*****************************************************************************/
4184
4190 ec_master_t *master,
4191 void *arg
4192 )
4193{
4194 ec_ioctl_slave_soe_write_t ioctl;
4195 u8 *data;
4196 int retval;
4197
4198 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4199 return -EFAULT;
4200 }
4201
4202 data = kmalloc(ioctl.data_size, GFP_KERNEL);
4203 if (!data) {
4204 EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4205 ioctl.data_size);
4206 return -ENOMEM;
4207 }
4208 if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4209 kfree(data);
4210 return -EFAULT;
4211 }
4212
4213 retval = ecrt_master_write_idn(master, ioctl.slave_position,
4214 ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4215 &ioctl.error_code);
4216 kfree(data);
4217 if (retval) {
4218 return retval;
4219 }
4220
4221 if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4222 retval = -EFAULT;
4223 }
4224
4225 EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4226 return retval;
4227}
4228
4229/*****************************************************************************/
4230
4233#ifdef EC_IOCTL_RTDM
4234#define EC_IOCTL ec_ioctl_rtdm
4235#else
4236#define EC_IOCTL ec_ioctl
4237#endif
4238
4244 ec_master_t *master,
4245 ec_ioctl_context_t *ctx,
4246 unsigned int cmd,
4247 void *arg
4248 )
4249{
4250#if DEBUG_LATENCY
4251 cycles_t a = get_cycles(), b;
4252 unsigned int t;
4253#endif
4254 int ret;
4255
4256 switch (cmd) {
4257 case EC_IOCTL_MODULE:
4258 ret = ec_ioctl_module(arg);
4259 break;
4260 case EC_IOCTL_MASTER:
4261 ret = ec_ioctl_master(master, arg);
4262 break;
4263 case EC_IOCTL_SLAVE:
4264 ret = ec_ioctl_slave(master, arg);
4265 break;
4266 case EC_IOCTL_SLAVE_SYNC:
4267 ret = ec_ioctl_slave_sync(master, arg);
4268 break;
4269 case EC_IOCTL_SLAVE_SYNC_PDO:
4270 ret = ec_ioctl_slave_sync_pdo(master, arg);
4271 break;
4272 case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
4273 ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
4274 break;
4275 case EC_IOCTL_DOMAIN:
4276 ret = ec_ioctl_domain(master, arg);
4277 break;
4278 case EC_IOCTL_DOMAIN_FMMU:
4279 ret = ec_ioctl_domain_fmmu(master, arg);
4280 break;
4281 case EC_IOCTL_DOMAIN_DATA:
4282 ret = ec_ioctl_domain_data(master, arg);
4283 break;
4284 case EC_IOCTL_MASTER_DEBUG:
4285 if (!ctx->writable) {
4286 ret = -EPERM;
4287 break;
4288 }
4289 ret = ec_ioctl_master_debug(master, arg);
4290 break;
4291 case EC_IOCTL_MASTER_RESCAN:
4292 if (!ctx->writable) {
4293 ret = -EPERM;
4294 break;
4295 }
4296 ret = ec_ioctl_master_rescan(master, arg);
4297 break;
4298 case EC_IOCTL_SLAVE_STATE:
4299 if (!ctx->writable) {
4300 ret = -EPERM;
4301 break;
4302 }
4303 ret = ec_ioctl_slave_state(master, arg);
4304 break;
4305 case EC_IOCTL_SLAVE_SDO:
4306 ret = ec_ioctl_slave_sdo(master, arg);
4307 break;
4308 case EC_IOCTL_SLAVE_SDO_ENTRY:
4309 ret = ec_ioctl_slave_sdo_entry(master, arg);
4310 break;
4311 case EC_IOCTL_SLAVE_SDO_UPLOAD:
4312 ret = ec_ioctl_slave_sdo_upload(master, arg);
4313 break;
4314 case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
4315 if (!ctx->writable) {
4316 ret = -EPERM;
4317 break;
4318 }
4319 ret = ec_ioctl_slave_sdo_download(master, arg);
4320 break;
4321 case EC_IOCTL_SLAVE_SII_READ:
4322 ret = ec_ioctl_slave_sii_read(master, arg);
4323 break;
4324 case EC_IOCTL_SLAVE_SII_WRITE:
4325 if (!ctx->writable) {
4326 ret = -EPERM;
4327 break;
4328 }
4329 ret = ec_ioctl_slave_sii_write(master, arg);
4330 break;
4331 case EC_IOCTL_SLAVE_REG_READ:
4332 ret = ec_ioctl_slave_reg_read(master, arg);
4333 break;
4334 case EC_IOCTL_SLAVE_REG_WRITE:
4335 if (!ctx->writable) {
4336 ret = -EPERM;
4337 break;
4338 }
4339 ret = ec_ioctl_slave_reg_write(master, arg);
4340 break;
4341 case EC_IOCTL_SLAVE_FOE_READ:
4342 ret = ec_ioctl_slave_foe_read(master, arg);
4343 break;
4344 case EC_IOCTL_SLAVE_FOE_WRITE:
4345 if (!ctx->writable) {
4346 ret = -EPERM;
4347 break;
4348 }
4349 ret = ec_ioctl_slave_foe_write(master, arg);
4350 break;
4351 case EC_IOCTL_SLAVE_SOE_READ:
4352 ret = ec_ioctl_slave_soe_read(master, arg);
4353 break;
4354 case EC_IOCTL_SLAVE_SOE_WRITE:
4355 if (!ctx->writable) {
4356 ret = -EPERM;
4357 break;
4358 }
4359 ret = ec_ioctl_slave_soe_write(master, arg);
4360 break;
4361 case EC_IOCTL_CONFIG:
4362 ret = ec_ioctl_config(master, arg);
4363 break;
4364 case EC_IOCTL_CONFIG_PDO:
4365 ret = ec_ioctl_config_pdo(master, arg);
4366 break;
4367 case EC_IOCTL_CONFIG_PDO_ENTRY:
4368 ret = ec_ioctl_config_pdo_entry(master, arg);
4369 break;
4370 case EC_IOCTL_CONFIG_SDO:
4371 ret = ec_ioctl_config_sdo(master, arg);
4372 break;
4373 case EC_IOCTL_CONFIG_IDN:
4374 ret = ec_ioctl_config_idn(master, arg);
4375 break;
4376 case EC_IOCTL_CONFIG_FLAG:
4377 ret = ec_ioctl_config_flag(master, arg);
4378 break;
4379#ifdef EC_EOE
4380 case EC_IOCTL_EOE_HANDLER:
4381 ret = ec_ioctl_eoe_handler(master, arg);
4382 break;
4383#endif
4384 case EC_IOCTL_REQUEST:
4385 if (!ctx->writable) {
4386 ret = -EPERM;
4387 break;
4388 }
4389 ret = ec_ioctl_request(master, arg, ctx);
4390 break;
4391 case EC_IOCTL_CREATE_DOMAIN:
4392 if (!ctx->writable) {
4393 ret = -EPERM;
4394 break;
4395 }
4396 ret = ec_ioctl_create_domain(master, arg, ctx);
4397 break;
4398 case EC_IOCTL_CREATE_SLAVE_CONFIG:
4399 if (!ctx->writable) {
4400 ret = -EPERM;
4401 break;
4402 }
4403 ret = ec_ioctl_create_slave_config(master, arg, ctx);
4404 break;
4405 case EC_IOCTL_SELECT_REF_CLOCK:
4406 if (!ctx->writable) {
4407 ret = -EPERM;
4408 break;
4409 }
4410 ret = ec_ioctl_select_ref_clock(master, arg, ctx);
4411 break;
4412 case EC_IOCTL_ACTIVATE:
4413 if (!ctx->writable) {
4414 ret = -EPERM;
4415 break;
4416 }
4417 ret = ec_ioctl_activate(master, arg, ctx);
4418 break;
4419 case EC_IOCTL_DEACTIVATE:
4420 if (!ctx->writable) {
4421 ret = -EPERM;
4422 break;
4423 }
4424 ret = ec_ioctl_deactivate(master, arg, ctx);
4425 break;
4426 case EC_IOCTL_SEND:
4427 if (!ctx->writable) {
4428 ret = -EPERM;
4429 break;
4430 }
4431 ret = ec_ioctl_send(master, arg, ctx);
4432 break;
4433 case EC_IOCTL_RECEIVE:
4434 if (!ctx->writable) {
4435 ret = -EPERM;
4436 break;
4437 }
4438 ret = ec_ioctl_receive(master, arg, ctx);
4439 break;
4440 case EC_IOCTL_MASTER_STATE:
4441 ret = ec_ioctl_master_state(master, arg, ctx);
4442 break;
4443 case EC_IOCTL_MASTER_LINK_STATE:
4444 ret = ec_ioctl_master_link_state(master, arg, ctx);
4445 break;
4446 case EC_IOCTL_APP_TIME:
4447 if (!ctx->writable) {
4448 ret = -EPERM;
4449 break;
4450 }
4451 ret = ec_ioctl_app_time(master, arg, ctx);
4452 break;
4453 case EC_IOCTL_SYNC_REF:
4454 if (!ctx->writable) {
4455 ret = -EPERM;
4456 break;
4457 }
4458 ret = ec_ioctl_sync_ref(master, arg, ctx);
4459 break;
4460 case EC_IOCTL_SYNC_REF_TO:
4461 if (!ctx->writable) {
4462 ret = -EPERM;
4463 break;
4464 }
4465 ret = ec_ioctl_sync_ref_to(master, arg, ctx);
4466 break;
4467 case EC_IOCTL_SYNC_SLAVES:
4468 if (!ctx->writable) {
4469 ret = -EPERM;
4470 break;
4471 }
4472 ret = ec_ioctl_sync_slaves(master, arg, ctx);
4473 break;
4474 case EC_IOCTL_REF_CLOCK_TIME:
4475 if (!ctx->writable) {
4476 ret = -EPERM;
4477 break;
4478 }
4479 ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4480 break;
4481 case EC_IOCTL_SYNC_MON_QUEUE:
4482 if (!ctx->writable) {
4483 ret = -EPERM;
4484 break;
4485 }
4486 ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4487 break;
4488 case EC_IOCTL_SYNC_MON_PROCESS:
4489 if (!ctx->writable) {
4490 ret = -EPERM;
4491 break;
4492 }
4493 ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4494 break;
4495 case EC_IOCTL_RESET:
4496 if (!ctx->writable) {
4497 ret = -EPERM;
4498 break;
4499 }
4500 ret = ec_ioctl_reset(master, arg, ctx);
4501 break;
4502 case EC_IOCTL_SC_SYNC:
4503 if (!ctx->writable) {
4504 ret = -EPERM;
4505 break;
4506 }
4507 ret = ec_ioctl_sc_sync(master, arg, ctx);
4508 break;
4509 case EC_IOCTL_SC_WATCHDOG:
4510 if (!ctx->writable) {
4511 ret = -EPERM;
4512 break;
4513 }
4514 ret = ec_ioctl_sc_watchdog(master, arg, ctx);
4515 break;
4516 case EC_IOCTL_SC_ADD_PDO:
4517 if (!ctx->writable) {
4518 ret = -EPERM;
4519 break;
4520 }
4521 ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
4522 break;
4523 case EC_IOCTL_SC_CLEAR_PDOS:
4524 if (!ctx->writable) {
4525 ret = -EPERM;
4526 break;
4527 }
4528 ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
4529 break;
4530 case EC_IOCTL_SC_ADD_ENTRY:
4531 if (!ctx->writable) {
4532 ret = -EPERM;
4533 break;
4534 }
4535 ret = ec_ioctl_sc_add_entry(master, arg, ctx);
4536 break;
4537 case EC_IOCTL_SC_CLEAR_ENTRIES:
4538 if (!ctx->writable) {
4539 ret = -EPERM;
4540 break;
4541 }
4542 ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
4543 break;
4544 case EC_IOCTL_SC_REG_PDO_ENTRY:
4545 if (!ctx->writable) {
4546 ret = -EPERM;
4547 break;
4548 }
4549 ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
4550 break;
4551 case EC_IOCTL_SC_REG_PDO_POS:
4552 if (!ctx->writable) {
4553 ret = -EPERM;
4554 break;
4555 }
4556 ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
4557 break;
4558 case EC_IOCTL_SC_DC:
4559 if (!ctx->writable) {
4560 ret = -EPERM;
4561 break;
4562 }
4563 ret = ec_ioctl_sc_dc(master, arg, ctx);
4564 break;
4565 case EC_IOCTL_SC_SDO:
4566 if (!ctx->writable) {
4567 ret = -EPERM;
4568 break;
4569 }
4570 ret = ec_ioctl_sc_sdo(master, arg, ctx);
4571 break;
4572 case EC_IOCTL_SC_EMERG_SIZE:
4573 if (!ctx->writable) {
4574 ret = -EPERM;
4575 break;
4576 }
4577 ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
4578 break;
4579 case EC_IOCTL_SC_EMERG_POP:
4580 if (!ctx->writable) {
4581 ret = -EPERM;
4582 break;
4583 }
4584 ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
4585 break;
4586 case EC_IOCTL_SC_EMERG_CLEAR:
4587 if (!ctx->writable) {
4588 ret = -EPERM;
4589 break;
4590 }
4591 ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
4592 break;
4593 case EC_IOCTL_SC_EMERG_OVERRUNS:
4594 ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
4595 break;
4596 case EC_IOCTL_SC_SDO_REQUEST:
4597 if (!ctx->writable) {
4598 ret = -EPERM;
4599 break;
4600 }
4601 ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
4602 break;
4603 case EC_IOCTL_SC_REG_REQUEST:
4604 if (!ctx->writable) {
4605 ret = -EPERM;
4606 break;
4607 }
4608 ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
4609 break;
4610 case EC_IOCTL_SC_VOE:
4611 if (!ctx->writable) {
4612 ret = -EPERM;
4613 break;
4614 }
4615 ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
4616 break;
4617 case EC_IOCTL_SC_STATE:
4618 ret = ec_ioctl_sc_state(master, arg, ctx);
4619 break;
4620 case EC_IOCTL_SC_IDN:
4621 if (!ctx->writable) {
4622 ret = -EPERM;
4623 break;
4624 }
4625 ret = ec_ioctl_sc_idn(master, arg, ctx);
4626 break;
4627 case EC_IOCTL_SC_FLAG:
4628 if (!ctx->writable) {
4629 ret = -EPERM;
4630 break;
4631 }
4632 ret = ec_ioctl_sc_flag(master, arg, ctx);
4633 break;
4634 case EC_IOCTL_DOMAIN_SIZE:
4635 ret = ec_ioctl_domain_size(master, arg, ctx);
4636 break;
4637 case EC_IOCTL_DOMAIN_OFFSET:
4638 ret = ec_ioctl_domain_offset(master, arg, ctx);
4639 break;
4640 case EC_IOCTL_DOMAIN_PROCESS:
4641 if (!ctx->writable) {
4642 ret = -EPERM;
4643 break;
4644 }
4645 ret = ec_ioctl_domain_process(master, arg, ctx);
4646 break;
4647 case EC_IOCTL_DOMAIN_QUEUE:
4648 if (!ctx->writable) {
4649 ret = -EPERM;
4650 break;
4651 }
4652 ret = ec_ioctl_domain_queue(master, arg, ctx);
4653 break;
4654 case EC_IOCTL_DOMAIN_STATE:
4655 ret = ec_ioctl_domain_state(master, arg, ctx);
4656 break;
4657 case EC_IOCTL_SDO_REQUEST_INDEX:
4658 if (!ctx->writable) {
4659 ret = -EPERM;
4660 break;
4661 }
4662 ret = ec_ioctl_sdo_request_index(master, arg, ctx);
4663 break;
4664 case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4665 if (!ctx->writable) {
4666 ret = -EPERM;
4667 break;
4668 }
4669 ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4670 break;
4671 case EC_IOCTL_SDO_REQUEST_STATE:
4672 ret = ec_ioctl_sdo_request_state(master, arg, ctx);
4673 break;
4674 case EC_IOCTL_SDO_REQUEST_READ:
4675 if (!ctx->writable) {
4676 ret = -EPERM;
4677 break;
4678 }
4679 ret = ec_ioctl_sdo_request_read(master, arg, ctx);
4680 break;
4681 case EC_IOCTL_SDO_REQUEST_WRITE:
4682 if (!ctx->writable) {
4683 ret = -EPERM;
4684 break;
4685 }
4686 ret = ec_ioctl_sdo_request_write(master, arg, ctx);
4687 break;
4688 case EC_IOCTL_SDO_REQUEST_DATA:
4689 ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4690 break;
4691 case EC_IOCTL_REG_REQUEST_DATA:
4692 ret = ec_ioctl_reg_request_data(master, arg, ctx);
4693 break;
4694 case EC_IOCTL_REG_REQUEST_STATE:
4695 ret = ec_ioctl_reg_request_state(master, arg, ctx);
4696 break;
4697 case EC_IOCTL_REG_REQUEST_WRITE:
4698 if (!ctx->writable) {
4699 ret = -EPERM;
4700 break;
4701 }
4702 ret = ec_ioctl_reg_request_write(master, arg, ctx);
4703 break;
4704 case EC_IOCTL_REG_REQUEST_READ:
4705 if (!ctx->writable) {
4706 ret = -EPERM;
4707 break;
4708 }
4709 ret = ec_ioctl_reg_request_read(master, arg, ctx);
4710 break;
4711 case EC_IOCTL_VOE_SEND_HEADER:
4712 if (!ctx->writable) {
4713 ret = -EPERM;
4714 break;
4715 }
4716 ret = ec_ioctl_voe_send_header(master, arg, ctx);
4717 break;
4718 case EC_IOCTL_VOE_REC_HEADER:
4719 ret = ec_ioctl_voe_rec_header(master, arg, ctx);
4720 break;
4721 case EC_IOCTL_VOE_READ:
4722 if (!ctx->writable) {
4723 ret = -EPERM;
4724 break;
4725 }
4726 ret = ec_ioctl_voe_read(master, arg, ctx);
4727 break;
4728 case EC_IOCTL_VOE_READ_NOSYNC:
4729 if (!ctx->writable) {
4730 ret = -EPERM;
4731 break;
4732 }
4733 ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
4734 break;
4735 case EC_IOCTL_VOE_WRITE:
4736 if (!ctx->writable) {
4737 ret = -EPERM;
4738 break;
4739 }
4740 ret = ec_ioctl_voe_write(master, arg, ctx);
4741 break;
4742 case EC_IOCTL_VOE_EXEC:
4743 if (!ctx->writable) {
4744 ret = -EPERM;
4745 break;
4746 }
4747 ret = ec_ioctl_voe_exec(master, arg, ctx);
4748 break;
4749 case EC_IOCTL_VOE_DATA:
4750 ret = ec_ioctl_voe_data(master, arg, ctx);
4751 break;
4752 case EC_IOCTL_SET_SEND_INTERVAL:
4753 if (!ctx->writable) {
4754 ret = -EPERM;
4755 break;
4756 }
4757 ret = ec_ioctl_set_send_interval(master, arg, ctx);
4758 break;
4759 default:
4760 ret = -ENOTTY;
4761 break;
4762 }
4763
4764#if DEBUG_LATENCY
4765 b = get_cycles();
4766 t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
4767 if (t > 50) {
4768 EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
4769 _IOC_NR(cmd), t);
4770 }
4771#endif
4772
4773 return ret;
4774}
4775
4776/*****************************************************************************/
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:332
const ec_fmmu_config_t * ec_domain_find_fmmu(const ec_domain_t *domain, unsigned int pos)
Get a certain FMMU configuration via its position in the list.
Definition: domain.c:350
Ethernet over EtherCAT (EoE)
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:228
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:214
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:111
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:57
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:78
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
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
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:537
@ EC_SDO_ENTRY_ACCESS_PREOP
Access rights in PREOP.
Definition: globals.h:181
@ EC_SDO_ENTRY_ACCESS_OP
Access rights in OP.
Definition: globals.h:183
@ EC_SDO_ENTRY_ACCESS_SAFEOP
Access rights in SAFEOP.
Definition: globals.h:182
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:104
@ EC_DEVICE_MAIN
Main device.
Definition: globals.h:190
void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
Definition: slave_config.c:937
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:2867
void ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id, uint16_t vendor_type)
Sets the VoE header for future send operations.
Definition: voe_handler.c:123
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:239
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:222
void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:177
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:187
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:2647
uint8_t * ecrt_sdo_request_data(ec_sdo_request_t *req)
Access to the SDO request's data.
Definition: sdo_request.c:203
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave via complete access.
Definition: master.c:2962
int ecrt_slave_config_pdo_mapping_add(ec_slave_config_t *sc, uint16_t pdo_index, uint16_t entry_index, uint8_t entry_subindex, uint8_t entry_bit_length)
Add a PDO entry to the given PDO's mapping.
Definition: slave_config.c:688
void ecrt_reg_request_write(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule an register write operation.
Definition: reg_request.c:100
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:2859
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_slave_config_reg_pdo_entry(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry for process data exchange in a domain.
Definition: slave_config.c:817
void ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2465
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2395
int ecrt_slave_config_sync_manager(ec_slave_config_t *sc, uint8_t sync_index, ec_direction_t dir, ec_watchdog_mode_t watchdog_mode)
Configure a sync manager.
Definition: slave_config.c:601
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:2878
void ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master's datagram queue.
Definition: domain.c:648
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:2796
int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position, uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size, uint16_t *error_code)
Executes an SoE write request.
Definition: master.c:3131
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:2743
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.
void ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
void ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:159
int ecrt_slave_config_reg_pdo_entry_pos(ec_slave_config_t *sc, uint8_t sync_index, unsigned int pdo_pos, unsigned int entry_pos, ec_domain_t *domain, unsigned int *bit_position)
Registers a PDO entry using its position.
Definition: slave_config.c:872
ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req)
Get the current state of the SDO request.
Definition: sdo_request.c:217
void ecrt_slave_config_pdo_mapping_clear(ec_slave_config_t *sc, uint16_t pdo_index)
Clear the mapping of a given PDO.
Definition: slave_config.c:725
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:224
uint8_t * ecrt_voe_handler_data(ec_voe_handler_t *voe)
Access to the VoE handler's data.
Definition: voe_handler.c:145
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:3048
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:210
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:2780
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2509
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:2757
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_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2321
void 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:2836
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:678
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:152
void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe, uint32_t *vendor_id, uint16_t *vendor_type)
Reads the header data of a received VoE message.
Definition: voe_handler.c:132
void ecrt_domain_external_memory(ec_domain_t *domain, uint8_t *mem)
Provide external memory to store the domain's process data.
Definition: domain.c:434
void ecrt_master_reset(ec_master_t *master)
Retry configuring slaves.
Definition: master.c:3291
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:213
void ecrt_slave_config_watchdog(ec_slave_config_t *sc, uint16_t divider, uint16_t intervals)
Configure a slave's watchdog times.
Definition: slave_config.c:628
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
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:93
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:3207
void ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain's datagrams.
Definition: domain.c:458
int ecrt_slave_config_sdo(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, const uint8_t *data, size_t size)
Add an SDO configuration.
Definition: slave_config.c:956
void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
Start a VoE read operation without querying the sync manager status.
Definition: voe_handler.c:168
int ecrt_slave_config_emerg_overruns(ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
void ecrt_reg_request_read(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule a register read operation.
Definition: reg_request.c:111
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:2849
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain's process data.
Definition: domain.c:427
void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex.
Definition: sdo_request.c:187
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
Set the timeout for an SDO request.
Definition: sdo_request.c:196
int ecrt_slave_config_pdo_assign_add(ec_slave_config_t *sc, uint8_t sync_index, uint16_t pdo_index)
Add a PDO to a sync manager's PDO assignment.
Definition: slave_config.c:640
int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
Get the lower 32 bit of the reference clock system time.
Definition: master.c:2807
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:235
uint8_t * ecrt_reg_request_data(ec_reg_request_t *reg)
Access to the register request's data.
Definition: reg_request.c:86
void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, uint8_t sync_index)
Clear a sync manager's PDO assignment.
Definition: slave_config.c:670
@ EC_DIR_INPUT
Values read by the master.
Definition: ecrt.h:433
@ EC_REQUEST_SUCCESS
Request was processed successfully.
Definition: ecrt.h:533
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave's SII.
Definition: ioctl.c:897
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: ioctl.c:1647
static ATTRIBUTES int ec_ioctl_sc_sync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a sync manager.
Definition: ioctl.c:2170
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: ioctl.c:1197
static ATTRIBUTES int ec_ioctl_sc_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the slave configuration's state.
Definition: ioctl.c:2918
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: ioctl.c:4140
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: ioctl.c:1570
static ATTRIBUTES int ec_ioctl_sdo_request_index(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request's SDO index and subindex.
Definition: ioctl.c:3228
static ATTRIBUTES int ec_ioctl_slave_foe_write(ec_master_t *master, void *arg)
Write a file to a slave via FoE.
Definition: ioctl.c:4052
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry.
Definition: ioctl.c:2407
static ATTRIBUTES int ec_ioctl_sc_clear_entries(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the mapping of a PDO.
Definition: ioctl.c:2372
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3162
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: ioctl.c:468
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: ioctl.c:3956
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave's registers.
Definition: ioctl.c:1112
static ATTRIBUTES int ec_ioctl_sc_clear_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the PDO assignment.
Definition: ioctl.c:2302
static ATTRIBUTES int ec_ioctl_sync_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the slave clocks.
Definition: ioctl.c:2056
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:1841
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: ioctl.c:565
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: ioctl.c:1622
static ATTRIBUTES int ec_ioctl_sdo_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO read operation.
Definition: ioctl.c:3347
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: ioctl.c:723
static ATTRIBUTES int ec_ioctl_voe_exec(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Executes the VoE state machine.
Definition: ioctl.c:3871
static ATTRIBUTES int ec_ioctl_sc_emerg_pop(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get an emergency message from the ring.
Definition: ioctl.c:2641
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: ioctl.c:2152
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: ioctl.c:1860
static ATTRIBUTES int ec_ioctl_slave_soe_write(ec_master_t *master, void *arg)
Write an IDN to a slave via SoE.
Definition: ioctl.c:4189
static ATTRIBUTES int ec_ioctl_master_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the master state.
Definition: ioctl.c:1932
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: ioctl.c:1892
static ATTRIBUTES int ec_ioctl_sc_watchdog(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a slave's watchdogs.
Definition: ioctl.c:2223
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: ioctl.c:513
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: ioctl.c:610
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: ioctl.c:803
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: ioctl.c:1377
static ATTRIBUTES int ec_ioctl_sc_create_reg_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a register request.
Definition: ioctl.c:2814
static ATTRIBUTES int ec_ioctl_sdo_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SDO request's state.
Definition: ioctl.c:3302
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: ioctl.c:2956
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2544
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: ioctl.c:200
static ATTRIBUTES int ec_ioctl_domain_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain's data size.
Definition: ioctl.c:3066
static ATTRIBUTES int ec_ioctl_voe_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reads the received VoE data.
Definition: ioctl.c:3916
static ATTRIBUTES int ec_ioctl_voe_send_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the VoE send header.
Definition: ioctl.c:3658
static ATTRIBUTES int ec_ioctl_sync_ref_to(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: ioctl.c:2031
static ATTRIBUTES int ec_ioctl_voe_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation.
Definition: ioctl.c:3751
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: ioctl.c:1256
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: ioctl.c:1912
static ATTRIBUTES int ec_ioctl_sync_ref(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: ioctl.c:2011
static ATTRIBUTES int ec_ioctl_create_slave_config(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a slave configuration.
Definition: ioctl.c:1671
#define EC_IOCTL
ioctl() function to use.
Definition: ioctl.c:4236
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: ioctl.c:3134
static ATTRIBUTES int ec_ioctl_sc_add_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add an entry to a PDO's mapping.
Definition: ioctl.c:2337
static ATTRIBUTES int ec_ioctl_voe_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE write operation.
Definition: ioctl.c:3825
static ATTRIBUTES int ec_ioctl_sdo_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO write operation.
Definition: ioctl.c:3384
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: ioctl.c:340
static ATTRIBUTES int ec_ioctl_master(ec_master_t *master, void *arg)
Get master information.
Definition: ioctl.c:104
static ATTRIBUTES int ec_ioctl_sc_add_pdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add a PDO to the assignment.
Definition: ioctl.c:2268
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave's registers.
Definition: ioctl.c:1033
static ATTRIBUTES int ec_ioctl_sync_mon_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Processes the sync monitoring datagram.
Definition: ioctl.c:2127
static ATTRIBUTES int ec_ioctl_sdo_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SDO data.
Definition: ioctl.c:3435
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: ioctl.c:1312
static ATTRIBUTES int ec_ioctl_domain_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the domain state.
Definition: ioctl.c:3190
static ATTRIBUTES int ec_ioctl_config_flag(ec_master_t *master, void *arg)
Get slave configuration feature flag information.
Definition: ioctl.c:1505
static ATTRIBUTES int ec_ioctl_sc_emerg_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the emergency ring buffer size.
Definition: ioctl.c:2603
static ATTRIBUTES int ec_ioctl_sc_create_sdo_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SDO request.
Definition: ioctl.c:2763
static ATTRIBUTES int ec_ioctl_reg_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register write operation.
Definition: ioctl.c:3567
static ATTRIBUTES int ec_ioctl_voe_rec_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the received VoE header.
Definition: ioctl.c:3703
static ATTRIBUTES int ec_ioctl_app_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the master DC application time.
Definition: ioctl.c:1986
static ATTRIBUTES int ec_ioctl_reg_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an register request's state.
Definition: ioctl.c:3522
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: ioctl.c:849
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: ioctl.c:624
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave's SII.
Definition: ioctl.c:945
static ATTRIBUTES int ec_ioctl_ref_clock_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the system time of the reference clock.
Definition: ioctl.c:2076
static ATTRIBUTES int ec_ioctl_sc_emerg_clear(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clear the emergency ring.
Definition: ioctl.c:2685
static void ec_ioctl_strcpy(char *target, const char *source)
Copies a string to an ioctl structure.
Definition: ioctl.c:64
static ATTRIBUTES int ec_ioctl_master_link_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the link state.
Definition: ioctl.c:1954
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: ioctl.c:639
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: ioctl.c:1441
static ATTRIBUTES int ec_ioctl_sc_create_voe_handler(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a VoE handler.
Definition: ioctl.c:2868
static ATTRIBUTES int ec_ioctl_module(void *arg)
Get module information.
Definition: ioctl.c:83
static ATTRIBUTES int ec_ioctl_sdo_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request's timeout.
Definition: ioctl.c:3265
static ATTRIBUTES int ec_ioctl_sc_flag(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures a feature flag.
Definition: ioctl.c:3010
static ATTRIBUTES int ec_ioctl_select_ref_clock(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Select the DC reference clock.
Definition: ioctl.c:1717
static ATTRIBUTES int ec_ioctl_domain_offset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain's offset in the total process data.
Definition: ioctl.c:3100
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: ioctl.c:57
static ATTRIBUTES int ec_ioctl_sync_mon_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the sync monitoring datagram.
Definition: ioctl.c:2107
static ATTRIBUTES int ec_ioctl_sc_emerg_overruns(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the number of emergency overruns.
Definition: ioctl.c:2718
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: ioctl.c:287
static ATTRIBUTES int ec_ioctl_sc_dc(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the DC AssignActivate word and the sync signal times.
Definition: ioctl.c:2504
static ATTRIBUTES int ec_ioctl_reg_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read register data.
Definition: ioctl.c:3475
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_pos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry by its position.
Definition: ioctl.c:2454
static ATTRIBUTES int ec_ioctl_slave_sync_pdo_entry(ec_master_t *master, void *arg)
Get slave sync manager PDO entry information.
Definition: ioctl.c:399
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1758
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: ioctl.c:674
static ATTRIBUTES int ec_ioctl_reg_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register read operation.
Definition: ioctl.c:3615
static ATTRIBUTES int ec_ioctl_voe_read_nosync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation without sending a sync message first.
Definition: ioctl.c:3788
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:2274
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2009
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:916
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:2578
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:1992
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:2031
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:1977
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2056
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:1848
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:1928
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:1864
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:1880
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:549
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:1943
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:1913
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:563
EtherCAT master structure.
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:330
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:111
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:85
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:97
const ec_pdo_entry_t * ec_pdo_find_entry_by_pos_const(const ec_pdo_t *pdo, unsigned int pos)
Finds a PDO entry via its position in the list.
Definition: pdo.c:279
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition: pdo.c:257
unsigned int ec_pdo_list_count(const ec_pdo_list_t *pl)
Get the number of PDOs in the list.
Definition: pdo_list.c:311
const ec_pdo_t * ec_pdo_list_find_pdo_by_pos_const(const ec_pdo_list_t *pl, unsigned int pos)
Finds a PDO via its position in the list.
Definition: pdo_list.c:289
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:48
int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address)
Memory-map process data to user space.
Definition: rtdm.c:220
const ec_sdo_entry_t * ec_sdo_get_entry_const(const ec_sdo_t *sdo, uint8_t subindex)
Get an SDO entry from an SDO via its subindex.
Definition: sdo.c:116
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
Definition: slave.c:296
const ec_sdo_t * ec_slave_get_sdo_const(const ec_slave_t *slave, uint16_t index)
Get an SDO from the dictionary.
Definition: slave.c:662
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:706
const ec_sdo_t * ec_slave_get_sdo_by_pos_const(const ec_slave_t *slave, uint16_t sdo_position)
Get an SDO from the dictionary, given its position in the list.
Definition: slave.c:684
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:106
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:76
ec_voe_handler_t * ec_slave_config_find_voe_handler(ec_slave_config_t *sc, unsigned int pos)
Finds a VoE handler via its position in the list.
Definition: slave_config.c:558
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.
const ec_sdo_request_t * ec_slave_config_get_sdo_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an SDO configuration via its position in the list.
Definition: slave_config.c:404
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.
Definition: slave_config.c:426
const ec_flag_t * ec_slave_config_get_flag_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds a flag via its position in the list.
Definition: slave_config.c:492
ec_reg_request_t * ec_slave_config_find_reg_request(ec_slave_config_t *sc, unsigned int pos)
Finds a register handler via its position in the list.
Definition: slave_config.c:536
ec_sdo_request_t * ec_slave_config_find_sdo_request(ec_slave_config_t *sc, unsigned int pos)
Finds a CoE handler via its position in the list.
Definition: slave_config.c:514
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:382
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:470
const ec_soe_request_t * ec_slave_config_get_idn_by_pos_const(const ec_slave_config_t *sc, unsigned int pos)
Finds an IDN configuration via its position in the list.
Definition: slave_config.c:448
ec_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:175
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:177
u64 tx_count
Number of frames sent.
Definition: master.h:156
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:170
u64 rx_bytes
Number of bytes received.
Definition: master.h:163
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:173
u64 tx_bytes
Number of bytes sent.
Definition: master.h:161
u64 rx_count
Number of frames received.
Definition: master.h:158
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:167
EtherCAT device.
Definition: device.h:82
u64 tx_errors
Number of transmit errors.
Definition: device.h:110
u64 tx_count
Number of frames sent.
Definition: device.h:100
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:111
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:119
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:117
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:114
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:84
u64 tx_bytes
Number of bytes sent.
Definition: device.h:105
u64 rx_count
Number of frames received.
Definition: device.h:102
uint8_t link_state
device link state
Definition: device.h:88
u64 rx_bytes
Number of bytes received.
Definition: device.h:107
Domain state.
Definition: ecrt.h:420
EtherCAT domain.
Definition: domain.h:55
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:57
uint32_t logical_base_address
Logical offset address of the process data.
Definition: domain.h:64
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
Definition: domain.h:68
size_t data_size
Size of the process data.
Definition: domain.h:61
uint8_t * data
Memory for the process data.
Definition: domain.h:62
unsigned int index
Index (just a number).
Definition: domain.h:58
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:70
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:77
unsigned int opened
net_device is opened
Definition: ethernet.h:85
unsigned int tx_queued_frames
number of frames in the queue
Definition: ethernet.h:99
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:79
struct net_device_stats stats
device statistics
Definition: ethernet.h:84
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:83
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:106
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:97
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:46
uint32_t logical_start_address
Logical start address.
Definition: fmmu_config.h:52
const ec_slave_config_t * sc
EtherCAT slave config.
Definition: fmmu_config.h:48
unsigned int data_size
Covered PDO size.
Definition: fmmu_config.h:53
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:50
ec_direction_t dir
FMMU direction.
Definition: fmmu_config.h:51
FoE request.
Definition: foe_request.h:50
uint32_t result
FoE request abort code.
Definition: foe_request.h:68
struct list_head list
List item.
Definition: foe_request.h:51
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:69
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:83
Master state.
Definition: ecrt.h:271
EtherCAT master.
Definition: master.h:194
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:308
struct semaphore master_sem
Master semaphore.
Definition: master.h:209
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:311
struct list_head sii_requests
SII write requests.
Definition: master.h:307
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:221
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:238
unsigned int scan_busy
Current scan state.
Definition: master.h:250
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:232
unsigned int index
Index.
Definition: master.h:195
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:219
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:248
struct list_head domains
List of domains.
Definition: master.h:236
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:239
unsigned int active
Master has been activated.
Definition: master.h:224
struct semaphore device_sem
Device semaphore.
Definition: master.h:218
struct list_head configs
List of slave configurations.
Definition: master.h:235
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:212
ec_master_phase_t phase
Master phase.
Definition: master.h:223
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:211
PDO entry description.
Definition: pdo_entry.h:48
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:53
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:51
char * name
entry name
Definition: pdo_entry.h:52
uint16_t index
PDO entry index.
Definition: pdo_entry.h:50
PDO description.
Definition: pdo.h:49
uint16_t index
PDO index.
Definition: pdo.h:51
char * name
PDO name.
Definition: pdo.h:53
Register request.
Definition: reg_request.h:48
size_t mem_size
Size of data memory.
Definition: reg_request.h:50
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:51
struct list_head list
List item.
Definition: reg_request.h:49
uint16_t address
Register address.
Definition: reg_request.h:54
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:57
ec_direction_t dir
Direction.
Definition: reg_request.h:52
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
CANopen SDO entry.
Definition: sdo_entry.h:54
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:60
char * description
Description.
Definition: sdo_entry.h:62
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:59
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
CANopen SDO request.
Definition: sdo_request.h:48
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:55
size_t data_size
Size of SDO data.
Definition: sdo_request.h:54
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
ec_direction_t dir
Direction.
Definition: sdo_request.h:60
uint16_t index
SDO index.
Definition: sdo_request.h:50
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:51
CANopen SDO.
Definition: sdo.h:49
uint16_t index
SDO index.
Definition: sdo.h:52
char * name
SDO name.
Definition: sdo.h:54
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:143
char * group
Group name.
Definition: slave.h:155
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:165
char * order
Order number.
Definition: slave.h:157
uint32_t serial_number
Serial number.
Definition: slave.h:138
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:146
char * image
Image name.
Definition: slave.h:156
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:142
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:162
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:136
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:147
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:160
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:161
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:141
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:145
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:140
uint32_t revision_number
Revision number.
Definition: slave.h:137
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:144
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:139
unsigned int has_general
General category present.
Definition: slave.h:154
uint32_t vendor_id
Vendor ID.
Definition: slave.h:135
unsigned int sync_count
Number of sync managers.
Definition: slave.h:166
char * name
Slave name.
Definition: slave.h:158
SII write request.
Definition: fsm_master.h:53
struct list_head list
List head.
Definition: fsm_master.h:54
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:55
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:59
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:58
size_t nwords
Number of words.
Definition: fsm_master.h:57
uint16_t offset
SII word offset.
Definition: fsm_master.h:56
Slave configuration state.
Definition: ecrt.h:319
EtherCAT slave configuration.
Definition: slave_config.h:119
uint32_t product_code
Slave product code.
Definition: slave_config.h:127
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:137
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:147
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:141
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:145
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:131
uint16_t alias
Slave alias.
Definition: slave_config.h:123
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:142
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:129
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:134
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:126
uint16_t position
Index after alias.
Definition: slave_config.h:124
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:146
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:122
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:121
ec_slave_port_link_t link
Port link status.
Definition: slave.h:120
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:124
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:119
EtherCAT slave.
Definition: slave.h:177
ec_sii_t sii
Extracted SII data.
Definition: slave.h:223
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:187
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:215
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:210
uint16_t ring_position
Ring position.
Definition: slave.h:183
struct list_head foe_requests
FoE write requests.
Definition: slave.h:231
uint16_t * sii_words
Complete SII image.
Definition: slave.h:219
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:209
struct list_head reg_requests
Register access requests.
Definition: slave.h:230
ec_slave_state_t current_state
Current application state.
Definition: slave.h:192
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:212
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:211
uint16_t effective_alias
Effective alias address.
Definition: slave.h:185
size_t sii_nwords
Size of the SII contents in words.
Definition: slave.h:220
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:179
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:193
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:47
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:48
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:49
Sync manager.
Definition: sync.h:47
uint16_t physical_start_address
Physical start address.
Definition: sync.h:49
uint8_t enable
Enable bit.
Definition: sync.h:52
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
uint16_t default_length
Data length in bytes.
Definition: sync.h:50
uint8_t control_register
Control register value.
Definition: sync.h:51
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:49
void(* state)(ec_voe_handler_t *)
State function.
Definition: voe_handler.h:59
ec_direction_t dir
Direction.
Definition: voe_handler.h:56
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:108
Vendor specific over EtherCAT protocol handler.