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