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#else
122 io.eoe_handler_count = 0;
123#endif
124 io.phase = (uint8_t) master->phase;
125 io.active = (uint8_t) master->active;
126 io.scan_busy = master->scan_busy;
127
128 up(&master->master_sem);
129
130 if (down_interruptible(&master->device_sem)) {
131 return -EINTR;
132 }
133
134 for (dev_idx = EC_DEVICE_MAIN;
135 dev_idx < ec_master_num_devices(master); dev_idx++) {
136 ec_device_t *device = &master->devices[dev_idx];
137
138 if (device->dev) {
139 memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
140 ETH_ALEN);
141 } else {
142 memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
143 ETH_ALEN);
144 }
145 io.devices[dev_idx].attached = device->dev ? 1 : 0;
146 io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
147 io.devices[dev_idx].tx_count = device->tx_count;
148 io.devices[dev_idx].rx_count = device->rx_count;
149 io.devices[dev_idx].tx_bytes = device->tx_bytes;
150 io.devices[dev_idx].rx_bytes = device->rx_bytes;
151 io.devices[dev_idx].tx_errors = device->tx_errors;
152 for (j = 0; j < EC_RATE_COUNT; j++) {
153 io.devices[dev_idx].tx_frame_rates[j] =
154 device->tx_frame_rates[j];
155 io.devices[dev_idx].rx_frame_rates[j] =
156 device->rx_frame_rates[j];
157 io.devices[dev_idx].tx_byte_rates[j] =
158 device->tx_byte_rates[j];
159 io.devices[dev_idx].rx_byte_rates[j] =
160 device->rx_byte_rates[j];
161 }
162 }
163 io.num_devices = ec_master_num_devices(master);
164
165 io.tx_count = master->device_stats.tx_count;
166 io.rx_count = master->device_stats.rx_count;
167 io.tx_bytes = master->device_stats.tx_bytes;
168 io.rx_bytes = master->device_stats.rx_bytes;
169 for (j = 0; j < EC_RATE_COUNT; j++) {
170 io.tx_frame_rates[j] =
171 master->device_stats.tx_frame_rates[j];
172 io.rx_frame_rates[j] =
173 master->device_stats.rx_frame_rates[j];
174 io.tx_byte_rates[j] =
175 master->device_stats.tx_byte_rates[j];
176 io.rx_byte_rates[j] =
177 master->device_stats.rx_byte_rates[j];
178 io.loss_rates[j] =
179 master->device_stats.loss_rates[j];
180 }
181
182 up(&master->device_sem);
183
184 io.app_time = master->app_time;
185 io.dc_ref_time = master->dc_ref_time;
186 io.ref_clock =
187 master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
188
189 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
190 return -EFAULT;
191 }
192
193 return 0;
194}
195
196/*****************************************************************************/
197
203 ec_master_t *master,
204 void *arg
205 )
206{
207 ec_ioctl_slave_t data;
208 const ec_slave_t *slave;
209 int i;
210
211 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
212 return -EFAULT;
213 }
214
215 if (down_interruptible(&master->master_sem))
216 return -EINTR;
217
218 if (!(slave = ec_master_find_slave_const(
219 master, 0, data.position))) {
220 up(&master->master_sem);
221 EC_MASTER_ERR(master, "Slave %u does not exist!\n", data.position);
222 return -EINVAL;
223 }
224
225 data.device_index = slave->device_index;
226 data.vendor_id = slave->sii.vendor_id;
227 data.product_code = slave->sii.product_code;
228 data.revision_number = slave->sii.revision_number;
229 data.serial_number = slave->sii.serial_number;
230 data.alias = slave->effective_alias;
231 data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
232 data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
233 data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
234 data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
235 data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
236 data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
237 data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
238 data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
239 data.mailbox_protocols = slave->sii.mailbox_protocols;
240 data.has_general_category = slave->sii.has_general;
241 data.coe_details = slave->sii.coe_details;
242 data.general_flags = slave->sii.general_flags;
243 data.current_on_ebus = slave->sii.current_on_ebus;
244 for (i = 0; i < EC_MAX_PORTS; i++) {
245 data.ports[i].desc = slave->ports[i].desc;
246 data.ports[i].link.link_up = slave->ports[i].link.link_up;
247 data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
248 data.ports[i].link.signal_detected =
249 slave->ports[i].link.signal_detected;
250 data.ports[i].receive_time = slave->ports[i].receive_time;
251 if (slave->ports[i].next_slave) {
252 data.ports[i].next_slave =
253 slave->ports[i].next_slave->ring_position;
254 } else {
255 data.ports[i].next_slave = 0xffff;
256 }
257 data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
258 }
259 data.fmmu_bit = slave->base_fmmu_bit_operation;
260 data.dc_supported = slave->base_dc_supported;
261 data.dc_range = slave->base_dc_range;
262 data.has_dc_system_time = slave->has_dc_system_time;
263 data.transmission_delay = slave->transmission_delay;
264 data.al_state = slave->current_state;
265 data.error_flag = slave->error_flag;
266
267 data.sync_count = slave->sii.sync_count;
268 data.sdo_count = ec_slave_sdo_count(slave);
269 data.sii_nwords = slave->sii_nwords;
270 ec_ioctl_strcpy(data.group, slave->sii.group);
271 ec_ioctl_strcpy(data.image, slave->sii.image);
272 ec_ioctl_strcpy(data.order, slave->sii.order);
273 ec_ioctl_strcpy(data.name, slave->sii.name);
274
275 up(&master->master_sem);
276
277 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
278 return -EFAULT;
279
280 return 0;
281}
282
283/*****************************************************************************/
284
290 ec_master_t *master,
291 void *arg
292 )
293{
294 ec_ioctl_slave_sync_t data;
295 const ec_slave_t *slave;
296 const ec_sync_t *sync;
297
298 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
299 return -EFAULT;
300 }
301
302 if (down_interruptible(&master->master_sem))
303 return -EINTR;
304
305 if (!(slave = ec_master_find_slave_const(
306 master, 0, data.slave_position))) {
307 up(&master->master_sem);
308 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
309 data.slave_position);
310 return -EINVAL;
311 }
312
313 if (data.sync_index >= slave->sii.sync_count) {
314 up(&master->master_sem);
315 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
316 data.sync_index);
317 return -EINVAL;
318 }
319
320 sync = &slave->sii.syncs[data.sync_index];
321
323 data.default_size = sync->default_length;
324 data.control_register = sync->control_register;
325 data.enable = sync->enable;
326 data.pdo_count = ec_pdo_list_count(&sync->pdos);
327
328 up(&master->master_sem);
329
330 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
331 return -EFAULT;
332
333 return 0;
334}
335
336/*****************************************************************************/
337
343 ec_master_t *master,
344 void *arg
345 )
346{
347 ec_ioctl_slave_sync_pdo_t data;
348 const ec_slave_t *slave;
349 const ec_sync_t *sync;
350 const ec_pdo_t *pdo;
351
352 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
353 return -EFAULT;
354 }
355
356 if (down_interruptible(&master->master_sem))
357 return -EINTR;
358
359 if (!(slave = ec_master_find_slave_const(
360 master, 0, data.slave_position))) {
361 up(&master->master_sem);
362 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
363 data.slave_position);
364 return -EINVAL;
365 }
366
367 if (data.sync_index >= slave->sii.sync_count) {
368 up(&master->master_sem);
369 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
370 data.sync_index);
371 return -EINVAL;
372 }
373
374 sync = &slave->sii.syncs[data.sync_index];
376 &sync->pdos, data.pdo_pos))) {
377 up(&master->master_sem);
378 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
379 "position %u!\n", data.sync_index, data.pdo_pos);
380 return -EINVAL;
381 }
382
383 data.index = pdo->index;
384 data.entry_count = ec_pdo_entry_count(pdo);
385 ec_ioctl_strcpy(data.name, pdo->name);
386
387 up(&master->master_sem);
388
389 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
390 return -EFAULT;
391
392 return 0;
393}
394
395/*****************************************************************************/
396
402 ec_master_t *master,
403 void *arg
404 )
405{
406 ec_ioctl_slave_sync_pdo_entry_t data;
407 const ec_slave_t *slave;
408 const ec_sync_t *sync;
409 const ec_pdo_t *pdo;
410 const ec_pdo_entry_t *entry;
411
412 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
413 return -EFAULT;
414 }
415
416 if (down_interruptible(&master->master_sem))
417 return -EINTR;
418
419 if (!(slave = ec_master_find_slave_const(
420 master, 0, data.slave_position))) {
421 up(&master->master_sem);
422 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
423 data.slave_position);
424 return -EINVAL;
425 }
426
427 if (data.sync_index >= slave->sii.sync_count) {
428 up(&master->master_sem);
429 EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
430 data.sync_index);
431 return -EINVAL;
432 }
433
434 sync = &slave->sii.syncs[data.sync_index];
436 &sync->pdos, data.pdo_pos))) {
437 up(&master->master_sem);
438 EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
439 "position %u!\n", data.sync_index, data.pdo_pos);
440 return -EINVAL;
441 }
442
443 if (!(entry = ec_pdo_find_entry_by_pos_const(
444 pdo, data.entry_pos))) {
445 up(&master->master_sem);
446 EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
447 "position %u!\n", data.pdo_pos, data.entry_pos);
448 return -EINVAL;
449 }
450
451 data.index = entry->index;
452 data.subindex = entry->subindex;
453 data.bit_length = entry->bit_length;
454 ec_ioctl_strcpy(data.name, entry->name);
455
456 up(&master->master_sem);
457
458 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
459 return -EFAULT;
460
461 return 0;
462}
463
464/*****************************************************************************/
465
471 ec_master_t *master,
472 void *arg
473 )
474{
475 ec_ioctl_domain_t data;
476 const ec_domain_t *domain;
477 unsigned int dev_idx;
478
479 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
480 return -EFAULT;
481 }
482
483 if (down_interruptible(&master->master_sem))
484 return -EINTR;
485
486 if (!(domain = ec_master_find_domain_const(master, data.index))) {
487 up(&master->master_sem);
488 EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
489 return -EINVAL;
490 }
491
492 data.data_size = domain->data_size;
493 data.logical_base_address = domain->logical_base_address;
494 for (dev_idx = EC_DEVICE_MAIN;
495 dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
496 data.working_counter[dev_idx] = domain->working_counter[dev_idx];
497 }
498 data.expected_working_counter = domain->expected_working_counter;
499 data.fmmu_count = ec_domain_fmmu_count(domain);
500
501 up(&master->master_sem);
502
503 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
504 return -EFAULT;
505
506 return 0;
507}
508
509/*****************************************************************************/
510
516 ec_master_t *master,
517 void *arg
518 )
519{
520 ec_ioctl_domain_fmmu_t data;
521 const ec_domain_t *domain;
522 const ec_fmmu_config_t *fmmu;
523
524 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
525 return -EFAULT;
526 }
527
528 if (down_interruptible(&master->master_sem))
529 return -EINTR;
530
531 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
532 up(&master->master_sem);
533 EC_MASTER_ERR(master, "Domain %u does not exist!\n",
534 data.domain_index);
535 return -EINVAL;
536 }
537
538 if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
539 up(&master->master_sem);
540 EC_MASTER_ERR(master, "Domain %u has less than %u"
541 " fmmu configurations.\n",
542 data.domain_index, data.fmmu_index + 1);
543 return -EINVAL;
544 }
545
546 data.slave_config_alias = fmmu->sc->alias;
547 data.slave_config_position = fmmu->sc->position;
548 data.sync_index = fmmu->sync_index;
549 data.dir = fmmu->dir;
550 data.logical_address = fmmu->logical_start_address;
551 data.data_size = fmmu->data_size;
552
553 up(&master->master_sem);
554
555 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
556 return -EFAULT;
557
558 return 0;
559}
560
561/*****************************************************************************/
562
568 ec_master_t *master,
569 void *arg
570 )
571{
572 ec_ioctl_domain_data_t data;
573 const ec_domain_t *domain;
574
575 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
576 return -EFAULT;
577 }
578
579 if (down_interruptible(&master->master_sem))
580 return -EINTR;
581
582 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
583 up(&master->master_sem);
584 EC_MASTER_ERR(master, "Domain %u does not exist!\n",
585 data.domain_index);
586 return -EINVAL;
587 }
588
589 if (domain->data_size != data.data_size) {
590 up(&master->master_sem);
591 EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
592 data.data_size, domain->data_size);
593 return -EFAULT;
594 }
595
596 if (copy_to_user((void __user *) data.target, domain->data,
597 domain->data_size)) {
598 up(&master->master_sem);
599 return -EFAULT;
600 }
601
602 up(&master->master_sem);
603 return 0;
604}
605
606/*****************************************************************************/
607
613 ec_master_t *master,
614 void *arg
615 )
616{
617 return ec_master_debug_level(master, (unsigned long) arg);
618}
619
620/*****************************************************************************/
621
627 ec_master_t *master,
628 void *arg
629 )
630{
631 master->fsm.rescan_required = 1;
632 return 0;
633}
634
635/*****************************************************************************/
636
642 ec_master_t *master,
643 void *arg
644 )
645{
646 ec_ioctl_slave_state_t data;
647 ec_slave_t *slave;
648
649 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
650 return -EFAULT;
651 }
652
653 if (down_interruptible(&master->master_sem))
654 return -EINTR;
655
656 if (!(slave = ec_master_find_slave(
657 master, 0, data.slave_position))) {
658 up(&master->master_sem);
659 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
660 data.slave_position);
661 return -EINVAL;
662 }
663
664 ec_slave_request_state(slave, data.al_state);
665
666 up(&master->master_sem);
667 return 0;
668}
669
670/*****************************************************************************/
671
677 ec_master_t *master,
678 void *arg
679 )
680{
681 ec_ioctl_slave_sdo_t data;
682 const ec_slave_t *slave;
683 const ec_sdo_t *sdo;
684
685 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
686 return -EFAULT;
687 }
688
689 if (down_interruptible(&master->master_sem))
690 return -EINTR;
691
692 if (!(slave = ec_master_find_slave_const(
693 master, 0, data.slave_position))) {
694 up(&master->master_sem);
695 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
696 data.slave_position);
697 return -EINVAL;
698 }
699
701 slave, data.sdo_position))) {
702 up(&master->master_sem);
703 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
704 return -EINVAL;
705 }
706
707 data.sdo_index = sdo->index;
708 data.max_subindex = sdo->max_subindex;
709 ec_ioctl_strcpy(data.name, sdo->name);
710
711 up(&master->master_sem);
712
713 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
714 return -EFAULT;
715
716 return 0;
717}
718
719/*****************************************************************************/
720
726 ec_master_t *master,
727 void *arg
728 )
729{
730 ec_ioctl_slave_sdo_entry_t data;
731 const ec_slave_t *slave;
732 const ec_sdo_t *sdo;
733 const ec_sdo_entry_t *entry;
734
735 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
736 return -EFAULT;
737 }
738
739 if (down_interruptible(&master->master_sem))
740 return -EINTR;
741
742 if (!(slave = ec_master_find_slave_const(
743 master, 0, data.slave_position))) {
744 up(&master->master_sem);
745 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
746 data.slave_position);
747 return -EINVAL;
748 }
749
750 if (data.sdo_spec <= 0) {
752 slave, -data.sdo_spec))) {
753 up(&master->master_sem);
754 EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
755 return -EINVAL;
756 }
757 } else {
758 if (!(sdo = ec_slave_get_sdo_const(
759 slave, data.sdo_spec))) {
760 up(&master->master_sem);
761 EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
762 data.sdo_spec);
763 return -EINVAL;
764 }
765 }
766
767 if (!(entry = ec_sdo_get_entry_const(
768 sdo, data.sdo_entry_subindex))) {
769 up(&master->master_sem);
770 EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
771 sdo->index, data.sdo_entry_subindex);
772 return -EINVAL;
773 }
774
775 data.data_type = entry->data_type;
776 data.bit_length = entry->bit_length;
777 data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
779 data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
781 data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
783 data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
785 data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
787 data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
789 ec_ioctl_strcpy(data.description, entry->description);
790
791 up(&master->master_sem);
792
793 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
794 return -EFAULT;
795
796 return 0;
797}
798
799/*****************************************************************************/
800
806 ec_master_t *master,
807 void *arg
808 )
809{
810 ec_ioctl_slave_sdo_upload_t data;
811 uint8_t *target;
812 int ret;
813
814 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
815 return -EFAULT;
816 }
817
818 if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
819 EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
820 " for SDO upload.\n", data.target_size);
821 return -ENOMEM;
822 }
823
824 ret = ecrt_master_sdo_upload(master, data.slave_position,
825 data.sdo_index, data.sdo_entry_subindex, target,
826 data.target_size, &data.data_size, &data.abort_code);
827
828 if (!ret) {
829 if (copy_to_user((void __user *) data.target,
830 target, data.data_size)) {
831 kfree(target);
832 return -EFAULT;
833 }
834 }
835
836 kfree(target);
837
838 if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
839 return -EFAULT;
840 }
841
842 return ret;
843}
844
845/*****************************************************************************/
846
852 ec_master_t *master,
853 void *arg
854 )
855{
856 ec_ioctl_slave_sdo_download_t data;
857 uint8_t *sdo_data;
858 int retval;
859
860 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
861 return -EFAULT;
862 }
863
864 if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
865 EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
866 " for SDO download.\n", data.data_size);
867 return -ENOMEM;
868 }
869
870 if (copy_from_user(sdo_data, (void __user *) data.data, data.data_size)) {
871 kfree(sdo_data);
872 return -EFAULT;
873 }
874
875 if (data.complete_access) {
876 retval = ecrt_master_sdo_download_complete(master, data.slave_position,
877 data.sdo_index, sdo_data, data.data_size, &data.abort_code);
878 } else {
879 retval = ecrt_master_sdo_download(master, data.slave_position,
880 data.sdo_index, data.sdo_entry_subindex, sdo_data,
881 data.data_size, &data.abort_code);
882 }
883
884 kfree(sdo_data);
885
886 if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
887 retval = -EFAULT;
888 }
889
890 return retval;
891}
892
893/*****************************************************************************/
894
900 ec_master_t *master,
901 void *arg
902 )
903{
904 ec_ioctl_slave_sii_t data;
905 const ec_slave_t *slave;
906 int retval;
907
908 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
909 return -EFAULT;
910 }
911
912 if (down_interruptible(&master->master_sem))
913 return -EINTR;
914
915 if (!(slave = ec_master_find_slave_const(
916 master, 0, data.slave_position))) {
917 up(&master->master_sem);
918 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
919 data.slave_position);
920 return -EINVAL;
921 }
922
923 if (!data.nwords
924 || data.offset + data.nwords > slave->sii_nwords) {
925 up(&master->master_sem);
926 EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
927 " size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
928 return -EINVAL;
929 }
930
931 if (copy_to_user((void __user *) data.words,
932 slave->sii_words + data.offset, data.nwords * 2))
933 retval = -EFAULT;
934 else
935 retval = 0;
936
937 up(&master->master_sem);
938 return retval;
939}
940
941/*****************************************************************************/
942
948 ec_master_t *master,
949 void *arg
950 )
951{
952 ec_ioctl_slave_sii_t data;
953 ec_slave_t *slave;
954 unsigned int byte_size;
955 uint16_t *words;
957
958 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
959 return -EFAULT;
960 }
961
962 if (!data.nwords) {
963 return 0;
964 }
965
966 byte_size = sizeof(uint16_t) * data.nwords;
967 if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
968 EC_MASTER_ERR(master, "Failed to allocate %u bytes"
969 " for SII contents.\n", byte_size);
970 return -ENOMEM;
971 }
972
973 if (copy_from_user(words,
974 (void __user *) data.words, byte_size)) {
975 kfree(words);
976 return -EFAULT;
977 }
978
979 if (down_interruptible(&master->master_sem)) {
980 kfree(words);
981 return -EINTR;
982 }
983
984 if (!(slave = ec_master_find_slave(
985 master, 0, data.slave_position))) {
986 up(&master->master_sem);
987 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
988 data.slave_position);
989 kfree(words);
990 return -EINVAL;
991 }
992
993 // init SII write request
994 INIT_LIST_HEAD(&request.list);
995 request.slave = slave;
996 request.words = words;
997 request.offset = data.offset;
998 request.nwords = data.nwords;
999 request.state = EC_INT_REQUEST_QUEUED;
1000
1001 // schedule SII write request.
1002 list_add_tail(&request.list, &master->sii_requests);
1003
1004 up(&master->master_sem);
1005
1006 // wait for processing through FSM
1007 if (wait_event_interruptible(master->request_queue,
1008 request.state != EC_INT_REQUEST_QUEUED)) {
1009 // interrupted by signal
1010 down(&master->master_sem);
1011 if (request.state == EC_INT_REQUEST_QUEUED) {
1012 // abort request
1013 list_del(&request.list);
1014 up(&master->master_sem);
1015 kfree(words);
1016 return -EINTR;
1017 }
1018 up(&master->master_sem);
1019 }
1020
1021 // wait until master FSM has finished processing
1022 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1023
1024 kfree(words);
1025
1026 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1027}
1028
1029/*****************************************************************************/
1030
1036 ec_master_t *master,
1037 void *arg
1038 )
1039{
1040 ec_ioctl_slave_reg_t io;
1041 ec_slave_t *slave;
1042 ec_reg_request_t request;
1043 int ret;
1044
1045 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1046 return -EFAULT;
1047 }
1048
1049 if (!io.size) {
1050 return 0;
1051 }
1052
1053 // init register request
1054 ret = ec_reg_request_init(&request, io.size);
1055 if (ret) {
1056 return ret;
1057 }
1058
1059 ecrt_reg_request_read(&request, io.address, io.size);
1060
1061 if (down_interruptible(&master->master_sem)) {
1062 ec_reg_request_clear(&request);
1063 return -EINTR;
1064 }
1065
1066 if (!(slave = ec_master_find_slave(
1067 master, 0, io.slave_position))) {
1068 up(&master->master_sem);
1069 ec_reg_request_clear(&request);
1070 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1071 io.slave_position);
1072 return -EINVAL;
1073 }
1074
1075 // schedule request.
1076 list_add_tail(&request.list, &slave->reg_requests);
1077
1078 up(&master->master_sem);
1079
1080 // wait for processing through FSM
1081 if (wait_event_interruptible(master->request_queue,
1082 request.state != EC_INT_REQUEST_QUEUED)) {
1083 // interrupted by signal
1084 down(&master->master_sem);
1085 if (request.state == EC_INT_REQUEST_QUEUED) {
1086 // abort request
1087 list_del(&request.list);
1088 up(&master->master_sem);
1089 ec_reg_request_clear(&request);
1090 return -EINTR;
1091 }
1092 up(&master->master_sem);
1093 }
1094
1095 // wait until master FSM has finished processing
1096 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1097
1098 if (request.state == EC_INT_REQUEST_SUCCESS) {
1099 if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1100 return -EFAULT;
1101 }
1102 }
1103 ec_reg_request_clear(&request);
1104
1105 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1106}
1107
1108/*****************************************************************************/
1109
1115 ec_master_t *master,
1116 void *arg
1117 )
1118{
1119 ec_ioctl_slave_reg_t io;
1120 ec_slave_t *slave;
1121 ec_reg_request_t request;
1122 int ret;
1123
1124 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1125 return -EFAULT;
1126 }
1127
1128 if (!io.size) {
1129 return 0;
1130 }
1131
1132 // init register request
1133 ret = ec_reg_request_init(&request, io.size);
1134 if (ret) {
1135 return ret;
1136 }
1137
1138 if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1139 ec_reg_request_clear(&request);
1140 return -EFAULT;
1141 }
1142
1143 ecrt_reg_request_write(&request, io.address, io.size);
1144
1145 if (down_interruptible(&master->master_sem)) {
1146 ec_reg_request_clear(&request);
1147 return -EINTR;
1148 }
1149
1150 if (io.emergency) {
1151 request.ring_position = io.slave_position;
1152 // schedule request.
1153 list_add_tail(&request.list, &master->emerg_reg_requests);
1154 }
1155 else {
1156 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1157 up(&master->master_sem);
1158 ec_reg_request_clear(&request);
1159 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1160 io.slave_position);
1161 return -EINVAL;
1162 }
1163
1164 // schedule request.
1165 list_add_tail(&request.list, &slave->reg_requests);
1166 }
1167
1168 up(&master->master_sem);
1169
1170 // wait for processing through FSM
1171 if (wait_event_interruptible(master->request_queue,
1172 request.state != EC_INT_REQUEST_QUEUED)) {
1173 // interrupted by signal
1174 down(&master->master_sem);
1175 if (request.state == EC_INT_REQUEST_QUEUED) {
1176 // abort request
1177 list_del(&request.list);
1178 up(&master->master_sem);
1179 ec_reg_request_clear(&request);
1180 return -EINTR;
1181 }
1182 up(&master->master_sem);
1183 }
1184
1185 // wait until master FSM has finished processing
1186 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1187
1188 ec_reg_request_clear(&request);
1189
1190 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1191}
1192
1193/*****************************************************************************/
1194
1200 ec_master_t *master,
1201 void *arg
1202 )
1203{
1204 ec_ioctl_config_t data;
1205 const ec_slave_config_t *sc;
1206 uint8_t i;
1207
1208 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1209 return -EFAULT;
1210 }
1211
1212 if (down_interruptible(&master->master_sem))
1213 return -EINTR;
1214
1215 if (!(sc = ec_master_get_config_const(
1216 master, data.config_index))) {
1217 up(&master->master_sem);
1218 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1219 data.config_index);
1220 return -EINVAL;
1221 }
1222
1223 data.alias = sc->alias;
1224 data.position = sc->position;
1225 data.vendor_id = sc->vendor_id;
1226 data.product_code = sc->product_code;
1227 for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1228 data.syncs[i].dir = sc->sync_configs[i].dir;
1229 data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1230 data.syncs[i].pdo_count =
1232 }
1233 data.watchdog_divider = sc->watchdog_divider;
1234 data.watchdog_intervals = sc->watchdog_intervals;
1235 data.sdo_count = ec_slave_config_sdo_count(sc);
1236 data.idn_count = ec_slave_config_idn_count(sc);
1237 data.flag_count = ec_slave_config_flag_count(sc);
1238 data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1239 data.dc_assign_activate = sc->dc_assign_activate;
1240 for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1241 data.dc_sync[i] = sc->dc_sync[i];
1242 }
1243
1244 up(&master->master_sem);
1245
1246 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1247 return -EFAULT;
1248
1249 return 0;
1250}
1251
1252/*****************************************************************************/
1253
1259 ec_master_t *master,
1260 void *arg
1261 )
1262{
1263 ec_ioctl_config_pdo_t data;
1264 const ec_slave_config_t *sc;
1265 const ec_pdo_t *pdo;
1266
1267 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1268 return -EFAULT;
1269 }
1270
1271 if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1272 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1273 data.sync_index);
1274 return -EINVAL;
1275 }
1276
1277 if (down_interruptible(&master->master_sem))
1278 return -EINTR;
1279
1280 if (!(sc = ec_master_get_config_const(
1281 master, data.config_index))) {
1282 up(&master->master_sem);
1283 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1284 data.config_index);
1285 return -EINVAL;
1286 }
1287
1289 &sc->sync_configs[data.sync_index].pdos,
1290 data.pdo_pos))) {
1291 up(&master->master_sem);
1292 EC_MASTER_ERR(master, "Invalid PDO position!\n");
1293 return -EINVAL;
1294 }
1295
1296 data.index = pdo->index;
1297 data.entry_count = ec_pdo_entry_count(pdo);
1298 ec_ioctl_strcpy(data.name, pdo->name);
1299
1300 up(&master->master_sem);
1301
1302 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1303 return -EFAULT;
1304
1305 return 0;
1306}
1307
1308/*****************************************************************************/
1309
1315 ec_master_t *master,
1316 void *arg
1317 )
1318{
1319 ec_ioctl_config_pdo_entry_t data;
1320 const ec_slave_config_t *sc;
1321 const ec_pdo_t *pdo;
1322 const ec_pdo_entry_t *entry;
1323
1324 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1325 return -EFAULT;
1326 }
1327
1328 if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1329 EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1330 data.sync_index);
1331 return -EINVAL;
1332 }
1333
1334 if (down_interruptible(&master->master_sem))
1335 return -EINTR;
1336
1337 if (!(sc = ec_master_get_config_const(
1338 master, data.config_index))) {
1339 up(&master->master_sem);
1340 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1341 data.config_index);
1342 return -EINVAL;
1343 }
1344
1346 &sc->sync_configs[data.sync_index].pdos,
1347 data.pdo_pos))) {
1348 up(&master->master_sem);
1349 EC_MASTER_ERR(master, "Invalid PDO position!\n");
1350 return -EINVAL;
1351 }
1352
1353 if (!(entry = ec_pdo_find_entry_by_pos_const(
1354 pdo, data.entry_pos))) {
1355 up(&master->master_sem);
1356 EC_MASTER_ERR(master, "Entry not found!\n");
1357 return -EINVAL;
1358 }
1359
1360 data.index = entry->index;
1361 data.subindex = entry->subindex;
1362 data.bit_length = entry->bit_length;
1363 ec_ioctl_strcpy(data.name, entry->name);
1364
1365 up(&master->master_sem);
1366
1367 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1368 return -EFAULT;
1369
1370 return 0;
1371}
1372
1373/*****************************************************************************/
1374
1380 ec_master_t *master,
1381 void *arg
1382 )
1383{
1384 ec_ioctl_config_sdo_t *ioctl;
1385 const ec_slave_config_t *sc;
1386 const ec_sdo_request_t *req;
1387
1388 if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1389 return -ENOMEM;
1390 }
1391
1392 if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1393 kfree(ioctl);
1394 return -EFAULT;
1395 }
1396
1397 if (down_interruptible(&master->master_sem)) {
1398 kfree(ioctl);
1399 return -EINTR;
1400 }
1401
1402 if (!(sc = ec_master_get_config_const(
1403 master, ioctl->config_index))) {
1404 up(&master->master_sem);
1405 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1406 ioctl->config_index);
1407 kfree(ioctl);
1408 return -EINVAL;
1409 }
1410
1412 sc, ioctl->sdo_pos))) {
1413 up(&master->master_sem);
1414 EC_MASTER_ERR(master, "Invalid SDO position!\n");
1415 kfree(ioctl);
1416 return -EINVAL;
1417 }
1418
1419 ioctl->index = req->index;
1420 ioctl->subindex = req->subindex;
1421 ioctl->size = req->data_size;
1422 memcpy(ioctl->data, req->data,
1423 min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1424 ioctl->complete_access = req->complete_access;
1425
1426 up(&master->master_sem);
1427
1428 if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1429 kfree(ioctl);
1430 return -EFAULT;
1431 }
1432
1433 kfree(ioctl);
1434 return 0;
1435}
1436
1437/*****************************************************************************/
1438
1444 ec_master_t *master,
1445 void *arg
1446 )
1447{
1448 ec_ioctl_config_idn_t *ioctl;
1449 const ec_slave_config_t *sc;
1450 const ec_soe_request_t *req;
1451
1452 if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1453 return -ENOMEM;
1454 }
1455
1456 if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1457 kfree(ioctl);
1458 return -EFAULT;
1459 }
1460
1461 if (down_interruptible(&master->master_sem)) {
1462 kfree(ioctl);
1463 return -EINTR;
1464 }
1465
1466 if (!(sc = ec_master_get_config_const(
1467 master, ioctl->config_index))) {
1468 up(&master->master_sem);
1469 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1470 ioctl->config_index);
1471 kfree(ioctl);
1472 return -EINVAL;
1473 }
1474
1476 sc, ioctl->idn_pos))) {
1477 up(&master->master_sem);
1478 EC_MASTER_ERR(master, "Invalid IDN position!\n");
1479 kfree(ioctl);
1480 return -EINVAL;
1481 }
1482
1483 ioctl->drive_no = req->drive_no;
1484 ioctl->idn = req->idn;
1485 ioctl->state = req->state;
1486 ioctl->size = req->data_size;
1487 memcpy(ioctl->data, req->data,
1488 min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1489
1490 up(&master->master_sem);
1491
1492 if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1493 kfree(ioctl);
1494 return -EFAULT;
1495 }
1496
1497 kfree(ioctl);
1498 return 0;
1499}
1500
1501/*****************************************************************************/
1502
1508 ec_master_t *master,
1509 void *arg
1510 )
1511{
1512 ec_ioctl_config_flag_t *ioctl;
1513 const ec_slave_config_t *sc;
1514 const ec_flag_t *flag;
1515 size_t size;
1516
1517 if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1518 return -ENOMEM;
1519 }
1520
1521 if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1522 kfree(ioctl);
1523 return -EFAULT;
1524 }
1525
1526 if (down_interruptible(&master->master_sem)) {
1527 kfree(ioctl);
1528 return -EINTR;
1529 }
1530
1531 if (!(sc = ec_master_get_config_const(
1532 master, ioctl->config_index))) {
1533 up(&master->master_sem);
1534 EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1535 ioctl->config_index);
1536 kfree(ioctl);
1537 return -EINVAL;
1538 }
1539
1541 sc, ioctl->flag_pos))) {
1542 up(&master->master_sem);
1543 EC_MASTER_ERR(master, "Invalid flag position!\n");
1544 kfree(ioctl);
1545 return -EINVAL;
1546 }
1547
1548 size = min((u32) strlen(flag->key), (u32) EC_MAX_FLAG_KEY_SIZE - 1);
1549 memcpy(ioctl->key, flag->key, size);
1550 ioctl->key[size] = 0x00;
1551 ioctl->value = flag->value;
1552
1553 up(&master->master_sem);
1554
1555 if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1556 kfree(ioctl);
1557 return -EFAULT;
1558 }
1559
1560 kfree(ioctl);
1561 return 0;
1562}
1563
1564/*****************************************************************************/
1565
1566#ifdef EC_EOE
1567
1573 ec_master_t *master,
1574 void *arg
1575 )
1576{
1577 ec_ioctl_eoe_handler_t data;
1578 const ec_eoe_t *eoe;
1579
1580 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1581 return -EFAULT;
1582 }
1583
1584 if (down_interruptible(&master->master_sem))
1585 return -EINTR;
1586
1587 if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1588 up(&master->master_sem);
1589 EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1590 data.eoe_index);
1591 return -EINVAL;
1592 }
1593
1594 if (eoe->slave) {
1595 data.slave_position = eoe->slave->ring_position;
1596 } else {
1597 data.slave_position = 0xffff;
1598 }
1599 snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1600 data.open = eoe->opened;
1601 data.rx_bytes = eoe->stats.tx_bytes;
1602 data.rx_rate = eoe->tx_rate;
1603 data.tx_bytes = eoe->stats.rx_bytes;
1604 data.tx_rate = eoe->tx_rate;
1605 data.tx_queued_frames = eoe->tx_queued_frames;
1606 data.tx_queue_size = eoe->tx_queue_size;
1607
1608 up(&master->master_sem);
1609
1610 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1611 return -EFAULT;
1612
1613 return 0;
1614}
1615
1616#endif
1617
1618/*****************************************************************************/
1619
1625 ec_master_t *master,
1626 void *arg,
1627 ec_ioctl_context_t *ctx
1628 )
1629{
1630 ec_master_t *m;
1631 int ret = 0;
1632
1633 m = ecrt_request_master_err(master->index);
1634 if (IS_ERR(m)) {
1635 ret = PTR_ERR(m);
1636 } else {
1637 ctx->requested = 1;
1638 }
1639
1640 return ret;
1641}
1642
1643/*****************************************************************************/
1644
1650 ec_master_t *master,
1651 void *arg,
1652 ec_ioctl_context_t *ctx
1653 )
1654{
1655 ec_domain_t *domain;
1656
1657 if (unlikely(!ctx->requested))
1658 return -EPERM;
1659
1660 domain = ecrt_master_create_domain_err(master);
1661 if (IS_ERR(domain))
1662 return PTR_ERR(domain);
1663
1664 return domain->index;
1665}
1666
1667/*****************************************************************************/
1668
1674 ec_master_t *master,
1675 void *arg,
1676 ec_ioctl_context_t *ctx
1677 )
1678{
1679 ec_ioctl_config_t data;
1680 ec_slave_config_t *sc, *entry;
1681
1682 if (unlikely(!ctx->requested))
1683 return -EPERM;
1684
1685 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1686 return -EFAULT;
1687 }
1688
1689 sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1690 data.vendor_id, data.product_code);
1691 if (IS_ERR(sc))
1692 return PTR_ERR(sc);
1693
1694 data.config_index = 0;
1695
1696 if (down_interruptible(&master->master_sem))
1697 return -EINTR;
1698
1699 list_for_each_entry(entry, &master->configs, list) {
1700 if (entry == sc)
1701 break;
1702 data.config_index++;
1703 }
1704
1705 up(&master->master_sem);
1706
1707 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1708 return -EFAULT;
1709
1710 return 0;
1711}
1712
1713/*****************************************************************************/
1714
1720 ec_master_t *master,
1721 void *arg,
1722 ec_ioctl_context_t *ctx
1723 )
1724{
1725 unsigned long config_index = (unsigned long) arg;
1726 ec_slave_config_t *sc = NULL;
1727 int ret = 0;
1728
1729 if (unlikely(!ctx->requested)) {
1730 ret = -EPERM;
1731 goto out_return;
1732 }
1733
1734 if (down_interruptible(&master->master_sem)) {
1735 ret = -EINTR;
1736 goto out_return;
1737 }
1738
1739 if (config_index != 0xFFFFFFFF) {
1740 if (!(sc = ec_master_get_config(master, config_index))) {
1741 ret = -ENOENT;
1742 goto out_up;
1743 }
1744 }
1745
1747
1748out_up:
1749 up(&master->master_sem);
1750out_return:
1751 return ret;
1752}
1753
1754/*****************************************************************************/
1755
1761 ec_master_t *master,
1762 void *arg,
1763 ec_ioctl_context_t *ctx
1764 )
1765{
1766 ec_ioctl_master_activate_t io;
1767 ec_domain_t *domain;
1768 off_t offset;
1769 int ret;
1770
1771 if (unlikely(!ctx->requested))
1772 return -EPERM;
1773
1774 io.process_data = NULL;
1775
1776 /* Get the sum of the domains' process data sizes. */
1777
1778 ctx->process_data_size = 0;
1779
1780 if (down_interruptible(&master->master_sem))
1781 return -EINTR;
1782
1783 list_for_each_entry(domain, &master->domains, list) {
1784 ctx->process_data_size += ecrt_domain_size(domain);
1785 }
1786
1787 up(&master->master_sem);
1788
1789 if (ctx->process_data_size) {
1790 ctx->process_data = vmalloc(ctx->process_data_size);
1791 if (!ctx->process_data) {
1792 ctx->process_data_size = 0;
1793 return -ENOMEM;
1794 }
1795
1796 /* Set the memory as external process data memory for the
1797 * domains.
1798 */
1799 offset = 0;
1800 list_for_each_entry(domain, &master->domains, list) {
1802 ctx->process_data + offset);
1803 offset += ecrt_domain_size(domain);
1804 }
1805
1806#ifdef EC_IOCTL_RTDM
1807 /* RTDM uses a different approach for memory-mapping, which has to be
1808 * initiated by the kernel.
1809 */
1810 ret = ec_rtdm_mmap(ctx, &io.process_data);
1811 if (ret < 0) {
1812 EC_MASTER_ERR(master, "Failed to map process data"
1813 " memory to user space (code %i).\n", ret);
1814 return ret;
1815 }
1816#endif
1817 }
1818
1819 io.process_data_size = ctx->process_data_size;
1820
1821#ifndef EC_IOCTL_RTDM
1824#endif
1825
1826 ret = ecrt_master_activate(master);
1827 if (ret < 0)
1828 return ret;
1829
1830 if (copy_to_user((void __user *) arg, &io,
1831 sizeof(ec_ioctl_master_activate_t)))
1832 return -EFAULT;
1833
1834 return 0;
1835}
1836
1837/*****************************************************************************/
1838
1844 ec_master_t *master,
1845 void *arg,
1846 ec_ioctl_context_t *ctx
1847 )
1848{
1849 if (unlikely(!ctx->requested))
1850 return -EPERM;
1851
1852 ecrt_master_deactivate(master);
1853 return 0;
1854}
1855
1856/*****************************************************************************/
1857
1863 ec_master_t *master,
1864 void *arg,
1865 ec_ioctl_context_t *ctx
1866 )
1867{
1868 size_t send_interval;
1869
1870 if (unlikely(!ctx->requested)) {
1871 return -EPERM;
1872 }
1873
1874 if (copy_from_user(&send_interval, (void __user *) arg,
1875 sizeof(send_interval))) {
1876 return -EFAULT;
1877 }
1878
1879 if (down_interruptible(&master->master_sem))
1880 return -EINTR;
1881
1882 ec_master_set_send_interval(master, send_interval);
1883
1884 up(&master->master_sem);
1885 return 0;
1886}
1887
1888/*****************************************************************************/
1889
1895 ec_master_t *master,
1896 void *arg,
1897 ec_ioctl_context_t *ctx
1898 )
1899{
1900 if (unlikely(!ctx->requested)) {
1901 return -EPERM;
1902 }
1903
1904 down( & master->io_sem );
1905 ecrt_master_send(master);
1906 up( & master->io_sem );
1907 return 0;
1908}
1909
1910/*****************************************************************************/
1911
1917 ec_master_t *master,
1918 void *arg,
1919 ec_ioctl_context_t *ctx
1920 )
1921{
1922 if (unlikely(!ctx->requested)) {
1923 return -EPERM;
1924 }
1925
1926 down( & master->io_sem );
1927 ecrt_master_receive(master);
1928 up( & master->io_sem );
1929 return 0;
1930}
1931
1932/*****************************************************************************/
1933
1939 ec_master_t *master,
1940 void *arg,
1941 ec_ioctl_context_t *ctx
1942 )
1943{
1944 ec_master_state_t data;
1945
1946 ecrt_master_state(master, &data);
1947
1948 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1949 return -EFAULT;
1950
1951 return 0;
1952}
1953
1954/*****************************************************************************/
1955
1961 ec_master_t *master,
1962 void *arg,
1963 ec_ioctl_context_t *ctx
1964 )
1965{
1966 ec_ioctl_link_state_t ioctl;
1968 int ret;
1969
1970 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
1971 return -EFAULT;
1972 }
1973
1974 ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
1975 if (ret < 0) {
1976 return ret;
1977 }
1978
1979 if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
1980 return -EFAULT;
1981 }
1982
1983 return 0;
1984}
1985
1986/*****************************************************************************/
1987
1993 ec_master_t *master,
1994 void *arg,
1995 ec_ioctl_context_t *ctx
1996 )
1997{
1998 uint64_t time;
1999
2000 if (unlikely(!ctx->requested))
2001 return -EPERM;
2002
2003 if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2004 return -EFAULT;
2005 }
2006
2007 ecrt_master_application_time(master, time);
2008 return 0;
2009}
2010
2011/*****************************************************************************/
2012
2018 ec_master_t *master,
2019 void *arg,
2020 ec_ioctl_context_t *ctx
2021 )
2022{
2023 if (unlikely(!ctx->requested)) {
2024 return -EPERM;
2025 }
2026
2027 down( & master->io_sem );
2029 up( & master->io_sem );
2030 return 0;
2031}
2032
2033/*****************************************************************************/
2034
2040 ec_master_t *master,
2041 void *arg,
2042 ec_ioctl_context_t *ctx
2043 )
2044{
2045 uint64_t time;
2046
2047 if (unlikely(!ctx->requested))
2048 return -EPERM;
2049
2050 if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2051 return -EFAULT;
2052 }
2053
2054 down( & master->io_sem );
2056 up( & master->io_sem );
2057 return 0;
2058}
2059
2060/*****************************************************************************/
2061
2067 ec_master_t *master,
2068 void *arg,
2069 ec_ioctl_context_t *ctx
2070 )
2071{
2072 if (unlikely(!ctx->requested)) {
2073 return -EPERM;
2074 }
2075
2076 down( & master->io_sem );
2078 up( & master->io_sem );
2079 return 0;
2080}
2081
2082/*****************************************************************************/
2083
2089 ec_master_t *master,
2090 void *arg,
2091 ec_ioctl_context_t *ctx
2092 )
2093{
2094 uint32_t time;
2095 int ret;
2096
2097 if (unlikely(!ctx->requested)) {
2098 return -EPERM;
2099 }
2100
2101 ret = ecrt_master_reference_clock_time(master, &time);
2102 if (ret) {
2103 return ret;
2104 }
2105
2106 if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2107 return -EFAULT;
2108 }
2109
2110 return 0;
2111}
2112
2113/*****************************************************************************/
2114
2120 ec_master_t *master,
2121 void *arg,
2122 ec_ioctl_context_t *ctx
2123 )
2124{
2125 if (unlikely(!ctx->requested)) {
2126 return -EPERM;
2127 }
2128
2129 down( & master->io_sem );
2131 up( & master->io_sem );
2132 return 0;
2133}
2134
2135/*****************************************************************************/
2136
2142 ec_master_t *master,
2143 void *arg,
2144 ec_ioctl_context_t *ctx
2145 )
2146{
2147 uint32_t time_diff;
2148
2149 if (unlikely(!ctx->requested))
2150 return -EPERM;
2151
2152 time_diff = ecrt_master_sync_monitor_process(master);
2153
2154 if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2155 return -EFAULT;
2156
2157 return 0;
2158}
2159
2160/*****************************************************************************/
2161
2167 ec_master_t *master,
2168 void *arg,
2169 ec_ioctl_context_t *ctx
2170 )
2171{
2172 down(&master->master_sem);
2173 ecrt_master_reset(master);
2174 up(&master->master_sem);
2175 return 0;
2176}
2177
2178/*****************************************************************************/
2179
2185 ec_master_t *master,
2186 void *arg,
2187 ec_ioctl_context_t *ctx
2188 )
2189{
2190 ec_ioctl_config_t data;
2192 unsigned int i;
2193 int ret = 0;
2194
2195 if (unlikely(!ctx->requested)) {
2196 ret = -EPERM;
2197 goto out_return;
2198 }
2199
2200 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2201 ret = -EFAULT;
2202 goto out_return;
2203 }
2204
2205 if (down_interruptible(&master->master_sem)) {
2206 ret = -EINTR;
2207 goto out_return;
2208 }
2209
2210 if (!(sc = ec_master_get_config(master, data.config_index))) {
2211 ret = -ENOENT;
2212 goto out_up;
2213 }
2214
2215 for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2216 if (data.syncs[i].config_this) {
2217 ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2218 data.syncs[i].watchdog_mode);
2219 if (ret) {
2220 goto out_up;
2221 }
2222 }
2223 }
2224
2225out_up:
2226 up(&master->master_sem);
2227out_return:
2228 return ret;
2229}
2230
2231/*****************************************************************************/
2232
2238 ec_master_t *master,
2239 void *arg,
2240 ec_ioctl_context_t *ctx
2241 )
2242{
2243 ec_ioctl_config_t data;
2245 int ret = 0;
2246
2247 if (unlikely(!ctx->requested)) {
2248 ret = -EPERM;
2249 goto out_return;
2250 }
2251
2252 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2253 ret = -EFAULT;
2254 goto out_return;
2255 }
2256
2257 if (down_interruptible(&master->master_sem)) {
2258 ret = -EINTR;
2259 goto out_return;
2260 }
2261
2262 if (!(sc = ec_master_get_config(master, data.config_index))) {
2263 ret = -ENOENT;
2264 goto out_up;
2265 }
2266
2268 data.watchdog_divider, data.watchdog_intervals);
2269
2270out_up:
2271 up(&master->master_sem);
2272out_return:
2273 return ret;
2274}
2275
2276/*****************************************************************************/
2277
2283 ec_master_t *master,
2284 void *arg,
2285 ec_ioctl_context_t *ctx
2286 )
2287{
2288 ec_ioctl_config_pdo_t data;
2290
2291 if (unlikely(!ctx->requested))
2292 return -EPERM;
2293
2294 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2295 return -EFAULT;
2296
2297 if (down_interruptible(&master->master_sem))
2298 return -EINTR;
2299
2300 if (!(sc = ec_master_get_config(master, data.config_index))) {
2301 up(&master->master_sem);
2302 return -ENOENT;
2303 }
2304
2305 up(&master->master_sem);
2307 return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2308}
2309
2310/*****************************************************************************/
2311
2317 ec_master_t *master,
2318 void *arg,
2319 ec_ioctl_context_t *ctx
2320 )
2321{
2322 ec_ioctl_config_pdo_t data;
2324
2325 if (unlikely(!ctx->requested))
2326 return -EPERM;
2327
2328 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2329 return -EFAULT;
2330
2331 if (down_interruptible(&master->master_sem))
2332 return -EINTR;
2333
2334 if (!(sc = ec_master_get_config(master, data.config_index))) {
2335 up(&master->master_sem);
2336 return -ENOENT;
2337 }
2338
2339 up(&master->master_sem);
2341 ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2342 return 0;
2343}
2344
2345/*****************************************************************************/
2346
2352 ec_master_t *master,
2353 void *arg,
2354 ec_ioctl_context_t *ctx
2355 )
2356{
2357 ec_ioctl_add_pdo_entry_t data;
2359
2360 if (unlikely(!ctx->requested))
2361 return -EPERM;
2362
2363 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2364 return -EFAULT;
2365
2366 if (down_interruptible(&master->master_sem))
2367 return -EINTR;
2368
2369 if (!(sc = ec_master_get_config(master, data.config_index))) {
2370 up(&master->master_sem);
2371 return -ENOENT;
2372 }
2373
2374 up(&master->master_sem);
2376 return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2377 data.entry_index, data.entry_subindex, data.entry_bit_length);
2378}
2379
2380/*****************************************************************************/
2381
2387 ec_master_t *master,
2388 void *arg,
2389 ec_ioctl_context_t *ctx
2390 )
2391{
2392 ec_ioctl_config_pdo_t data;
2394
2395 if (unlikely(!ctx->requested))
2396 return -EPERM;
2397
2398 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2399 return -EFAULT;
2400
2401 if (down_interruptible(&master->master_sem))
2402 return -EINTR;
2403
2404 if (!(sc = ec_master_get_config(master, data.config_index))) {
2405 up(&master->master_sem);
2406 return -ENOENT;
2407 }
2408
2409 up(&master->master_sem);
2412 return 0;
2413}
2414
2415/*****************************************************************************/
2416
2422 ec_master_t *master,
2423 void *arg,
2424 ec_ioctl_context_t *ctx
2425 )
2426{
2427 ec_ioctl_reg_pdo_entry_t data;
2429 ec_domain_t *domain;
2430 int ret;
2431
2432 if (unlikely(!ctx->requested))
2433 return -EPERM;
2434
2435 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2436 return -EFAULT;
2437
2438 if (down_interruptible(&master->master_sem))
2439 return -EINTR;
2440
2441 if (!(sc = ec_master_get_config(master, data.config_index))) {
2442 up(&master->master_sem);
2443 return -ENOENT;
2444 }
2445
2446 if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2447 up(&master->master_sem);
2448 return -ENOENT;
2449 }
2450
2451 up(&master->master_sem);
2453 ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2454 data.entry_subindex, domain, &data.bit_position);
2455
2456 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2457 return -EFAULT;
2458
2459 return ret;
2460}
2461
2462/*****************************************************************************/
2463
2469 ec_master_t *master,
2470 void *arg,
2471 ec_ioctl_context_t *ctx
2472 )
2473{
2474 ec_ioctl_reg_pdo_pos_t io;
2476 ec_domain_t *domain;
2477 int ret;
2478
2479 if (unlikely(!ctx->requested)) {
2480 return -EPERM;
2481 }
2482
2483 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2484 return -EFAULT;
2485 }
2486
2487 if (down_interruptible(&master->master_sem)) {
2488 return -EINTR;
2489 }
2490
2491 if (!(sc = ec_master_get_config(master, io.config_index))) {
2492 up(&master->master_sem);
2493 return -ENOENT;
2494 }
2495
2496 if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2497 up(&master->master_sem);
2498 return -ENOENT;
2499 }
2500
2501 up(&master->master_sem);
2503 ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2504 io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2505
2506 if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2507 return -EFAULT;
2508
2509 return ret;
2510}
2511
2512/*****************************************************************************/
2513
2519 ec_master_t *master,
2520 void *arg,
2521 ec_ioctl_context_t *ctx
2522 )
2523{
2524 ec_ioctl_config_t data;
2526
2527 if (unlikely(!ctx->requested))
2528 return -EPERM;
2529
2530 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2531 return -EFAULT;
2532
2533 if (down_interruptible(&master->master_sem))
2534 return -EINTR;
2535
2536 if (!(sc = ec_master_get_config(master, data.config_index))) {
2537 up(&master->master_sem);
2538 return -ENOENT;
2539 }
2540
2542 data.dc_sync[0].cycle_time,
2543 data.dc_sync[0].shift_time,
2544 data.dc_sync[1].cycle_time,
2545 data.dc_sync[1].shift_time);
2546
2547 up(&master->master_sem);
2548
2549 return 0;
2550}
2551
2552/*****************************************************************************/
2553
2559 ec_master_t *master,
2560 void *arg,
2561 ec_ioctl_context_t *ctx
2562 )
2563{
2564 ec_ioctl_sc_sdo_t data;
2566 uint8_t *sdo_data = NULL;
2567 int ret;
2568
2569 if (unlikely(!ctx->requested))
2570 return -EPERM;
2571
2572 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2573 return -EFAULT;
2574
2575 if (!data.size)
2576 return -EINVAL;
2577
2578 if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2579 return -ENOMEM;
2580 }
2581
2582 if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2583 kfree(sdo_data);
2584 return -EFAULT;
2585 }
2586
2587 if (down_interruptible(&master->master_sem)) {
2588 kfree(sdo_data);
2589 return -EINTR;
2590 }
2591
2592 if (!(sc = ec_master_get_config(master, data.config_index))) {
2593 up(&master->master_sem);
2594 kfree(sdo_data);
2595 return -ENOENT;
2596 }
2597
2598 up(&master->master_sem);
2600 if (data.complete_access) {
2602 data.index, sdo_data, data.size);
2603 } else {
2604 ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2605 data.size);
2606 }
2607 kfree(sdo_data);
2608 return ret;
2609}
2610
2611/*****************************************************************************/
2612
2618 ec_master_t *master,
2619 void *arg,
2620 ec_ioctl_context_t *ctx
2621 )
2622{
2623 ec_ioctl_sc_emerg_t io;
2625 int ret;
2626
2627 if (unlikely(!ctx->requested))
2628 return -EPERM;
2629
2630 if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2631 return -EFAULT;
2632
2633 if (down_interruptible(&master->master_sem)) {
2634 return -EINTR;
2635 }
2636
2637 if (!(sc = ec_master_get_config(master, io.config_index))) {
2638 up(&master->master_sem);
2639 return -ENOENT;
2640 }
2641
2642 ret = ecrt_slave_config_emerg_size(sc, io.size);
2643
2644 up(&master->master_sem);
2645
2646 return ret;
2647}
2648
2649/*****************************************************************************/
2650
2656 ec_master_t *master,
2657 void *arg,
2658 ec_ioctl_context_t *ctx
2659 )
2660{
2661 ec_ioctl_sc_emerg_t io;
2664 int ret;
2665
2666 if (unlikely(!ctx->requested)) {
2667 return -EPERM;
2668 }
2669
2670 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2671 return -EFAULT;
2672 }
2673
2674 /* no locking of master_sem needed, because configuration will not be
2675 * deleted in the meantime. */
2676
2677 if (!(sc = ec_master_get_config(master, io.config_index))) {
2678 return -ENOENT;
2679 }
2680
2681 ret = ecrt_slave_config_emerg_pop(sc, msg);
2682 if (ret < 0) {
2683 return ret;
2684 }
2685
2686 if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
2687 return -EFAULT;
2688 }
2689
2690 return ret;
2691}
2692
2693/*****************************************************************************/
2694
2700 ec_master_t *master,
2701 void *arg,
2702 ec_ioctl_context_t *ctx
2703 )
2704{
2705 ec_ioctl_sc_emerg_t io;
2707
2708 if (unlikely(!ctx->requested)) {
2709 return -EPERM;
2710 }
2711
2712 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2713 return -EFAULT;
2714 }
2715
2716 /* no locking of master_sem needed, because configuration will not be
2717 * deleted in the meantime. */
2718
2719 if (!(sc = ec_master_get_config(master, io.config_index))) {
2720 return -ENOENT;
2721 }
2722
2724}
2725
2726/*****************************************************************************/
2727
2733 ec_master_t *master,
2734 void *arg,
2735 ec_ioctl_context_t *ctx
2736 )
2737{
2738 ec_ioctl_sc_emerg_t io;
2740 int ret;
2741
2742 if (unlikely(!ctx->requested)) {
2743 return -EPERM;
2744 }
2745
2746 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2747 return -EFAULT;
2748 }
2749
2750 /* no locking of master_sem needed, because configuration will not be
2751 * deleted in the meantime. */
2752
2753 if (!(sc = ec_master_get_config(master, io.config_index))) {
2754 return -ENOENT;
2755 }
2756
2758 if (ret < 0) {
2759 return ret;
2760 }
2761
2762 io.overruns = ret;
2763
2764 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2765 return -EFAULT;
2766 }
2767
2768 return 0;
2769}
2770
2771/*****************************************************************************/
2772
2778 ec_master_t *master,
2779 void *arg,
2780 ec_ioctl_context_t *ctx
2781 )
2782{
2783 ec_ioctl_sdo_request_t data;
2785 ec_sdo_request_t *req;
2786
2787 if (unlikely(!ctx->requested))
2788 return -EPERM;
2789
2790 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2791 return -EFAULT;
2792 }
2793
2794 data.request_index = 0;
2795
2796 if (down_interruptible(&master->master_sem))
2797 return -EINTR;
2798
2799 sc = ec_master_get_config(master, data.config_index);
2800 if (!sc) {
2801 up(&master->master_sem);
2802 return -ENOENT;
2803 }
2804
2805 list_for_each_entry(req, &sc->sdo_requests, list) {
2806 data.request_index++;
2807 }
2808
2809 up(&master->master_sem);
2811 req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
2812 data.sdo_subindex, data.size);
2813 if (IS_ERR(req))
2814 return PTR_ERR(req);
2815
2816 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2817 return -EFAULT;
2818
2819 return 0;
2820}
2821
2822/*****************************************************************************/
2823
2829 ec_master_t *master,
2830 void *arg,
2831 ec_ioctl_context_t *ctx
2832 )
2833{
2834 ec_ioctl_reg_request_t io;
2836 ec_reg_request_t *reg;
2837
2838 if (unlikely(!ctx->requested)) {
2839 return -EPERM;
2840 }
2841
2842 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2843 return -EFAULT;
2844 }
2845
2846 io.request_index = 0;
2847
2848 if (down_interruptible(&master->master_sem)) {
2849 return -EINTR;
2850 }
2851
2852 sc = ec_master_get_config(master, io.config_index);
2853 if (!sc) {
2854 up(&master->master_sem);
2855 return -ENOENT;
2856 }
2857
2858 list_for_each_entry(reg, &sc->reg_requests, list) {
2859 io.request_index++;
2860 }
2861
2862 up(&master->master_sem);
2864 reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
2865 if (IS_ERR(reg)) {
2866 return PTR_ERR(reg);
2867 }
2868
2869 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
2870 return -EFAULT;
2871 }
2872
2873 return 0;
2874}
2875
2876/*****************************************************************************/
2877
2883 ec_master_t *master,
2884 void *arg,
2885 ec_ioctl_context_t *ctx
2886 )
2887{
2888 ec_ioctl_voe_t data;
2890 ec_voe_handler_t *voe;
2891
2892 if (unlikely(!ctx->requested))
2893 return -EPERM;
2894
2895 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2896 return -EFAULT;
2897 }
2898
2899 data.voe_index = 0;
2900
2901 if (down_interruptible(&master->master_sem))
2902 return -EINTR;
2903
2904 sc = ec_master_get_config(master, data.config_index);
2905 if (!sc) {
2906 up(&master->master_sem);
2907 return -ENOENT;
2908 }
2909
2910 list_for_each_entry(voe, &sc->voe_handlers, list) {
2911 data.voe_index++;
2912 }
2913
2914 up(&master->master_sem);
2916 voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
2917 if (IS_ERR(voe))
2918 return PTR_ERR(voe);
2919
2920 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2921 return -EFAULT;
2922
2923 return 0;
2924}
2925
2926/*****************************************************************************/
2927
2933 ec_master_t *master,
2934 void *arg,
2935 ec_ioctl_context_t *ctx
2936 )
2937{
2938 ec_ioctl_sc_state_t data;
2939 const ec_slave_config_t *sc;
2941
2942 if (unlikely(!ctx->requested))
2943 return -EPERM;
2944
2945 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2946 return -EFAULT;
2947 }
2948
2949 /* no locking of master_sem needed, because sc will not be deleted in the
2950 * meantime. */
2951
2952 if (!(sc = ec_master_get_config_const(master, data.config_index))) {
2953 return -ENOENT;
2954 }
2955
2956 ecrt_slave_config_state(sc, &state);
2957
2958 if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
2959 return -EFAULT;
2960
2961 return 0;
2962}
2963
2964/*****************************************************************************/
2965
2971 ec_master_t *master,
2972 void *arg,
2973 ec_ioctl_context_t *ctx
2974 )
2975{
2976 ec_ioctl_sc_idn_t ioctl;
2978 uint8_t *data = NULL;
2979 int ret;
2980
2981 if (unlikely(!ctx->requested))
2982 return -EPERM;
2983
2984 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
2985 return -EFAULT;
2986
2987 if (!ioctl.size)
2988 return -EINVAL;
2989
2990 if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
2991 return -ENOMEM;
2992 }
2993
2994 if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
2995 kfree(data);
2996 return -EFAULT;
2997 }
2998
2999 if (down_interruptible(&master->master_sem)) {
3000 kfree(data);
3001 return -EINTR;
3002 }
3003
3004 if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3005 up(&master->master_sem);
3006 kfree(data);
3007 return -ENOENT;
3008 }
3009
3010 up(&master->master_sem);
3013 sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3014 kfree(data);
3015 return ret;
3016}
3017
3018/*****************************************************************************/
3019
3025 ec_master_t *master,
3026 void *arg,
3027 ec_ioctl_context_t *ctx
3028 )
3029{
3030 ec_ioctl_sc_flag_t ioctl;
3032 uint8_t *key;
3033 int ret;
3034
3035 if (unlikely(!ctx->requested)) {
3036 return -EPERM;
3037 }
3038
3039 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3040 return -EFAULT;
3041 }
3042
3043 if (!ioctl.key_size) {
3044 return -EINVAL;
3045 }
3046
3047 if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3048 return -ENOMEM;
3049 }
3050
3051 if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3052 kfree(key);
3053 return -EFAULT;
3054 }
3055
3056 if (down_interruptible(&master->master_sem)) {
3057 kfree(key);
3058 return -EINTR;
3059 }
3060
3061 if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3062 up(&master->master_sem);
3063 kfree(key);
3064 return -ENOENT;
3065 }
3066
3067 up(&master->master_sem);
3069 ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3070 kfree(key);
3071 return ret;
3072}
3073
3074/*****************************************************************************/
3075
3081 ec_master_t *master,
3082 void *arg,
3083 ec_ioctl_context_t *ctx
3084 )
3085{
3086 const ec_domain_t *domain;
3087
3088 if (unlikely(!ctx->requested)) {
3089 return -EPERM;
3090 }
3091
3092 if (down_interruptible(&master->master_sem)) {
3093 return -EINTR;
3094 }
3095
3096 list_for_each_entry(domain, &master->domains, list) {
3097 if (domain->index == (unsigned long) arg) {
3098 size_t size = ecrt_domain_size(domain);
3099 up(&master->master_sem);
3100 return size;
3101 }
3102 }
3103
3104 up(&master->master_sem);
3105 return -ENOENT;
3106}
3107
3108/*****************************************************************************/
3109
3115 ec_master_t *master,
3116 void *arg,
3117 ec_ioctl_context_t *ctx
3118 )
3119{
3120 int offset = 0;
3121 const ec_domain_t *domain;
3122
3123 if (unlikely(!ctx->requested))
3124 return -EPERM;
3125
3126 if (down_interruptible(&master->master_sem)) {
3127 return -EINTR;
3128 }
3129
3130 list_for_each_entry(domain, &master->domains, list) {
3131 if (domain->index == (unsigned long) arg) {
3132 up(&master->master_sem);
3133 return offset;
3134 }
3135 offset += ecrt_domain_size(domain);
3136 }
3137
3138 up(&master->master_sem);
3139 return -ENOENT;
3140}
3141
3142/*****************************************************************************/
3143
3149 ec_master_t *master,
3150 void *arg,
3151 ec_ioctl_context_t *ctx
3152 )
3153{
3154 ec_domain_t *domain;
3155
3156 if (unlikely(!ctx->requested))
3157 return -EPERM;
3158
3159 /* no locking of master_sem needed, because domain will not be deleted in
3160 * the meantime. */
3161
3162 if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3163 return -ENOENT;
3164 }
3165
3166 ecrt_domain_process(domain);
3167 return 0;
3168}
3169
3170/*****************************************************************************/
3171
3177 ec_master_t *master,
3178 void *arg,
3179 ec_ioctl_context_t *ctx
3180 )
3181{
3182 ec_domain_t *domain;
3183
3184 if (unlikely(!ctx->requested))
3185 return -EPERM;
3186
3187 /* no locking of master_sem needed, because domain will not be deleted in
3188 * the meantime. */
3189
3190 if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3191 return -ENOENT;
3192 }
3193
3194 down( & master->io_sem );
3195 ecrt_domain_queue(domain);
3196 up( & master->io_sem );
3197 return 0;
3198}
3199
3200/*****************************************************************************/
3201
3207 ec_master_t *master,
3208 void *arg,
3209 ec_ioctl_context_t *ctx
3210 )
3211{
3212 ec_ioctl_domain_state_t data;
3213 const ec_domain_t *domain;
3214 ec_domain_state_t state;
3215
3216 if (unlikely(!ctx->requested))
3217 return -EPERM;
3218
3219 if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3220 return -EFAULT;
3221 }
3222
3223 /* no locking of master_sem needed, because domain will not be deleted in
3224 * the meantime. */
3225
3226 if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3227 return -ENOENT;
3228 }
3229
3230 ecrt_domain_state(domain, &state);
3231
3232 if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3233 return -EFAULT;
3234
3235 return 0;
3236}
3237
3238/*****************************************************************************/
3239
3245 ec_master_t *master,
3246 void *arg,
3247 ec_ioctl_context_t *ctx
3248 )
3249{
3250 ec_ioctl_sdo_request_t data;
3252 ec_sdo_request_t *req;
3253
3254 if (unlikely(!ctx->requested))
3255 return -EPERM;
3256
3257 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3258 return -EFAULT;
3259
3260 /* no locking of master_sem needed, because neither sc nor req will not be
3261 * deleted in the meantime. */
3262
3263 if (!(sc = ec_master_get_config(master, data.config_index))) {
3264 return -ENOENT;
3265 }
3266
3267 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3268 return -ENOENT;
3269 }
3270
3271 ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3272 return 0;
3273}
3274
3275/*****************************************************************************/
3276
3282 ec_master_t *master,
3283 void *arg,
3284 ec_ioctl_context_t *ctx
3285 )
3286{
3287 ec_ioctl_sdo_request_t data;
3289 ec_sdo_request_t *req;
3290
3291 if (unlikely(!ctx->requested))
3292 return -EPERM;
3293
3294 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3295 return -EFAULT;
3296
3297 /* no locking of master_sem needed, because neither sc nor req will not be
3298 * deleted in the meantime. */
3299
3300 if (!(sc = ec_master_get_config(master, data.config_index))) {
3301 return -ENOENT;
3302 }
3303
3304 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3305 return -ENOENT;
3306 }
3307
3308 ecrt_sdo_request_timeout(req, data.timeout);
3309 return 0;
3310}
3311
3312/*****************************************************************************/
3313
3319 ec_master_t *master,
3320 void *arg,
3321 ec_ioctl_context_t *ctx
3322 )
3323{
3324 ec_ioctl_sdo_request_t data;
3326 ec_sdo_request_t *req;
3327
3328 if (unlikely(!ctx->requested))
3329 return -EPERM;
3330
3331 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3332 return -EFAULT;
3333
3334 /* no locking of master_sem needed, because neither sc nor req will not be
3335 * deleted in the meantime. */
3336
3337 if (!(sc = ec_master_get_config(master, data.config_index))) {
3338 return -ENOENT;
3339 }
3340
3341 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3342 return -ENOENT;
3343 }
3344
3345 data.state = ecrt_sdo_request_state(req);
3346 if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3347 data.size = ecrt_sdo_request_data_size(req);
3348 else
3349 data.size = 0;
3350
3351 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3352 return -EFAULT;
3353
3354 return 0;
3355}
3356
3357/*****************************************************************************/
3358
3364 ec_master_t *master,
3365 void *arg,
3366 ec_ioctl_context_t *ctx
3367 )
3368{
3369 ec_ioctl_sdo_request_t data;
3371 ec_sdo_request_t *req;
3372
3373 if (unlikely(!ctx->requested))
3374 return -EPERM;
3375
3376 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3377 return -EFAULT;
3378
3379 /* no locking of master_sem needed, because neither sc nor req will not be
3380 * deleted in the meantime. */
3381
3382 if (!(sc = ec_master_get_config(master, data.config_index))) {
3383 return -ENOENT;
3384 }
3385
3386 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3387 return -ENOENT;
3388 }
3389
3391 return 0;
3392}
3393
3394/*****************************************************************************/
3395
3401 ec_master_t *master,
3402 void *arg,
3403 ec_ioctl_context_t *ctx
3404 )
3405{
3406 ec_ioctl_sdo_request_t data;
3408 ec_sdo_request_t *req;
3409 int ret;
3410
3411 if (unlikely(!ctx->requested))
3412 return -EPERM;
3413
3414 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3415 return -EFAULT;
3416
3417 if (!data.size) {
3418 EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3419 return -EINVAL;
3420 }
3421
3422 /* no locking of master_sem needed, because neither sc nor req will not be
3423 * deleted in the meantime. */
3424
3425 if (!(sc = ec_master_get_config(master, data.config_index))) {
3426 return -ENOENT;
3427 }
3428
3429 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3430 return -ENOENT;
3431 }
3432
3433 ret = ec_sdo_request_alloc(req, data.size);
3434 if (ret)
3435 return ret;
3436
3437 if (copy_from_user(req->data, (void __user *) data.data, data.size))
3438 return -EFAULT;
3439
3440 req->data_size = data.size;
3442 return 0;
3443}
3444
3445/*****************************************************************************/
3446
3452 ec_master_t *master,
3453 void *arg,
3454 ec_ioctl_context_t *ctx
3455 )
3456{
3457 ec_ioctl_sdo_request_t data;
3459 ec_sdo_request_t *req;
3460
3461 if (unlikely(!ctx->requested))
3462 return -EPERM;
3463
3464 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3465 return -EFAULT;
3466
3467 /* no locking of master_sem needed, because neither sc nor req will not be
3468 * deleted in the meantime. */
3469
3470 if (!(sc = ec_master_get_config(master, data.config_index))) {
3471 return -ENOENT;
3472 }
3473
3474 if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3475 return -ENOENT;
3476 }
3477
3478 if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3480 return -EFAULT;
3481
3482 return 0;
3483}
3484
3485/*****************************************************************************/
3486
3492 ec_master_t *master,
3493 void *arg,
3494 ec_ioctl_context_t *ctx
3495 )
3496{
3497 ec_ioctl_reg_request_t io;
3499 ec_reg_request_t *reg;
3500
3501 if (unlikely(!ctx->requested)) {
3502 return -EPERM;
3503 }
3504
3505 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3506 return -EFAULT;
3507 }
3508
3509 if (io.mem_size <= 0) {
3510 return 0;
3511 }
3512
3513 /* no locking of master_sem needed, because neither sc nor reg will not be
3514 * deleted in the meantime. */
3515
3516 if (!(sc = ec_master_get_config(master, io.config_index))) {
3517 return -ENOENT;
3518 }
3519
3520 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3521 return -ENOENT;
3522 }
3523
3524 if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3525 min(reg->mem_size, io.mem_size))) {
3526 return -EFAULT;
3527 }
3528
3529 return 0;
3530}
3531
3532/*****************************************************************************/
3533
3539 ec_master_t *master,
3540 void *arg,
3541 ec_ioctl_context_t *ctx
3542 )
3543{
3544 ec_ioctl_reg_request_t io;
3546 ec_reg_request_t *reg;
3547
3548 if (unlikely(!ctx->requested)) {
3549 return -EPERM;
3550 }
3551
3552 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3553 return -EFAULT;
3554 }
3555
3556 /* no locking of master_sem needed, because neither sc nor reg will not be
3557 * deleted in the meantime. */
3558
3559 if (!(sc = ec_master_get_config(master, io.config_index))) {
3560 return -ENOENT;
3561 }
3562
3563 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3564 return -ENOENT;
3565 }
3566
3567 io.state = ecrt_reg_request_state(reg);
3568 io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
3569
3570 if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3571 return -EFAULT;
3572 }
3573
3574 return 0;
3575}
3576
3577/*****************************************************************************/
3578
3584 ec_master_t *master,
3585 void *arg,
3586 ec_ioctl_context_t *ctx
3587 )
3588{
3589 ec_ioctl_reg_request_t io;
3591 ec_reg_request_t *reg;
3592
3593 if (unlikely(!ctx->requested)) {
3594 return -EPERM;
3595 }
3596
3597 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3598 return -EFAULT;
3599 }
3600
3601 /* no locking of master_sem needed, because neither sc nor reg will not be
3602 * deleted in the meantime. */
3603
3604 if (!(sc = ec_master_get_config(master, io.config_index))) {
3605 return -ENOENT;
3606 }
3607
3608 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3609 return -ENOENT;
3610 }
3611
3612 if (io.transfer_size > reg->mem_size) {
3613 return -EOVERFLOW;
3614 }
3615
3616 if (copy_from_user(reg->data, (void __user *) io.data,
3617 io.transfer_size)) {
3618 return -EFAULT;
3619 }
3620
3621 ecrt_reg_request_write(reg, io.address, io.transfer_size);
3622 return 0;
3623}
3624
3625/*****************************************************************************/
3626
3632 ec_master_t *master,
3633 void *arg,
3634 ec_ioctl_context_t *ctx
3635 )
3636{
3637 ec_ioctl_reg_request_t io;
3639 ec_reg_request_t *reg;
3640
3641 if (unlikely(!ctx->requested)) {
3642 return -EPERM;
3643 }
3644
3645 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3646 return -EFAULT;
3647 }
3648
3649 /* no locking of master_sem needed, because neither sc nor reg will not be
3650 * deleted in the meantime. */
3651
3652 if (!(sc = ec_master_get_config(master, io.config_index))) {
3653 return -ENOENT;
3654 }
3655
3656 if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3657 return -ENOENT;
3658 }
3659
3660 if (io.transfer_size > reg->mem_size) {
3661 return -EOVERFLOW;
3662 }
3663
3664 ecrt_reg_request_read(reg, io.address, io.transfer_size);
3665 return 0;
3666}
3667
3668/*****************************************************************************/
3669
3675 ec_master_t *master,
3676 void *arg,
3677 ec_ioctl_context_t *ctx
3678 )
3679{
3680 ec_ioctl_voe_t data;
3682 ec_voe_handler_t *voe;
3683 uint32_t vendor_id;
3684 uint16_t vendor_type;
3685
3686 if (unlikely(!ctx->requested))
3687 return -EPERM;
3688
3689 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3690 return -EFAULT;
3691
3692 if (get_user(vendor_id, data.vendor_id))
3693 return -EFAULT;
3694
3695 if (get_user(vendor_type, data.vendor_type))
3696 return -EFAULT;
3697
3698 /* no locking of master_sem needed, because neither sc nor voe will not be
3699 * deleted in the meantime. */
3700
3701 if (!(sc = ec_master_get_config(master, data.config_index))) {
3702 return -ENOENT;
3703 }
3704
3705 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3706 return -ENOENT;
3707 }
3708
3709 ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
3710 return 0;
3711}
3712
3713/*****************************************************************************/
3714
3720 ec_master_t *master,
3721 void *arg,
3722 ec_ioctl_context_t *ctx
3723 )
3724{
3725 ec_ioctl_voe_t data;
3727 ec_voe_handler_t *voe;
3728 uint32_t vendor_id;
3729 uint16_t vendor_type;
3730
3731 if (unlikely(!ctx->requested))
3732 return -EPERM;
3733
3734 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3735 return -EFAULT;
3736
3737 /* no locking of master_sem needed, because neither sc nor voe will not be
3738 * deleted in the meantime. */
3739
3740 if (!(sc = ec_master_get_config(master, data.config_index))) {
3741 return -ENOENT;
3742 }
3743
3744 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3745 return -ENOENT;
3746 }
3747
3748 ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
3749
3750 if (likely(data.vendor_id))
3751 if (put_user(vendor_id, data.vendor_id))
3752 return -EFAULT;
3753
3754 if (likely(data.vendor_type))
3755 if (put_user(vendor_type, data.vendor_type))
3756 return -EFAULT;
3757
3758 return 0;
3759}
3760
3761/*****************************************************************************/
3762
3768 ec_master_t *master,
3769 void *arg,
3770 ec_ioctl_context_t *ctx
3771 )
3772{
3773 ec_ioctl_voe_t data;
3775 ec_voe_handler_t *voe;
3776
3777 if (unlikely(!ctx->requested))
3778 return -EPERM;
3779
3780 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3781 return -EFAULT;
3782
3783 /* no locking of master_sem needed, because neither sc nor voe will not be
3784 * deleted in the meantime. */
3785
3786 if (!(sc = ec_master_get_config(master, data.config_index))) {
3787 return -ENOENT;
3788 }
3789
3790 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3791 return -ENOENT;
3792 }
3793
3795 return 0;
3796}
3797
3798/*****************************************************************************/
3799
3805 ec_master_t *master,
3806 void *arg,
3807 ec_ioctl_context_t *ctx
3808 )
3809{
3810 ec_ioctl_voe_t data;
3812 ec_voe_handler_t *voe;
3813
3814 if (unlikely(!ctx->requested))
3815 return -EPERM;
3816
3817 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3818 return -EFAULT;
3819
3820 /* no locking of master_sem needed, because neither sc nor voe will not be
3821 * deleted in the meantime. */
3822
3823 if (!(sc = ec_master_get_config(master, data.config_index))) {
3824 return -ENOENT;
3825 }
3826
3827 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3828 return -ENOENT;
3829 }
3830
3832 return 0;
3833}
3834
3835/*****************************************************************************/
3836
3842 ec_master_t *master,
3843 void *arg,
3844 ec_ioctl_context_t *ctx
3845 )
3846{
3847 ec_ioctl_voe_t data;
3849 ec_voe_handler_t *voe;
3850
3851 if (unlikely(!ctx->requested))
3852 return -EPERM;
3853
3854 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3855 return -EFAULT;
3856
3857 /* no locking of master_sem needed, because neither sc nor voe will not be
3858 * deleted in the meantime. */
3859
3860 if (!(sc = ec_master_get_config(master, data.config_index))) {
3861 return -ENOENT;
3862 }
3863
3864 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3865 return -ENOENT;
3866 }
3867
3868 if (data.size) {
3869 if (data.size > ec_voe_handler_mem_size(voe))
3870 return -EOVERFLOW;
3871
3872 if (copy_from_user(ecrt_voe_handler_data(voe),
3873 (void __user *) data.data, data.size))
3874 return -EFAULT;
3875 }
3876
3877 ecrt_voe_handler_write(voe, data.size);
3878 return 0;
3879}
3880
3881/*****************************************************************************/
3882
3888 ec_master_t *master,
3889 void *arg,
3890 ec_ioctl_context_t *ctx
3891 )
3892{
3893 ec_ioctl_voe_t data;
3895 ec_voe_handler_t *voe;
3896
3897 if (unlikely(!ctx->requested))
3898 return -EPERM;
3899
3900 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3901 return -EFAULT;
3902
3903 /* no locking of master_sem needed, because neither sc nor voe will not be
3904 * deleted in the meantime. */
3905
3906 if (!(sc = ec_master_get_config(master, data.config_index))) {
3907 return -ENOENT;
3908 }
3909
3910 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3911 return -ENOENT;
3912 }
3913
3914 down( & master->io_sem );
3915 data.state = ecrt_voe_handler_execute(voe);
3916 up( & master->io_sem );
3917 if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
3918 data.size = ecrt_voe_handler_data_size(voe);
3919 else
3920 data.size = 0;
3921
3922 if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3923 return -EFAULT;
3924
3925 return 0;
3926}
3927
3928/*****************************************************************************/
3929
3935 ec_master_t *master,
3936 void *arg,
3937 ec_ioctl_context_t *ctx
3938 )
3939{
3940 ec_ioctl_voe_t data;
3942 ec_voe_handler_t *voe;
3943
3944 if (unlikely(!ctx->requested))
3945 return -EPERM;
3946
3947 if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3948 return -EFAULT;
3949
3950 /* no locking of master_sem needed, because neither sc nor voe will not be
3951 * deleted in the meantime. */
3952
3953 if (!(sc = ec_master_get_config(master, data.config_index))) {
3954 return -ENOENT;
3955 }
3956
3957 if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
3958 return -ENOENT;
3959 }
3960
3961 if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
3963 return -EFAULT;
3964
3965 return 0;
3966}
3967
3968/*****************************************************************************/
3969
3975 ec_master_t *master,
3976 void *arg
3977 )
3978{
3979 ec_ioctl_slave_foe_t io;
3980 ec_foe_request_t request;
3981 ec_slave_t *slave;
3982 int ret;
3983
3984 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3985 return -EFAULT;
3986 }
3987
3988 ec_foe_request_init(&request, io.file_name);
3989 ret = ec_foe_request_alloc(&request, 10000); // FIXME
3990 if (ret) {
3991 ec_foe_request_clear(&request);
3992 return ret;
3993 }
3994
3995 ec_foe_request_read(&request);
3996
3997 if (down_interruptible(&master->master_sem)) {
3998 ec_foe_request_clear(&request);
3999 return -EINTR;
4000 }
4001
4002 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4003 up(&master->master_sem);
4004 ec_foe_request_clear(&request);
4005 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4006 io.slave_position);
4007 return -EINVAL;
4008 }
4009
4010 EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
4011
4012 // schedule request.
4013 list_add_tail(&request.list, &slave->foe_requests);
4014
4015 up(&master->master_sem);
4016
4017 // wait for processing through FSM
4018 if (wait_event_interruptible(master->request_queue,
4019 request.state != EC_INT_REQUEST_QUEUED)) {
4020 // interrupted by signal
4021 down(&master->master_sem);
4022 if (request.state == EC_INT_REQUEST_QUEUED) {
4023 list_del(&request.list);
4024 up(&master->master_sem);
4025 ec_foe_request_clear(&request);
4026 return -EINTR;
4027 }
4028 // request already processing: interrupt not possible.
4029 up(&master->master_sem);
4030 }
4031
4032 // wait until master FSM has finished processing
4033 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4034
4035 io.result = request.result;
4036 io.error_code = request.error_code;
4037
4038 if (request.state != EC_INT_REQUEST_SUCCESS) {
4039 io.data_size = 0;
4040 ret = -EIO;
4041 } else {
4042 if (request.data_size > io.buffer_size) {
4043 EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4044 ec_foe_request_clear(&request);
4045 return -EOVERFLOW;
4046 }
4047 io.data_size = request.data_size;
4048 if (copy_to_user((void __user *) io.buffer,
4049 request.buffer, io.data_size)) {
4050 ec_foe_request_clear(&request);
4051 return -EFAULT;
4052 }
4053 ret = 0;
4054 }
4055
4056 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4057 ret = -EFAULT;
4058 }
4059
4060 ec_foe_request_clear(&request);
4061 return ret;
4062}
4063
4064/*****************************************************************************/
4065
4071 ec_master_t *master,
4072 void *arg
4073 )
4074{
4075 ec_ioctl_slave_foe_t io;
4076 ec_foe_request_t request;
4077 ec_slave_t *slave;
4078 int ret;
4079
4080 if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4081 return -EFAULT;
4082 }
4083
4084 ec_foe_request_init(&request, io.file_name);
4085
4086 ret = ec_foe_request_alloc(&request, io.buffer_size);
4087 if (ret) {
4088 ec_foe_request_clear(&request);
4089 return ret;
4090 }
4091
4092 if (copy_from_user(request.buffer,
4093 (void __user *) io.buffer, io.buffer_size)) {
4094 ec_foe_request_clear(&request);
4095 return -EFAULT;
4096 }
4097
4098 request.data_size = io.buffer_size;
4099 ec_foe_request_write(&request);
4100
4101 if (down_interruptible(&master->master_sem)) {
4102 ec_foe_request_clear(&request);
4103 return -EINTR;
4104 }
4105
4106 if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4107 up(&master->master_sem);
4108 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4109 io.slave_position);
4110 ec_foe_request_clear(&request);
4111 return -EINVAL;
4112 }
4113
4114 EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4115
4116 // schedule FoE write request.
4117 list_add_tail(&request.list, &slave->foe_requests);
4118
4119 up(&master->master_sem);
4120
4121 // wait for processing through FSM
4122 if (wait_event_interruptible(master->request_queue,
4123 request.state != EC_INT_REQUEST_QUEUED)) {
4124 // interrupted by signal
4125 down(&master->master_sem);
4126 if (request.state == EC_INT_REQUEST_QUEUED) {
4127 // abort request
4128 list_del(&request.list);
4129 up(&master->master_sem);
4130 ec_foe_request_clear(&request);
4131 return -EINTR;
4132 }
4133 up(&master->master_sem);
4134 }
4135
4136 // wait until master FSM has finished processing
4137 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4138
4139 io.result = request.result;
4140 io.error_code = request.error_code;
4141
4142 ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4143
4144 if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4145 ret = -EFAULT;
4146 }
4147
4148 ec_foe_request_clear(&request);
4149 return ret;
4150}
4151
4152/*****************************************************************************/
4153
4159 ec_master_t *master,
4160 void *arg
4161 )
4162{
4163 ec_ioctl_slave_soe_read_t ioctl;
4164 u8 *data;
4165 int retval;
4166
4167 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4168 return -EFAULT;
4169 }
4170
4171 data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4172 if (!data) {
4173 EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4174 ioctl.mem_size);
4175 return -ENOMEM;
4176 }
4177
4178 retval = ecrt_master_read_idn(master, ioctl.slave_position,
4179 ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4180 &ioctl.error_code);
4181 if (retval) {
4182 kfree(data);
4183 return retval;
4184 }
4185
4186 if (copy_to_user((void __user *) ioctl.data,
4187 data, ioctl.data_size)) {
4188 kfree(data);
4189 return -EFAULT;
4190 }
4191 kfree(data);
4192
4193 if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4194 retval = -EFAULT;
4195 }
4196
4197 EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4198 return retval;
4199}
4200
4201/*****************************************************************************/
4202
4208 ec_master_t *master,
4209 void *arg
4210 )
4211{
4212 ec_ioctl_slave_soe_write_t ioctl;
4213 u8 *data;
4214 int retval;
4215
4216 if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4217 return -EFAULT;
4218 }
4219
4220 data = kmalloc(ioctl.data_size, GFP_KERNEL);
4221 if (!data) {
4222 EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4223 ioctl.data_size);
4224 return -ENOMEM;
4225 }
4226 if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4227 kfree(data);
4228 return -EFAULT;
4229 }
4230
4231 retval = ecrt_master_write_idn(master, ioctl.slave_position,
4232 ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4233 &ioctl.error_code);
4234 kfree(data);
4235 if (retval) {
4236 return retval;
4237 }
4238
4239 if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4240 retval = -EFAULT;
4241 }
4242
4243 EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4244 return retval;
4245}
4246
4247/*****************************************************************************/
4248
4251#ifdef EC_IOCTL_RTDM
4252#define EC_IOCTL ec_ioctl_rtdm
4253#else
4254#define EC_IOCTL ec_ioctl
4255#endif
4256
4262 ec_master_t *master,
4263 ec_ioctl_context_t *ctx,
4264 unsigned int cmd,
4265 void *arg
4266 )
4267{
4268#if DEBUG_LATENCY
4269 cycles_t a = get_cycles(), b;
4270 unsigned int t;
4271#endif
4272 int ret;
4273
4274 switch (cmd) {
4275 case EC_IOCTL_MODULE:
4276 ret = ec_ioctl_module(arg);
4277 break;
4278 case EC_IOCTL_MASTER:
4279 ret = ec_ioctl_master(master, arg);
4280 break;
4281 case EC_IOCTL_SLAVE:
4282 ret = ec_ioctl_slave(master, arg);
4283 break;
4284 case EC_IOCTL_SLAVE_SYNC:
4285 ret = ec_ioctl_slave_sync(master, arg);
4286 break;
4287 case EC_IOCTL_SLAVE_SYNC_PDO:
4288 ret = ec_ioctl_slave_sync_pdo(master, arg);
4289 break;
4290 case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
4291 ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
4292 break;
4293 case EC_IOCTL_DOMAIN:
4294 ret = ec_ioctl_domain(master, arg);
4295 break;
4296 case EC_IOCTL_DOMAIN_FMMU:
4297 ret = ec_ioctl_domain_fmmu(master, arg);
4298 break;
4299 case EC_IOCTL_DOMAIN_DATA:
4300 ret = ec_ioctl_domain_data(master, arg);
4301 break;
4302 case EC_IOCTL_MASTER_DEBUG:
4303 if (!ctx->writable) {
4304 ret = -EPERM;
4305 break;
4306 }
4307 ret = ec_ioctl_master_debug(master, arg);
4308 break;
4309 case EC_IOCTL_MASTER_RESCAN:
4310 if (!ctx->writable) {
4311 ret = -EPERM;
4312 break;
4313 }
4314 ret = ec_ioctl_master_rescan(master, arg);
4315 break;
4316 case EC_IOCTL_SLAVE_STATE:
4317 if (!ctx->writable) {
4318 ret = -EPERM;
4319 break;
4320 }
4321 ret = ec_ioctl_slave_state(master, arg);
4322 break;
4323 case EC_IOCTL_SLAVE_SDO:
4324 ret = ec_ioctl_slave_sdo(master, arg);
4325 break;
4326 case EC_IOCTL_SLAVE_SDO_ENTRY:
4327 ret = ec_ioctl_slave_sdo_entry(master, arg);
4328 break;
4329 case EC_IOCTL_SLAVE_SDO_UPLOAD:
4330 ret = ec_ioctl_slave_sdo_upload(master, arg);
4331 break;
4332 case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
4333 if (!ctx->writable) {
4334 ret = -EPERM;
4335 break;
4336 }
4337 ret = ec_ioctl_slave_sdo_download(master, arg);
4338 break;
4339 case EC_IOCTL_SLAVE_SII_READ:
4340 ret = ec_ioctl_slave_sii_read(master, arg);
4341 break;
4342 case EC_IOCTL_SLAVE_SII_WRITE:
4343 if (!ctx->writable) {
4344 ret = -EPERM;
4345 break;
4346 }
4347 ret = ec_ioctl_slave_sii_write(master, arg);
4348 break;
4349 case EC_IOCTL_SLAVE_REG_READ:
4350 ret = ec_ioctl_slave_reg_read(master, arg);
4351 break;
4352 case EC_IOCTL_SLAVE_REG_WRITE:
4353 if (!ctx->writable) {
4354 ret = -EPERM;
4355 break;
4356 }
4357 ret = ec_ioctl_slave_reg_write(master, arg);
4358 break;
4359 case EC_IOCTL_SLAVE_FOE_READ:
4360 ret = ec_ioctl_slave_foe_read(master, arg);
4361 break;
4362 case EC_IOCTL_SLAVE_FOE_WRITE:
4363 if (!ctx->writable) {
4364 ret = -EPERM;
4365 break;
4366 }
4367 ret = ec_ioctl_slave_foe_write(master, arg);
4368 break;
4369 case EC_IOCTL_SLAVE_SOE_READ:
4370 ret = ec_ioctl_slave_soe_read(master, arg);
4371 break;
4372 case EC_IOCTL_SLAVE_SOE_WRITE:
4373 if (!ctx->writable) {
4374 ret = -EPERM;
4375 break;
4376 }
4377 ret = ec_ioctl_slave_soe_write(master, arg);
4378 break;
4379 case EC_IOCTL_CONFIG:
4380 ret = ec_ioctl_config(master, arg);
4381 break;
4382 case EC_IOCTL_CONFIG_PDO:
4383 ret = ec_ioctl_config_pdo(master, arg);
4384 break;
4385 case EC_IOCTL_CONFIG_PDO_ENTRY:
4386 ret = ec_ioctl_config_pdo_entry(master, arg);
4387 break;
4388 case EC_IOCTL_CONFIG_SDO:
4389 ret = ec_ioctl_config_sdo(master, arg);
4390 break;
4391 case EC_IOCTL_CONFIG_IDN:
4392 ret = ec_ioctl_config_idn(master, arg);
4393 break;
4394 case EC_IOCTL_CONFIG_FLAG:
4395 ret = ec_ioctl_config_flag(master, arg);
4396 break;
4397#ifdef EC_EOE
4398 case EC_IOCTL_EOE_HANDLER:
4399 ret = ec_ioctl_eoe_handler(master, arg);
4400 break;
4401#endif
4402 case EC_IOCTL_REQUEST:
4403 if (!ctx->writable) {
4404 ret = -EPERM;
4405 break;
4406 }
4407 ret = ec_ioctl_request(master, arg, ctx);
4408 break;
4409 case EC_IOCTL_CREATE_DOMAIN:
4410 if (!ctx->writable) {
4411 ret = -EPERM;
4412 break;
4413 }
4414 ret = ec_ioctl_create_domain(master, arg, ctx);
4415 break;
4416 case EC_IOCTL_CREATE_SLAVE_CONFIG:
4417 if (!ctx->writable) {
4418 ret = -EPERM;
4419 break;
4420 }
4421 ret = ec_ioctl_create_slave_config(master, arg, ctx);
4422 break;
4423 case EC_IOCTL_SELECT_REF_CLOCK:
4424 if (!ctx->writable) {
4425 ret = -EPERM;
4426 break;
4427 }
4428 ret = ec_ioctl_select_ref_clock(master, arg, ctx);
4429 break;
4430 case EC_IOCTL_ACTIVATE:
4431 if (!ctx->writable) {
4432 ret = -EPERM;
4433 break;
4434 }
4435 ret = ec_ioctl_activate(master, arg, ctx);
4436 break;
4437 case EC_IOCTL_DEACTIVATE:
4438 if (!ctx->writable) {
4439 ret = -EPERM;
4440 break;
4441 }
4442 ret = ec_ioctl_deactivate(master, arg, ctx);
4443 break;
4444 case EC_IOCTL_SEND:
4445 if (!ctx->writable) {
4446 ret = -EPERM;
4447 break;
4448 }
4449 ret = ec_ioctl_send(master, arg, ctx);
4450 break;
4451 case EC_IOCTL_RECEIVE:
4452 if (!ctx->writable) {
4453 ret = -EPERM;
4454 break;
4455 }
4456 ret = ec_ioctl_receive(master, arg, ctx);
4457 break;
4458 case EC_IOCTL_MASTER_STATE:
4459 ret = ec_ioctl_master_state(master, arg, ctx);
4460 break;
4461 case EC_IOCTL_MASTER_LINK_STATE:
4462 ret = ec_ioctl_master_link_state(master, arg, ctx);
4463 break;
4464 case EC_IOCTL_APP_TIME:
4465 if (!ctx->writable) {
4466 ret = -EPERM;
4467 break;
4468 }
4469 ret = ec_ioctl_app_time(master, arg, ctx);
4470 break;
4471 case EC_IOCTL_SYNC_REF:
4472 if (!ctx->writable) {
4473 ret = -EPERM;
4474 break;
4475 }
4476 ret = ec_ioctl_sync_ref(master, arg, ctx);
4477 break;
4478 case EC_IOCTL_SYNC_REF_TO:
4479 if (!ctx->writable) {
4480 ret = -EPERM;
4481 break;
4482 }
4483 ret = ec_ioctl_sync_ref_to(master, arg, ctx);
4484 break;
4485 case EC_IOCTL_SYNC_SLAVES:
4486 if (!ctx->writable) {
4487 ret = -EPERM;
4488 break;
4489 }
4490 ret = ec_ioctl_sync_slaves(master, arg, ctx);
4491 break;
4492 case EC_IOCTL_REF_CLOCK_TIME:
4493 if (!ctx->writable) {
4494 ret = -EPERM;
4495 break;
4496 }
4497 ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4498 break;
4499 case EC_IOCTL_SYNC_MON_QUEUE:
4500 if (!ctx->writable) {
4501 ret = -EPERM;
4502 break;
4503 }
4504 ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4505 break;
4506 case EC_IOCTL_SYNC_MON_PROCESS:
4507 if (!ctx->writable) {
4508 ret = -EPERM;
4509 break;
4510 }
4511 ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4512 break;
4513 case EC_IOCTL_RESET:
4514 if (!ctx->writable) {
4515 ret = -EPERM;
4516 break;
4517 }
4518 ret = ec_ioctl_reset(master, arg, ctx);
4519 break;
4520 case EC_IOCTL_SC_SYNC:
4521 if (!ctx->writable) {
4522 ret = -EPERM;
4523 break;
4524 }
4525 ret = ec_ioctl_sc_sync(master, arg, ctx);
4526 break;
4527 case EC_IOCTL_SC_WATCHDOG:
4528 if (!ctx->writable) {
4529 ret = -EPERM;
4530 break;
4531 }
4532 ret = ec_ioctl_sc_watchdog(master, arg, ctx);
4533 break;
4534 case EC_IOCTL_SC_ADD_PDO:
4535 if (!ctx->writable) {
4536 ret = -EPERM;
4537 break;
4538 }
4539 ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
4540 break;
4541 case EC_IOCTL_SC_CLEAR_PDOS:
4542 if (!ctx->writable) {
4543 ret = -EPERM;
4544 break;
4545 }
4546 ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
4547 break;
4548 case EC_IOCTL_SC_ADD_ENTRY:
4549 if (!ctx->writable) {
4550 ret = -EPERM;
4551 break;
4552 }
4553 ret = ec_ioctl_sc_add_entry(master, arg, ctx);
4554 break;
4555 case EC_IOCTL_SC_CLEAR_ENTRIES:
4556 if (!ctx->writable) {
4557 ret = -EPERM;
4558 break;
4559 }
4560 ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
4561 break;
4562 case EC_IOCTL_SC_REG_PDO_ENTRY:
4563 if (!ctx->writable) {
4564 ret = -EPERM;
4565 break;
4566 }
4567 ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
4568 break;
4569 case EC_IOCTL_SC_REG_PDO_POS:
4570 if (!ctx->writable) {
4571 ret = -EPERM;
4572 break;
4573 }
4574 ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
4575 break;
4576 case EC_IOCTL_SC_DC:
4577 if (!ctx->writable) {
4578 ret = -EPERM;
4579 break;
4580 }
4581 ret = ec_ioctl_sc_dc(master, arg, ctx);
4582 break;
4583 case EC_IOCTL_SC_SDO:
4584 if (!ctx->writable) {
4585 ret = -EPERM;
4586 break;
4587 }
4588 ret = ec_ioctl_sc_sdo(master, arg, ctx);
4589 break;
4590 case EC_IOCTL_SC_EMERG_SIZE:
4591 if (!ctx->writable) {
4592 ret = -EPERM;
4593 break;
4594 }
4595 ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
4596 break;
4597 case EC_IOCTL_SC_EMERG_POP:
4598 if (!ctx->writable) {
4599 ret = -EPERM;
4600 break;
4601 }
4602 ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
4603 break;
4604 case EC_IOCTL_SC_EMERG_CLEAR:
4605 if (!ctx->writable) {
4606 ret = -EPERM;
4607 break;
4608 }
4609 ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
4610 break;
4611 case EC_IOCTL_SC_EMERG_OVERRUNS:
4612 ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
4613 break;
4614 case EC_IOCTL_SC_SDO_REQUEST:
4615 if (!ctx->writable) {
4616 ret = -EPERM;
4617 break;
4618 }
4619 ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
4620 break;
4621 case EC_IOCTL_SC_REG_REQUEST:
4622 if (!ctx->writable) {
4623 ret = -EPERM;
4624 break;
4625 }
4626 ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
4627 break;
4628 case EC_IOCTL_SC_VOE:
4629 if (!ctx->writable) {
4630 ret = -EPERM;
4631 break;
4632 }
4633 ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
4634 break;
4635 case EC_IOCTL_SC_STATE:
4636 ret = ec_ioctl_sc_state(master, arg, ctx);
4637 break;
4638 case EC_IOCTL_SC_IDN:
4639 if (!ctx->writable) {
4640 ret = -EPERM;
4641 break;
4642 }
4643 ret = ec_ioctl_sc_idn(master, arg, ctx);
4644 break;
4645 case EC_IOCTL_SC_FLAG:
4646 if (!ctx->writable) {
4647 ret = -EPERM;
4648 break;
4649 }
4650 ret = ec_ioctl_sc_flag(master, arg, ctx);
4651 break;
4652 case EC_IOCTL_DOMAIN_SIZE:
4653 ret = ec_ioctl_domain_size(master, arg, ctx);
4654 break;
4655 case EC_IOCTL_DOMAIN_OFFSET:
4656 ret = ec_ioctl_domain_offset(master, arg, ctx);
4657 break;
4658 case EC_IOCTL_DOMAIN_PROCESS:
4659 if (!ctx->writable) {
4660 ret = -EPERM;
4661 break;
4662 }
4663 ret = ec_ioctl_domain_process(master, arg, ctx);
4664 break;
4665 case EC_IOCTL_DOMAIN_QUEUE:
4666 if (!ctx->writable) {
4667 ret = -EPERM;
4668 break;
4669 }
4670 ret = ec_ioctl_domain_queue(master, arg, ctx);
4671 break;
4672 case EC_IOCTL_DOMAIN_STATE:
4673 ret = ec_ioctl_domain_state(master, arg, ctx);
4674 break;
4675 case EC_IOCTL_SDO_REQUEST_INDEX:
4676 if (!ctx->writable) {
4677 ret = -EPERM;
4678 break;
4679 }
4680 ret = ec_ioctl_sdo_request_index(master, arg, ctx);
4681 break;
4682 case EC_IOCTL_SDO_REQUEST_TIMEOUT:
4683 if (!ctx->writable) {
4684 ret = -EPERM;
4685 break;
4686 }
4687 ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
4688 break;
4689 case EC_IOCTL_SDO_REQUEST_STATE:
4690 ret = ec_ioctl_sdo_request_state(master, arg, ctx);
4691 break;
4692 case EC_IOCTL_SDO_REQUEST_READ:
4693 if (!ctx->writable) {
4694 ret = -EPERM;
4695 break;
4696 }
4697 ret = ec_ioctl_sdo_request_read(master, arg, ctx);
4698 break;
4699 case EC_IOCTL_SDO_REQUEST_WRITE:
4700 if (!ctx->writable) {
4701 ret = -EPERM;
4702 break;
4703 }
4704 ret = ec_ioctl_sdo_request_write(master, arg, ctx);
4705 break;
4706 case EC_IOCTL_SDO_REQUEST_DATA:
4707 ret = ec_ioctl_sdo_request_data(master, arg, ctx);
4708 break;
4709 case EC_IOCTL_REG_REQUEST_DATA:
4710 ret = ec_ioctl_reg_request_data(master, arg, ctx);
4711 break;
4712 case EC_IOCTL_REG_REQUEST_STATE:
4713 ret = ec_ioctl_reg_request_state(master, arg, ctx);
4714 break;
4715 case EC_IOCTL_REG_REQUEST_WRITE:
4716 if (!ctx->writable) {
4717 ret = -EPERM;
4718 break;
4719 }
4720 ret = ec_ioctl_reg_request_write(master, arg, ctx);
4721 break;
4722 case EC_IOCTL_REG_REQUEST_READ:
4723 if (!ctx->writable) {
4724 ret = -EPERM;
4725 break;
4726 }
4727 ret = ec_ioctl_reg_request_read(master, arg, ctx);
4728 break;
4729 case EC_IOCTL_VOE_SEND_HEADER:
4730 if (!ctx->writable) {
4731 ret = -EPERM;
4732 break;
4733 }
4734 ret = ec_ioctl_voe_send_header(master, arg, ctx);
4735 break;
4736 case EC_IOCTL_VOE_REC_HEADER:
4737 ret = ec_ioctl_voe_rec_header(master, arg, ctx);
4738 break;
4739 case EC_IOCTL_VOE_READ:
4740 if (!ctx->writable) {
4741 ret = -EPERM;
4742 break;
4743 }
4744 ret = ec_ioctl_voe_read(master, arg, ctx);
4745 break;
4746 case EC_IOCTL_VOE_READ_NOSYNC:
4747 if (!ctx->writable) {
4748 ret = -EPERM;
4749 break;
4750 }
4751 ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
4752 break;
4753 case EC_IOCTL_VOE_WRITE:
4754 if (!ctx->writable) {
4755 ret = -EPERM;
4756 break;
4757 }
4758 ret = ec_ioctl_voe_write(master, arg, ctx);
4759 break;
4760 case EC_IOCTL_VOE_EXEC:
4761 if (!ctx->writable) {
4762 ret = -EPERM;
4763 break;
4764 }
4765 ret = ec_ioctl_voe_exec(master, arg, ctx);
4766 break;
4767 case EC_IOCTL_VOE_DATA:
4768 ret = ec_ioctl_voe_data(master, arg, ctx);
4769 break;
4770 case EC_IOCTL_SET_SEND_INTERVAL:
4771 if (!ctx->writable) {
4772 ret = -EPERM;
4773 break;
4774 }
4775 ret = ec_ioctl_set_send_interval(master, arg, ctx);
4776 break;
4777 default:
4778 ret = -ENOTTY;
4779 break;
4780 }
4781
4782#if DEBUG_LATENCY
4783 b = get_cycles();
4784 t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
4785 if (t > 50) {
4786 EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
4787 _IOC_NR(cmd), t);
4788 }
4789#endif
4790
4791 return ret;
4792}
4793
4794/*****************************************************************************/
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:211
#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:541
@ 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:2957
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:3121
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:3038
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:3281
#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:3197
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:899
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: ioctl.c:1649
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:2184
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: ioctl.c:1199
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:2932
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: ioctl.c:4158
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: ioctl.c:1572
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:3244
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:4070
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:2421
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:2386
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3176
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: ioctl.c:470
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:3974
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave's registers.
Definition: ioctl.c:1114
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:2316
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:2066
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:1843
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: ioctl.c:567
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:1624
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:3363
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: ioctl.c:725
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:3887
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:2655
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: ioctl.c:2166
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: ioctl.c:1862
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:4207
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:1938
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: ioctl.c:1894
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:2237
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: ioctl.c:515
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: ioctl.c:612
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: ioctl.c:805
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: ioctl.c:1379
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:2828
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:3318
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: ioctl.c:2970
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2558
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: ioctl.c:202
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:3080
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:3934
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:3674
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:2039
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:3767
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: ioctl.c:1258
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: ioctl.c:1916
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:2017
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:1673
#define EC_IOCTL
ioctl() function to use.
Definition: ioctl.c:4254
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: ioctl.c:3148
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:2351
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:3841
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:3400
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: ioctl.c:342
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:2282
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave's registers.
Definition: ioctl.c:1035
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:2141
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:3451
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: ioctl.c:1314
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:3206
static ATTRIBUTES int ec_ioctl_config_flag(ec_master_t *master, void *arg)
Get slave configuration feature flag information.
Definition: ioctl.c:1507
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:2617
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:2777
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:3583
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:3719
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:1992
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:3538
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: ioctl.c:851
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: ioctl.c:626
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave's SII.
Definition: ioctl.c:947
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:2088
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:2699
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:1960
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: ioctl.c:641
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: ioctl.c:1443
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:2882
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:3281
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:3024
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:1719
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:3114
#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:2119
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:2732
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: ioctl.c:289
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:2518
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:3491
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:2468
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:401
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1760
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: ioctl.c:676
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:3631
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:3804
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
struct semaphore io_sem
Semaphore used in IDLE phase.
Definition: master.h:296
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
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.