IgH EtherCAT Master  1.6.0-rc1
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 
62 #ifdef EC_IOCTL_RTDM
63 #define ec_ioctl_lock_down_interruptible(p) 0
64 #define ec_ioctl_lock_up(p) do {} while (0)
65 #else
66 #define ec_ioctl_lock_down_interruptible(p) ec_lock_down_interruptible(p)
67 #define ec_ioctl_lock_up(p) ec_lock_up(p)
68 #endif
69 
70 /*****************************************************************************/
71 
74 static void ec_ioctl_strcpy(
75  char *target,
76  const char *source
77  )
78 {
79  if (source) {
80  strncpy(target, source, EC_IOCTL_STRING_SIZE);
81  target[EC_IOCTL_STRING_SIZE - 1] = 0;
82  } else {
83  target[0] = 0;
84  }
85 }
86 
87 /*****************************************************************************/
88 
94  void *arg
95  )
96 {
97  ec_ioctl_module_t data;
98 
99  data.ioctl_version_magic = EC_IOCTL_VERSION_MAGIC;
100  data.master_count = ec_master_count();
101 
102  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
103  return -EFAULT;
104 
105  return 0;
106 }
107 
108 /*****************************************************************************/
109 
116  void *arg
117  )
118 {
119  ec_ioctl_master_t io;
120  unsigned int dev_idx, j;
121 
122  if (ec_lock_down_interruptible(&master->master_sem)) {
123  return -EINTR;
124  }
125 
126  io.slave_count = master->slave_count;
127  io.config_count = ec_master_config_count(master);
128  io.domain_count = ec_master_domain_count(master);
129 #ifdef EC_EOE
130  io.eoe_handler_count = ec_master_eoe_handler_count(master);
131 #else
132  io.eoe_handler_count = 0;
133 #endif
134  io.phase = (uint8_t) master->phase;
135  io.active = (uint8_t) master->active;
136  io.scan_busy = master->scan_busy;
137 
138  ec_lock_up(&master->master_sem);
139 
140  if (ec_lock_down_interruptible(&master->device_sem)) {
141  return -EINTR;
142  }
143 
144  for (dev_idx = EC_DEVICE_MAIN;
145  dev_idx < ec_master_num_devices(master); dev_idx++) {
146  ec_device_t *device = &master->devices[dev_idx];
147 
148  if (device->dev) {
149  memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
150  ETH_ALEN);
151  } else {
152  memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
153  ETH_ALEN);
154  }
155  io.devices[dev_idx].attached = device->dev ? 1 : 0;
156  io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
157  io.devices[dev_idx].tx_count = device->tx_count;
158  io.devices[dev_idx].rx_count = device->rx_count;
159  io.devices[dev_idx].tx_bytes = device->tx_bytes;
160  io.devices[dev_idx].rx_bytes = device->rx_bytes;
161  io.devices[dev_idx].tx_errors = device->tx_errors;
162  for (j = 0; j < EC_RATE_COUNT; j++) {
163  io.devices[dev_idx].tx_frame_rates[j] =
164  device->tx_frame_rates[j];
165  io.devices[dev_idx].rx_frame_rates[j] =
166  device->rx_frame_rates[j];
167  io.devices[dev_idx].tx_byte_rates[j] =
168  device->tx_byte_rates[j];
169  io.devices[dev_idx].rx_byte_rates[j] =
170  device->rx_byte_rates[j];
171  }
172  }
173  io.num_devices = ec_master_num_devices(master);
174 
175  io.tx_count = master->device_stats.tx_count;
176  io.rx_count = master->device_stats.rx_count;
177  io.tx_bytes = master->device_stats.tx_bytes;
178  io.rx_bytes = master->device_stats.rx_bytes;
179  for (j = 0; j < EC_RATE_COUNT; j++) {
180  io.tx_frame_rates[j] =
181  master->device_stats.tx_frame_rates[j];
182  io.rx_frame_rates[j] =
183  master->device_stats.rx_frame_rates[j];
184  io.tx_byte_rates[j] =
185  master->device_stats.tx_byte_rates[j];
186  io.rx_byte_rates[j] =
187  master->device_stats.rx_byte_rates[j];
188  io.loss_rates[j] =
189  master->device_stats.loss_rates[j];
190  }
191 
192  ec_lock_up(&master->device_sem);
193 
194  io.app_time = master->app_time;
195  io.dc_ref_time = master->dc_ref_time;
196  io.ref_clock =
197  master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
198 
199  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
200  return -EFAULT;
201  }
202 
203  return 0;
204 }
205 
206 /*****************************************************************************/
207 
214  void *arg
215  )
216 {
217  ec_ioctl_slave_t data;
218  const ec_slave_t *slave;
219  int i;
220 
221  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
222  return -EFAULT;
223  }
224 
225  if (ec_lock_down_interruptible(&master->master_sem))
226  return -EINTR;
227 
228  if (!(slave = ec_master_find_slave_const(
229  master, 0, data.position))) {
230  ec_lock_up(&master->master_sem);
231  EC_MASTER_DBG(master, 1, "Slave %u does not exist!\n", data.position);
232  return -EINVAL;
233  }
234 
235  data.device_index = slave->device_index;
236  data.vendor_id = slave->sii.vendor_id;
237  data.product_code = slave->sii.product_code;
238  data.revision_number = slave->sii.revision_number;
239  data.serial_number = slave->sii.serial_number;
240  data.alias = slave->effective_alias;
241  data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
242  data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
243  data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
244  data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
245  data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
246  data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
247  data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
248  data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
249  data.mailbox_protocols = slave->sii.mailbox_protocols;
250  data.has_general_category = slave->sii.has_general;
251  data.coe_details = slave->sii.coe_details;
252  data.general_flags = slave->sii.general_flags;
253  data.current_on_ebus = slave->sii.current_on_ebus;
254  for (i = 0; i < EC_MAX_PORTS; i++) {
255  data.ports[i].desc = slave->ports[i].desc;
256  data.ports[i].link.link_up = slave->ports[i].link.link_up;
257  data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
258  data.ports[i].link.signal_detected =
259  slave->ports[i].link.signal_detected;
260  data.ports[i].receive_time = slave->ports[i].receive_time;
261  if (slave->ports[i].next_slave) {
262  data.ports[i].next_slave =
263  slave->ports[i].next_slave->ring_position;
264  } else {
265  data.ports[i].next_slave = 0xffff;
266  }
267  data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
268  }
269  data.fmmu_bit = slave->base_fmmu_bit_operation;
270  data.dc_supported = slave->base_dc_supported;
271  data.dc_range = slave->base_dc_range;
272  data.has_dc_system_time = slave->has_dc_system_time;
273  data.transmission_delay = slave->transmission_delay;
274  data.al_state = slave->current_state;
275  data.error_flag = slave->error_flag;
276 
277  data.sync_count = slave->sii.sync_count;
278  data.sdo_count = ec_slave_sdo_count(slave);
279  data.sii_nwords = slave->sii_nwords;
280  ec_ioctl_strcpy(data.group, slave->sii.group);
281  ec_ioctl_strcpy(data.image, slave->sii.image);
282  ec_ioctl_strcpy(data.order, slave->sii.order);
283  ec_ioctl_strcpy(data.name, slave->sii.name);
284 
285  ec_lock_up(&master->master_sem);
286 
287  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
288  return -EFAULT;
289 
290  return 0;
291 }
292 
293 /*****************************************************************************/
294 
301  void *arg
302  )
303 {
304  ec_ioctl_slave_sync_t data;
305  const ec_slave_t *slave;
306  const ec_sync_t *sync;
307 
308  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
309  return -EFAULT;
310  }
311 
312  if (ec_lock_down_interruptible(&master->master_sem))
313  return -EINTR;
314 
315  if (!(slave = ec_master_find_slave_const(
316  master, 0, data.slave_position))) {
317  ec_lock_up(&master->master_sem);
318  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
319  data.slave_position);
320  return -EINVAL;
321  }
322 
323  if (data.sync_index >= slave->sii.sync_count) {
324  ec_lock_up(&master->master_sem);
325  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
326  data.sync_index);
327  return -EINVAL;
328  }
329 
330  sync = &slave->sii.syncs[data.sync_index];
331 
333  data.default_size = sync->default_length;
334  data.control_register = sync->control_register;
335  data.enable = sync->enable;
336  data.pdo_count = ec_pdo_list_count(&sync->pdos);
337 
338  ec_lock_up(&master->master_sem);
339 
340  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
341  return -EFAULT;
342 
343  return 0;
344 }
345 
346 /*****************************************************************************/
347 
354  void *arg
355  )
356 {
357  ec_ioctl_slave_sync_pdo_t data;
358  const ec_slave_t *slave;
359  const ec_sync_t *sync;
360  const ec_pdo_t *pdo;
361 
362  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
363  return -EFAULT;
364  }
365 
366  if (ec_lock_down_interruptible(&master->master_sem))
367  return -EINTR;
368 
369  if (!(slave = ec_master_find_slave_const(
370  master, 0, data.slave_position))) {
371  ec_lock_up(&master->master_sem);
372  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
373  data.slave_position);
374  return -EINVAL;
375  }
376 
377  if (data.sync_index >= slave->sii.sync_count) {
378  ec_lock_up(&master->master_sem);
379  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
380  data.sync_index);
381  return -EINVAL;
382  }
383 
384  sync = &slave->sii.syncs[data.sync_index];
386  &sync->pdos, data.pdo_pos))) {
387  ec_lock_up(&master->master_sem);
388  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
389  "position %u!\n", data.sync_index, data.pdo_pos);
390  return -EINVAL;
391  }
392 
393  data.index = pdo->index;
394  data.entry_count = ec_pdo_entry_count(pdo);
395  ec_ioctl_strcpy(data.name, pdo->name);
396 
397  ec_lock_up(&master->master_sem);
398 
399  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
400  return -EFAULT;
401 
402  return 0;
403 }
404 
405 /*****************************************************************************/
406 
413  void *arg
414  )
415 {
416  ec_ioctl_slave_sync_pdo_entry_t data;
417  const ec_slave_t *slave;
418  const ec_sync_t *sync;
419  const ec_pdo_t *pdo;
420  const ec_pdo_entry_t *entry;
421 
422  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
423  return -EFAULT;
424  }
425 
426  if (ec_lock_down_interruptible(&master->master_sem))
427  return -EINTR;
428 
429  if (!(slave = ec_master_find_slave_const(
430  master, 0, data.slave_position))) {
431  ec_lock_up(&master->master_sem);
432  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
433  data.slave_position);
434  return -EINVAL;
435  }
436 
437  if (data.sync_index >= slave->sii.sync_count) {
438  ec_lock_up(&master->master_sem);
439  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
440  data.sync_index);
441  return -EINVAL;
442  }
443 
444  sync = &slave->sii.syncs[data.sync_index];
446  &sync->pdos, data.pdo_pos))) {
447  ec_lock_up(&master->master_sem);
448  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
449  "position %u!\n", data.sync_index, data.pdo_pos);
450  return -EINVAL;
451  }
452 
453  if (!(entry = ec_pdo_find_entry_by_pos_const(
454  pdo, data.entry_pos))) {
455  ec_lock_up(&master->master_sem);
456  EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
457  "position %u!\n", data.pdo_pos, data.entry_pos);
458  return -EINVAL;
459  }
460 
461  data.index = entry->index;
462  data.subindex = entry->subindex;
463  data.bit_length = entry->bit_length;
464  ec_ioctl_strcpy(data.name, entry->name);
465 
466  ec_lock_up(&master->master_sem);
467 
468  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
469  return -EFAULT;
470 
471  return 0;
472 }
473 
474 /*****************************************************************************/
475 
482  void *arg
483  )
484 {
485  ec_ioctl_domain_t data;
486  const ec_domain_t *domain;
487  unsigned int dev_idx;
488 
489  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
490  return -EFAULT;
491  }
492 
493  if (ec_lock_down_interruptible(&master->domains_lock))
494  return -EINTR;
495 
496  if (!(domain = ec_master_find_domain_const(master, data.index))) {
497  ec_lock_up(&master->domains_lock);
498  EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
499  return -EINVAL;
500  }
501 
502  data.data_size = domain->data_size;
503  data.logical_base_address = domain->logical_base_address;
504  for (dev_idx = EC_DEVICE_MAIN;
505  dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
506  data.working_counter[dev_idx] = domain->working_counter[dev_idx];
507  }
508  data.expected_working_counter = domain->expected_working_counter;
509  data.fmmu_count = ec_domain_fmmu_count(domain);
510 
511  ec_lock_up(&master->domains_lock);
512 
513  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
514  return -EFAULT;
515 
516  return 0;
517 }
518 
519 /*****************************************************************************/
520 
527  void *arg
528  )
529 {
530  ec_ioctl_domain_fmmu_t data;
531  const ec_domain_t *domain;
532  const ec_fmmu_config_t *fmmu;
533 
534  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
535  return -EFAULT;
536  }
537 
538  if (ec_lock_down_interruptible(&master->domains_lock))
539  return -EINTR;
540 
541  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
542  ec_lock_up(&master->domains_lock);
543  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
544  data.domain_index);
545  return -EINVAL;
546  }
547 
548  if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
549  ec_lock_up(&master->domains_lock);
550  EC_MASTER_ERR(master, "Domain %u has less than %u"
551  " fmmu configurations.\n",
552  data.domain_index, data.fmmu_index + 1);
553  return -EINVAL;
554  }
555 
556  data.slave_config_alias = fmmu->sc->alias;
557  data.slave_config_position = fmmu->sc->position;
558  data.sync_index = fmmu->sync_index;
559  data.dir = fmmu->dir;
560  data.logical_address = fmmu->domain->logical_base_address + fmmu->logical_domain_offset;
561  data.data_size = fmmu->data_size;
562 
563  ec_lock_up(&master->domains_lock);
564 
565  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
566  return -EFAULT;
567 
568  return 0;
569 }
570 
571 /*****************************************************************************/
572 
579  void *arg
580  )
581 {
582  ec_ioctl_domain_data_t data;
583  const ec_domain_t *domain;
584 
585  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
586  return -EFAULT;
587  }
588 
589  if (ec_lock_down_interruptible(&master->domains_lock))
590  return -EINTR;
591 
592  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
593  ec_lock_up(&master->domains_lock);
594  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
595  data.domain_index);
596  return -EINVAL;
597  }
598 
599  if (domain->data_size != data.data_size) {
600  ec_lock_up(&master->domains_lock);
601  EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
602  data.data_size, domain->data_size);
603  return -EFAULT;
604  }
605 
606  if (copy_to_user((void __user *) data.target, domain->data,
607  domain->data_size)) {
608  ec_lock_up(&master->domains_lock);
609  return -EFAULT;
610  }
611 
612  ec_lock_up(&master->domains_lock);
613  return 0;
614 }
615 
616 /*****************************************************************************/
617 
624  void *arg
625  )
626 {
627  return ec_master_debug_level(master, (unsigned long) arg);
628 }
629 
630 /*****************************************************************************/
631 
638  void *arg
639  )
640 {
641  master->fsm.rescan_required = 1;
642  return 0;
643 }
644 
645 /*****************************************************************************/
646 
653  void *arg
654  )
655 {
656  ec_ioctl_slave_state_t data;
657  ec_slave_t *slave;
658 
659  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
660  return -EFAULT;
661  }
662 
663  if (ec_lock_down_interruptible(&master->master_sem))
664  return -EINTR;
665 
666  if (!(slave = ec_master_find_slave(
667  master, 0, data.slave_position))) {
668  ec_lock_up(&master->master_sem);
669  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
670  data.slave_position);
671  return -EINVAL;
672  }
673 
674  ec_slave_request_state(slave, data.al_state);
675 
676  ec_lock_up(&master->master_sem);
677  return 0;
678 }
679 
680 /*****************************************************************************/
681 
688  void *arg
689  )
690 {
691  ec_ioctl_slave_sdo_t data;
692  const ec_slave_t *slave;
693  const ec_sdo_t *sdo;
694 
695  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
696  return -EFAULT;
697  }
698 
699  if (ec_lock_down_interruptible(&master->master_sem))
700  return -EINTR;
701 
702  if (!(slave = ec_master_find_slave_const(
703  master, 0, data.slave_position))) {
704  ec_lock_up(&master->master_sem);
705  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
706  data.slave_position);
707  return -EINVAL;
708  }
709 
710  if (!(sdo = ec_slave_get_sdo_by_pos_const(
711  slave, data.sdo_position))) {
712  ec_lock_up(&master->master_sem);
713  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
714  return -EINVAL;
715  }
716 
717  data.sdo_index = sdo->index;
718  data.max_subindex = sdo->max_subindex;
719  ec_ioctl_strcpy(data.name, sdo->name);
720 
721  ec_lock_up(&master->master_sem);
722 
723  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
724  return -EFAULT;
725 
726  return 0;
727 }
728 
729 /*****************************************************************************/
730 
737  void *arg
738  )
739 {
740  ec_ioctl_slave_sdo_entry_t data;
741  const ec_slave_t *slave;
742  const ec_sdo_t *sdo;
743  const ec_sdo_entry_t *entry;
744 
745  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
746  return -EFAULT;
747  }
748 
749  if (ec_lock_down_interruptible(&master->master_sem))
750  return -EINTR;
751 
752  if (!(slave = ec_master_find_slave_const(
753  master, 0, data.slave_position))) {
754  ec_lock_up(&master->master_sem);
755  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
756  data.slave_position);
757  return -EINVAL;
758  }
759 
760  if (data.sdo_spec <= 0) {
761  if (!(sdo = ec_slave_get_sdo_by_pos_const(
762  slave, -data.sdo_spec))) {
763  ec_lock_up(&master->master_sem);
764  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
765  return -EINVAL;
766  }
767  } else {
768  if (!(sdo = ec_slave_get_sdo_const(
769  slave, data.sdo_spec))) {
770  ec_lock_up(&master->master_sem);
771  EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
772  data.sdo_spec);
773  return -EINVAL;
774  }
775  }
776 
777  if (!(entry = ec_sdo_get_entry_const(
778  sdo, data.sdo_entry_subindex))) {
779  ec_lock_up(&master->master_sem);
780  EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
781  sdo->index, data.sdo_entry_subindex);
782  return -EINVAL;
783  }
784 
785  data.data_type = entry->data_type;
786  data.bit_length = entry->bit_length;
787  data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
789  data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
791  data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
793  data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
795  data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
797  data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
799  ec_ioctl_strcpy(data.description, entry->description);
800 
801  ec_lock_up(&master->master_sem);
802 
803  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
804  return -EFAULT;
805 
806  return 0;
807 }
808 
809 /*****************************************************************************/
810 
817  void *arg
818  )
819 {
820  ec_ioctl_slave_sdo_upload_t data;
821  uint8_t *target;
822  int ret;
823 
824  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
825  return -EFAULT;
826  }
827 
828  if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
829  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
830  " for SDO upload.\n", data.target_size);
831  return -ENOMEM;
832  }
833 
834  ret = ecrt_master_sdo_upload(master, data.slave_position,
835  data.sdo_index, data.sdo_entry_subindex, target,
836  data.target_size, &data.data_size, &data.abort_code);
837 
838  if (!ret) {
839  if (copy_to_user((void __user *) data.target,
840  target, data.data_size)) {
841  kfree(target);
842  return -EFAULT;
843  }
844  }
845 
846  kfree(target);
847 
848  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
849  return -EFAULT;
850  }
851 
852  return ret;
853 }
854 
855 /*****************************************************************************/
856 
863  void *arg
864  )
865 {
866  ec_ioctl_slave_sdo_download_t data;
867  uint8_t *sdo_data;
868  int retval;
869 
870  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
871  return -EFAULT;
872  }
873 
874  if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
875  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
876  " for SDO download.\n", data.data_size);
877  return -ENOMEM;
878  }
879 
880  if (copy_from_user(sdo_data, (const void __user *) data.data, data.data_size)) {
881  kfree(sdo_data);
882  return -EFAULT;
883  }
884 
885  if (data.complete_access) {
886  retval = ecrt_master_sdo_download_complete(master, data.slave_position,
887  data.sdo_index, sdo_data, data.data_size, &data.abort_code);
888  } else {
889  retval = ecrt_master_sdo_download(master, data.slave_position,
890  data.sdo_index, data.sdo_entry_subindex, sdo_data,
891  data.data_size, &data.abort_code);
892  }
893 
894  kfree(sdo_data);
895 
896  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
897  retval = -EFAULT;
898  }
899 
900  return retval;
901 }
902 
903 /*****************************************************************************/
904 
911  void *arg
912  )
913 {
914  ec_ioctl_slave_sii_t data;
915  const ec_slave_t *slave;
916  int retval;
917 
918  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
919  return -EFAULT;
920  }
921 
922  if (ec_lock_down_interruptible(&master->master_sem))
923  return -EINTR;
924 
925  if (!(slave = ec_master_find_slave_const(
926  master, 0, data.slave_position))) {
927  ec_lock_up(&master->master_sem);
928  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
929  data.slave_position);
930  return -EINVAL;
931  }
932 
933  if (!data.nwords
934  || data.offset + data.nwords > slave->sii_nwords) {
935  ec_lock_up(&master->master_sem);
936  EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
937  " size %zu!\n", data.offset, data.nwords, slave->sii_nwords);
938  return -EINVAL;
939  }
940 
941  if (copy_to_user((void __user *) data.words,
942  slave->sii_words + data.offset, data.nwords * 2))
943  retval = -EFAULT;
944  else
945  retval = 0;
946 
947  ec_lock_up(&master->master_sem);
948  return retval;
949 }
950 
951 /*****************************************************************************/
952 
959  void *arg
960  )
961 {
962  ec_ioctl_slave_sii_t data;
963  ec_slave_t *slave;
964  unsigned int byte_size;
965  uint16_t *words;
966  ec_sii_write_request_t request;
967 
968  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
969  return -EFAULT;
970  }
971 
972  if (!data.nwords) {
973  return 0;
974  }
975 
976  byte_size = sizeof(uint16_t) * data.nwords;
977  if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
978  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
979  " for SII contents.\n", byte_size);
980  return -ENOMEM;
981  }
982 
983  if (copy_from_user(words,
984  (void __user *) data.words, byte_size)) {
985  kfree(words);
986  return -EFAULT;
987  }
988 
989  if (ec_lock_down_interruptible(&master->master_sem)) {
990  kfree(words);
991  return -EINTR;
992  }
993 
994  if (!(slave = ec_master_find_slave(
995  master, 0, data.slave_position))) {
996  ec_lock_up(&master->master_sem);
997  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
998  data.slave_position);
999  kfree(words);
1000  return -EINVAL;
1001  }
1002 
1003  // init SII write request
1004  INIT_LIST_HEAD(&request.list);
1005  request.slave = slave;
1006  request.words = words;
1007  request.offset = data.offset;
1008  request.nwords = data.nwords;
1009  request.state = EC_INT_REQUEST_QUEUED;
1010 
1011  // schedule SII write request.
1012  list_add_tail(&request.list, &master->sii_requests);
1013 
1014  ec_lock_up(&master->master_sem);
1015 
1016  // wait for processing through FSM
1017  if (wait_event_interruptible(master->request_queue,
1018  request.state != EC_INT_REQUEST_QUEUED)) {
1019  // interrupted by signal
1020  ec_lock_down(&master->master_sem);
1021  if (request.state == EC_INT_REQUEST_QUEUED) {
1022  // abort request
1023  list_del(&request.list);
1024  ec_lock_up(&master->master_sem);
1025  kfree(words);
1026  return -EINTR;
1027  }
1028  ec_lock_up(&master->master_sem);
1029  }
1030 
1031  // wait until master FSM has finished processing
1032  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1033 
1034  kfree(words);
1035 
1036  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1037 }
1038 
1039 /*****************************************************************************/
1040 
1046  ec_master_t *master,
1047  void *arg
1048  )
1049 {
1050  ec_ioctl_slave_reg_t io;
1051  ec_slave_t *slave;
1052  ec_reg_request_t request;
1053  int ret;
1054 
1055  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1056  return -EFAULT;
1057  }
1058 
1059  if (!io.size) {
1060  return 0;
1061  }
1062 
1063  // init register request
1064  ret = ec_reg_request_init(&request, io.size);
1065  if (ret) {
1066  return ret;
1067  }
1068 
1069  ecrt_reg_request_read(&request, io.address, io.size);
1070 
1071  if (ec_lock_down_interruptible(&master->master_sem)) {
1072  ec_reg_request_clear(&request);
1073  return -EINTR;
1074  }
1075 
1076  if (!(slave = ec_master_find_slave(
1077  master, 0, io.slave_position))) {
1078  ec_lock_up(&master->master_sem);
1079  ec_reg_request_clear(&request);
1080  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1081  io.slave_position);
1082  return -EINVAL;
1083  }
1084 
1085  // schedule request.
1086  list_add_tail(&request.list, &slave->reg_requests);
1087 
1088  ec_lock_up(&master->master_sem);
1089 
1090  // wait for processing through FSM
1091  if (wait_event_interruptible(master->request_queue,
1092  request.state != EC_INT_REQUEST_QUEUED)) {
1093  // interrupted by signal
1094  ec_lock_down(&master->master_sem);
1095  if (request.state == EC_INT_REQUEST_QUEUED) {
1096  // abort request
1097  list_del(&request.list);
1098  ec_lock_up(&master->master_sem);
1099  ec_reg_request_clear(&request);
1100  return -EINTR;
1101  }
1102  ec_lock_up(&master->master_sem);
1103  }
1104 
1105  // wait until master FSM has finished processing
1106  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1107 
1108  if (request.state == EC_INT_REQUEST_SUCCESS) {
1109  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1110  return -EFAULT;
1111  }
1112  }
1113  ec_reg_request_clear(&request);
1114 
1115  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1116 }
1117 
1118 /*****************************************************************************/
1119 
1125  ec_master_t *master,
1126  void *arg
1127  )
1128 {
1129  ec_ioctl_slave_reg_t io;
1130  ec_slave_t *slave;
1131  ec_reg_request_t request;
1132  int ret;
1133 
1134  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1135  return -EFAULT;
1136  }
1137 
1138  if (!io.size) {
1139  return 0;
1140  }
1141 
1142  // init register request
1143  ret = ec_reg_request_init(&request, io.size);
1144  if (ret) {
1145  return ret;
1146  }
1147 
1148  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1149  ec_reg_request_clear(&request);
1150  return -EFAULT;
1151  }
1152 
1153  ecrt_reg_request_write(&request, io.address, io.size);
1154 
1155  if (ec_lock_down_interruptible(&master->master_sem)) {
1156  ec_reg_request_clear(&request);
1157  return -EINTR;
1158  }
1159 
1160  if (io.emergency) {
1161  request.ring_position = io.slave_position;
1162  // schedule request.
1163  list_add_tail(&request.list, &master->emerg_reg_requests);
1164  }
1165  else {
1166  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1167  ec_lock_up(&master->master_sem);
1168  ec_reg_request_clear(&request);
1169  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1170  io.slave_position);
1171  return -EINVAL;
1172  }
1173 
1174  // schedule request.
1175  list_add_tail(&request.list, &slave->reg_requests);
1176  }
1177 
1178  ec_lock_up(&master->master_sem);
1179 
1180  // wait for processing through FSM
1181  if (wait_event_interruptible(master->request_queue,
1182  request.state != EC_INT_REQUEST_QUEUED)) {
1183  // interrupted by signal
1184  ec_lock_down(&master->master_sem);
1185  if (request.state == EC_INT_REQUEST_QUEUED) {
1186  // abort request
1187  list_del(&request.list);
1188  ec_lock_up(&master->master_sem);
1189  ec_reg_request_clear(&request);
1190  return -EINTR;
1191  }
1192  ec_lock_up(&master->master_sem);
1193  }
1194 
1195  // wait until master FSM has finished processing
1196  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1197 
1198  ec_reg_request_clear(&request);
1199 
1200  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1201 }
1202 
1203 /*****************************************************************************/
1204 
1210  ec_master_t *master,
1211  void *arg
1212  )
1213 {
1214  ec_ioctl_config_t data;
1215  const ec_slave_config_t *sc;
1216  uint8_t i;
1217 
1218  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1219  return -EFAULT;
1220  }
1221 
1222  if (ec_lock_down_interruptible(&master->master_sem))
1223  return -EINTR;
1224 
1225  if (!(sc = ec_master_get_config_const(
1226  master, data.config_index))) {
1227  ec_lock_up(&master->master_sem);
1228  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1229  data.config_index);
1230  return -EINVAL;
1231  }
1232 
1233  data.alias = sc->alias;
1234  data.position = sc->position;
1235  data.vendor_id = sc->vendor_id;
1236  data.product_code = sc->product_code;
1237  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1238  data.syncs[i].dir = sc->sync_configs[i].dir;
1239  data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1240  data.syncs[i].pdo_count =
1242  }
1243  data.watchdog_divider = sc->watchdog_divider;
1244  data.watchdog_intervals = sc->watchdog_intervals;
1245  data.sdo_count = ec_slave_config_sdo_count(sc);
1246  data.idn_count = ec_slave_config_idn_count(sc);
1247  data.flag_count = ec_slave_config_flag_count(sc);
1248  data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1249  data.dc_assign_activate = sc->dc_assign_activate;
1250  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1251  data.dc_sync[i] = sc->dc_sync[i];
1252  }
1253 
1254  ec_lock_up(&master->master_sem);
1255 
1256  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1257  return -EFAULT;
1258 
1259  return 0;
1260 }
1261 
1262 /*****************************************************************************/
1263 
1269  ec_master_t *master,
1270  void *arg
1271  )
1272 {
1273  ec_ioctl_config_pdo_t data;
1274  const ec_slave_config_t *sc;
1275  const ec_pdo_t *pdo;
1276 
1277  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1278  return -EFAULT;
1279  }
1280 
1281  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1282  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1283  data.sync_index);
1284  return -EINVAL;
1285  }
1286 
1287  if (ec_lock_down_interruptible(&master->master_sem))
1288  return -EINTR;
1289 
1290  if (!(sc = ec_master_get_config_const(
1291  master, data.config_index))) {
1292  ec_lock_up(&master->master_sem);
1293  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1294  data.config_index);
1295  return -EINVAL;
1296  }
1297 
1299  &sc->sync_configs[data.sync_index].pdos,
1300  data.pdo_pos))) {
1301  ec_lock_up(&master->master_sem);
1302  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1303  return -EINVAL;
1304  }
1305 
1306  data.index = pdo->index;
1307  data.entry_count = ec_pdo_entry_count(pdo);
1308  ec_ioctl_strcpy(data.name, pdo->name);
1309 
1310  ec_lock_up(&master->master_sem);
1311 
1312  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1313  return -EFAULT;
1314 
1315  return 0;
1316 }
1317 
1318 /*****************************************************************************/
1319 
1325  ec_master_t *master,
1326  void *arg
1327  )
1328 {
1329  ec_ioctl_config_pdo_entry_t data;
1330  const ec_slave_config_t *sc;
1331  const ec_pdo_t *pdo;
1332  const ec_pdo_entry_t *entry;
1333 
1334  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1335  return -EFAULT;
1336  }
1337 
1338  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1339  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1340  data.sync_index);
1341  return -EINVAL;
1342  }
1343 
1344  if (ec_lock_down_interruptible(&master->master_sem))
1345  return -EINTR;
1346 
1347  if (!(sc = ec_master_get_config_const(
1348  master, data.config_index))) {
1349  ec_lock_up(&master->master_sem);
1350  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1351  data.config_index);
1352  return -EINVAL;
1353  }
1354 
1356  &sc->sync_configs[data.sync_index].pdos,
1357  data.pdo_pos))) {
1358  ec_lock_up(&master->master_sem);
1359  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1360  return -EINVAL;
1361  }
1362 
1363  if (!(entry = ec_pdo_find_entry_by_pos_const(
1364  pdo, data.entry_pos))) {
1365  ec_lock_up(&master->master_sem);
1366  EC_MASTER_ERR(master, "Entry not found!\n");
1367  return -EINVAL;
1368  }
1369 
1370  data.index = entry->index;
1371  data.subindex = entry->subindex;
1372  data.bit_length = entry->bit_length;
1373  ec_ioctl_strcpy(data.name, entry->name);
1374 
1375  ec_lock_up(&master->master_sem);
1376 
1377  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1378  return -EFAULT;
1379 
1380  return 0;
1381 }
1382 
1383 /*****************************************************************************/
1384 
1390  ec_master_t *master,
1391  void *arg
1392  )
1393 {
1394  ec_ioctl_config_sdo_t *ioctl;
1395  const ec_slave_config_t *sc;
1396  const ec_sdo_request_t *req;
1397 
1398  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1399  return -ENOMEM;
1400  }
1401 
1402  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1403  kfree(ioctl);
1404  return -EFAULT;
1405  }
1406 
1407  if (ec_lock_down_interruptible(&master->master_sem)) {
1408  kfree(ioctl);
1409  return -EINTR;
1410  }
1411 
1412  if (!(sc = ec_master_get_config_const(
1413  master, ioctl->config_index))) {
1414  ec_lock_up(&master->master_sem);
1415  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1416  ioctl->config_index);
1417  kfree(ioctl);
1418  return -EINVAL;
1419  }
1420 
1422  sc, ioctl->sdo_pos))) {
1423  ec_lock_up(&master->master_sem);
1424  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1425  kfree(ioctl);
1426  return -EINVAL;
1427  }
1428 
1429  ioctl->index = req->index;
1430  ioctl->subindex = req->subindex;
1431  ioctl->size = req->data_size;
1432  memcpy(ioctl->data, req->data,
1433  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1434  ioctl->complete_access = req->complete_access;
1435 
1436  ec_lock_up(&master->master_sem);
1437 
1438  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1439  kfree(ioctl);
1440  return -EFAULT;
1441  }
1442 
1443  kfree(ioctl);
1444  return 0;
1445 }
1446 
1447 /*****************************************************************************/
1448 
1454  ec_master_t *master,
1455  void *arg
1456  )
1457 {
1458  ec_ioctl_config_idn_t *ioctl;
1459  const ec_slave_config_t *sc;
1460  const ec_soe_request_t *req;
1461 
1462  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1463  return -ENOMEM;
1464  }
1465 
1466  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1467  kfree(ioctl);
1468  return -EFAULT;
1469  }
1470 
1471  if (ec_lock_down_interruptible(&master->master_sem)) {
1472  kfree(ioctl);
1473  return -EINTR;
1474  }
1475 
1476  if (!(sc = ec_master_get_config_const(
1477  master, ioctl->config_index))) {
1478  ec_lock_up(&master->master_sem);
1479  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1480  ioctl->config_index);
1481  kfree(ioctl);
1482  return -EINVAL;
1483  }
1484 
1486  sc, ioctl->idn_pos))) {
1487  ec_lock_up(&master->master_sem);
1488  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1489  kfree(ioctl);
1490  return -EINVAL;
1491  }
1492 
1493  ioctl->drive_no = req->drive_no;
1494  ioctl->idn = req->idn;
1495  ioctl->state = req->state;
1496  ioctl->size = req->data_size;
1497  memcpy(ioctl->data, req->data,
1498  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1499 
1500  ec_lock_up(&master->master_sem);
1501 
1502  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1503  kfree(ioctl);
1504  return -EFAULT;
1505  }
1506 
1507  kfree(ioctl);
1508  return 0;
1509 }
1510 
1511 /*****************************************************************************/
1512 
1518  ec_master_t *master,
1519  void *arg
1520  )
1521 {
1522  ec_ioctl_config_flag_t *ioctl;
1523  const ec_slave_config_t *sc;
1524  const ec_flag_t *flag;
1525  size_t size;
1526 
1527  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1528  return -ENOMEM;
1529  }
1530 
1531  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1532  kfree(ioctl);
1533  return -EFAULT;
1534  }
1535 
1536  if (ec_lock_down_interruptible(&master->master_sem)) {
1537  kfree(ioctl);
1538  return -EINTR;
1539  }
1540 
1541  if (!(sc = ec_master_get_config_const(
1542  master, ioctl->config_index))) {
1543  ec_lock_up(&master->master_sem);
1544  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1545  ioctl->config_index);
1546  kfree(ioctl);
1547  return -EINVAL;
1548  }
1549 
1551  sc, ioctl->flag_pos))) {
1552  ec_lock_up(&master->master_sem);
1553  EC_MASTER_ERR(master, "Invalid flag position!\n");
1554  kfree(ioctl);
1555  return -EINVAL;
1556  }
1557 
1558  size = min((u32) strlen(flag->key), (u32) EC_MAX_FLAG_KEY_SIZE - 1);
1559  memcpy(ioctl->key, flag->key, size);
1560  ioctl->key[size] = 0x00;
1561  ioctl->value = flag->value;
1562 
1563  ec_lock_up(&master->master_sem);
1564 
1565  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1566  kfree(ioctl);
1567  return -EFAULT;
1568  }
1569 
1570  kfree(ioctl);
1571  return 0;
1572 }
1573 
1574 /*****************************************************************************/
1575 
1576 #ifdef EC_EOE
1577 
1583  ec_master_t *master,
1584  void *arg
1585  )
1586 {
1587  ec_ioctl_eoe_handler_t data;
1588  const ec_eoe_t *eoe;
1589 
1590  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1591  return -EFAULT;
1592  }
1593 
1594  if (ec_lock_down_interruptible(&master->master_sem))
1595  return -EINTR;
1596 
1597  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1598  ec_lock_up(&master->master_sem);
1599  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1600  data.eoe_index);
1601  return -EINVAL;
1602  }
1603 
1604  if (eoe->slave) {
1605  data.slave_position = eoe->slave->ring_position;
1606  } else {
1607  data.slave_position = 0xffff;
1608  }
1609  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1610  data.open = eoe->opened;
1611  data.rx_bytes = eoe->stats.tx_bytes;
1612  data.rx_rate = eoe->tx_rate;
1613  data.tx_bytes = eoe->stats.rx_bytes;
1614  data.tx_rate = eoe->tx_rate;
1615  data.tx_queued_frames = eoe->tx_queued_frames;
1616  data.tx_queue_size = eoe->tx_queue_size;
1617 
1618  ec_lock_up(&master->master_sem);
1619 
1620  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1621  return -EFAULT;
1622 
1623  return 0;
1624 }
1625 
1626 #endif
1627 
1628 /*****************************************************************************/
1629 
1630 #ifdef EC_EOE
1631 
1636  ec_master_t *master,
1637  void *arg
1638  )
1639 {
1640  ec_ioctl_slave_eoe_ip_t io;
1641  ec_eoe_request_t req;
1642  ec_slave_t *slave;
1643 
1644  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1645  return -EFAULT;
1646  }
1647 
1648  // init EoE request
1649  ec_eoe_request_init(&req);
1650 
1651  req.mac_address_included = io.mac_address_included;
1652  req.ip_address_included = io.ip_address_included;
1653  req.subnet_mask_included = io.subnet_mask_included;
1654  req.gateway_included = io.gateway_included;
1655  req.dns_included = io.dns_included;
1656  req.name_included = io.name_included;
1657 
1658  memcpy(req.mac_address, io.mac_address, ETH_ALEN);
1659  req.ip_address = io.ip_address;
1660  req.subnet_mask = io.subnet_mask;
1661  req.gateway = io.gateway;
1662  req.dns = io.dns;
1663  memcpy(req.name, io.name, EC_MAX_HOSTNAME_SIZE);
1664 
1665  req.state = EC_INT_REQUEST_QUEUED;
1666 
1667  if (ec_lock_down_interruptible(&master->master_sem)) {
1668  return -EINTR;
1669  }
1670 
1671  if (!(slave = ec_master_find_slave(
1672  master, 0, io.slave_position))) {
1673  ec_lock_up(&master->master_sem);
1674  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1675  io.slave_position);
1676  return -EINVAL;
1677  }
1678 
1679  EC_MASTER_DBG(master, 1, "Scheduling EoE request.\n");
1680 
1681  // schedule request.
1682  list_add_tail(&req.list, &slave->eoe_requests);
1683 
1684  ec_lock_up(&master->master_sem);
1685 
1686  // wait for processing through FSM
1687  if (wait_event_interruptible(master->request_queue,
1688  req.state != EC_INT_REQUEST_QUEUED)) {
1689  // interrupted by signal
1690  ec_lock_down(&master->master_sem);
1691  if (req.state == EC_INT_REQUEST_QUEUED) {
1692  // abort request
1693  list_del(&req.list);
1694  ec_lock_up(&master->master_sem);
1695  return -EINTR;
1696  }
1697  ec_lock_up(&master->master_sem);
1698  }
1699 
1700  // wait until master FSM has finished processing
1701  wait_event(master->request_queue, req.state != EC_INT_REQUEST_BUSY);
1702 
1703  io.result = req.result;
1704 
1705  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
1706  return -EFAULT;
1707  }
1708 
1709  return req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1710 }
1711 #endif
1712 
1713 /*****************************************************************************/
1714 
1720  ec_master_t *master,
1721  void *arg,
1722  ec_ioctl_context_t *ctx
1723  )
1724 {
1725  ec_master_t *m;
1726  int ret = 0;
1727 
1728  m = ecrt_request_master_err(master->index);
1729  if (IS_ERR(m)) {
1730  ret = PTR_ERR(m);
1731  } else {
1732  ctx->requested = 1;
1733  }
1734 
1735  return ret;
1736 }
1737 
1738 /*****************************************************************************/
1739 
1745  ec_master_t *master,
1746  void *arg,
1747  ec_ioctl_context_t *ctx
1748  )
1749 {
1750  ec_domain_t *domain;
1751 
1752  if (unlikely(!ctx->requested))
1753  return -EPERM;
1754 
1755  domain = ecrt_master_create_domain_err(master);
1756  if (IS_ERR(domain))
1757  return PTR_ERR(domain);
1758 
1759  return domain->index;
1760 }
1761 
1762 /*****************************************************************************/
1763 
1769  ec_master_t *master,
1770  void *arg,
1771  ec_ioctl_context_t *ctx
1772  )
1773 {
1774  ec_ioctl_config_t data;
1775  ec_slave_config_t *sc, *entry;
1776 
1777  if (unlikely(!ctx->requested))
1778  return -EPERM;
1779 
1780  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1781  return -EFAULT;
1782  }
1783 
1784  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
1785  data.vendor_id, data.product_code);
1786  if (IS_ERR(sc))
1787  return PTR_ERR(sc);
1788 
1789  data.config_index = 0;
1790 
1791  if (ec_lock_down_interruptible(&master->master_sem))
1792  return -EINTR;
1793 
1794  list_for_each_entry(entry, &master->configs, list) {
1795  if (entry == sc)
1796  break;
1797  data.config_index++;
1798  }
1799 
1800  ec_lock_up(&master->master_sem);
1801 
1802  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1803  return -EFAULT;
1804 
1805  return 0;
1806 }
1807 
1808 /*****************************************************************************/
1809 
1815  ec_master_t *master,
1816  void *arg,
1817  ec_ioctl_context_t *ctx
1818  )
1819 {
1820  unsigned long config_index = (unsigned long) arg;
1821  ec_slave_config_t *sc = NULL;
1822  int ret = 0;
1823 
1824  if (unlikely(!ctx->requested)) {
1825  ret = -EPERM;
1826  goto out_return;
1827  }
1828 
1829  if (ec_lock_down_interruptible(&master->master_sem)) {
1830  ret = -EINTR;
1831  goto out_return;
1832  }
1833 
1834  if (config_index != 0xFFFFFFFF) {
1835  if (!(sc = ec_master_get_config(master, config_index))) {
1836  ret = -ENOENT;
1837  goto out_up;
1838  }
1839  }
1840 
1842 
1843 out_up:
1844  ec_lock_up(&master->master_sem);
1845 out_return:
1846  return ret;
1847 }
1848 
1849 /*****************************************************************************/
1850 
1856  ec_master_t *master,
1857  void *arg,
1858  ec_ioctl_context_t *ctx
1859  )
1860 {
1861  ec_ioctl_master_activate_t io;
1862  ec_domain_t *domain;
1863  off_t offset;
1864 #ifdef EC_IOCTL_RTDM
1865  int ret;
1866 #endif
1867 
1868  if (unlikely(!ctx->requested))
1869  return -EPERM;
1870 
1871 
1872  if (!ctx->process_data)
1873  {
1874  io.process_data = NULL;
1875 
1876  /* Get the sum of the domains' process data sizes. */
1877 
1878  ctx->process_data_size = 0;
1879 
1880  if (ec_lock_down_interruptible(&master->domains_lock))
1881  return -EINTR;
1882 
1883  list_for_each_entry(domain, &master->domains, list) {
1884  ctx->process_data_size += ecrt_domain_size(domain);
1885  }
1886 
1887  if (ctx->process_data_size) {
1888  ctx->process_data = vmalloc(ctx->process_data_size);
1889  if (!ctx->process_data) {
1890  ctx->process_data_size = 0;
1891  return -ENOMEM;
1892  }
1893 
1894  /* Set the memory as external process data memory for the
1895  * domains.
1896  */
1897  offset = 0;
1898  list_for_each_entry(domain, &master->domains, list) {
1900  ctx->process_data + offset);
1901  offset += ecrt_domain_size(domain);
1902  }
1903 
1904  ec_lock_up(&master->domains_lock);
1905 
1906 #ifdef EC_IOCTL_RTDM
1907  /* RTDM uses a different approach for memory-mapping, which has to be
1908  * initiated by the kernel.
1909  */
1910  ret = ec_rtdm_mmap(ctx, &io.process_data);
1911  if (ret < 0) {
1912  EC_MASTER_ERR(master, "Failed to map process data"
1913  " memory to user space (code %i).\n", ret);
1914  return ret;
1915  }
1916 #endif
1917  } else {
1918  ec_lock_up(&master->domains_lock);
1919  }
1920 
1921  io.process_data_size = ctx->process_data_size;
1922  }
1923  else
1924  {
1925  io.process_data = NULL;
1926  io.process_data_size = 0;
1927  }
1928 
1929 
1930  if (copy_to_user((void __user *) arg, &io,
1931  sizeof(ec_ioctl_master_activate_t)))
1932  return -EFAULT;
1933 
1934  return 0;
1935 }
1936 
1937 /*****************************************************************************/
1938 
1944  ec_master_t *master,
1945  void *arg,
1946  ec_ioctl_context_t *ctx
1947  )
1948 {
1949  ec_ioctl_master_activate_t io;
1950  ec_domain_t *domain;
1951  off_t offset;
1952  int ret;
1953 
1954  if (unlikely(!ctx->requested))
1955  return -EPERM;
1956 
1957 
1958  if (!ctx->process_data)
1959  {
1960  io.process_data = NULL;
1961 
1962  /* Get the sum of the domains' process data sizes. */
1963 
1964  ctx->process_data_size = 0;
1965 
1966  if (ec_lock_down_interruptible(&master->domains_lock))
1967  return -EINTR;
1968 
1969  list_for_each_entry(domain, &master->domains, list) {
1970  ctx->process_data_size += ecrt_domain_size(domain);
1971  }
1972 
1973  if (ctx->process_data_size) {
1974  ctx->process_data = vmalloc(ctx->process_data_size);
1975  if (!ctx->process_data) {
1976  ctx->process_data_size = 0;
1977  return -ENOMEM;
1978  }
1979 
1980  /* Set the memory as external process data memory for the
1981  * domains.
1982  */
1983  offset = 0;
1984  list_for_each_entry(domain, &master->domains, list) {
1986  ctx->process_data + offset);
1987  offset += ecrt_domain_size(domain);
1988  }
1989 
1990 #ifdef EC_IOCTL_RTDM
1991  /* RTDM uses a different approach for memory-mapping, which has to be
1992  * initiated by the kernel.
1993  */
1994  ret = ec_rtdm_mmap(ctx, &io.process_data);
1995  if (ret < 0) {
1996  EC_MASTER_ERR(master, "Failed to map process data"
1997  " memory to user space (code %i).\n", ret);
1998  return ret;
1999  }
2000 #endif
2001  }
2002 
2003  ec_lock_up(&master->domains_lock);
2004 
2005  io.process_data_size = ctx->process_data_size;
2006  }
2007  else
2008  {
2009  io.process_data = NULL;
2010  io.process_data_size = 0;
2011  }
2012 
2013 #ifndef EC_IOCTL_RTDM
2016 #endif
2017 
2018  ret = ecrt_master_activate(master);
2019  if (ret < 0)
2020  return ret;
2021 
2022  if (copy_to_user((void __user *) arg, &io,
2023  sizeof(ec_ioctl_master_activate_t)))
2024  return -EFAULT;
2025 
2026  return 0;
2027 }
2028 
2029 /*****************************************************************************/
2030 
2036  ec_master_t *master,
2037  void *arg,
2038  ec_ioctl_context_t *ctx
2039  )
2040 {
2041  if (unlikely(!ctx->requested))
2042  return -EPERM;
2043 
2045  return 0;
2046 }
2047 
2048 /*****************************************************************************/
2049 
2055  ec_master_t *master,
2056  void *arg,
2057  ec_ioctl_context_t *ctx
2058  )
2059 {
2060  if (unlikely(!ctx->requested))
2061  return -EPERM;
2062 
2063  ecrt_master_deactivate(master);
2064  return 0;
2065 }
2066 
2067 /*****************************************************************************/
2068 
2074  ec_master_t *master,
2075  void *arg,
2076  ec_ioctl_context_t *ctx
2077  )
2078 {
2079  size_t send_interval;
2080 
2081  if (unlikely(!ctx->requested)) {
2082  return -EPERM;
2083  }
2084 
2085  if (copy_from_user(&send_interval, (void __user *) arg,
2086  sizeof(send_interval))) {
2087  return -EFAULT;
2088  }
2089 
2090  if (ec_lock_down_interruptible(&master->master_sem))
2091  return -EINTR;
2092 
2093  ec_master_set_send_interval(master, send_interval);
2094 
2095  ec_lock_up(&master->master_sem);
2096  return 0;
2097 }
2098 
2099 /*****************************************************************************/
2100 
2106  ec_master_t *master,
2107  void *arg,
2108  ec_ioctl_context_t *ctx
2109  )
2110 {
2111  size_t sent_bytes;
2112 
2113  if (unlikely(!ctx->requested)) {
2114  return -EPERM;
2115  }
2116 
2117  /* Locking added as send is likely to be used by more than
2118  one application tasks */
2120  return -EINTR;
2121 
2122  if (master->send_cb != NULL) {
2123  master->send_cb(master->cb_data);
2124  sent_bytes = 0;
2125  } else
2126  sent_bytes = ecrt_master_send(master);
2127 
2128  ec_ioctl_lock_up(&master->io_sem);
2129 
2130  if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) {
2131  return -EFAULT;
2132  }
2133 
2134  return 0;
2135 }
2136 
2137 /*****************************************************************************/
2138 
2144  ec_master_t *master,
2145  void *arg,
2146  ec_ioctl_context_t *ctx
2147  )
2148 {
2149  if (unlikely(!ctx->requested)) {
2150  return -EPERM;
2151  }
2152 
2153  /* Locking added as receive is likely to be used by more than
2154  one application tasks */
2156  return -EINTR;
2157 
2158  if (master->receive_cb != NULL)
2159  master->receive_cb(master->cb_data);
2160  else
2161  ecrt_master_receive(master);
2162 
2163  ec_ioctl_lock_up(&master->io_sem);
2164 
2165  return 0;
2166 }
2167 
2168 /*****************************************************************************/
2169 
2175  ec_master_t *master,
2176  void *arg,
2177  ec_ioctl_context_t *ctx
2178  )
2179 {
2180  ec_master_state_t data;
2181 
2182  ecrt_master_state(master, &data);
2183 
2184  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2185  return -EFAULT;
2186 
2187  return 0;
2188 }
2189 
2190 /*****************************************************************************/
2191 
2197  ec_master_t *master,
2198  void *arg,
2199  ec_ioctl_context_t *ctx
2200  )
2201 {
2202  ec_ioctl_link_state_t ioctl;
2203  ec_master_link_state_t state;
2204  int ret;
2205 
2206  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
2207  return -EFAULT;
2208  }
2209 
2210  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
2211  if (ret < 0) {
2212  return ret;
2213  }
2214 
2215  if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
2216  return -EFAULT;
2217  }
2218 
2219  return 0;
2220 }
2221 
2222 /*****************************************************************************/
2223 
2229  ec_master_t *master,
2230  void *arg,
2231  ec_ioctl_context_t *ctx
2232  )
2233 {
2234  uint64_t time;
2235 
2236  if (unlikely(!ctx->requested))
2237  return -EPERM;
2238 
2239  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2240  return -EFAULT;
2241  }
2242 
2243  ecrt_master_application_time(master, time);
2244  return 0;
2245 }
2246 
2247 /*****************************************************************************/
2248 
2254  ec_master_t *master,
2255  void *arg,
2256  ec_ioctl_context_t *ctx
2257  )
2258 {
2259  if (unlikely(!ctx->requested)) {
2260  return -EPERM;
2261  }
2262 
2264  return -EINTR;
2266  ec_ioctl_lock_up(&master->io_sem);
2267  return 0;
2268 }
2269 
2270 /*****************************************************************************/
2271 
2277  ec_master_t *master,
2278  void *arg,
2279  ec_ioctl_context_t *ctx
2280  )
2281 {
2282  uint64_t time;
2283 
2284  if (unlikely(!ctx->requested))
2285  return -EPERM;
2286 
2287  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2288  return -EFAULT;
2289  }
2290 
2292  return -EINTR;
2294  ec_ioctl_lock_up(&master->io_sem);
2295  return 0;
2296 }
2297 
2298 /*****************************************************************************/
2299 
2305  ec_master_t *master,
2306  void *arg,
2307  ec_ioctl_context_t *ctx
2308  )
2309 {
2310  if (unlikely(!ctx->requested)) {
2311  return -EPERM;
2312  }
2313 
2315  return -EINTR;
2317  ec_ioctl_lock_up(&master->io_sem);
2318  return 0;
2319 }
2320 
2321 /*****************************************************************************/
2322 
2328  ec_master_t *master,
2329  void *arg,
2330  ec_ioctl_context_t *ctx
2331  )
2332 {
2333  uint32_t time;
2334  int ret;
2335 
2336  if (unlikely(!ctx->requested)) {
2337  return -EPERM;
2338  }
2339 
2340  ret = ecrt_master_reference_clock_time(master, &time);
2341  if (ret) {
2342  return ret;
2343  }
2344 
2345  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2346  return -EFAULT;
2347  }
2348 
2349  return 0;
2350 }
2351 
2352 /*****************************************************************************/
2353 
2359  ec_master_t *master,
2360  void *arg,
2361  ec_ioctl_context_t *ctx
2362  )
2363 {
2364  if (unlikely(!ctx->requested)) {
2365  return -EPERM;
2366  }
2367 
2369  return -EINTR;
2371  ec_ioctl_lock_up(&master->io_sem);
2372  return 0;
2373 }
2374 
2375 /*****************************************************************************/
2376 
2382  ec_master_t *master,
2383  void *arg,
2384  ec_ioctl_context_t *ctx
2385  )
2386 {
2387  uint64_t time;
2388  int ret;
2389 
2390  if (unlikely(!ctx->requested)) {
2391  return -EPERM;
2392  }
2393 
2394  ret = ecrt_master_64bit_reference_clock_time(master, &time);
2395  if (ret) {
2396  return ret;
2397  }
2398 
2399  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2400  return -EFAULT;
2401  }
2402 
2403  return 0;
2404 }
2405 
2406 /*****************************************************************************/
2407 
2413  ec_master_t *master,
2414  void *arg,
2415  ec_ioctl_context_t *ctx
2416  )
2417 {
2418  if (unlikely(!ctx->requested)) {
2419  return -EPERM;
2420  }
2421 
2423  return -EINTR;
2425  ec_ioctl_lock_up(&master->io_sem);
2426  return 0;
2427 }
2428 
2429 /*****************************************************************************/
2430 
2436  ec_master_t *master,
2437  void *arg,
2438  ec_ioctl_context_t *ctx
2439  )
2440 {
2441  uint32_t time_diff;
2442 
2443  if (unlikely(!ctx->requested))
2444  return -EPERM;
2445 
2446  time_diff = ecrt_master_sync_monitor_process(master);
2447 
2448  if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2449  return -EFAULT;
2450 
2451  return 0;
2452 }
2453 
2454 /*****************************************************************************/
2455 
2461  ec_master_t *master,
2462  void *arg,
2463  ec_ioctl_context_t *ctx
2464  )
2465 {
2466  ec_lock_down(&master->master_sem);
2467  ecrt_master_reset(master);
2468  ec_lock_up(&master->master_sem);
2469  return 0;
2470 }
2471 
2472 /*****************************************************************************/
2473 
2479  ec_master_t *master,
2480  void *arg,
2481  ec_ioctl_context_t *ctx
2482  )
2483 {
2484  ec_ioctl_config_t data;
2485  ec_slave_config_t *sc;
2486  unsigned int i;
2487  int ret = 0;
2488 
2489  if (unlikely(!ctx->requested)) {
2490  ret = -EPERM;
2491  goto out_return;
2492  }
2493 
2494  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2495  ret = -EFAULT;
2496  goto out_return;
2497  }
2498 
2499  if (ec_lock_down_interruptible(&master->master_sem)) {
2500  ret = -EINTR;
2501  goto out_return;
2502  }
2503 
2504  if (!(sc = ec_master_get_config(master, data.config_index))) {
2505  ret = -ENOENT;
2506  goto out_up;
2507  }
2508 
2509  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2510  if (data.syncs[i].config_this) {
2511  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2512  data.syncs[i].watchdog_mode);
2513  if (ret) {
2514  goto out_up;
2515  }
2516  }
2517  }
2518 
2519 out_up:
2520  ec_lock_up(&master->master_sem);
2521 out_return:
2522  return ret;
2523 }
2524 
2525 /*****************************************************************************/
2526 
2532  ec_master_t *master,
2533  void *arg,
2534  ec_ioctl_context_t *ctx
2535  )
2536 {
2537  ec_ioctl_config_t data;
2538  ec_slave_config_t *sc;
2539  int ret = 0;
2540 
2541  if (unlikely(!ctx->requested)) {
2542  ret = -EPERM;
2543  goto out_return;
2544  }
2545 
2546  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2547  ret = -EFAULT;
2548  goto out_return;
2549  }
2550 
2551  if (ec_lock_down_interruptible(&master->master_sem)) {
2552  ret = -EINTR;
2553  goto out_return;
2554  }
2555 
2556  if (!(sc = ec_master_get_config(master, data.config_index))) {
2557  ret = -ENOENT;
2558  goto out_up;
2559  }
2560 
2562  data.watchdog_divider, data.watchdog_intervals);
2563 
2564 out_up:
2565  ec_lock_up(&master->master_sem);
2566 out_return:
2567  return ret;
2568 }
2569 
2570 /*****************************************************************************/
2571 
2575  ec_master_t *master,
2576  void *arg,
2577  ec_ioctl_context_t *ctx
2578  )
2579 {
2580  ec_ioctl_config_t data;
2581  ec_slave_config_t *sc;
2582  int ret = 0;
2583 
2584  if (unlikely(!ctx->requested)) {
2585  ret = -EPERM;
2586  goto out_return;
2587  }
2588 
2589  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2590  ret = -EFAULT;
2591  goto out_return;
2592  }
2593 
2594  if (ec_lock_down_interruptible(&master->master_sem)) {
2595  ret = -EINTR;
2596  goto out_return;
2597  }
2598 
2599  if (!(sc = ec_master_get_config(master, data.config_index))) {
2600  ret = -ENOENT;
2601  goto out_up;
2602  }
2603 
2605  data.allow_overlapping_pdos);
2606 
2607 out_up:
2608  ec_lock_up(&master->master_sem);
2609 out_return:
2610  return ret;
2611 }
2612 /*****************************************************************************/
2613 
2619  ec_master_t *master,
2620  void *arg,
2621  ec_ioctl_context_t *ctx
2622  )
2623 {
2624  ec_ioctl_config_pdo_t data;
2625  ec_slave_config_t *sc;
2626 
2627  if (unlikely(!ctx->requested))
2628  return -EPERM;
2629 
2630  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2631  return -EFAULT;
2632 
2633  if (ec_lock_down_interruptible(&master->master_sem))
2634  return -EINTR;
2635 
2636  if (!(sc = ec_master_get_config(master, data.config_index))) {
2637  ec_lock_up(&master->master_sem);
2638  return -ENOENT;
2639  }
2640 
2641  ec_lock_up(&master->master_sem);
2643  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
2644 }
2645 
2646 /*****************************************************************************/
2647 
2653  ec_master_t *master,
2654  void *arg,
2655  ec_ioctl_context_t *ctx
2656  )
2657 {
2658  ec_ioctl_config_pdo_t data;
2659  ec_slave_config_t *sc;
2660 
2661  if (unlikely(!ctx->requested))
2662  return -EPERM;
2663 
2664  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2665  return -EFAULT;
2666 
2667  if (ec_lock_down_interruptible(&master->master_sem))
2668  return -EINTR;
2669 
2670  if (!(sc = ec_master_get_config(master, data.config_index))) {
2671  ec_lock_up(&master->master_sem);
2672  return -ENOENT;
2673  }
2674 
2675  ec_lock_up(&master->master_sem);
2677  ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
2678  return 0;
2679 }
2680 
2681 /*****************************************************************************/
2682 
2688  ec_master_t *master,
2689  void *arg,
2690  ec_ioctl_context_t *ctx
2691  )
2692 {
2693  ec_ioctl_add_pdo_entry_t data;
2694  ec_slave_config_t *sc;
2695 
2696  if (unlikely(!ctx->requested))
2697  return -EPERM;
2698 
2699  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2700  return -EFAULT;
2701 
2702  if (ec_lock_down_interruptible(&master->master_sem))
2703  return -EINTR;
2704 
2705  if (!(sc = ec_master_get_config(master, data.config_index))) {
2706  ec_lock_up(&master->master_sem);
2707  return -ENOENT;
2708  }
2709 
2710  ec_lock_up(&master->master_sem);
2712  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
2713  data.entry_index, data.entry_subindex, data.entry_bit_length);
2714 }
2715 
2716 /*****************************************************************************/
2717 
2723  ec_master_t *master,
2724  void *arg,
2725  ec_ioctl_context_t *ctx
2726  )
2727 {
2728  ec_ioctl_config_pdo_t data;
2729  ec_slave_config_t *sc;
2730 
2731  if (unlikely(!ctx->requested))
2732  return -EPERM;
2733 
2734  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2735  return -EFAULT;
2736 
2737  if (ec_lock_down_interruptible(&master->master_sem))
2738  return -EINTR;
2739 
2740  if (!(sc = ec_master_get_config(master, data.config_index))) {
2741  ec_lock_up(&master->master_sem);
2742  return -ENOENT;
2743  }
2744 
2745  ec_lock_up(&master->master_sem);
2747  ecrt_slave_config_pdo_mapping_clear(sc, data.index);
2748  return 0;
2749 }
2750 
2751 /*****************************************************************************/
2752 
2758  ec_master_t *master,
2759  void *arg,
2760  ec_ioctl_context_t *ctx
2761  )
2762 {
2763  ec_ioctl_reg_pdo_entry_t data;
2764  ec_slave_config_t *sc;
2765  ec_domain_t *domain;
2766  int ret;
2767 
2768  if (unlikely(!ctx->requested))
2769  return -EPERM;
2770 
2771  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2772  return -EFAULT;
2773 
2774  if (ec_lock_down_interruptible(&master->master_sem))
2775  return -EINTR;
2776 
2777  if (!(sc = ec_master_get_config(master, data.config_index))) {
2778  ec_lock_up(&master->master_sem);
2779  return -ENOENT;
2780  }
2781 
2782  ec_lock_up(&master->master_sem);
2783 
2784  if (ec_lock_down_interruptible(&master->domains_lock))
2785  return -EINTR;
2786  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
2787  ec_lock_up(&master->domains_lock);
2788  return -ENOENT;
2789  }
2790  ec_lock_up(&master->domains_lock);
2791 
2794  /* FIXME: As ecrt_slave_config_reg_pdo_entry() calls
2795  * ec_slave_config_prepare_fmmu() which locks master_sem we must release
2796  * domains_lock, as it would break lock ordering, and thus cause
2797  * deadlocks. Unfortunately, this leaves a race condition, as the domain
2798  * could be cleared/deleted while ecrt_slave_config_reg_pdo_entry() is
2799  * called. So the above todo statement still holds :( */
2800 
2801  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
2802  data.entry_subindex, domain, &data.bit_position);
2803 
2804  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2805  return -EFAULT;
2806 
2807  return ret;
2808 }
2809 
2810 /*****************************************************************************/
2811 
2817  ec_master_t *master,
2818  void *arg,
2819  ec_ioctl_context_t *ctx
2820  )
2821 {
2822  ec_ioctl_reg_pdo_pos_t io;
2823  ec_slave_config_t *sc;
2824  ec_domain_t *domain;
2825  int ret;
2826 
2827  if (unlikely(!ctx->requested)) {
2828  return -EPERM;
2829  }
2830 
2831  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
2832  return -EFAULT;
2833  }
2834 
2835  if (ec_lock_down_interruptible(&master->master_sem)) {
2836  return -EINTR;
2837  }
2838 
2839  if (!(sc = ec_master_get_config(master, io.config_index))) {
2840  ec_lock_up(&master->master_sem);
2841  return -ENOENT;
2842  }
2843  ec_lock_up(&master->master_sem);
2844 
2845  if (ec_lock_down_interruptible(&master->domains_lock))
2846  return -EINTR;
2847  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
2848  ec_lock_up(&master->domains_lock);
2849  return -ENOENT;
2850  }
2851  ec_lock_up(&master->domains_lock);
2852 
2855  /* FIXME: As ecrt_slave_config_reg_pdo_entry_pos() calls
2856  * ec_slave_config_prepare_fmmu() which locks master_sem we must release
2857  * domains_lock, as it would break lock ordering, and thus cause
2858  * deadlocks. Unfortunately, this leaves a race condition, as the domain
2859  * could be cleared/deleted while ecrt_slave_config_reg_pdo_entry() is
2860  * called. So the above todo statement still holds :( */
2861 
2862  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
2863  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
2864 
2865  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
2866  return -EFAULT;
2867 
2868  return ret;
2869 }
2870 
2871 /*****************************************************************************/
2872 
2878  ec_master_t *master,
2879  void *arg,
2880  ec_ioctl_context_t *ctx
2881  )
2882 {
2883  ec_ioctl_config_t data;
2884  ec_slave_config_t *sc;
2885 
2886  if (unlikely(!ctx->requested))
2887  return -EPERM;
2888 
2889  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2890  return -EFAULT;
2891 
2892  if (ec_lock_down_interruptible(&master->master_sem))
2893  return -EINTR;
2894 
2895  if (!(sc = ec_master_get_config(master, data.config_index))) {
2896  ec_lock_up(&master->master_sem);
2897  return -ENOENT;
2898  }
2899 
2901  data.dc_sync[0].cycle_time,
2902  data.dc_sync[0].shift_time,
2903  data.dc_sync[1].cycle_time,
2904  data.dc_sync[1].shift_time);
2905 
2906  ec_lock_up(&master->master_sem);
2907 
2908  return 0;
2909 }
2910 
2911 /*****************************************************************************/
2912 
2918  ec_master_t *master,
2919  void *arg,
2920  ec_ioctl_context_t *ctx
2921  )
2922 {
2923  ec_ioctl_sc_sdo_t data;
2924  ec_slave_config_t *sc;
2925  uint8_t *sdo_data = NULL;
2926  int ret;
2927 
2928  if (unlikely(!ctx->requested))
2929  return -EPERM;
2930 
2931  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2932  return -EFAULT;
2933 
2934  if (!data.size)
2935  return -EINVAL;
2936 
2937  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
2938  return -ENOMEM;
2939  }
2940 
2941  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
2942  kfree(sdo_data);
2943  return -EFAULT;
2944  }
2945 
2946  if (ec_lock_down_interruptible(&master->master_sem)) {
2947  kfree(sdo_data);
2948  return -EINTR;
2949  }
2950 
2951  if (!(sc = ec_master_get_config(master, data.config_index))) {
2952  ec_lock_up(&master->master_sem);
2953  kfree(sdo_data);
2954  return -ENOENT;
2955  }
2956 
2957  ec_lock_up(&master->master_sem);
2959  if (data.complete_access) {
2961  data.index, sdo_data, data.size);
2962  } else {
2963  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
2964  data.size);
2965  }
2966  kfree(sdo_data);
2967  return ret;
2968 }
2969 
2970 /*****************************************************************************/
2971 
2977  ec_master_t *master,
2978  void *arg,
2979  ec_ioctl_context_t *ctx
2980  )
2981 {
2982  ec_ioctl_sc_emerg_t io;
2983  ec_slave_config_t *sc;
2984  int ret;
2985 
2986  if (unlikely(!ctx->requested))
2987  return -EPERM;
2988 
2989  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
2990  return -EFAULT;
2991 
2992  if (ec_lock_down_interruptible(&master->master_sem)) {
2993  return -EINTR;
2994  }
2995 
2996  if (!(sc = ec_master_get_config(master, io.config_index))) {
2997  ec_lock_up(&master->master_sem);
2998  return -ENOENT;
2999  }
3000 
3001  ret = ecrt_slave_config_emerg_size(sc, io.size);
3002 
3003  ec_lock_up(&master->master_sem);
3004 
3005  return ret;
3006 }
3007 
3008 /*****************************************************************************/
3009 
3015  ec_master_t *master,
3016  void *arg,
3017  ec_ioctl_context_t *ctx
3018  )
3019 {
3020  ec_ioctl_sc_emerg_t io;
3021  ec_slave_config_t *sc;
3022  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
3023  int ret;
3024 
3025  if (unlikely(!ctx->requested)) {
3026  return -EPERM;
3027  }
3028 
3029  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3030  return -EFAULT;
3031  }
3032 
3033  /* no locking of master_sem needed, because configuration will not be
3034  * deleted in the meantime. */
3035 
3036  if (!(sc = ec_master_get_config(master, io.config_index))) {
3037  return -ENOENT;
3038  }
3039 
3040  ret = ecrt_slave_config_emerg_pop(sc, msg);
3041  if (ret < 0) {
3042  return ret;
3043  }
3044 
3045  if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
3046  return -EFAULT;
3047  }
3048 
3049  return ret;
3050 }
3051 
3052 /*****************************************************************************/
3053 
3059  ec_master_t *master,
3060  void *arg,
3061  ec_ioctl_context_t *ctx
3062  )
3063 {
3064  ec_ioctl_sc_emerg_t io;
3065  ec_slave_config_t *sc;
3066 
3067  if (unlikely(!ctx->requested)) {
3068  return -EPERM;
3069  }
3070 
3071  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3072  return -EFAULT;
3073  }
3074 
3075  /* no locking of master_sem needed, because configuration will not be
3076  * deleted in the meantime. */
3077 
3078  if (!(sc = ec_master_get_config(master, io.config_index))) {
3079  return -ENOENT;
3080  }
3081 
3082  return ecrt_slave_config_emerg_clear(sc);
3083 }
3084 
3085 /*****************************************************************************/
3086 
3092  ec_master_t *master,
3093  void *arg,
3094  ec_ioctl_context_t *ctx
3095  )
3096 {
3097  ec_ioctl_sc_emerg_t io;
3098  ec_slave_config_t *sc;
3099  int ret;
3100 
3101  if (unlikely(!ctx->requested)) {
3102  return -EPERM;
3103  }
3104 
3105  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3106  return -EFAULT;
3107  }
3108 
3109  /* no locking of master_sem needed, because configuration will not be
3110  * deleted in the meantime. */
3111 
3112  if (!(sc = ec_master_get_config(master, io.config_index))) {
3113  return -ENOENT;
3114  }
3115 
3117  if (ret < 0) {
3118  return ret;
3119  }
3120 
3121  io.overruns = ret;
3122 
3123  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3124  return -EFAULT;
3125  }
3126 
3127  return 0;
3128 }
3129 
3130 /*****************************************************************************/
3131 
3137  ec_master_t *master,
3138  void *arg,
3139  ec_ioctl_context_t *ctx
3140  )
3141 {
3142  ec_ioctl_sdo_request_t data;
3143  ec_slave_config_t *sc;
3144  ec_sdo_request_t *req;
3145 
3146  if (unlikely(!ctx->requested))
3147  return -EPERM;
3148 
3149  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3150  return -EFAULT;
3151  }
3152 
3153  data.request_index = 0;
3154 
3155  if (ec_lock_down_interruptible(&master->master_sem))
3156  return -EINTR;
3157 
3158  sc = ec_master_get_config(master, data.config_index);
3159  if (!sc) {
3160  ec_lock_up(&master->master_sem);
3161  return -ENOENT;
3162  }
3163 
3164  list_for_each_entry(req, &sc->sdo_requests, list) {
3165  data.request_index++;
3166  }
3167 
3168  ec_lock_up(&master->master_sem);
3170  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
3171  data.sdo_subindex, data.size);
3172  if (IS_ERR(req))
3173  return PTR_ERR(req);
3174 
3175  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3176  return -EFAULT;
3177 
3178  return 0;
3179 }
3180 
3181 /*****************************************************************************/
3182 
3188  ec_master_t *master,
3189  void *arg,
3190  ec_ioctl_context_t *ctx
3191  )
3192 {
3193  ec_ioctl_reg_request_t io;
3194  ec_slave_config_t *sc;
3195  ec_reg_request_t *reg;
3196 
3197  if (unlikely(!ctx->requested)) {
3198  return -EPERM;
3199  }
3200 
3201  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3202  return -EFAULT;
3203  }
3204 
3205  io.request_index = 0;
3206 
3207  if (ec_lock_down_interruptible(&master->master_sem)) {
3208  return -EINTR;
3209  }
3210 
3211  sc = ec_master_get_config(master, io.config_index);
3212  if (!sc) {
3213  ec_lock_up(&master->master_sem);
3214  return -ENOENT;
3215  }
3216 
3217  list_for_each_entry(reg, &sc->reg_requests, list) {
3218  io.request_index++;
3219  }
3220 
3221  ec_lock_up(&master->master_sem);
3223  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
3224  if (IS_ERR(reg)) {
3225  return PTR_ERR(reg);
3226  }
3227 
3228  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3229  return -EFAULT;
3230  }
3231 
3232  return 0;
3233 }
3234 
3235 /*****************************************************************************/
3236 
3242  ec_master_t *master,
3243  void *arg,
3244  ec_ioctl_context_t *ctx
3245  )
3246 {
3247  ec_ioctl_voe_t data;
3248  ec_slave_config_t *sc;
3249  ec_voe_handler_t *voe;
3250 
3251  if (unlikely(!ctx->requested))
3252  return -EPERM;
3253 
3254  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3255  return -EFAULT;
3256  }
3257 
3258  data.voe_index = 0;
3259 
3260  if (ec_lock_down_interruptible(&master->master_sem))
3261  return -EINTR;
3262 
3263  sc = ec_master_get_config(master, data.config_index);
3264  if (!sc) {
3265  ec_lock_up(&master->master_sem);
3266  return -ENOENT;
3267  }
3268 
3269  list_for_each_entry(voe, &sc->voe_handlers, list) {
3270  data.voe_index++;
3271  }
3272 
3273  ec_lock_up(&master->master_sem);
3275  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
3276  if (IS_ERR(voe))
3277  return PTR_ERR(voe);
3278 
3279  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3280  return -EFAULT;
3281 
3282  return 0;
3283 }
3284 
3285 /*****************************************************************************/
3286 
3292  ec_master_t *master,
3293  void *arg,
3294  ec_ioctl_context_t *ctx
3295  )
3296 {
3297  ec_ioctl_sc_state_t data;
3298  const ec_slave_config_t *sc;
3300 
3301  if (unlikely(!ctx->requested))
3302  return -EPERM;
3303 
3304  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3305  return -EFAULT;
3306  }
3307 
3308  /* no locking of master_sem needed, because sc will not be deleted in the
3309  * meantime. */
3310 
3311  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
3312  return -ENOENT;
3313  }
3314 
3315  ecrt_slave_config_state(sc, &state);
3316 
3317  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3318  return -EFAULT;
3319 
3320  return 0;
3321 }
3322 
3323 /*****************************************************************************/
3324 
3330  ec_master_t *master,
3331  void *arg,
3332  ec_ioctl_context_t *ctx
3333  )
3334 {
3335  ec_ioctl_sc_idn_t ioctl;
3336  ec_slave_config_t *sc;
3337  uint8_t *data = NULL;
3338  int ret;
3339 
3340  if (unlikely(!ctx->requested))
3341  return -EPERM;
3342 
3343  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
3344  return -EFAULT;
3345 
3346  if (!ioctl.size)
3347  return -EINVAL;
3348 
3349  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
3350  return -ENOMEM;
3351  }
3352 
3353  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
3354  kfree(data);
3355  return -EFAULT;
3356  }
3357 
3358  if (ec_lock_down_interruptible(&master->master_sem)) {
3359  kfree(data);
3360  return -EINTR;
3361  }
3362 
3363  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3364  ec_lock_up(&master->master_sem);
3365  kfree(data);
3366  return -ENOENT;
3367  }
3368 
3369  ec_lock_up(&master->master_sem);
3371  ret = ecrt_slave_config_idn(
3372  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3373  kfree(data);
3374  return ret;
3375 }
3376 
3377 /*****************************************************************************/
3378 
3384  ec_master_t *master,
3385  void *arg,
3386  ec_ioctl_context_t *ctx
3387  )
3388 {
3389  ec_ioctl_sc_flag_t ioctl;
3390  ec_slave_config_t *sc;
3391  uint8_t *key;
3392  int ret;
3393 
3394  if (unlikely(!ctx->requested)) {
3395  return -EPERM;
3396  }
3397 
3398  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
3399  return -EFAULT;
3400  }
3401 
3402  if (!ioctl.key_size) {
3403  return -EINVAL;
3404  }
3405 
3406  if (!(key = kmalloc(ioctl.key_size + 1, GFP_KERNEL))) {
3407  return -ENOMEM;
3408  }
3409 
3410  if (copy_from_user(key, (void __user *) ioctl.key, ioctl.key_size)) {
3411  kfree(key);
3412  return -EFAULT;
3413  }
3414 
3415  if (ec_lock_down_interruptible(&master->master_sem)) {
3416  kfree(key);
3417  return -EINTR;
3418  }
3419 
3420  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3421  ec_lock_up(&master->master_sem);
3422  kfree(key);
3423  return -ENOENT;
3424  }
3425 
3426  ec_lock_up(&master->master_sem);
3428  ret = ecrt_slave_config_flag(sc, key, ioctl.value);
3429  kfree(key);
3430  return ret;
3431 }
3432 
3433 /*****************************************************************************/
3434 
3440  ec_master_t *master,
3441  void *arg,
3442  ec_ioctl_context_t *ctx
3443  )
3444 {
3445  const ec_domain_t *domain;
3446 
3447  if (unlikely(!ctx->requested)) {
3448  return -EPERM;
3449  }
3450 
3451  if (ec_lock_down_interruptible(&master->domains_lock)) {
3452  return -EINTR;
3453  }
3454 
3455  list_for_each_entry(domain, &master->domains, list) {
3456  if (domain->index == (unsigned long) arg) {
3457  size_t size = ecrt_domain_size(domain);
3458  ec_lock_up(&master->domains_lock);
3459  return size;
3460  }
3461  }
3462 
3463  ec_lock_up(&master->domains_lock);
3464  return -ENOENT;
3465 }
3466 
3467 /*****************************************************************************/
3468 
3474  ec_master_t *master,
3475  void *arg,
3476  ec_ioctl_context_t *ctx
3477  )
3478 {
3479  int offset = 0;
3480  const ec_domain_t *domain;
3481 
3482  if (unlikely(!ctx->requested))
3483  return -EPERM;
3484 
3485  if (ec_lock_down_interruptible(&master->domains_lock)) {
3486  return -EINTR;
3487  }
3488 
3489  list_for_each_entry(domain, &master->domains, list) {
3490  if (domain->index == (unsigned long) arg) {
3491  ec_lock_up(&master->domains_lock);
3492  return offset;
3493  }
3494  offset += ecrt_domain_size(domain);
3495  }
3496 
3497  ec_lock_up(&master->domains_lock);
3498  return -ENOENT;
3499 }
3500 
3501 /*****************************************************************************/
3502 
3508  ec_master_t *master,
3509  void *arg,
3510  ec_ioctl_context_t *ctx
3511  )
3512 {
3513  ec_domain_t *domain;
3514 
3515  if (unlikely(!ctx->requested))
3516  return -EPERM;
3517 
3518  /* Locking added as domain processing is likely to be used by more than
3519  one application tasks */
3521  return -EINTR;
3522  }
3523 
3524  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3525  ec_ioctl_lock_up(&master->domains_lock);
3526  return -ENOENT;
3527  }
3528 
3529  ecrt_domain_process(domain);
3530  ec_ioctl_lock_up(&master->domains_lock);
3531  return 0;
3532 }
3533 
3534 /*****************************************************************************/
3535 
3541  ec_master_t *master,
3542  void *arg,
3543  ec_ioctl_context_t *ctx
3544  )
3545 {
3546  ec_domain_t *domain;
3547 
3548  if (unlikely(!ctx->requested))
3549  return -EPERM;
3550 
3551  /* Locking added as domain queing is likely to be used by more than
3552  one application tasks */
3554  return -EINTR;
3555  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3556  ec_ioctl_lock_up(&master->domains_lock);
3557  return -ENOENT;
3558  }
3559 
3560  if (ec_ioctl_lock_down_interruptible(&master->io_sem)) {
3561  ec_ioctl_lock_up(&master->domains_lock);
3562  return -EINTR;
3563  }
3564  ecrt_domain_queue(domain);
3565  ec_ioctl_lock_up(&master->io_sem);
3566 
3567  ec_ioctl_lock_up(&master->domains_lock);
3568 
3569  return 0;
3570 }
3571 
3572 /*****************************************************************************/
3573 
3579  ec_master_t *master,
3580  void *arg,
3581  ec_ioctl_context_t *ctx
3582  )
3583 {
3584  ec_ioctl_domain_state_t data;
3585  const ec_domain_t *domain;
3586  ec_domain_state_t state;
3587 
3588  if (unlikely(!ctx->requested))
3589  return -EPERM;
3590 
3591  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3592  return -EFAULT;
3593  }
3594 
3596  return -EINTR;
3597 
3598  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3599  ec_ioctl_lock_up(&master->domains_lock);
3600  return -ENOENT;
3601  }
3602 
3603  ecrt_domain_state(domain, &state);
3604 
3605  ec_ioctl_lock_up(&master->domains_lock);
3606 
3607  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3608  return -EFAULT;
3609 
3610  return 0;
3611 }
3612 
3613 /*****************************************************************************/
3614 
3620  ec_master_t *master,
3621  void *arg,
3622  ec_ioctl_context_t *ctx
3623  )
3624 {
3625  ec_ioctl_sdo_request_t data;
3626  ec_slave_config_t *sc;
3627  ec_sdo_request_t *req;
3628 
3629  if (unlikely(!ctx->requested))
3630  return -EPERM;
3631 
3632  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3633  return -EFAULT;
3634 
3635  /* no locking of master_sem needed, because neither sc nor req will not be
3636  * deleted in the meantime. */
3637 
3638  if (!(sc = ec_master_get_config(master, data.config_index))) {
3639  return -ENOENT;
3640  }
3641 
3642  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3643  return -ENOENT;
3644  }
3645 
3646  ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3647  return 0;
3648 }
3649 
3650 /*****************************************************************************/
3651 
3657  ec_master_t *master,
3658  void *arg,
3659  ec_ioctl_context_t *ctx
3660  )
3661 {
3662  ec_ioctl_sdo_request_t data;
3663  ec_slave_config_t *sc;
3664  ec_sdo_request_t *req;
3665 
3666  if (unlikely(!ctx->requested))
3667  return -EPERM;
3668 
3669  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3670  return -EFAULT;
3671 
3672  /* no locking of master_sem needed, because neither sc nor req will not be
3673  * deleted in the meantime. */
3674 
3675  if (!(sc = ec_master_get_config(master, data.config_index))) {
3676  return -ENOENT;
3677  }
3678 
3679  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3680  return -ENOENT;
3681  }
3682 
3683  ecrt_sdo_request_timeout(req, data.timeout);
3684  return 0;
3685 }
3686 
3687 /*****************************************************************************/
3688 
3694  ec_master_t *master,
3695  void *arg,
3696  ec_ioctl_context_t *ctx
3697  )
3698 {
3699  ec_ioctl_sdo_request_t data;
3700  ec_slave_config_t *sc;
3701  ec_sdo_request_t *req;
3702 
3703  if (unlikely(!ctx->requested))
3704  return -EPERM;
3705 
3706  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3707  return -EFAULT;
3708 
3709  /* no locking of master_sem needed, because neither sc nor req will not be
3710  * deleted in the meantime. */
3711 
3712  if (!(sc = ec_master_get_config(master, data.config_index))) {
3713  return -ENOENT;
3714  }
3715 
3716  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3717  return -ENOENT;
3718  }
3719 
3720  data.state = ecrt_sdo_request_state(req);
3721  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
3722  data.size = ecrt_sdo_request_data_size(req);
3723  else
3724  data.size = 0;
3725 
3726  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3727  return -EFAULT;
3728 
3729  return 0;
3730 }
3731 
3732 /*****************************************************************************/
3733 
3739  ec_master_t *master,
3740  void *arg,
3741  ec_ioctl_context_t *ctx
3742  )
3743 {
3744  ec_ioctl_sdo_request_t data;
3745  ec_slave_config_t *sc;
3746  ec_sdo_request_t *req;
3747 
3748  if (unlikely(!ctx->requested))
3749  return -EPERM;
3750 
3751  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3752  return -EFAULT;
3753 
3754  /* no locking of master_sem needed, because neither sc nor req will not be
3755  * deleted in the meantime. */
3756 
3757  if (!(sc = ec_master_get_config(master, data.config_index))) {
3758  return -ENOENT;
3759  }
3760 
3761  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3762  return -ENOENT;
3763  }
3764 
3765  ecrt_sdo_request_read(req);
3766  return 0;
3767 }
3768 
3769 /*****************************************************************************/
3770 
3776  ec_master_t *master,
3777  void *arg,
3778  ec_ioctl_context_t *ctx
3779  )
3780 {
3781  ec_ioctl_sdo_request_t data;
3782  ec_slave_config_t *sc;
3783  ec_sdo_request_t *req;
3784  int ret;
3785 
3786  if (unlikely(!ctx->requested))
3787  return -EPERM;
3788 
3789  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3790  return -EFAULT;
3791 
3792  if (!data.size) {
3793  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
3794  return -EINVAL;
3795  }
3796 
3797  /* no locking of master_sem needed, because neither sc nor req will not be
3798  * deleted in the meantime. */
3799 
3800  if (!(sc = ec_master_get_config(master, data.config_index))) {
3801  return -ENOENT;
3802  }
3803 
3804  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3805  return -ENOENT;
3806  }
3807 
3808  ret = ec_sdo_request_alloc(req, data.size);
3809  if (ret)
3810  return ret;
3811 
3812  if (copy_from_user(req->data, (void __user *) data.data, data.size))
3813  return -EFAULT;
3814 
3815  req->data_size = data.size;
3817  return 0;
3818 }
3819 
3820 /*****************************************************************************/
3821 
3827  ec_master_t *master,
3828  void *arg,
3829  ec_ioctl_context_t *ctx
3830  )
3831 {
3832  ec_ioctl_sdo_request_t data;
3833  ec_slave_config_t *sc;
3834  ec_sdo_request_t *req;
3835 
3836  if (unlikely(!ctx->requested))
3837  return -EPERM;
3838 
3839  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3840  return -EFAULT;
3841 
3842  /* no locking of master_sem needed, because neither sc nor req will not be
3843  * deleted in the meantime. */
3844 
3845  if (!(sc = ec_master_get_config(master, data.config_index))) {
3846  return -ENOENT;
3847  }
3848 
3849  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3850  return -ENOENT;
3851  }
3852 
3853  if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
3855  return -EFAULT;
3856 
3857  return 0;
3858 }
3859 
3860 /*****************************************************************************/
3861 
3867  ec_master_t *master,
3868  void *arg,
3869  ec_ioctl_context_t *ctx
3870  )
3871 {
3872  ec_ioctl_reg_request_t io;
3873  ec_slave_config_t *sc;
3874  ec_reg_request_t *reg;
3875 
3876  if (unlikely(!ctx->requested)) {
3877  return -EPERM;
3878  }
3879 
3880  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3881  return -EFAULT;
3882  }
3883 
3884  if (io.mem_size <= 0) {
3885  return 0;
3886  }
3887 
3888  /* no locking of master_sem needed, because neither sc nor reg will not be
3889  * deleted in the meantime. */
3890 
3891  if (!(sc = ec_master_get_config(master, io.config_index))) {
3892  return -ENOENT;
3893  }
3894 
3895  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3896  return -ENOENT;
3897  }
3898 
3899  if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
3900  min(reg->mem_size, io.mem_size))) {
3901  return -EFAULT;
3902  }
3903 
3904  return 0;
3905 }
3906 
3907 /*****************************************************************************/
3908 
3914  ec_master_t *master,
3915  void *arg,
3916  ec_ioctl_context_t *ctx
3917  )
3918 {
3919  ec_ioctl_reg_request_t io;
3920  ec_slave_config_t *sc;
3921  ec_reg_request_t *reg;
3922 
3923  if (unlikely(!ctx->requested)) {
3924  return -EPERM;
3925  }
3926 
3927  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3928  return -EFAULT;
3929  }
3930 
3931  /* no locking of master_sem needed, because neither sc nor reg will not be
3932  * deleted in the meantime. */
3933 
3934  if (!(sc = ec_master_get_config(master, io.config_index))) {
3935  return -ENOENT;
3936  }
3937 
3938  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3939  return -ENOENT;
3940  }
3941 
3942  io.state = ecrt_reg_request_state(reg);
3943  io.new_data = io.state == EC_REQUEST_SUCCESS && reg->dir == EC_DIR_INPUT;
3944 
3945  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3946  return -EFAULT;
3947  }
3948 
3949  return 0;
3950 }
3951 
3952 /*****************************************************************************/
3953 
3959  ec_master_t *master,
3960  void *arg,
3961  ec_ioctl_context_t *ctx
3962  )
3963 {
3964  ec_ioctl_reg_request_t io;
3965  ec_slave_config_t *sc;
3966  ec_reg_request_t *reg;
3967 
3968  if (unlikely(!ctx->requested)) {
3969  return -EPERM;
3970  }
3971 
3972  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3973  return -EFAULT;
3974  }
3975 
3976  /* no locking of master_sem needed, because neither sc nor reg will not be
3977  * deleted in the meantime. */
3978 
3979  if (!(sc = ec_master_get_config(master, io.config_index))) {
3980  return -ENOENT;
3981  }
3982 
3983  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
3984  return -ENOENT;
3985  }
3986 
3987  if (io.transfer_size > reg->mem_size) {
3988  return -EOVERFLOW;
3989  }
3990 
3991  if (copy_from_user(reg->data, (void __user *) io.data,
3992  io.transfer_size)) {
3993  return -EFAULT;
3994  }
3995 
3996  ecrt_reg_request_write(reg, io.address, io.transfer_size);
3997  return 0;
3998 }
3999 
4000 /*****************************************************************************/
4001 
4007  ec_master_t *master,
4008  void *arg,
4009  ec_ioctl_context_t *ctx
4010  )
4011 {
4012  ec_ioctl_reg_request_t io;
4013  ec_slave_config_t *sc;
4014  ec_reg_request_t *reg;
4015 
4016  if (unlikely(!ctx->requested)) {
4017  return -EPERM;
4018  }
4019 
4020  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4021  return -EFAULT;
4022  }
4023 
4024  /* no locking of master_sem needed, because neither sc nor reg will not be
4025  * deleted in the meantime. */
4026 
4027  if (!(sc = ec_master_get_config(master, io.config_index))) {
4028  return -ENOENT;
4029  }
4030 
4031  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4032  return -ENOENT;
4033  }
4034 
4035  if (io.transfer_size > reg->mem_size) {
4036  return -EOVERFLOW;
4037  }
4038 
4039  ecrt_reg_request_read(reg, io.address, io.transfer_size);
4040  return 0;
4041 }
4042 
4043 /*****************************************************************************/
4044 
4050  ec_master_t *master,
4051  void *arg,
4052  ec_ioctl_context_t *ctx
4053  )
4054 {
4055  ec_ioctl_voe_t data;
4056  ec_slave_config_t *sc;
4057  ec_voe_handler_t *voe;
4058  uint32_t vendor_id;
4059  uint16_t vendor_type;
4060 
4061  if (unlikely(!ctx->requested))
4062  return -EPERM;
4063 
4064  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4065  return -EFAULT;
4066 
4067  if (get_user(vendor_id, data.vendor_id))
4068  return -EFAULT;
4069 
4070  if (get_user(vendor_type, data.vendor_type))
4071  return -EFAULT;
4072 
4073  /* no locking of master_sem needed, because neither sc nor voe will not be
4074  * deleted in the meantime. */
4075 
4076  if (!(sc = ec_master_get_config(master, data.config_index))) {
4077  return -ENOENT;
4078  }
4079 
4080  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4081  return -ENOENT;
4082  }
4083 
4084  ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
4085  return 0;
4086 }
4087 
4088 /*****************************************************************************/
4089 
4095  ec_master_t *master,
4096  void *arg,
4097  ec_ioctl_context_t *ctx
4098  )
4099 {
4100  ec_ioctl_voe_t data;
4101  ec_slave_config_t *sc;
4102  ec_voe_handler_t *voe;
4103  uint32_t vendor_id;
4104  uint16_t vendor_type;
4105 
4106  if (unlikely(!ctx->requested))
4107  return -EPERM;
4108 
4109  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4110  return -EFAULT;
4111 
4112  /* no locking of master_sem needed, because neither sc nor voe will not be
4113  * deleted in the meantime. */
4114 
4115  if (!(sc = ec_master_get_config(master, data.config_index))) {
4116  return -ENOENT;
4117  }
4118 
4119  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4120  return -ENOENT;
4121  }
4122 
4123  ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
4124 
4125  if (likely(data.vendor_id))
4126  if (put_user(vendor_id, data.vendor_id))
4127  return -EFAULT;
4128 
4129  if (likely(data.vendor_type))
4130  if (put_user(vendor_type, data.vendor_type))
4131  return -EFAULT;
4132 
4133  return 0;
4134 }
4135 
4136 /*****************************************************************************/
4137 
4143  ec_master_t *master,
4144  void *arg,
4145  ec_ioctl_context_t *ctx
4146  )
4147 {
4148  ec_ioctl_voe_t data;
4149  ec_slave_config_t *sc;
4150  ec_voe_handler_t *voe;
4151 
4152  if (unlikely(!ctx->requested))
4153  return -EPERM;
4154 
4155  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4156  return -EFAULT;
4157 
4158  /* no locking of master_sem needed, because neither sc nor voe will not be
4159  * deleted in the meantime. */
4160 
4161  if (!(sc = ec_master_get_config(master, data.config_index))) {
4162  return -ENOENT;
4163  }
4164 
4165  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4166  return -ENOENT;
4167  }
4168 
4169  ecrt_voe_handler_read(voe);
4170  return 0;
4171 }
4172 
4173 /*****************************************************************************/
4174 
4180  ec_master_t *master,
4181  void *arg,
4182  ec_ioctl_context_t *ctx
4183  )
4184 {
4185  ec_ioctl_voe_t data;
4186  ec_slave_config_t *sc;
4187  ec_voe_handler_t *voe;
4188 
4189  if (unlikely(!ctx->requested))
4190  return -EPERM;
4191 
4192  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4193  return -EFAULT;
4194 
4195  /* no locking of master_sem needed, because neither sc nor voe will not be
4196  * deleted in the meantime. */
4197 
4198  if (!(sc = ec_master_get_config(master, data.config_index))) {
4199  return -ENOENT;
4200  }
4201 
4202  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4203  return -ENOENT;
4204  }
4205 
4207  return 0;
4208 }
4209 
4210 /*****************************************************************************/
4211 
4217  ec_master_t *master,
4218  void *arg,
4219  ec_ioctl_context_t *ctx
4220  )
4221 {
4222  ec_ioctl_voe_t data;
4223  ec_slave_config_t *sc;
4224  ec_voe_handler_t *voe;
4225 
4226  if (unlikely(!ctx->requested))
4227  return -EPERM;
4228 
4229  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4230  return -EFAULT;
4231 
4232  /* no locking of master_sem needed, because neither sc nor voe will not be
4233  * deleted in the meantime. */
4234 
4235  if (!(sc = ec_master_get_config(master, data.config_index))) {
4236  return -ENOENT;
4237  }
4238 
4239  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4240  return -ENOENT;
4241  }
4242 
4243  if (data.size) {
4244  if (data.size > ec_voe_handler_mem_size(voe))
4245  return -EOVERFLOW;
4246 
4247  if (copy_from_user(ecrt_voe_handler_data(voe),
4248  (void __user *) data.data, data.size))
4249  return -EFAULT;
4250  }
4251 
4252  ecrt_voe_handler_write(voe, data.size);
4253  return 0;
4254 }
4255 
4256 /*****************************************************************************/
4257 
4263  ec_master_t *master,
4264  void *arg,
4265  ec_ioctl_context_t *ctx
4266  )
4267 {
4268  ec_ioctl_voe_t data;
4269  ec_slave_config_t *sc;
4270  ec_voe_handler_t *voe;
4271 
4272  if (unlikely(!ctx->requested))
4273  return -EPERM;
4274 
4275  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4276  return -EFAULT;
4277 
4278  /* no locking of master_sem needed, because neither sc nor voe will not be
4279  * deleted in the meantime. */
4280 
4281  if (!(sc = ec_master_get_config(master, data.config_index))) {
4282  return -ENOENT;
4283  }
4284 
4285  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4286  return -ENOENT;
4287  }
4288 
4290  return -EINTR;
4291  data.state = ecrt_voe_handler_execute(voe);
4292  ec_ioctl_lock_up(&master->io_sem);
4293  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
4294  data.size = ecrt_voe_handler_data_size(voe);
4295  else
4296  data.size = 0;
4297 
4298  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
4299  return -EFAULT;
4300 
4301  return 0;
4302 }
4303 
4304 /*****************************************************************************/
4305 
4311  ec_master_t *master,
4312  void *arg,
4313  ec_ioctl_context_t *ctx
4314  )
4315 {
4316  ec_ioctl_voe_t data;
4317  ec_slave_config_t *sc;
4318  ec_voe_handler_t *voe;
4319 
4320  if (unlikely(!ctx->requested))
4321  return -EPERM;
4322 
4323  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4324  return -EFAULT;
4325 
4326  /* no locking of master_sem needed, because neither sc nor voe will not be
4327  * deleted in the meantime. */
4328 
4329  if (!(sc = ec_master_get_config(master, data.config_index))) {
4330  return -ENOENT;
4331  }
4332 
4333  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4334  return -ENOENT;
4335  }
4336 
4337  if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
4339  return -EFAULT;
4340 
4341  return 0;
4342 }
4343 
4344 /*****************************************************************************/
4345 
4351  ec_master_t *master,
4352  void *arg
4353  )
4354 {
4355  ec_ioctl_slave_foe_t io;
4356  ec_foe_request_t request;
4357  ec_slave_t *slave;
4358  int ret;
4359 
4360  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4361  return -EFAULT;
4362  }
4363 
4364  ec_foe_request_init(&request, io.file_name);
4365  ret = ec_foe_request_alloc(&request, io.buffer_size); // FIXME
4366  if (ret) {
4367  ec_foe_request_clear(&request);
4368  return ret;
4369  }
4370 
4371  request.password = io.password;
4372  ec_foe_request_read(&request);
4373 
4374  if (ec_lock_down_interruptible(&master->master_sem)) {
4375  ec_foe_request_clear(&request);
4376  return -EINTR;
4377  }
4378 
4379  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4380  ec_lock_up(&master->master_sem);
4381  ec_foe_request_clear(&request);
4382  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4383  io.slave_position);
4384  return -EINVAL;
4385  }
4386 
4387  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
4388 
4389  // schedule request.
4390  list_add_tail(&request.list, &slave->foe_requests);
4391 
4392  ec_lock_up(&master->master_sem);
4393 
4394  // wait for processing through FSM
4395  if (wait_event_interruptible(master->request_queue,
4396  request.state != EC_INT_REQUEST_QUEUED)) {
4397  // interrupted by signal
4398  ec_lock_down(&master->master_sem);
4399  if (request.state == EC_INT_REQUEST_QUEUED) {
4400  list_del(&request.list);
4401  ec_lock_up(&master->master_sem);
4402  ec_foe_request_clear(&request);
4403  return -EINTR;
4404  }
4405  // request already processing: interrupt not possible.
4406  ec_lock_up(&master->master_sem);
4407  }
4408 
4409  // wait until master FSM has finished processing
4410  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4411 
4412  io.result = request.result;
4413  io.error_code = request.error_code;
4414 
4415  if (request.state != EC_INT_REQUEST_SUCCESS) {
4416  io.data_size = 0;
4417  ret = -EIO;
4418  } else {
4419  if (request.data_size > io.buffer_size) {
4420  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
4421  ec_foe_request_clear(&request);
4422  return -EOVERFLOW;
4423  }
4424  io.data_size = request.data_size;
4425  if (copy_to_user((void __user *) io.buffer,
4426  request.buffer, io.data_size)) {
4427  ec_foe_request_clear(&request);
4428  return -EFAULT;
4429  }
4430  ret = 0;
4431  }
4432 
4433  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4434  ret = -EFAULT;
4435  }
4436 
4437  ec_foe_request_clear(&request);
4438  return ret;
4439 }
4440 
4441 /*****************************************************************************/
4442 
4448  ec_master_t *master,
4449  void *arg
4450  )
4451 {
4452  ec_ioctl_slave_foe_t io;
4453  ec_foe_request_t request;
4454  ec_slave_t *slave;
4455  int ret;
4456 
4457  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4458  return -EFAULT;
4459  }
4460 
4461  ec_foe_request_init(&request, io.file_name);
4462 
4463  ret = ec_foe_request_alloc(&request, io.buffer_size);
4464  if (ret) {
4465  ec_foe_request_clear(&request);
4466  return ret;
4467  }
4468 
4469  if (copy_from_user(request.buffer,
4470  (void __user *) io.buffer, io.buffer_size)) {
4471  ec_foe_request_clear(&request);
4472  return -EFAULT;
4473  }
4474 
4475  request.data_size = io.buffer_size;
4476  request.password = io.password;
4477  ec_foe_request_write(&request);
4478 
4479  if (ec_lock_down_interruptible(&master->master_sem)) {
4480  ec_foe_request_clear(&request);
4481  return -EINTR;
4482  }
4483 
4484  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
4485  ec_lock_up(&master->master_sem);
4486  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
4487  io.slave_position);
4488  ec_foe_request_clear(&request);
4489  return -EINVAL;
4490  }
4491 
4492  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
4493 
4494  // schedule FoE write request.
4495  list_add_tail(&request.list, &slave->foe_requests);
4496 
4497  ec_lock_up(&master->master_sem);
4498 
4499  // wait for processing through FSM
4500  if (wait_event_interruptible(master->request_queue,
4501  request.state != EC_INT_REQUEST_QUEUED)) {
4502  // interrupted by signal
4503  ec_lock_down(&master->master_sem);
4504  if (request.state == EC_INT_REQUEST_QUEUED) {
4505  // abort request
4506  list_del(&request.list);
4507  ec_lock_up(&master->master_sem);
4508  ec_foe_request_clear(&request);
4509  return -EINTR;
4510  }
4511  ec_lock_up(&master->master_sem);
4512  }
4513 
4514  // wait until master FSM has finished processing
4515  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
4516 
4517  io.result = request.result;
4518  io.error_code = request.error_code;
4519 
4520  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
4521 
4522  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
4523  ret = -EFAULT;
4524  }
4525 
4526  ec_foe_request_clear(&request);
4527  return ret;
4528 }
4529 
4530 /*****************************************************************************/
4531 
4537  ec_master_t *master,
4538  void *arg
4539  )
4540 {
4541  ec_ioctl_slave_soe_read_t ioctl;
4542  u8 *data;
4543  int retval;
4544 
4545  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4546  return -EFAULT;
4547  }
4548 
4549  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
4550  if (!data) {
4551  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4552  ioctl.mem_size);
4553  return -ENOMEM;
4554  }
4555 
4556  retval = ecrt_master_read_idn(master, ioctl.slave_position,
4557  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
4558  &ioctl.error_code);
4559  if (retval) {
4560  kfree(data);
4561  return retval;
4562  }
4563 
4564  if (copy_to_user((void __user *) ioctl.data,
4565  data, ioctl.data_size)) {
4566  kfree(data);
4567  return -EFAULT;
4568  }
4569  kfree(data);
4570 
4571  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4572  retval = -EFAULT;
4573  }
4574 
4575  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
4576  return retval;
4577 }
4578 
4579 /*****************************************************************************/
4580 
4586  ec_master_t *master,
4587  void *arg
4588  )
4589 {
4590  ec_ioctl_slave_soe_write_t ioctl;
4591  u8 *data;
4592  int retval;
4593 
4594  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
4595  return -EFAULT;
4596  }
4597 
4598  data = kmalloc(ioctl.data_size, GFP_KERNEL);
4599  if (!data) {
4600  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
4601  ioctl.data_size);
4602  return -ENOMEM;
4603  }
4604  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
4605  kfree(data);
4606  return -EFAULT;
4607  }
4608 
4609  retval = ecrt_master_write_idn(master, ioctl.slave_position,
4610  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
4611  &ioctl.error_code);
4612  kfree(data);
4613  if (retval) {
4614  return retval;
4615  }
4616 
4617  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
4618  retval = -EFAULT;
4619  }
4620 
4621  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
4622  return retval;
4623 }
4624 
4625 /*****************************************************************************/
4631  ec_master_t *master,
4632  void *arg
4633  )
4634 {
4635  ec_ioctl_slave_dict_upload_t data;
4636  int ret;
4637 
4638  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
4639  return -EFAULT;
4640  }
4641 
4642  ret = ec_master_dict_upload(master, data.slave_position);
4643 
4644  return ret;
4645 }
4646 
4647 /*****************************************************************************/
4648 
4651 #ifdef EC_IOCTL_RTDM
4652 #define EC_IOCTL ec_ioctl_rtdm
4653 #else
4654 #define EC_IOCTL ec_ioctl
4655 #endif
4656 
4662  ec_master_t *master,
4663  ec_ioctl_context_t *ctx,
4664  unsigned int cmd,
4665  void *arg
4666  )
4667 {
4668 #if DEBUG_LATENCY
4669  cycles_t a = get_cycles(), b;
4670  unsigned int t;
4671 #endif
4672  int ret;
4673 
4674  switch (cmd) {
4675  case EC_IOCTL_MODULE:
4676  ret = ec_ioctl_module(arg);
4677  break;
4678  case EC_IOCTL_MASTER:
4679  ret = ec_ioctl_master(master, arg);
4680  break;
4681  case EC_IOCTL_SLAVE:
4682  ret = ec_ioctl_slave(master, arg);
4683  break;
4684  case EC_IOCTL_SLAVE_SYNC:
4685  ret = ec_ioctl_slave_sync(master, arg);
4686  break;
4687  case EC_IOCTL_SLAVE_SYNC_PDO:
4688  ret = ec_ioctl_slave_sync_pdo(master, arg);
4689  break;
4690  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
4691  ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
4692  break;
4693  case EC_IOCTL_DOMAIN:
4694  ret = ec_ioctl_domain(master, arg);
4695  break;
4696  case EC_IOCTL_DOMAIN_FMMU:
4697  ret = ec_ioctl_domain_fmmu(master, arg);
4698  break;
4699  case EC_IOCTL_DOMAIN_DATA:
4700  ret = ec_ioctl_domain_data(master, arg);
4701  break;
4702  case EC_IOCTL_MASTER_DEBUG:
4703  if (!ctx->writable) {
4704  ret = -EPERM;
4705  break;
4706  }
4707  ret = ec_ioctl_master_debug(master, arg);
4708  break;
4709  case EC_IOCTL_MASTER_RESCAN:
4710  if (!ctx->writable) {
4711  ret = -EPERM;
4712  break;
4713  }
4714  ret = ec_ioctl_master_rescan(master, arg);
4715  break;
4716  case EC_IOCTL_SLAVE_STATE:
4717  if (!ctx->writable) {
4718  ret = -EPERM;
4719  break;
4720  }
4721  ret = ec_ioctl_slave_state(master, arg);
4722  break;
4723  case EC_IOCTL_SLAVE_SDO:
4724  ret = ec_ioctl_slave_sdo(master, arg);
4725  break;
4726  case EC_IOCTL_SLAVE_SDO_ENTRY:
4727  ret = ec_ioctl_slave_sdo_entry(master, arg);
4728  break;
4729  case EC_IOCTL_SLAVE_SDO_UPLOAD:
4730  ret = ec_ioctl_slave_sdo_upload(master, arg);
4731  break;
4732  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
4733  if (!ctx->writable) {
4734  ret = -EPERM;
4735  break;
4736  }
4737  ret = ec_ioctl_slave_sdo_download(master, arg);
4738  break;
4739  case EC_IOCTL_SLAVE_SII_READ:
4740  ret = ec_ioctl_slave_sii_read(master, arg);
4741  break;
4742  case EC_IOCTL_SLAVE_SII_WRITE:
4743  if (!ctx->writable) {
4744  ret = -EPERM;
4745  break;
4746  }
4747  ret = ec_ioctl_slave_sii_write(master, arg);
4748  break;
4749  case EC_IOCTL_SLAVE_REG_READ:
4750  ret = ec_ioctl_slave_reg_read(master, arg);
4751  break;
4752  case EC_IOCTL_SLAVE_REG_WRITE:
4753  if (!ctx->writable) {
4754  ret = -EPERM;
4755  break;
4756  }
4757  ret = ec_ioctl_slave_reg_write(master, arg);
4758  break;
4759  case EC_IOCTL_SLAVE_FOE_READ:
4760  ret = ec_ioctl_slave_foe_read(master, arg);
4761  break;
4762  case EC_IOCTL_SLAVE_FOE_WRITE:
4763  if (!ctx->writable) {
4764  ret = -EPERM;
4765  break;
4766  }
4767  ret = ec_ioctl_slave_foe_write(master, arg);
4768  break;
4769  case EC_IOCTL_SLAVE_SOE_READ:
4770  ret = ec_ioctl_slave_soe_read(master, arg);
4771  break;
4772 #ifdef EC_EOE
4773  case EC_IOCTL_SLAVE_EOE_IP_PARAM:
4774  if (!ctx->writable) {
4775  ret = -EPERM;
4776  break;
4777  }
4778  ret = ec_ioctl_slave_eoe_ip_param(master, arg);
4779  break;
4780 #endif
4781  case EC_IOCTL_SLAVE_SOE_WRITE:
4782  if (!ctx->writable) {
4783  ret = -EPERM;
4784  break;
4785  }
4786  ret = ec_ioctl_slave_soe_write(master, arg);
4787  break;
4788  case EC_IOCTL_CONFIG:
4789  ret = ec_ioctl_config(master, arg);
4790  break;
4791  case EC_IOCTL_CONFIG_PDO:
4792  ret = ec_ioctl_config_pdo(master, arg);
4793  break;
4794  case EC_IOCTL_CONFIG_PDO_ENTRY:
4795  ret = ec_ioctl_config_pdo_entry(master, arg);
4796  break;
4797  case EC_IOCTL_CONFIG_SDO:
4798  ret = ec_ioctl_config_sdo(master, arg);
4799  break;
4800  case EC_IOCTL_CONFIG_IDN:
4801  ret = ec_ioctl_config_idn(master, arg);
4802  break;
4803  case EC_IOCTL_CONFIG_FLAG:
4804  ret = ec_ioctl_config_flag(master, arg);
4805  break;
4806 #ifdef EC_EOE
4807  case EC_IOCTL_EOE_HANDLER:
4808  ret = ec_ioctl_eoe_handler(master, arg);
4809  break;
4810 #endif
4811  case EC_IOCTL_REQUEST:
4812  if (!ctx->writable) {
4813  ret = -EPERM;
4814  break;
4815  }
4816  ret = ec_ioctl_request(master, arg, ctx);
4817  break;
4818  case EC_IOCTL_CREATE_DOMAIN:
4819  if (!ctx->writable) {
4820  ret = -EPERM;
4821  break;
4822  }
4823  ret = ec_ioctl_create_domain(master, arg, ctx);
4824  break;
4825  case EC_IOCTL_CREATE_SLAVE_CONFIG:
4826  if (!ctx->writable) {
4827  ret = -EPERM;
4828  break;
4829  }
4830  ret = ec_ioctl_create_slave_config(master, arg, ctx);
4831  break;
4832  case EC_IOCTL_SELECT_REF_CLOCK:
4833  if (!ctx->writable) {
4834  ret = -EPERM;
4835  break;
4836  }
4837  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
4838  break;
4839  case EC_IOCTL_SETUP_DOMAIN_MEMORY:
4840  if (!ctx->writable) {
4841  ret = -EPERM;
4842  break;
4843  }
4844  ret = ec_ioctl_setup_domain_memory(master, arg, ctx);
4845  break;
4846  case EC_IOCTL_ACTIVATE:
4847  if (!ctx->writable) {
4848  ret = -EPERM;
4849  break;
4850  }
4851  ret = ec_ioctl_activate(master, arg, ctx);
4852  break;
4853  case EC_IOCTL_DEACTIVATE_SLAVES:
4854  if (!ctx->writable) {
4855  ret = -EPERM;
4856  break;
4857  }
4858  ret = ec_ioctl_deactivate_slaves(master, arg, ctx);
4859  break;
4860  case EC_IOCTL_DEACTIVATE:
4861  if (!ctx->writable) {
4862  ret = -EPERM;
4863  break;
4864  }
4865  ret = ec_ioctl_deactivate(master, arg, ctx);
4866  break;
4867  case EC_IOCTL_SEND:
4868  if (!ctx->writable) {
4869  ret = -EPERM;
4870  break;
4871  }
4872  ret = ec_ioctl_send(master, arg, ctx);
4873  break;
4874  case EC_IOCTL_RECEIVE:
4875  if (!ctx->writable) {
4876  ret = -EPERM;
4877  break;
4878  }
4879  ret = ec_ioctl_receive(master, arg, ctx);
4880  break;
4881  case EC_IOCTL_MASTER_STATE:
4882  ret = ec_ioctl_master_state(master, arg, ctx);
4883  break;
4884  case EC_IOCTL_MASTER_LINK_STATE:
4885  ret = ec_ioctl_master_link_state(master, arg, ctx);
4886  break;
4887  case EC_IOCTL_APP_TIME:
4888  if (!ctx->writable) {
4889  ret = -EPERM;
4890  break;
4891  }
4892  ret = ec_ioctl_app_time(master, arg, ctx);
4893  break;
4894  case EC_IOCTL_SYNC_REF:
4895  if (!ctx->writable) {
4896  ret = -EPERM;
4897  break;
4898  }
4899  ret = ec_ioctl_sync_ref(master, arg, ctx);
4900  break;
4901  case EC_IOCTL_SYNC_REF_TO:
4902  if (!ctx->writable) {
4903  ret = -EPERM;
4904  break;
4905  }
4906  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
4907  break;
4908  case EC_IOCTL_SYNC_SLAVES:
4909  if (!ctx->writable) {
4910  ret = -EPERM;
4911  break;
4912  }
4913  ret = ec_ioctl_sync_slaves(master, arg, ctx);
4914  break;
4915  case EC_IOCTL_REF_CLOCK_TIME:
4916  if (!ctx->writable) {
4917  ret = -EPERM;
4918  break;
4919  }
4920  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
4921  break;
4922  case EC_IOCTL_64_REF_CLK_TIME_QUEUE:
4923  if (!ctx->writable) {
4924  ret = -EPERM;
4925  break;
4926  }
4927  ret = ec_ioctl_64bit_ref_clock_time_queue(master, arg, ctx);
4928  break;
4929  case EC_IOCTL_64_REF_CLK_TIME:
4930  if (!ctx->writable) {
4931  ret = -EPERM;
4932  break;
4933  }
4934  ret = ec_ioctl_64bit_ref_clock_time(master, arg, ctx);
4935  break;
4936  case EC_IOCTL_SYNC_MON_QUEUE:
4937  if (!ctx->writable) {
4938  ret = -EPERM;
4939  break;
4940  }
4941  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
4942  break;
4943  case EC_IOCTL_SYNC_MON_PROCESS:
4944  if (!ctx->writable) {
4945  ret = -EPERM;
4946  break;
4947  }
4948  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
4949  break;
4950  case EC_IOCTL_RESET:
4951  if (!ctx->writable) {
4952  ret = -EPERM;
4953  break;
4954  }
4955  ret = ec_ioctl_reset(master, arg, ctx);
4956  break;
4957  case EC_IOCTL_SC_SYNC:
4958  if (!ctx->writable) {
4959  ret = -EPERM;
4960  break;
4961  }
4962  ret = ec_ioctl_sc_sync(master, arg, ctx);
4963  break;
4964  case EC_IOCTL_SC_WATCHDOG:
4965  if (!ctx->writable) {
4966  ret = -EPERM;
4967  break;
4968  }
4969  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
4970  break;
4971  case EC_IOCTL_SC_OVERLAPPING_IO:
4972  if (!ctx->writable) {
4973  ret = -EPERM;
4974  break;
4975  }
4976  ret = ec_ioctl_sc_allow_overlapping_pdos(master, arg, ctx);
4977  break;
4978  case EC_IOCTL_SC_ADD_PDO:
4979  if (!ctx->writable) {
4980  ret = -EPERM;
4981  break;
4982  }
4983  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
4984  break;
4985  case EC_IOCTL_SC_CLEAR_PDOS:
4986  if (!ctx->writable) {
4987  ret = -EPERM;
4988  break;
4989  }
4990  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
4991  break;
4992  case EC_IOCTL_SC_ADD_ENTRY:
4993  if (!ctx->writable) {
4994  ret = -EPERM;
4995  break;
4996  }
4997  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
4998  break;
4999  case EC_IOCTL_SC_CLEAR_ENTRIES:
5000  if (!ctx->writable) {
5001  ret = -EPERM;
5002  break;
5003  }
5004  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
5005  break;
5006  case EC_IOCTL_SC_REG_PDO_ENTRY:
5007  if (!ctx->writable) {
5008  ret = -EPERM;
5009  break;
5010  }
5011  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
5012  break;
5013  case EC_IOCTL_SC_REG_PDO_POS:
5014  if (!ctx->writable) {
5015  ret = -EPERM;
5016  break;
5017  }
5018  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
5019  break;
5020  case EC_IOCTL_SC_DC:
5021  if (!ctx->writable) {
5022  ret = -EPERM;
5023  break;
5024  }
5025  ret = ec_ioctl_sc_dc(master, arg, ctx);
5026  break;
5027  case EC_IOCTL_SC_SDO:
5028  if (!ctx->writable) {
5029  ret = -EPERM;
5030  break;
5031  }
5032  ret = ec_ioctl_sc_sdo(master, arg, ctx);
5033  break;
5034  case EC_IOCTL_SC_EMERG_SIZE:
5035  if (!ctx->writable) {
5036  ret = -EPERM;
5037  break;
5038  }
5039  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
5040  break;
5041  case EC_IOCTL_SC_EMERG_POP:
5042  if (!ctx->writable) {
5043  ret = -EPERM;
5044  break;
5045  }
5046  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
5047  break;
5048  case EC_IOCTL_SC_EMERG_CLEAR:
5049  if (!ctx->writable) {
5050  ret = -EPERM;
5051  break;
5052  }
5053  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
5054  break;
5055  case EC_IOCTL_SC_EMERG_OVERRUNS:
5056  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
5057  break;
5058  case EC_IOCTL_SC_SDO_REQUEST:
5059  if (!ctx->writable) {
5060  ret = -EPERM;
5061  break;
5062  }
5063  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
5064  break;
5065  case EC_IOCTL_SC_REG_REQUEST:
5066  if (!ctx->writable) {
5067  ret = -EPERM;
5068  break;
5069  }
5070  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
5071  break;
5072  case EC_IOCTL_SC_VOE:
5073  if (!ctx->writable) {
5074  ret = -EPERM;
5075  break;
5076  }
5077  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
5078  break;
5079  case EC_IOCTL_SC_STATE:
5080  ret = ec_ioctl_sc_state(master, arg, ctx);
5081  break;
5082  case EC_IOCTL_SC_IDN:
5083  if (!ctx->writable) {
5084  ret = -EPERM;
5085  break;
5086  }
5087  ret = ec_ioctl_sc_idn(master, arg, ctx);
5088  break;
5089  case EC_IOCTL_SC_FLAG:
5090  if (!ctx->writable) {
5091  ret = -EPERM;
5092  break;
5093  }
5094  ret = ec_ioctl_sc_flag(master, arg, ctx);
5095  break;
5096  case EC_IOCTL_DOMAIN_SIZE:
5097  ret = ec_ioctl_domain_size(master, arg, ctx);
5098  break;
5099  case EC_IOCTL_DOMAIN_OFFSET:
5100  ret = ec_ioctl_domain_offset(master, arg, ctx);
5101  break;
5102  case EC_IOCTL_DOMAIN_PROCESS:
5103  if (!ctx->writable) {
5104  ret = -EPERM;
5105  break;
5106  }
5107  ret = ec_ioctl_domain_process(master, arg, ctx);
5108  break;
5109  case EC_IOCTL_DOMAIN_QUEUE:
5110  if (!ctx->writable) {
5111  ret = -EPERM;
5112  break;
5113  }
5114  ret = ec_ioctl_domain_queue(master, arg, ctx);
5115  break;
5116  case EC_IOCTL_DOMAIN_STATE:
5117  ret = ec_ioctl_domain_state(master, arg, ctx);
5118  break;
5119  case EC_IOCTL_SDO_REQUEST_INDEX:
5120  if (!ctx->writable) {
5121  ret = -EPERM;
5122  break;
5123  }
5124  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
5125  break;
5126  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
5127  if (!ctx->writable) {
5128  ret = -EPERM;
5129  break;
5130  }
5131  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
5132  break;
5133  case EC_IOCTL_SDO_REQUEST_STATE:
5134  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
5135  break;
5136  case EC_IOCTL_SDO_REQUEST_READ:
5137  if (!ctx->writable) {
5138  ret = -EPERM;
5139  break;
5140  }
5141  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
5142  break;
5143  case EC_IOCTL_SDO_REQUEST_WRITE:
5144  if (!ctx->writable) {
5145  ret = -EPERM;
5146  break;
5147  }
5148  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
5149  break;
5150  case EC_IOCTL_SDO_REQUEST_DATA:
5151  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
5152  break;
5153  case EC_IOCTL_REG_REQUEST_DATA:
5154  ret = ec_ioctl_reg_request_data(master, arg, ctx);
5155  break;
5156  case EC_IOCTL_REG_REQUEST_STATE:
5157  ret = ec_ioctl_reg_request_state(master, arg, ctx);
5158  break;
5159  case EC_IOCTL_REG_REQUEST_WRITE:
5160  if (!ctx->writable) {
5161  ret = -EPERM;
5162  break;
5163  }
5164  ret = ec_ioctl_reg_request_write(master, arg, ctx);
5165  break;
5166  case EC_IOCTL_REG_REQUEST_READ:
5167  if (!ctx->writable) {
5168  ret = -EPERM;
5169  break;
5170  }
5171  ret = ec_ioctl_reg_request_read(master, arg, ctx);
5172  break;
5173  case EC_IOCTL_VOE_SEND_HEADER:
5174  if (!ctx->writable) {
5175  ret = -EPERM;
5176  break;
5177  }
5178  ret = ec_ioctl_voe_send_header(master, arg, ctx);
5179  break;
5180  case EC_IOCTL_VOE_REC_HEADER:
5181  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
5182  break;
5183  case EC_IOCTL_VOE_READ:
5184  if (!ctx->writable) {
5185  ret = -EPERM;
5186  break;
5187  }
5188  ret = ec_ioctl_voe_read(master, arg, ctx);
5189  break;
5190  case EC_IOCTL_VOE_READ_NOSYNC:
5191  if (!ctx->writable) {
5192  ret = -EPERM;
5193  break;
5194  }
5195  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
5196  break;
5197  case EC_IOCTL_VOE_WRITE:
5198  if (!ctx->writable) {
5199  ret = -EPERM;
5200  break;
5201  }
5202  ret = ec_ioctl_voe_write(master, arg, ctx);
5203  break;
5204  case EC_IOCTL_VOE_EXEC:
5205  if (!ctx->writable) {
5206  ret = -EPERM;
5207  break;
5208  }
5209  ret = ec_ioctl_voe_exec(master, arg, ctx);
5210  break;
5211  case EC_IOCTL_VOE_DATA:
5212  ret = ec_ioctl_voe_data(master, arg, ctx);
5213  break;
5214  case EC_IOCTL_SET_SEND_INTERVAL:
5215  if (!ctx->writable) {
5216  ret = -EPERM;
5217  break;
5218  }
5219  ret = ec_ioctl_set_send_interval(master, arg, ctx);
5220  break;
5221  case EC_IOCTL_SLAVE_DICT_UPLOAD:
5222  ret = ec_ioctl_slave_dict_upload(master, arg);
5223  break;
5224  default:
5225  ret = -ENOTTY;
5226  break;
5227  }
5228 
5229 #if DEBUG_LATENCY
5230  b = get_cycles();
5231  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
5232  if (t > 50) {
5233  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
5234  _IOC_NR(cmd), t);
5235  }
5236 #endif
5237 
5238  return ret;
5239 }
5240 
5241 /*****************************************************************************/
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain&#39;s process data.
Definition: domain.c:512
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:184
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
uint16_t ring_position
Ring position for emergency requests.
Definition: reg_request.h:57
const ec_slave_config_t * sc
EtherCAT slave config.
Definition: fmmu_config.h:48
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: ioctl.c:480
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
static ATTRIBUTES int ec_ioctl_sdo_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request&#39;s timeout.
Definition: ioctl.c:3656
unsigned int ec_slave_config_flag_count(const ec_slave_config_t *sc)
Get the number of feature flags.
Definition: slave_config.c:506
uint16_t offset
SII word offset.
Definition: fsm_master.h:56
uint16_t ring_position
Ring position.
Definition: slave.h:206
uint32_t revision_number
Revision number.
Definition: slave.h:160
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
static ATTRIBUTES int ec_ioctl_sc_emerg_clear(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clear the emergency ring.
Definition: ioctl.c:3058
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:828
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:162
int ecrt_slave_config_emerg_size(ec_slave_config_t *sc, size_t elements)
Set the size of the CoE emergency ring buffer.
#define EC_DATAGRAM_NAME_SIZE
Size of the datagram description string.
Definition: globals.h:110
ec_sii_t sii
Extracted SII data.
Definition: slave.h:246
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:3198
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:572
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:133
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: ioctl.c:651
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
uint8_t * data
Pointer to SDO data.
Definition: soe_request.h:53
uint32_t logical_domain_offset
Logical offset address relative to domain->logical_base_address.
Definition: fmmu_config.h:52
size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
Returns the current data size.
Definition: voe_handler.c:153
static ATTRIBUTES int ec_ioctl_sdo_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO write operation.
Definition: ioctl.c:3775
FMMU configuration.
Definition: fmmu_config.h:46
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: ioctl.c:1389
static ATTRIBUTES int ec_ioctl_master_link_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the link state.
Definition: ioctl.c:2196
u64 tx_count
Number of frames sent.
Definition: master.h:151
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave&#39;s registers.
Definition: ioctl.c:1045
struct list_head sii_requests
SII write requests.
Definition: master.h:304
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:3147
static ATTRIBUTES int ec_ioctl_domain_offset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain&#39;s offset in the total process data.
Definition: ioctl.c:3473
static ATTRIBUTES int ec_ioctl_create_slave_config(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a slave configuration.
Definition: ioctl.c:1768
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:484
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.
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.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:107
CANopen SDO entry.
Definition: sdo_entry.h:54
static ATTRIBUTES int ec_ioctl_reg_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register read operation.
Definition: ioctl.c:4006
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: ioctl.c:815
size_t data_size
Size of the process data.
Definition: domain.h:62
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:87
static ATTRIBUTES int ec_ioctl_voe_send_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the VoE send header.
Definition: ioctl.c:4049
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:168
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:59
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:2070
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&#39;s PDO assignment.
Definition: slave_config.c:721
size_t ec_voe_handler_mem_size(const ec_voe_handler_t *voe)
Get usable memory size.
Definition: voe_handler.c:109
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:3074
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:210
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:3090
unsigned int tx_queue_size
Transmit queue size.
Definition: ethernet.h:105
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:528
CANopen SDO request.
Definition: sdo_request.h:48
ec_slave_state_t current_state
Current application state.
Definition: slave.h:215
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:327
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: ioctl.c:3507
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:60
static ATTRIBUTES int ec_ioctl_module(void *arg)
Get module information.
Definition: ioctl.c:93
size_t nwords
Number of words.
Definition: fsm_master.h:57
ec_internal_request_state_t state
SDO request state.
Definition: sdo_request.h:63
uint16_t address
Register address.
Definition: reg_request.h:54
uint16_t bit_length
Data size in bit.
Definition: sdo_entry.h:59
Register request.
Definition: reg_request.h:48
static ATTRIBUTES int ec_ioctl_slave_eoe_ip_param(ec_master_t *master, void *arg)
Request EoE IP parameter setting.
Definition: ioctl.c:1635
size_t mem_size
Size of data memory.
Definition: reg_request.h:50
void ec_foe_request_write(ec_foe_request_t *req)
Prepares a write request (master to slave).
Definition: foe_request.c:229
static ATTRIBUTES int ec_ioctl_reg_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an register request&#39;s state.
Definition: ioctl.c:3913
static ATTRIBUTES int ec_ioctl_reg_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register write operation.
Definition: ioctl.c:3958
uint32_t product_code
Slave product code.
Definition: slave_config.h:127
static ATTRIBUTES int ec_ioctl_ref_clock_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the system time of the reference clock.
Definition: ioctl.c:2327
ec_slave_port_link_t link
Port link status.
Definition: slave.h:139
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:577
uint16_t position
Index after alias.
Definition: slave_config.h:124
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:2021
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:83
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:3037
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:440
uint32_t serial_number
Serial number.
Definition: slave.h:161
int ec_foe_request_alloc(ec_foe_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: foe_request.c:112
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: device.h:111
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:183
char * order
Order number.
Definition: slave.h:180
int ec_reg_request_init(ec_reg_request_t *reg, size_t size)
Register request constructor.
Definition: reg_request.c:48
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:2151
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:2190
uint16_t index
SDO index.
Definition: sdo_request.h:50
static ATTRIBUTES int ec_ioctl_sync_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the slave clocks.
Definition: ioctl.c:2304
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:235
unsigned int data_size
Covered PDO size.
Definition: fmmu_config.h:54
struct list_head emerg_reg_requests
Emergency register access requests.
Definition: master.h:305
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
uint16_t alias
Slave alias.
Definition: slave_config.h:123
static ATTRIBUTES int ec_ioctl_sc_create_reg_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a register request.
Definition: ioctl.c:3187
struct list_head domains
List of domains.
Definition: master.h:231
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: ioctl.c:4536
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:953
struct list_head reg_requests
Register access requests.
Definition: slave.h:253
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: ioctl.c:735
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
CANopen SDO.
Definition: sdo.h:49
uint16_t index
SDO index.
Definition: sdo.h:52
uint8_t * data
Pointer to SDO data.
Definition: sdo_request.h:52
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: ioctl.c:1268
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:185
static ATTRIBUTES int ec_ioctl_64bit_ref_clock_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the 64bit system time of the reference clock.
Definition: ioctl.c:2381
void ecrt_voe_handler_read(ec_voe_handler_t *voe)
Start a VoE read operation.
Definition: voe_handler.c:160
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:2005
ec_lock_t domains_lock
Lock for access to domains list.
Definition: master.h:232
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&#39;s mapping.
Definition: ioctl.c:2687
uint8_t link_state
device link state
Definition: device.h:88
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
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:538
static ATTRIBUTES int ec_ioctl_sc_allow_overlapping_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure wether a slave allows overlapping PDOs.
Definition: ioctl.c:2574
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:165
#define EC_IOCTL
ioctl() function to use.
Definition: ioctl.c:4654
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:207
uint32_t result
FoE request abort code.
Definition: foe_request.h:69
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:3051
u64 rx_count
Number of frames received.
Definition: device.h:102
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:169
#define EC_MAX_HOSTNAME_SIZE
Maximum hostname size.
Definition: globals.h:116
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:308
void ec_eoe_request_init(ec_eoe_request_t *req)
EoE request constructor.
Definition: eoe_request.c:46
int ecrt_slave_config_emerg_clear(ec_slave_config_t *sc)
Clears CoE emergency ring buffer and the overrun counter.
void ecrt_domain_external_memory(ec_domain_t *domain, uint8_t *mem)
Provide external memory to store the domain&#39;s process data.
Definition: domain.c:519
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:3134
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
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: ioctl.c:1324
unsigned int sync_count
Number of sync managers.
Definition: slave.h:189
struct list_head list
List head.
Definition: fsm_master.h:54
SII write request.
Definition: fsm_master.h:53
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:2495
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:114
char * key
Flag key (null-terminated ASCII string.
Definition: flag.h:40
int ecrt_slave_config_flag(ec_slave_config_t *sc, const char *key, int32_t value)
Adds a feature flag to a slave configuration.
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:167
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: ioctl.c:4350
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:2085
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.
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:168
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:114
uint8_t * ecrt_sdo_request_data(ec_sdo_request_t *req)
Access to the SDO request&#39;s data.
Definition: sdo_request.c:203
static ATTRIBUTES int ec_ioctl_master_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the master state.
Definition: ioctl.c:2174
ec_direction_t dir
Direction.
Definition: sdo_request.h:60
PDO entry description.
Definition: pdo_entry.h:48
static ATTRIBUTES int ec_ioctl_sc_emerg_overruns(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the number of emergency overruns.
Definition: ioctl.c:3091
EtherCAT master structure.
uint8_t * data
Memory for the process data.
Definition: domain.h:63
int ecrt_master_64bit_reference_clock_time(ec_master_t *master, uint64_t *time)
Get the 64 bit DC reference slave clock time.
Definition: master.c:3167
void * cb_data
Current callback data.
Definition: master.h:297
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:144
uint16_t index
PDO index.
Definition: pdo.h:51
static ATTRIBUTES int ec_ioctl_slave_foe_write(ec_master_t *master, void *arg)
Write a file to a slave via FoE.
Definition: ioctl.c:4447
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:106
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: ioctl.c:636
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:164
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
static ATTRIBUTES int ec_ioctl_sc_create_sdo_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SDO request.
Definition: ioctl.c:3136
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:55
uint16_t index
PDO entry index.
Definition: pdo_entry.h:50
EtherCAT slave.
Definition: slave.h:199
static ATTRIBUTES int ec_ioctl_sdo_request_index(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an SDO request&#39;s SDO index and subindex.
Definition: ioctl.c:3619
ec_lock_t device_sem
Device semaphore.
Definition: master.h:213
unsigned int ec_pdo_entry_count(const ec_pdo_t *pdo)
Get the number of PDO entries.
Definition: pdo.c:257
void ec_foe_request_clear(ec_foe_request_t *req)
FoE request destructor.
Definition: foe_request.c:79
void ecrt_sdo_request_read(ec_sdo_request_t *req)
Schedule an SDO read operation.
Definition: sdo_request.c:224
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
static ATTRIBUTES int ec_ioctl_sdo_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO read operation.
Definition: ioctl.c:3738
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: ioctl.c:525
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.
Master state.
Definition: ecrt.h:276
static ATTRIBUTES int ec_ioctl_sdo_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an SDO request&#39;s state.
Definition: ioctl.c:3693
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.
const ec_domain_t * domain
Domain.
Definition: fmmu_config.h:49
char * description
Description.
Definition: sdo_entry.h:62
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2215
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: ioctl.c:57
Slave configuration state.
Definition: ecrt.h:324
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:162
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:170
Ethernet over EtherCAT (EoE)
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:139
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:214
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: ioctl.c:1719
static ATTRIBUTES int ec_ioctl_deactivate_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the slaves.
Definition: ioctl.c:2035
void(* state)(ec_voe_handler_t *)
State function.
Definition: voe_handler.h:59
struct list_head reg_requests
List of register requests.
Definition: slave_config.h:149
static ATTRIBUTES int ec_ioctl_app_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the master DC application time.
Definition: ioctl.c:2228
ec_master_phase_t phase
Master phase.
Definition: master.h:218
Domain state.
Definition: ecrt.h:425
static ATTRIBUTES int ec_ioctl_sc_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the slave configuration&#39;s state.
Definition: ioctl.c:3291
static ATTRIBUTES int ec_ioctl_64bit_ref_clock_time_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the 64bit dc reference slave clock datagram.
Definition: ioctl.c:2358
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: ioctl.c:577
uint8_t * buffer
Pointer to FoE data.
Definition: foe_request.h:52
uint8_t sync_index
Index of sync manager to use.
Definition: fmmu_config.h:50
Slave configutation feature flag.
Definition: flag.h:38
static ATTRIBUTES int ec_ioctl_sc_watchdog(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a slave&#39;s watchdogs.
Definition: ioctl.c:2531
static ATTRIBUTES int ec_ioctl_sc_add_pdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add a PDO to the assignment.
Definition: ioctl.c:2618
PDO description.
Definition: pdo.h:49
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: device.h:119
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:147
EtherCAT device.
Definition: device.h:81
uint16_t * sii_words
Complete SII image.
Definition: slave.h:242
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:170
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:2136
Access rights in OP.
Definition: globals.h:198
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
static ATTRIBUTES int ec_ioctl_sc_dc(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the DC AssignActivate word and the sync signal times.
Definition: ioctl.c:2877
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.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
Definition: slave.h:77
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:2100
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:234
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:53
Sync manager.
Definition: sync.h:47
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: ioctl.c:622
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:166
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:232
static ATTRIBUTES int ec_ioctl_sc_flag(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures a feature flag.
Definition: ioctl.c:3383
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:172
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:238
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:2937
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:227
unsigned int scan_busy
Current scan state.
Definition: master.h:249
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync_config.h:49
struct list_head voe_handlers
List of VoE handlers.
Definition: slave_config.h:148
char * name
SDO name.
Definition: sdo.h:54
void(* receive_cb)(void *)
Current receive datagrams callback.
Definition: master.h:296
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:143
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:165
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave&#39;s SII.
Definition: ioctl.c:909
unsigned int index
Index (just a number).
Definition: domain.h:59
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:117
Main device.
Definition: globals.h:205
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: ioctl.c:2105
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: ioctl.c:212
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:131
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:138
#define EC_MASTER_WARN(master, fmt, args...)
Convenience macro for printing master-specific warnings to syslog.
Definition: master.h:92
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: ioctl.c:1453
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: ioctl.c:1209
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:49
unsigned int active
Master has been activated.
Definition: master.h:219
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: ioctl.c:2073
ec_master_t * master
Master owning the slave.
Definition: slave.h:201
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
Execute the handler.
Definition: voe_handler.c:188
static ATTRIBUTES int ec_ioctl_voe_read_nosync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation without sending a sync message first.
Definition: ioctl.c:4179
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:418
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:806
static ATTRIBUTES int ec_ioctl_master(ec_master_t *master, void *arg)
Get master information.
Definition: ioctl.c:114
static ATTRIBUTES int ec_ioctl_reg_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read register data.
Definition: ioctl.c:3866
u64 rx_bytes
Number of bytes received.
Definition: device.h:107
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:3369
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:235
void ec_foe_request_init(ec_foe_request_t *req, uint8_t *file_name)
FoE request constructor.
Definition: foe_request.c:57
static ATTRIBUTES int ec_ioctl_sc_sync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a sync manager.
Definition: ioctl.c:2478
u64 tx_count
Number of frames sent.
Definition: device.h:100
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:417
static ATTRIBUTES int ec_ioctl_sync_ref_to(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: ioctl.c:2276
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave&#39;s SII.
Definition: ioctl.c:957
static ATTRIBUTES int ec_ioctl_sync_mon_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the sync monitoring datagram.
Definition: ioctl.c:2412
#define EC_MASTER_ERR(master, fmt, args...)
Convenience macro for printing master-specific errors to syslog.
Definition: master.h:80
uint8_t subindex
PDO entry subindex.
Definition: pdo_entry.h:51
uint8_t control_register
Control register value.
Definition: sync.h:51
static ATTRIBUTES int ec_ioctl_sync_ref(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: ioctl.c:2253
Values read by the master.
Definition: ecrt.h:438
ec_direction_t dir
Sync manager direction.
Definition: sync_config.h:47
int ec_rtdm_mmap(ec_ioctl_context_t *ioctl_ctx, void **user_address)
Memory-map process data to user space.
Definition: rtdm.c:220
Access rights in SAFEOP.
Definition: globals.h:197
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
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
struct list_head configs
List of slave configurations.
Definition: master.h:230
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:136
unsigned int opened
net_device is opened
Definition: ethernet.h:93
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: ioctl.c:1744
static ATTRIBUTES int ec_ioctl_setup_domain_memory(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets up domain memory.
Definition: ioctl.c:1855
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: ioctl.c:2460
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:129
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:550
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.
void ecrt_master_reset(ec_master_t *master)
Retry configuring slaves.
Definition: master.c:3612
static ATTRIBUTES int ec_ioctl_voe_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE write operation.
Definition: ioctl.c:4216
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: ioctl.c:3540
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
static ATTRIBUTES int ec_ioctl_slave_dict_upload(ec_master_t *master, void *arg)
Upload Dictionary.
Definition: ioctl.c:4630
static ATTRIBUTES int ec_ioctl_voe_rec_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the received VoE header.
Definition: ioctl.c:4094
static ATTRIBUTES int ec_ioctl_config_flag(ec_master_t *master, void *arg)
Get slave configuration feature flag information.
Definition: ioctl.c:1517
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:3190
void ecrt_master_deactivate_slaves(ec_master_t *master)
Deactivates the slaves distributed clocks and sends the slaves into PREOP.
Definition: master.c:2625
void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
Start a VoE write operation.
Definition: voe_handler.c:178
Ethernet-over-EtherCAT set IP parameter request.
Definition: eoe_request.h:49
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: ioctl.c:2143
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
Definition: domain.h:71
uint8_t * file_name
Pointer to the filename.
Definition: foe_request.h:67
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:784
uint32_t logical_base_address
Logical offset address of the process data.
Definition: domain.h:65
static ATTRIBUTES int ec_ioctl_sc_emerg_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the emergency ring buffer size.
Definition: ioctl.c:2976
uint8_t read_access[EC_SDO_ENTRY_ACCESS_COUNT]
Read access.
Definition: sdo_entry.h:60
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&#39;s mapping.
Definition: slave_config.c:769
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:48
struct net_device_stats stats
device statistics
Definition: ethernet.h:92
char * name
PDO name.
Definition: pdo.h:53
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:51
FoE request.
Definition: foe_request.h:50
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:73
static ATTRIBUTES int ec_ioctl_slave_sync_pdo_entry(ec_master_t *master, void *arg)
Get slave sync manager PDO entry information.
Definition: ioctl.c:411
uint8_t allow_overlapping_pdos
Allow input PDOs use the same frame space as output PDOs.
Definition: slave_config.h:134
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:462
u64 tx_errors
Number of transmit errors.
Definition: device.h:110
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:898
uint16_t effective_alias
Effective alias address.
Definition: slave.h:208
char * name
entry name
Definition: pdo_entry.h:52
size_t data_size
Size of SDO data.
Definition: sdo_request.h:54
ec_lock_t master_sem
Master semaphore.
Definition: master.h:204
ec_internal_request_state_t state
Request state.
Definition: eoe_request.h:51
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:3528
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: ioctl.c:299
struct list_head foe_requests
FoE requests.
Definition: slave.h:254
ec_direction_t dir
Direction.
Definition: voe_handler.h:56
static ATTRIBUTES int ec_ioctl_voe_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation.
Definition: ioctl.c:4142
u64 tx_bytes
Number of bytes sent.
Definition: master.h:156
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2550
static ATTRIBUTES int ec_ioctl_sc_create_voe_handler(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a VoE handler.
Definition: ioctl.c:3241
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2168
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:210
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:806
uint8_t enable
Enable bit.
Definition: sync.h:52
size_t ecrt_master_send(ec_master_t *master)
Sends all datagrams in the queue.
Definition: master.c:2748
static ATTRIBUTES int ec_ioctl_sc_clear_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the PDO assignment.
Definition: ioctl.c:2652
uint8_t * data
Pointer to data memory.
Definition: reg_request.h:51
Vendor specific over EtherCAT protocol handler.
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
Definition: slave.h:163
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:227
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position, uint16_t index, uint8_t subindex, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave.
Definition: master.c:3209
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:140
ec_direction_t dir
Direction.
Definition: reg_request.h:52
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: ioctl.c:2054
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:126
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:141
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: ioctl.c:2917
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:565
char * image
Image name.
Definition: slave.h:179
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
int32_t value
Flag value (meaning depends on key).
Definition: flag.h:41
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry.
Definition: ioctl.c:2757
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: ioctl.c:1943
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:234
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:418
uint16_t physical_start_address
Physical start address.
Definition: sync.h:49
static ATTRIBUTES int ec_ioctl_domain_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the domain state.
Definition: ioctl.c:3578
void ec_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:215
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:233
u64 rx_count
Number of frames received.
Definition: master.h:153
void ecrt_slave_config_watchdog(ec_slave_config_t *sc, uint16_t divider, uint16_t intervals)
Configure a slave&#39;s watchdog times.
Definition: slave_config.c:698
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2673
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: ioctl.c:686
size_t sii_nwords
Size of the SII contents in words.
Definition: slave.h:243
void ecrt_slave_config_overlapping_pdos(ec_slave_config_t *sc, uint8_t allow_overlapping_pdos)
Configure whether a slave allows overlapping PDOs.
Definition: slave_config.c:710
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:208
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
char * group
Group name.
Definition: slave.h:178
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:671
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:3452
EtherCAT slave configuration.
Definition: slave_config.h:119
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:124
static ATTRIBUTES int ec_ioctl_sc_emerg_pop(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get an emergency message from the ring.
Definition: ioctl.c:3014
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:70
static ATTRIBUTES int ec_ioctl_domain_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the domain&#39;s data size.
Definition: ioctl.c:3439
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:84
EtherCAT master character device IOCTL commands.
static void ec_ioctl_strcpy(char *target, const char *source)
Copies a string to an ioctl structure.
Definition: ioctl.c:74
Request was processed successfully.
Definition: ecrt.h:538
EtherCAT slave configuration structure.
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:63
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
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:2868
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:202
uint8_t * ecrt_reg_request_data(ec_reg_request_t *reg)
Access to the register request&#39;s data.
Definition: reg_request.c:86
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:3101
unsigned int index
Index.
Definition: master.h:190
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:2037
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:764
void ecrt_master_64bit_reference_clock_time_queue(ec_master_t *master)
Queues the 64 bit DC reference slave clock time value datagram for sending.
Definition: master.c:3157
uint16_t default_length
Data length in bytes.
Definition: sync.h:50
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.
static ATTRIBUTES int ec_ioctl_voe_exec(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Executes the VoE state machine.
Definition: ioctl.c:4262
uint32_t password
Password needed for FoE.
Definition: foe_request.h:68
void ecrt_slave_config_pdo_assign_clear(ec_slave_config_t *sc, uint8_t sync_index)
Clear a sync manager&#39;s PDO assignment.
Definition: slave_config.c:751
int ec_sdo_request_alloc(ec_sdo_request_t *req, size_t size)
Pre-allocates the data memory.
Definition: sdo_request.c:127
uint32_t product_code
Vendor-specific product code.
Definition: slave.h:159
void ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain&#39;s datagrams.
Definition: domain.c:540
ec_direction_t dir
FMMU direction.
Definition: fmmu_config.h:51
void ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state)
Outputs the state of the slave configuration.
int ecrt_master_sdo_download_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, const uint8_t *data, size_t data_size, uint32_t *abort_code)
Executes an SDO download request to write data to a slave via complete access.
Definition: master.c:3288
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
Ethernet over EtherCAT (EoE) handler.
Definition: ethernet.h:84
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:216
u64 rx_bytes
Number of bytes received.
Definition: master.h:158
Access rights in PREOP.
Definition: globals.h:196
void ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master&#39;s datagram queue.
Definition: domain.c:732
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:244
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:216
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:188
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:169
EtherCAT master.
Definition: master.h:189
#define ec_ioctl_lock_down_interruptible(p)
Ioctl locking is disabled for RTDM as the RT app needs to use RTAI locks.
Definition: ioctl.c:66
struct list_head list
List item.
Definition: reg_request.h:49
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:256
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3124
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_pos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry by its position.
Definition: ioctl.c:2816
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:218
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:206
static ATTRIBUTES int ec_ioctl_slave_soe_write(ec_master_t *master, void *arg)
Write an IDN to a slave via SoE.
Definition: ioctl.c:4585
u64 tx_bytes
Number of bytes sent.
Definition: device.h:105
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: ioctl.c:352
static ATTRIBUTES int ec_ioctl_select_ref_clock(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Select the DC reference clock.
Definition: ioctl.c:1814
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:104
uint8_t * ecrt_voe_handler_data(ec_voe_handler_t *voe)
Access to the VoE handler&#39;s data.
Definition: voe_handler.c:146
void ecrt_sdo_request_write(ec_sdo_request_t *req)
Schedule an SDO write operation.
Definition: sdo_request.c:235
struct list_head list
List item.
Definition: eoe_request.h:50
ec_lock_t io_sem
Semaphore protecting the datagram_queue.
Definition: master.h:264
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave&#39;s registers.
Definition: ioctl.c:1124
int ecrt_slave_config_emerg_overruns(ec_slave_config_t *sc)
Read the number of CoE emergency overruns.
const uint16_t * words
Pointer to the data words.
Definition: fsm_master.h:58
static ATTRIBUTES int ec_ioctl_voe_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reads the received VoE data.
Definition: ioctl.c:4310
char * name
Slave name.
Definition: slave.h:181
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:911
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
static ATTRIBUTES int ec_ioctl_sdo_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SDO data.
Definition: ioctl.c:3826
EtherCAT domain.
Definition: domain.h:55
void(* send_cb)(void *)
Current send datagrams callback.
Definition: master.h:295
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:91
static ATTRIBUTES int ec_ioctl_sync_mon_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Processes the sync monitoring datagram.
Definition: ioctl.c:2435
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: ioctl.c:1582
uint32_t vendor_id
Vendor ID.
Definition: slave.h:158
uint8_t complete_access
SDO shall be transferred completely.
Definition: sdo_request.h:55
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
Definition: slave.h:143
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: ioctl.c:861
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
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:247
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:594
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:58
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: ioctl.c:3329
struct list_head list
List item.
Definition: foe_request.h:51
unsigned int has_general
General category present.
Definition: slave.h:177
unsigned int tx_queued_frames
number of frames in the queue
Definition: ethernet.h:107
static ATTRIBUTES int ec_ioctl_sc_clear_entries(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the mapping of a PDO.
Definition: ioctl.c:2722
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:2797
Sercos-over-EtherCAT request.
Definition: soe_request.h:48
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:435