IgH EtherCAT Master  1.5.2
rtdm-ioctl.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * $Id$
4  *
5  * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
6  *
7  * This file is part of the IgH EtherCAT Master.
8  *
9  * The IgH EtherCAT Master is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version 2, as
11  * published by the Free Software Foundation.
12  *
13  * The IgH EtherCAT Master is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with the IgH EtherCAT Master; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  * ---
23  *
24  * The license mentioned above concerns the source code only. Using the
25  * EtherCAT technology and brand is only permitted in compliance with the
26  * industrial property and similar rights of Beckhoff Automation GmbH.
27  *
28  *****************************************************************************/
29 
35 /*****************************************************************************/
36 
37 #include <linux/module.h>
38 #include <linux/vmalloc.h>
39 
40 #include "master.h"
41 #include "slave_config.h"
42 #include "voe_handler.h"
43 #include "ethernet.h"
44 #include "ioctl.h"
45 
50 #define DEBUG_LATENCY 0
51 
54 #if 0
55 #define ATTRIBUTES __attribute__ ((__noinline__))
56 #else
57 #define ATTRIBUTES
58 #endif
59 
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 
115  ec_master_t *master,
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 #endif
132  io.phase = (uint8_t) master->phase;
133  io.active = (uint8_t) master->active;
134  io.scan_busy = master->scan_busy;
135 
136  ec_lock_up(&master->master_sem);
137 
138  if (ec_lock_down_interruptible(&master->device_sem)) {
139  return -EINTR;
140  }
141 
142  for (dev_idx = EC_DEVICE_MAIN;
143  dev_idx < ec_master_num_devices(master); dev_idx++) {
144  ec_device_t *device = &master->devices[dev_idx];
145 
146  if (device->dev) {
147  memcpy(io.devices[dev_idx].address, device->dev->dev_addr,
148  ETH_ALEN);
149  } else {
150  memcpy(io.devices[dev_idx].address, master->macs[dev_idx],
151  ETH_ALEN);
152  }
153  io.devices[dev_idx].attached = device->dev ? 1 : 0;
154  io.devices[dev_idx].link_state = device->link_state ? 1 : 0;
155  io.devices[dev_idx].tx_count = device->tx_count;
156  io.devices[dev_idx].rx_count = device->rx_count;
157  io.devices[dev_idx].tx_bytes = device->tx_bytes;
158  io.devices[dev_idx].rx_bytes = device->rx_bytes;
159  io.devices[dev_idx].tx_errors = device->tx_errors;
160  for (j = 0; j < EC_RATE_COUNT; j++) {
161  io.devices[dev_idx].tx_frame_rates[j] =
162  device->tx_frame_rates[j];
163  io.devices[dev_idx].rx_frame_rates[j] =
164  device->rx_frame_rates[j];
165  io.devices[dev_idx].tx_byte_rates[j] =
166  device->tx_byte_rates[j];
167  io.devices[dev_idx].rx_byte_rates[j] =
168  device->rx_byte_rates[j];
169  }
170  }
171  io.num_devices = ec_master_num_devices(master);
172 
173  io.tx_count = master->device_stats.tx_count;
174  io.rx_count = master->device_stats.rx_count;
175  io.tx_bytes = master->device_stats.tx_bytes;
176  io.rx_bytes = master->device_stats.rx_bytes;
177  for (j = 0; j < EC_RATE_COUNT; j++) {
178  io.tx_frame_rates[j] =
179  master->device_stats.tx_frame_rates[j];
180  io.rx_frame_rates[j] =
181  master->device_stats.rx_frame_rates[j];
182  io.tx_byte_rates[j] =
183  master->device_stats.tx_byte_rates[j];
184  io.rx_byte_rates[j] =
185  master->device_stats.rx_byte_rates[j];
186  io.loss_rates[j] =
187  master->device_stats.loss_rates[j];
188  }
189 
190  ec_lock_up(&master->device_sem);
191 
192  io.app_time = master->app_time;
193  io.dc_ref_time = master->dc_ref_time;
194  io.ref_clock =
195  master->dc_ref_clock ? master->dc_ref_clock->ring_position : 0xffff;
196 
197  if (master->pcap_data) {
198  io.pcap_size = sizeof(pcap_hdr_t) + pcap_size;
199  } else {
200  io.pcap_size = 0;
201  }
202 
203  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
204  return -EFAULT;
205  }
206 
207  return 0;
208 }
209 
210 /*****************************************************************************/
211 
217  ec_master_t *master,
218  void *arg
219  )
220 {
221  ec_ioctl_slave_t data;
222  const ec_slave_t *slave;
223  int i;
224 
225  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
226  return -EFAULT;
227  }
228 
229  if (ec_lock_down_interruptible(&master->master_sem))
230  return -EINTR;
231 
232  if (!(slave = ec_master_find_slave_const(
233  master, 0, data.position))) {
234  ec_lock_up(&master->master_sem);
235  EC_MASTER_DBG(master, 1, "Slave %u does not exist!\n", data.position);
236  return -EINVAL;
237  }
238 
239  data.device_index = slave->device_index;
240  data.alias = slave->effective_alias;
241  if (slave->sii_image) {
242  data.vendor_id = slave->sii_image->sii.vendor_id;
243  data.product_code = slave->sii_image->sii.product_code;
244  data.revision_number = slave->sii_image->sii.revision_number;
245  data.serial_number = slave->sii_image->sii.serial_number;
246  data.boot_rx_mailbox_offset = slave->sii_image->sii.boot_rx_mailbox_offset;
247  data.boot_rx_mailbox_size = slave->sii_image->sii.boot_rx_mailbox_size;
248  data.boot_tx_mailbox_offset = slave->sii_image->sii.boot_tx_mailbox_offset;
249  data.boot_tx_mailbox_size = slave->sii_image->sii.boot_tx_mailbox_size;
250  data.std_rx_mailbox_offset = slave->sii_image->sii.std_rx_mailbox_offset;
251  data.std_rx_mailbox_size = slave->sii_image->sii.std_rx_mailbox_size;
252  data.std_tx_mailbox_offset = slave->sii_image->sii.std_tx_mailbox_offset;
253  data.std_tx_mailbox_size = slave->sii_image->sii.std_tx_mailbox_size;
254  data.mailbox_protocols = slave->sii_image->sii.mailbox_protocols;
255  data.has_general_category = slave->sii_image->sii.has_general;
256  data.coe_details = slave->sii_image->sii.coe_details;
257  data.general_flags = slave->sii_image->sii.general_flags;
258  data.current_on_ebus = slave->sii_image->sii.current_on_ebus;
259  data.sync_count = slave->sii_image->sii.sync_count;
260  data.sii_nwords = slave->sii_image->nwords;
261  ec_ioctl_strcpy(data.group, slave->sii_image->sii.group);
262  ec_ioctl_strcpy(data.image, slave->sii_image->sii.image);
263  ec_ioctl_strcpy(data.order, slave->sii_image->sii.order);
264  ec_ioctl_strcpy(data.name, slave->sii_image->sii.name);
265  }
266  else {
267  data.vendor_id = 0x00000000;
268  data.product_code = 0x00000000;
269  data.revision_number = 0x00000000;
270  data.serial_number = 0x00000000;
271  data.boot_rx_mailbox_offset = 0x0000;
272  data.boot_rx_mailbox_size = 0x0000;
273  data.boot_tx_mailbox_offset = 0x0000;
274  data.boot_tx_mailbox_size = 0x0000;
275  data.std_rx_mailbox_offset = 0x0000;
276  data.std_rx_mailbox_size = 0x0000;
277  data.std_tx_mailbox_offset = 0x0000;
278  data.std_tx_mailbox_size = 0x0000;
279  data.mailbox_protocols = 0;
280  data.has_general_category = 0;
281  data.coe_details.enable_pdo_assign = 0;
282  data.coe_details.enable_pdo_configuration = 0;
283  data.coe_details.enable_sdo = 0;
284  data.coe_details.enable_sdo_complete_access = 0;
285  data.coe_details.enable_sdo_info = 0;
286  data.coe_details.enable_upload_at_startup = 0;
287  data.general_flags.enable_not_lrw = 0;
288  data.general_flags.enable_safeop = 0;
289  data.sync_count = 0;
290  data.sii_nwords = 0;
291  ec_ioctl_strcpy(data.group, "");
292  ec_ioctl_strcpy(data.image, "");
293  ec_ioctl_strcpy(data.order, "");
294  ec_ioctl_strcpy(data.name, "");
295  }
296 
297  for (i = 0; i < EC_MAX_PORTS; i++) {
298  data.ports[i].desc = slave->ports[i].desc;
299  data.ports[i].link.link_up = slave->ports[i].link.link_up;
300  data.ports[i].link.loop_closed = slave->ports[i].link.loop_closed;
301  data.ports[i].link.signal_detected =
302  slave->ports[i].link.signal_detected;
303  data.ports[i].link.bypassed = slave->ports[i].link.bypassed;
304  data.ports[i].receive_time = slave->ports[i].receive_time;
305  if (slave->ports[i].next_slave) {
306  data.ports[i].next_slave =
307  slave->ports[i].next_slave->ring_position;
308  } else {
309  data.ports[i].next_slave = 0xffff;
310  }
311  data.ports[i].delay_to_next_dc = slave->ports[i].delay_to_next_dc;
312  }
313  data.upstream_port = slave->upstream_port;
314  data.fmmu_bit = slave->base_fmmu_bit_operation;
315  data.dc_supported = slave->base_dc_supported;
316  data.dc_range = slave->base_dc_range;
317  data.has_dc_system_time = slave->has_dc_system_time;
318  data.transmission_delay = slave->transmission_delay;
319  data.al_state = slave->current_state;
320  data.error_flag = slave->error_flag;
321  data.scan_required = slave->scan_required;
322  data.sdo_count = ec_slave_sdo_count(slave);
323  data.ready = ec_fsm_slave_is_ready(&slave->fsm);
324 
325  ec_lock_up(&master->master_sem);
326 
327  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
328  return -EFAULT;
329 
330  return 0;
331 }
332 
333 /*****************************************************************************/
334 
340  ec_master_t *master,
341  void *arg
342  )
343 {
344  ec_ioctl_slave_sync_t data;
345  const ec_slave_t *slave;
346  const ec_sync_t *sync;
347 
348  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
349  return -EFAULT;
350  }
351 
352  if (ec_lock_down_interruptible(&master->master_sem))
353  return -EINTR;
354 
355  if (!(slave = ec_master_find_slave_const(
356  master, 0, data.slave_position))) {
357  ec_lock_up(&master->master_sem);
358  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
359  data.slave_position);
360  return -EINVAL;
361  }
362 
363  if (slave->sii_image) {
364  if (data.sync_index >= slave->sii_image->sii.sync_count) {
365  ec_lock_up(&master->master_sem);
366  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
367  data.sync_index);
368  return -EINVAL;
369  }
370 
371  sync = &slave->sii_image->sii.syncs[data.sync_index];
372 
374  data.default_size = sync->default_length;
375  data.control_register = sync->control_register;
376  data.enable = sync->enable;
377  data.pdo_count = ec_pdo_list_count(&sync->pdos);
378  }
379  else {
380  EC_SLAVE_INFO(slave, "No access to SII data for SyncManager %u!\n",
381  data.sync_index);
382 
383  data.physical_start_address = 0;
384  data.default_size = 0;
385  data.control_register = 0;
386  data.enable = 0;
387  data.pdo_count = 0;
388  }
389  ec_lock_up(&master->master_sem);
390 
391  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
392  return -EFAULT;
393 
394  return 0;
395 }
396 
397 /*****************************************************************************/
398 
404  ec_master_t *master,
405  void *arg
406  )
407 {
408  ec_ioctl_slave_sync_pdo_t data;
409  const ec_slave_t *slave;
410  const ec_sync_t *sync;
411  const ec_pdo_t *pdo;
412 
413  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
414  return -EFAULT;
415  }
416 
417  if (ec_lock_down_interruptible(&master->master_sem))
418  return -EINTR;
419 
420  if (!(slave = ec_master_find_slave_const(
421  master, 0, data.slave_position))) {
422  ec_lock_up(&master->master_sem);
423  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
424  data.slave_position);
425  return -EINVAL;
426  }
427 
428  if (slave->sii_image) {
429  if (data.sync_index >= slave->sii_image->sii.sync_count) {
430  ec_lock_up(&master->master_sem);
431  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
432  data.sync_index);
433  return -EINVAL;
434  }
435 
436  sync = &slave->sii_image->sii.syncs[data.sync_index];
438  &sync->pdos, data.pdo_pos))) {
439  ec_lock_up(&master->master_sem);
440  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
441  "position %u!\n", data.sync_index, data.pdo_pos);
442  return -EINVAL;
443  }
444 
445  data.index = pdo->index;
446  data.entry_count = ec_pdo_entry_count(pdo);
447  ec_ioctl_strcpy(data.name, pdo->name);
448  }
449  else {
450  EC_SLAVE_INFO(slave, "No access to SII data for SyncManager %u!\n",
451  data.sync_index);
452 
453  data.index = 0;
454  data.entry_count = 0;
455  ec_ioctl_strcpy(data.name, "");
456  }
457  ec_lock_up(&master->master_sem);
458 
459  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
460  return -EFAULT;
461 
462  return 0;
463 }
464 
465 /*****************************************************************************/
466 
472  ec_master_t *master,
473  void *arg
474  )
475 {
476  ec_ioctl_slave_sync_pdo_entry_t data;
477  const ec_slave_t *slave;
478  const ec_sync_t *sync;
479  const ec_pdo_t *pdo;
480  const ec_pdo_entry_t *entry;
481 
482  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
483  return -EFAULT;
484  }
485 
486  if (ec_lock_down_interruptible(&master->master_sem))
487  return -EINTR;
488 
489  if (!(slave = ec_master_find_slave_const(
490  master, 0, data.slave_position))) {
491  ec_lock_up(&master->master_sem);
492  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
493  data.slave_position);
494  return -EINVAL;
495  }
496 
497  if (slave->sii_image) {
498  if (data.sync_index >= slave->sii_image->sii.sync_count) {
499  ec_lock_up(&master->master_sem);
500  EC_SLAVE_ERR(slave, "Sync manager %u does not exist!\n",
501  data.sync_index);
502  return -EINVAL;
503  }
504 
505  sync = &slave->sii_image->sii.syncs[data.sync_index];
507  &sync->pdos, data.pdo_pos))) {
508  ec_lock_up(&master->master_sem);
509  EC_SLAVE_ERR(slave, "Sync manager %u does not contain a PDO with "
510  "position %u!\n", data.sync_index, data.pdo_pos);
511  return -EINVAL;
512  }
513 
514  if (!(entry = ec_pdo_find_entry_by_pos_const(
515  pdo, data.entry_pos))) {
516  ec_lock_up(&master->master_sem);
517  EC_SLAVE_ERR(slave, "PDO 0x%04X does not contain an entry with "
518  "position %u!\n", data.pdo_pos, data.entry_pos);
519  return -EINVAL;
520  }
521 
522  data.index = entry->index;
523  data.subindex = entry->subindex;
524  data.bit_length = entry->bit_length;
525  ec_ioctl_strcpy(data.name, entry->name);
526  }
527  else {
528  EC_SLAVE_INFO(slave, "No access to SII data for Sync manager %u!\n",
529  data.sync_index);
530 
531  data.index = 0;
532  data.subindex = 0;
533  data.bit_length = 0;
534  ec_ioctl_strcpy(data.name, "");
535  }
536  ec_lock_up(&master->master_sem);
537 
538  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
539  return -EFAULT;
540 
541  return 0;
542 }
543 
544 /*****************************************************************************/
545 
551  ec_master_t *master,
552  void *arg
553  )
554 {
555  ec_ioctl_domain_t data;
556  const ec_domain_t *domain;
557  unsigned int dev_idx;
558 
559  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
560  return -EFAULT;
561  }
562 
563  if (ec_lock_down_interruptible(&master->master_sem))
564  return -EINTR;
565 
566  if (!(domain = ec_master_find_domain_const(master, data.index))) {
567  ec_lock_up(&master->master_sem);
568  EC_MASTER_ERR(master, "Domain %u does not exist!\n", data.index);
569  return -EINVAL;
570  }
571 
572  data.data_size = domain->data_size;
573  data.logical_base_address = domain->logical_base_address;
574  for (dev_idx = EC_DEVICE_MAIN;
575  dev_idx < ec_master_num_devices(domain->master); dev_idx++) {
576  data.working_counter[dev_idx] = domain->working_counter[dev_idx];
577  }
578  data.expected_working_counter = domain->expected_working_counter;
579  data.fmmu_count = ec_domain_fmmu_count(domain);
580 
581  ec_lock_up(&master->master_sem);
582 
583  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
584  return -EFAULT;
585 
586  return 0;
587 }
588 
589 /*****************************************************************************/
590 
596  ec_master_t *master,
597  void *arg
598  )
599 {
600  ec_ioctl_domain_fmmu_t data;
601  const ec_domain_t *domain;
602  const ec_fmmu_config_t *fmmu;
603 
604  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
605  return -EFAULT;
606  }
607 
608  if (ec_lock_down_interruptible(&master->master_sem))
609  return -EINTR;
610 
611  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
612  ec_lock_up(&master->master_sem);
613  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
614  data.domain_index);
615  return -EINVAL;
616  }
617 
618  if (!(fmmu = ec_domain_find_fmmu(domain, data.fmmu_index))) {
619  ec_lock_up(&master->master_sem);
620  EC_MASTER_ERR(master, "Domain %u has less than %u"
621  " fmmu configurations.\n",
622  data.domain_index, data.fmmu_index + 1);
623  return -EINVAL;
624  }
625 
626  data.slave_config_alias = fmmu->sc->alias;
627  data.slave_config_position = fmmu->sc->position;
628  data.sync_index = fmmu->sync_index;
629  data.dir = fmmu->dir;
630  data.logical_address = fmmu->domain->logical_base_address + fmmu->logical_domain_offset;
631  data.data_size = fmmu->data_size;
632 
633  ec_lock_up(&master->master_sem);
634 
635  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
636  return -EFAULT;
637 
638  return 0;
639 }
640 
641 /*****************************************************************************/
642 
648  ec_master_t *master,
649  void *arg
650  )
651 {
652  ec_ioctl_domain_data_t data;
653  const ec_domain_t *domain;
654 
655  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
656  return -EFAULT;
657  }
658 
659  if (ec_lock_down_interruptible(&master->master_sem))
660  return -EINTR;
661 
662  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
663  ec_lock_up(&master->master_sem);
664  EC_MASTER_ERR(master, "Domain %u does not exist!\n",
665  data.domain_index);
666  return -EINVAL;
667  }
668 
669  if (domain->data_size != data.data_size) {
670  ec_lock_up(&master->master_sem);
671  EC_MASTER_ERR(master, "Data size mismatch %u/%zu!\n",
672  data.data_size, domain->data_size);
673  return -EFAULT;
674  }
675 
676  if (copy_to_user((void __user *) data.target, domain->data,
677  domain->data_size)) {
678  ec_lock_up(&master->master_sem);
679  return -EFAULT;
680  }
681 
682  ec_lock_up(&master->master_sem);
683  return 0;
684 }
685 
686 /*****************************************************************************/
687 
693  ec_master_t *master,
694  void *arg
695  )
696 {
697  ec_ioctl_pcap_data_t data;
698  pcap_hdr_t pcaphdr;
699  size_t data_size;
700  size_t total_size;
701  void *curr_data;
702 
703  if (!master->pcap_data) {
704  return -EOPNOTSUPP;
705  }
706 
707  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
708  return -EFAULT;
709  }
710 
711  if (ec_lock_down_interruptible(&master->master_sem))
712  return -EINTR;
713 
714  curr_data = master->pcap_curr_data;
715  data_size = curr_data - master->pcap_data;
716  total_size = sizeof(pcap_hdr_t) + data_size;
717  if (data.data_size < sizeof(pcap_hdr_t)) {
718  ec_lock_up(&master->master_sem);
719  EC_MASTER_ERR(master, "Pcap data size too small %u/%zu!\n",
720  data.data_size, sizeof(pcap_hdr_t));
721  return -EFAULT;
722  }
723  if (data.data_size > total_size) {
724  data.data_size = total_size;
725  }
726 
727  // fill in pcap header and copy to user mem
728  pcaphdr.magic_number = 0xa1b2c3d4;
729  pcaphdr.version_major = 2;
730  pcaphdr.version_minor = 4;
731  pcaphdr.thiszone = 0;
732  pcaphdr.sigfigs = 0;
733  pcaphdr.snaplen = 65535;
734  pcaphdr.network = 1;
735  if (copy_to_user((void __user *) data.target, &pcaphdr,
736  sizeof(pcap_hdr_t))) {
737  ec_lock_up(&master->master_sem);
738  return -EFAULT;
739  }
740 
741  // copy pcap data, up to requested size; also copy updated data_size
742  if ( (data_size > 0) &&
743  (copy_to_user((void __user *) (data.target + sizeof(pcap_hdr_t)),
744  master->pcap_data, data.data_size - sizeof(pcap_hdr_t)) ||
745  copy_to_user((void __user *) arg, &data, sizeof(data)))) {
746  ec_lock_up(&master->master_sem);
747  return -EFAULT;
748  }
749 
750  // remove copied data?
751  // Note: will remove any data that has not been copied
752  if (data.reset_data) {
753  master->pcap_curr_data = master->pcap_data;
754  }
755 
756  ec_lock_up(&master->master_sem);
757  return 0;
758 }
759 
760 /*****************************************************************************/
761 
767  ec_master_t *master,
768  void *arg
769  )
770 {
771  return ec_master_debug_level(master, (unsigned long) arg);
772 }
773 
774 /*****************************************************************************/
775 
781  ec_master_t *master,
782  void *arg
783  )
784 {
785  master->fsm.rescan_required = 1;
786  return 0;
787 }
788 
789 /*****************************************************************************/
790 
796  ec_master_t *master,
797  void *arg
798  )
799 {
800  ec_ioctl_slave_state_t data;
801  ec_slave_t *slave;
802 
803  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
804  return -EFAULT;
805  }
806 
807  if (ec_lock_down_interruptible(&master->master_sem))
808  return -EINTR;
809 
810  if (!(slave = ec_master_find_slave(
811  master, 0, data.slave_position))) {
812  ec_lock_up(&master->master_sem);
813  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
814  data.slave_position);
815  return -EINVAL;
816  }
817 
818  ec_slave_request_state(slave, data.al_state);
819 
820  ec_lock_up(&master->master_sem);
821  return 0;
822 }
823 
824 /*****************************************************************************/
825 
831  ec_master_t *master,
832  void *arg
833  )
834 {
835  ec_ioctl_slave_reboot_t io;
836  ec_slave_t *slave;
837 
838  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
839  return -EFAULT;
840  }
841 
842  if (ec_lock_down_interruptible(&master->master_sem)) {
843  return -EINTR;
844  }
845 
846  if (io.broadcast) {
847  ec_master_reboot_slaves(master);
848  } else {
849  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
850  ec_lock_up(&master->master_sem);
851  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
852  io.slave_position);
853  return -EINVAL;
854  }
855 
857  }
858 
859  ec_lock_up(&master->master_sem);
860 
861  return 0;
862 }
863 
864 /*****************************************************************************/
865 
871  ec_master_t *master,
872  void *arg
873  )
874 {
875  ec_ioctl_slave_sdo_t data;
876  const ec_slave_t *slave;
877  const ec_sdo_t *sdo;
878 
879  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
880  return -EFAULT;
881  }
882 
883  if (ec_lock_down_interruptible(&master->master_sem))
884  return -EINTR;
885 
886  if (!(slave = ec_master_find_slave_const(
887  master, 0, data.slave_position))) {
888  ec_lock_up(&master->master_sem);
889  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
890  data.slave_position);
891  return -EINVAL;
892  }
893 
894  if (!(sdo = ec_slave_get_sdo_by_pos_const(
895  slave, data.sdo_position))) {
896  ec_lock_up(&master->master_sem);
897  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", data.sdo_position);
898  return -EINVAL;
899  }
900 
901  data.sdo_index = sdo->index;
902  data.max_subindex = sdo->max_subindex;
903  ec_ioctl_strcpy(data.name, sdo->name);
904 
905  ec_lock_up(&master->master_sem);
906 
907  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
908  return -EFAULT;
909 
910  return 0;
911 }
912 
913 /*****************************************************************************/
914 
920  ec_master_t *master,
921  void *arg
922  )
923 {
924  ec_ioctl_slave_sdo_entry_t data;
925  const ec_slave_t *slave;
926  const ec_sdo_t *sdo;
927  const ec_sdo_entry_t *entry;
928 
929  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
930  return -EFAULT;
931  }
932 
933  if (ec_lock_down_interruptible(&master->master_sem))
934  return -EINTR;
935 
936  if (!(slave = ec_master_find_slave_const(
937  master, 0, data.slave_position))) {
938  ec_lock_up(&master->master_sem);
939  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
940  data.slave_position);
941  return -EINVAL;
942  }
943 
944  if (data.sdo_spec <= 0) {
945  if (!(sdo = ec_slave_get_sdo_by_pos_const(
946  slave, -data.sdo_spec))) {
947  ec_lock_up(&master->master_sem);
948  EC_SLAVE_ERR(slave, "SDO %u does not exist!\n", -data.sdo_spec);
949  return -EINVAL;
950  }
951  } else {
952  if (!(sdo = ec_slave_get_sdo_const(
953  slave, data.sdo_spec))) {
954  ec_lock_up(&master->master_sem);
955  EC_SLAVE_ERR(slave, "SDO 0x%04X does not exist!\n",
956  data.sdo_spec);
957  return -EINVAL;
958  }
959  }
960 
961  if (!(entry = ec_sdo_get_entry_const(
962  sdo, data.sdo_entry_subindex))) {
963  ec_lock_up(&master->master_sem);
964  EC_SLAVE_ERR(slave, "SDO entry 0x%04X:%02X does not exist!\n",
965  sdo->index, data.sdo_entry_subindex);
966  return -EINVAL;
967  }
968 
969  data.data_type = entry->data_type;
970  data.bit_length = entry->bit_length;
971  data.read_access[EC_SDO_ENTRY_ACCESS_PREOP] =
973  data.read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
975  data.read_access[EC_SDO_ENTRY_ACCESS_OP] =
977  data.write_access[EC_SDO_ENTRY_ACCESS_PREOP] =
979  data.write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] =
981  data.write_access[EC_SDO_ENTRY_ACCESS_OP] =
983  ec_ioctl_strcpy(data.description, entry->description);
984 
985  ec_lock_up(&master->master_sem);
986 
987  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
988  return -EFAULT;
989 
990  return 0;
991 }
992 
993 /*****************************************************************************/
994 
1000  ec_master_t *master,
1001  void *arg
1002  )
1003 {
1004  ec_ioctl_slave_sdo_upload_t data;
1005  uint8_t *target;
1006  int ret;
1007 
1008  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1009  return -EFAULT;
1010  }
1011 
1012  if (!(target = kmalloc(data.target_size, GFP_KERNEL))) {
1013  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
1014  " for SDO upload.\n", data.target_size);
1015  return -ENOMEM;
1016  }
1017 
1018  if (data.complete_access) {
1019  ret = ecrt_master_sdo_upload_complete(master, data.slave_position,
1020  data.sdo_index, target, data.target_size,
1021  &data.data_size, &data.abort_code);
1022  } else {
1023  ret = ecrt_master_sdo_upload(master, data.slave_position,
1024  data.sdo_index, data.sdo_entry_subindex, target,
1025  data.target_size, &data.data_size, &data.abort_code);
1026  }
1027 
1028  if (!ret) {
1029  if (copy_to_user((void __user *) data.target,
1030  target, data.data_size)) {
1031  kfree(target);
1032  return -EFAULT;
1033  }
1034  }
1035 
1036  kfree(target);
1037 
1038  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
1039  return -EFAULT;
1040  }
1041 
1042  return ret;
1043 }
1044 
1045 /*****************************************************************************/
1046 
1052  ec_master_t *master,
1053  void *arg
1054  )
1055 {
1056  ec_ioctl_slave_sdo_download_t data;
1057  uint8_t *sdo_data;
1058  int retval;
1059 
1060  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1061  return -EFAULT;
1062  }
1063 
1064  if (!(sdo_data = kmalloc(data.data_size, GFP_KERNEL))) {
1065  EC_MASTER_ERR(master, "Failed to allocate %zu bytes"
1066  " for SDO download.\n", data.data_size);
1067  return -ENOMEM;
1068  }
1069 
1070  if (copy_from_user(sdo_data, (const void __user *) data.data, data.data_size)) {
1071  kfree(sdo_data);
1072  return -EFAULT;
1073  }
1074 
1075  if (data.complete_access) {
1076  retval = ecrt_master_sdo_download_complete(master, data.slave_position,
1077  data.sdo_index, sdo_data, data.data_size, &data.abort_code);
1078  } else {
1079  retval = ecrt_master_sdo_download(master, data.slave_position,
1080  data.sdo_index, data.sdo_entry_subindex, sdo_data,
1081  data.data_size, &data.abort_code);
1082  }
1083 
1084  kfree(sdo_data);
1085 
1086  if (__copy_to_user((void __user *) arg, &data, sizeof(data))) {
1087  retval = -EFAULT;
1088  }
1089 
1090  return retval;
1091 }
1092 
1093 /*****************************************************************************/
1094 
1100  ec_master_t *master,
1101  void *arg
1102  )
1103 {
1104  ec_ioctl_slave_sii_t data;
1105  const ec_slave_t *slave;
1106  int retval;
1107 
1108  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1109  return -EFAULT;
1110  }
1111 
1112  if (ec_lock_down_interruptible(&master->master_sem))
1113  return -EINTR;
1114 
1115  if (!(slave = ec_master_find_slave_const(
1116  master, 0, data.slave_position))) {
1117  ec_lock_up(&master->master_sem);
1118  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1119  data.slave_position);
1120  return -EINVAL;
1121  }
1122 
1123  if (!slave->sii_image) {
1124  EC_SLAVE_INFO(slave, "No access to SII data. Try again!\n");
1125  return -EAGAIN;
1126  }
1127 
1128  if (!data.nwords
1129  || data.offset + data.nwords > slave->sii_image->nwords) {
1130  ec_lock_up(&master->master_sem);
1131  EC_SLAVE_ERR(slave, "Invalid SII read offset/size %u/%u for slave SII"
1132  " size %zu!\n", data.offset, data.nwords, slave->sii_image->nwords);
1133  return -EINVAL;
1134  }
1135 
1136  if (copy_to_user((void __user *) data.words,
1137  slave->sii_image->words + data.offset, data.nwords * 2))
1138  retval = -EFAULT;
1139  else
1140  retval = 0;
1141 
1142  ec_lock_up(&master->master_sem);
1143  return retval;
1144 }
1145 
1146 /*****************************************************************************/
1147 
1153  ec_master_t *master,
1154  void *arg
1155  )
1156 {
1157  ec_ioctl_slave_sii_t data;
1158  ec_slave_t *slave;
1159  unsigned int byte_size;
1160  uint16_t *words;
1161  ec_sii_write_request_t request;
1162 
1163  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1164  return -EFAULT;
1165  }
1166 
1167  if (!data.nwords) {
1168  return 0;
1169  }
1170 
1171  byte_size = sizeof(uint16_t) * data.nwords;
1172  if (!(words = kmalloc(byte_size, GFP_KERNEL))) {
1173  EC_MASTER_ERR(master, "Failed to allocate %u bytes"
1174  " for SII contents.\n", byte_size);
1175  return -ENOMEM;
1176  }
1177 
1178  if (copy_from_user(words,
1179  (void __user *) data.words, byte_size)) {
1180  kfree(words);
1181  return -EFAULT;
1182  }
1183 
1184  if (ec_lock_down_interruptible(&master->master_sem)) {
1185  kfree(words);
1186  return -EINTR;
1187  }
1188 
1189  if (!(slave = ec_master_find_slave(
1190  master, 0, data.slave_position))) {
1191  ec_lock_up(&master->master_sem);
1192  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1193  data.slave_position);
1194  kfree(words);
1195  return -EINVAL;
1196  }
1197 
1198  // init SII write request
1199  INIT_LIST_HEAD(&request.list);
1200  request.slave = slave;
1201  request.words = words;
1202  request.offset = data.offset;
1203  request.nwords = data.nwords;
1204  request.state = EC_INT_REQUEST_QUEUED;
1205 
1206  // schedule SII write request.
1207  list_add_tail(&request.list, &master->sii_requests);
1208 
1209  ec_lock_up(&master->master_sem);
1210 
1211  // wait for processing through FSM
1212  if (wait_event_interruptible(master->request_queue,
1213  request.state != EC_INT_REQUEST_QUEUED)) {
1214  // interrupted by signal
1215  ec_lock_down(&master->master_sem);
1216  if (request.state == EC_INT_REQUEST_QUEUED) {
1217  // abort request
1218  list_del(&request.list);
1219  ec_lock_up(&master->master_sem);
1220  kfree(words);
1221  return -EINTR;
1222  }
1223  ec_lock_up(&master->master_sem);
1224  }
1225 
1226  // wait until master FSM has finished processing
1227  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1228 
1229  kfree(words);
1230 
1231  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1232 }
1233 
1234 /*****************************************************************************/
1235 
1241  ec_master_t *master,
1242  void *arg
1243  )
1244 {
1245  ec_ioctl_slave_reg_t io;
1246  ec_slave_t *slave;
1247  ec_reg_request_t request;
1248  int ret;
1249 
1250  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1251  return -EFAULT;
1252  }
1253 
1254  if (!io.size) {
1255  return 0;
1256  }
1257 
1258  // init register request
1259  ret = ec_reg_request_init(&request, io.size);
1260  if (ret) {
1261  return ret;
1262  }
1263 
1264  ecrt_reg_request_read(&request, io.address, io.size);
1265 
1266  if (ec_lock_down_interruptible(&master->master_sem)) {
1267  ec_reg_request_clear(&request);
1268  return -EINTR;
1269  }
1270 
1271  if (!(slave = ec_master_find_slave(
1272  master, 0, io.slave_position))) {
1273  ec_lock_up(&master->master_sem);
1274  ec_reg_request_clear(&request);
1275  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1276  io.slave_position);
1277  return -EINVAL;
1278  }
1279 
1280  // schedule request.
1281  list_add_tail(&request.list, &slave->reg_requests);
1282 
1283  ec_lock_up(&master->master_sem);
1284 
1285  // wait for processing through FSM
1286  if (wait_event_interruptible(master->request_queue,
1287  request.state != EC_INT_REQUEST_QUEUED)) {
1288  // interrupted by signal
1289  ec_lock_down(&master->master_sem);
1290  if (request.state == EC_INT_REQUEST_QUEUED) {
1291  // abort request
1292  list_del(&request.list);
1293  ec_lock_up(&master->master_sem);
1294  ec_reg_request_clear(&request);
1295  return -EINTR;
1296  }
1297  ec_lock_up(&master->master_sem);
1298  }
1299 
1300  // wait until master FSM has finished processing
1301  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1302 
1303  if (request.state == EC_INT_REQUEST_SUCCESS) {
1304  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1305  return -EFAULT;
1306  }
1307  }
1308  ec_reg_request_clear(&request);
1309 
1310  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1311 }
1312 
1313 /*****************************************************************************/
1314 
1320  ec_master_t *master,
1321  void *arg
1322  )
1323 {
1324  ec_ioctl_slave_reg_t io;
1325  ec_slave_t *slave;
1326  ec_reg_request_t request;
1327  int ret;
1328 
1329  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1330  return -EFAULT;
1331  }
1332 
1333  if (!io.size) {
1334  return 0;
1335  }
1336 
1337  // init register request
1338  ret = ec_reg_request_init(&request, io.size);
1339  if (ret) {
1340  return ret;
1341  }
1342 
1343  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1344  ec_reg_request_clear(&request);
1345  return -EFAULT;
1346  }
1347 
1348  ecrt_reg_request_write(&request, io.address, io.size);
1349 
1350  if (ec_lock_down_interruptible(&master->master_sem)) {
1351  ec_reg_request_clear(&request);
1352  return -EINTR;
1353  }
1354 
1355  if (io.emergency) {
1356  request.ring_position = io.slave_position;
1357  // schedule request.
1358  list_add_tail(&request.list, &master->emerg_reg_requests);
1359  }
1360  else {
1361  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1362  ec_lock_up(&master->master_sem);
1363  ec_reg_request_clear(&request);
1364  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1365  io.slave_position);
1366  return -EINVAL;
1367  }
1368 
1369  // schedule request.
1370  list_add_tail(&request.list, &slave->reg_requests);
1371  }
1372 
1373  ec_lock_up(&master->master_sem);
1374 
1375  // wait for processing through FSM
1376  if (wait_event_interruptible(master->request_queue,
1377  request.state != EC_INT_REQUEST_QUEUED)) {
1378  // interrupted by signal
1379  ec_lock_down(&master->master_sem);
1380  if (request.state == EC_INT_REQUEST_QUEUED) {
1381  // abort request
1382  list_del(&request.list);
1383  ec_lock_up(&master->master_sem);
1384  ec_reg_request_clear(&request);
1385  return -EINTR;
1386  }
1387  ec_lock_up(&master->master_sem);
1388  }
1389 
1390  // wait until master FSM has finished processing
1391  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1392 
1393  ec_reg_request_clear(&request);
1394 
1395  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1396 }
1397 
1398 /*****************************************************************************/
1399 
1405  ec_master_t *master,
1406  void *arg
1407  )
1408 {
1409  ec_ioctl_slave_reg_t io;
1410  ec_slave_t *slave;
1411  ec_reg_request_t request;
1412  int ret;
1413 
1414  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1415  return -EFAULT;
1416  }
1417 
1418  if (!io.size) {
1419  return 0;
1420  }
1421 
1422  // init register request
1423  ret = ec_reg_request_init(&request, io.size);
1424  if (ret) {
1425  return ret;
1426  }
1427 
1428  if (copy_from_user(request.data, (void __user *) io.data, io.size)) {
1429  ec_reg_request_clear(&request);
1430  return -EFAULT;
1431  }
1432 
1433  ecrt_reg_request_readwrite(&request, io.address, io.size);
1434 
1435  if (ec_lock_down_interruptible(&master->master_sem)) {
1436  ec_reg_request_clear(&request);
1437  return -EINTR;
1438  }
1439 
1440  if (io.emergency) {
1441  request.ring_position = io.slave_position;
1442  // schedule request.
1443  list_add_tail(&request.list, &master->emerg_reg_requests);
1444  } else {
1445  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
1446  ec_lock_up(&master->master_sem);
1447  ec_reg_request_clear(&request);
1448  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1449  io.slave_position);
1450  return -EINVAL;
1451  }
1452 
1453  // schedule request.
1454  list_add_tail(&request.list, &slave->reg_requests);
1455  }
1456 
1457  ec_lock_up(&master->master_sem);
1458 
1459  // wait for processing through FSM
1460  if (wait_event_interruptible(master->request_queue,
1461  request.state != EC_INT_REQUEST_QUEUED)) {
1462  // interrupted by signal
1463  ec_lock_down(&master->master_sem);
1464  if (request.state == EC_INT_REQUEST_QUEUED) {
1465  // abort request
1466  list_del(&request.list);
1467  ec_lock_up(&master->master_sem);
1468  ec_reg_request_clear(&request);
1469  return -EINTR;
1470  }
1471  ec_lock_up(&master->master_sem);
1472  }
1473 
1474  // wait until master FSM has finished processing
1475  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
1476 
1477  if (request.state == EC_INT_REQUEST_SUCCESS) {
1478  if (copy_to_user((void __user *) io.data, request.data, io.size)) {
1479  return -EFAULT;
1480  }
1481  }
1482  ec_reg_request_clear(&request);
1483 
1484  return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1485 }
1486 
1487 /*****************************************************************************/
1488 
1494  ec_master_t *master,
1495  void *arg
1496  )
1497 {
1498  ec_ioctl_config_t data;
1499  const ec_slave_config_t *sc;
1500  uint8_t i;
1501 
1502  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1503  return -EFAULT;
1504  }
1505 
1506  if (ec_lock_down_interruptible(&master->master_sem))
1507  return -EINTR;
1508 
1509  if (!(sc = ec_master_get_config_const(
1510  master, data.config_index))) {
1511  ec_lock_up(&master->master_sem);
1512  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1513  data.config_index);
1514  return -EINVAL;
1515  }
1516 
1517  data.alias = sc->alias;
1518  data.position = sc->position;
1519  data.vendor_id = sc->vendor_id;
1520  data.product_code = sc->product_code;
1521  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
1522  data.syncs[i].dir = sc->sync_configs[i].dir;
1523  data.syncs[i].watchdog_mode = sc->sync_configs[i].watchdog_mode;
1524  data.syncs[i].pdo_count =
1526  }
1527  data.watchdog_divider = sc->watchdog_divider;
1528  data.watchdog_intervals = sc->watchdog_intervals;
1529  data.sdo_count = ec_slave_config_sdo_count(sc);
1530  data.idn_count = ec_slave_config_idn_count(sc);
1531  data.slave_position = sc->slave ? sc->slave->ring_position : -1;
1532  data.dc_assign_activate = sc->dc_assign_activate;
1533  for (i = 0; i < EC_SYNC_SIGNAL_COUNT; i++) {
1534  data.dc_sync[i] = sc->dc_sync[i];
1535  }
1536 
1537  ec_lock_up(&master->master_sem);
1538 
1539  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1540  return -EFAULT;
1541 
1542  return 0;
1543 }
1544 
1545 /*****************************************************************************/
1546 
1552  ec_master_t *master,
1553  void *arg
1554  )
1555 {
1556  ec_ioctl_config_pdo_t data;
1557  const ec_slave_config_t *sc;
1558  const ec_pdo_t *pdo;
1559 
1560  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1561  return -EFAULT;
1562  }
1563 
1564  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1565  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1566  data.sync_index);
1567  return -EINVAL;
1568  }
1569 
1570  if (ec_lock_down_interruptible(&master->master_sem))
1571  return -EINTR;
1572 
1573  if (!(sc = ec_master_get_config_const(
1574  master, data.config_index))) {
1575  ec_lock_up(&master->master_sem);
1576  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1577  data.config_index);
1578  return -EINVAL;
1579  }
1580 
1582  &sc->sync_configs[data.sync_index].pdos,
1583  data.pdo_pos))) {
1584  ec_lock_up(&master->master_sem);
1585  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1586  return -EINVAL;
1587  }
1588 
1589  data.index = pdo->index;
1590  data.entry_count = ec_pdo_entry_count(pdo);
1591  ec_ioctl_strcpy(data.name, pdo->name);
1592 
1593  ec_lock_up(&master->master_sem);
1594 
1595  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1596  return -EFAULT;
1597 
1598  return 0;
1599 }
1600 
1601 /*****************************************************************************/
1602 
1608  ec_master_t *master,
1609  void *arg
1610  )
1611 {
1612  ec_ioctl_config_pdo_entry_t data;
1613  const ec_slave_config_t *sc;
1614  const ec_pdo_t *pdo;
1615  const ec_pdo_entry_t *entry;
1616 
1617  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1618  return -EFAULT;
1619  }
1620 
1621  if (data.sync_index >= EC_MAX_SYNC_MANAGERS) {
1622  EC_MASTER_ERR(master, "Invalid sync manager index %u!\n",
1623  data.sync_index);
1624  return -EINVAL;
1625  }
1626 
1627  if (ec_lock_down_interruptible(&master->master_sem))
1628  return -EINTR;
1629 
1630  if (!(sc = ec_master_get_config_const(
1631  master, data.config_index))) {
1632  ec_lock_up(&master->master_sem);
1633  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1634  data.config_index);
1635  return -EINVAL;
1636  }
1637 
1639  &sc->sync_configs[data.sync_index].pdos,
1640  data.pdo_pos))) {
1641  ec_lock_up(&master->master_sem);
1642  EC_MASTER_ERR(master, "Invalid PDO position!\n");
1643  return -EINVAL;
1644  }
1645 
1646  if (!(entry = ec_pdo_find_entry_by_pos_const(
1647  pdo, data.entry_pos))) {
1648  ec_lock_up(&master->master_sem);
1649  EC_MASTER_ERR(master, "Entry not found!\n");
1650  return -EINVAL;
1651  }
1652 
1653  data.index = entry->index;
1654  data.subindex = entry->subindex;
1655  data.bit_length = entry->bit_length;
1656  ec_ioctl_strcpy(data.name, entry->name);
1657 
1658  ec_lock_up(&master->master_sem);
1659 
1660  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1661  return -EFAULT;
1662 
1663  return 0;
1664 }
1665 
1666 /*****************************************************************************/
1667 
1673  ec_master_t *master,
1674  void *arg
1675  )
1676 {
1677  ec_ioctl_config_sdo_t *ioctl;
1678  const ec_slave_config_t *sc;
1679  const ec_sdo_request_t *req;
1680 
1681  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1682  return -ENOMEM;
1683  }
1684 
1685  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1686  kfree(ioctl);
1687  return -EFAULT;
1688  }
1689 
1690  if (ec_lock_down_interruptible(&master->master_sem)) {
1691  kfree(ioctl);
1692  return -EINTR;
1693  }
1694 
1695  if (!(sc = ec_master_get_config_const(
1696  master, ioctl->config_index))) {
1697  ec_lock_up(&master->master_sem);
1698  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1699  ioctl->config_index);
1700  kfree(ioctl);
1701  return -EINVAL;
1702  }
1703 
1705  sc, ioctl->sdo_pos))) {
1706  ec_lock_up(&master->master_sem);
1707  EC_MASTER_ERR(master, "Invalid SDO position!\n");
1708  kfree(ioctl);
1709  return -EINVAL;
1710  }
1711 
1712  ioctl->index = req->index;
1713  ioctl->subindex = req->subindex;
1714  ioctl->size = req->data_size;
1715  memcpy(ioctl->data, req->data,
1716  min((u32) ioctl->size, (u32) EC_MAX_SDO_DATA_SIZE));
1717  ioctl->complete_access = req->complete_access;
1718 
1719  ec_lock_up(&master->master_sem);
1720 
1721  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1722  kfree(ioctl);
1723  return -EFAULT;
1724  }
1725 
1726  kfree(ioctl);
1727  return 0;
1728 }
1729 
1730 /*****************************************************************************/
1731 
1737  ec_master_t *master,
1738  void *arg
1739  )
1740 {
1741  ec_ioctl_config_idn_t *ioctl;
1742  const ec_slave_config_t *sc;
1743  const ec_soe_request_t *req;
1744 
1745  if (!(ioctl = kmalloc(sizeof(*ioctl), GFP_KERNEL))) {
1746  return -ENOMEM;
1747  }
1748 
1749  if (copy_from_user(ioctl, (void __user *) arg, sizeof(*ioctl))) {
1750  kfree(ioctl);
1751  return -EFAULT;
1752  }
1753 
1754  if (ec_lock_down_interruptible(&master->master_sem)) {
1755  kfree(ioctl);
1756  return -EINTR;
1757  }
1758 
1759  if (!(sc = ec_master_get_config_const(
1760  master, ioctl->config_index))) {
1761  ec_lock_up(&master->master_sem);
1762  EC_MASTER_ERR(master, "Slave config %u does not exist!\n",
1763  ioctl->config_index);
1764  kfree(ioctl);
1765  return -EINVAL;
1766  }
1767 
1769  sc, ioctl->idn_pos))) {
1770  ec_lock_up(&master->master_sem);
1771  EC_MASTER_ERR(master, "Invalid IDN position!\n");
1772  kfree(ioctl);
1773  return -EINVAL;
1774  }
1775 
1776  ioctl->drive_no = req->drive_no;
1777  ioctl->idn = req->idn;
1778  ioctl->state = req->state;
1779  ioctl->size = req->data_size;
1780  memcpy(ioctl->data, req->data,
1781  min((u32) ioctl->size, (u32) EC_MAX_IDN_DATA_SIZE));
1782 
1783  ec_lock_up(&master->master_sem);
1784 
1785  if (copy_to_user((void __user *) arg, ioctl, sizeof(*ioctl))) {
1786  kfree(ioctl);
1787  return -EFAULT;
1788  }
1789 
1790  kfree(ioctl);
1791  return 0;
1792 }
1793 
1794 /*****************************************************************************/
1795 
1796 #ifdef EC_EOE
1797 
1803  ec_master_t *master,
1804  void *arg
1805  )
1806 {
1807  ec_ioctl_eoe_handler_t data;
1808  const ec_eoe_t *eoe;
1809 
1810  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
1811  return -EFAULT;
1812  }
1813 
1814  if (ec_lock_down_interruptible(&master->master_sem))
1815  return -EINTR;
1816 
1817  if (!(eoe = ec_master_get_eoe_handler_const(master, data.eoe_index))) {
1818  ec_lock_up(&master->master_sem);
1819  EC_MASTER_ERR(master, "EoE handler %u does not exist!\n",
1820  data.eoe_index);
1821  return -EINVAL;
1822  }
1823 
1824  if (eoe->slave) {
1825  data.slave_position = eoe->slave->ring_position;
1826  } else {
1827  data.slave_position = 0xffff;
1828  }
1829  snprintf(data.name, EC_DATAGRAM_NAME_SIZE, eoe->dev->name);
1830  data.open = eoe->opened;
1831  data.rx_bytes = eoe->stats.rx_bytes;
1832  data.rx_rate = eoe->rx_rate;
1833  data.tx_bytes = eoe->stats.tx_bytes;
1834  data.tx_rate = eoe->tx_rate;
1835  data.tx_queued_frames = ec_eoe_tx_queued_frames(eoe);
1836  data.tx_queue_size = eoe->tx_ring_count;
1837 
1838  EC_MASTER_DBG(master, 1, "EOE %s Info:\n", eoe->dev->name);
1839  EC_MASTER_DBG(master, 1, " opened: %u\n", eoe->opened);
1840  EC_MASTER_DBG(master, 1, " rate_jiffies: %lu\n", eoe->rate_jiffies);
1841  EC_MASTER_DBG(master, 1, " queue_datagram: %u\n", eoe->queue_datagram);
1842  EC_MASTER_DBG(master, 1, " have_mbox_lock: %u\n", eoe->have_mbox_lock);
1843  EC_MASTER_DBG(master, 1, " rx_skb: %p\n", eoe->rx_skb);
1844  EC_MASTER_DBG(master, 1, " rx_skb_offset: %d\n", (int)eoe->rx_skb_offset);
1845  EC_MASTER_DBG(master, 1, " rx_skb_size: %zu\n", eoe->rx_skb_size);
1846  EC_MASTER_DBG(master, 1, " rx_expected_fragment: %hhu\n", eoe->rx_expected_fragment);
1847  EC_MASTER_DBG(master, 1, " rx_counter: %u\n", eoe->rx_counter);
1848  EC_MASTER_DBG(master, 1, " rx_rate: %u\n", eoe->rx_rate);
1849  EC_MASTER_DBG(master, 1, " rx_idle: %u\n", eoe->rx_idle);
1850  EC_MASTER_DBG(master, 1, " tx_ring_count: %u\n", eoe->tx_ring_count);
1851  EC_MASTER_DBG(master, 1, " tx_ring_size: %u\n", eoe->tx_ring_size);
1852  EC_MASTER_DBG(master, 1, " tx_next_to_use: %u\n", eoe->tx_next_to_use);
1853  EC_MASTER_DBG(master, 1, " tx_next_to_clean: %u\n", eoe->tx_next_to_clean);
1854  EC_MASTER_DBG(master, 1, " tx_queue_active: %u\n", eoe->tx_queue_active);
1855  EC_MASTER_DBG(master, 1, " tx_queued_frames: %u\n", data.tx_queued_frames);
1856  EC_MASTER_DBG(master, 1, " tx_frame_number: %hhu\n", eoe->tx_frame_number);
1857  EC_MASTER_DBG(master, 1, " tx_fragment_number: %hhu\n", eoe->tx_fragment_number);
1858  EC_MASTER_DBG(master, 1, " tx_offset: %zu\n", eoe->tx_offset);
1859  EC_MASTER_DBG(master, 1, " tx_counter: %u\n", eoe->tx_counter);
1860  EC_MASTER_DBG(master, 1, " tx_rate: %u\n", eoe->tx_rate);
1861  EC_MASTER_DBG(master, 1, " tx_idle: %u\n", eoe->tx_idle);
1862  EC_MASTER_DBG(master, 1, " tries: %u\n", eoe->tries);
1863 
1864  ec_lock_up(&master->master_sem);
1865 
1866  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
1867  return -EFAULT;
1868 
1869  return 0;
1870 }
1871 
1872 #endif
1873 
1874 /*****************************************************************************/
1875 
1876 #ifdef EC_EOE
1877 
1882  ec_master_t *master,
1883  void *arg
1884  )
1885 {
1886  ec_ioctl_slave_eoe_ip_t io;
1887  ec_eoe_request_t req;
1888  ec_slave_t *slave;
1889 
1890  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
1891  return -EFAULT;
1892  }
1893 
1894  // init EoE request
1895  ec_eoe_request_init(&req);
1896 
1897  req.mac_address_included = io.mac_address_included;
1898  req.ip_address_included = io.ip_address_included;
1899  req.subnet_mask_included = io.subnet_mask_included;
1900  req.gateway_included = io.gateway_included;
1901  req.dns_included = io.dns_included;
1902  req.name_included = io.name_included;
1903 
1904  memcpy(req.mac_address, io.mac_address, ETH_ALEN);
1905  req.ip_address = io.ip_address;
1906  req.subnet_mask = io.subnet_mask;
1907  req.gateway = io.gateway;
1908  req.dns = io.dns;
1909  memcpy(req.name, io.name, EC_MAX_HOSTNAME_SIZE);
1910 
1911  req.state = EC_INT_REQUEST_QUEUED;
1912 
1913  if (ec_lock_down_interruptible(&master->master_sem)) {
1914  return -EINTR;
1915  }
1916 
1917  if (!(slave = ec_master_find_slave(
1918  master, 0, io.slave_position))) {
1919  ec_lock_up(&master->master_sem);
1920  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
1921  io.slave_position);
1922  return -EINVAL;
1923  }
1924 
1925  EC_MASTER_DBG(master, 1, "Scheduling EoE request.\n");
1926 
1927  // schedule request.
1928  list_add_tail(&req.list, &slave->eoe_requests);
1929 
1930  ec_lock_up(&master->master_sem);
1931 
1932  // wait for processing through FSM
1933  if (wait_event_interruptible(master->request_queue,
1934  req.state != EC_INT_REQUEST_QUEUED)) {
1935  // interrupted by signal
1936  ec_lock_down(&master->master_sem);
1937  if (req.state == EC_INT_REQUEST_QUEUED) {
1938  // abort request
1939  list_del(&req.list);
1940  ec_lock_up(&master->master_sem);
1941  return -EINTR;
1942  }
1943  ec_lock_up(&master->master_sem);
1944  }
1945 
1946  // wait until master FSM has finished processing
1947  wait_event(master->request_queue, req.state != EC_INT_REQUEST_BUSY);
1948 
1949  io.result = req.result;
1950 
1951  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
1952  return -EFAULT;
1953  }
1954 
1955  return req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
1956 }
1957 #endif
1958 
1959 /*****************************************************************************/
1960 
1966  ec_master_t *master,
1967  void *arg,
1968  ec_ioctl_context_t *ctx
1969  )
1970 {
1971  ec_master_t *m;
1972  int ret = 0;
1973 
1974  m = ecrt_request_master_err(master->index);
1975  if (IS_ERR(m)) {
1976  ret = PTR_ERR(m);
1977  } else {
1978  ctx->requested = 1;
1979  }
1980 
1981  return ret;
1982 }
1983 
1984 /*****************************************************************************/
1985 
1986 #if defined(EC_RTDM) && defined(EC_EOE)
1987 
1993 static ATTRIBUTES int ec_ioctl_eoe_is_open(
1994  ec_master_t *master,
1995  void *arg,
1996  ec_ioctl_context_t *ctx
1997  )
1998 {
1999  if (unlikely(!ctx->requested)) {
2000  return -EPERM;
2001  }
2002 
2003  return ec_master_eoe_is_open(master);
2004 }
2005 
2006 /*****************************************************************************/
2007 
2013 static ATTRIBUTES int ec_ioctl_eoe_process(
2014  ec_master_t *master,
2015  void *arg,
2016  ec_ioctl_context_t *ctx
2017  )
2018 {
2019  if (unlikely(!ctx->requested)) {
2020  return -EPERM;
2021  }
2022 
2023  return ec_master_eoe_process(master);
2024 }
2025 
2026 #endif
2027 
2028 /*****************************************************************************/
2029 
2035  ec_master_t *master,
2036  void *arg,
2037  ec_ioctl_context_t *ctx
2038  )
2039 {
2040  ec_domain_t *domain;
2041 
2042  if (unlikely(!ctx->requested))
2043  return -EPERM;
2044 
2045  domain = ecrt_master_create_domain_err(master);
2046  if (IS_ERR(domain))
2047  return PTR_ERR(domain);
2048 
2049  return domain->index;
2050 }
2051 
2052 /*****************************************************************************/
2053 
2059  ec_master_t *master,
2060  void *arg,
2061  ec_ioctl_context_t *ctx
2062  )
2063 {
2064  ec_ioctl_config_t data;
2065  ec_slave_config_t *sc, *entry;
2066 
2067  if (unlikely(!ctx->requested))
2068  return -EPERM;
2069 
2070  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2071  return -EFAULT;
2072  }
2073 
2074  sc = ecrt_master_slave_config_err(master, data.alias, data.position,
2075  data.vendor_id, data.product_code);
2076  if (IS_ERR(sc))
2077  return PTR_ERR(sc);
2078 
2079  data.config_index = 0;
2080 
2081  if (ec_lock_down_interruptible(&master->master_sem))
2082  return -EINTR;
2083 
2084  list_for_each_entry(entry, &master->configs, list) {
2085  if (entry == sc)
2086  break;
2087  data.config_index++;
2088  }
2089 
2090  ec_lock_up(&master->master_sem);
2091 
2092  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2093  return -EFAULT;
2094 
2095  return 0;
2096 }
2097 
2098 /*****************************************************************************/
2099 
2105  ec_master_t *master,
2106  void *arg,
2107  ec_ioctl_context_t *ctx
2108  )
2109 {
2110  unsigned long config_index = (unsigned long) arg;
2111  ec_slave_config_t *sc = NULL;
2112  int ret = 0;
2113 
2114  if (unlikely(!ctx->requested)) {
2115  ret = -EPERM;
2116  goto out_return;
2117  }
2118 
2119  if (ec_lock_down_interruptible(&master->master_sem)) {
2120  ret = -EINTR;
2121  goto out_return;
2122  }
2123 
2124  if (config_index != 0xFFFFFFFF) {
2125  if (!(sc = ec_master_get_config(master, config_index))) {
2126  ret = -ENOENT;
2127  goto out_up;
2128  }
2129  }
2130 
2132 
2133 out_up:
2134  ec_lock_up(&master->master_sem);
2135 out_return:
2136  return ret;
2137 }
2138 
2139 /*****************************************************************************/
2140 
2146  ec_master_t *master,
2147  void *arg,
2148  ec_ioctl_context_t *ctx
2149  )
2150 {
2151  ec_ioctl_master_activate_t io;
2152  ec_domain_t *domain;
2153  off_t offset;
2154 #ifdef EC_IOCTL_RTDM
2155  int ret;
2156 #endif
2157 
2158  if (unlikely(!ctx->requested))
2159  return -EPERM;
2160 
2161 
2162  if (!ctx->process_data)
2163  {
2164  io.process_data = NULL;
2165 
2166  /* Get the sum of the domains' process data sizes. */
2167 
2168  ctx->process_data_size = 0;
2169 
2170  if (ec_lock_down_interruptible(&master->master_sem))
2171  return -EINTR;
2172 
2173  list_for_each_entry(domain, &master->domains, list) {
2174  ctx->process_data_size += ecrt_domain_size(domain);
2175  }
2176 
2177  ec_lock_up(&master->master_sem);
2178 
2179  if (ctx->process_data_size) {
2180  ctx->process_data = vmalloc(ctx->process_data_size);
2181  if (!ctx->process_data) {
2182  ctx->process_data_size = 0;
2183  return -ENOMEM;
2184  }
2185 
2186  /* Set the memory as external process data memory for the
2187  * domains.
2188  */
2189  offset = 0;
2190  list_for_each_entry(domain, &master->domains, list) {
2192  ctx->process_data + offset);
2193  offset += ecrt_domain_size(domain);
2194  }
2195 
2196 #ifdef EC_IOCTL_RTDM
2197  /* RTDM uses a different approach for memory-mapping, which has to be
2198  * initiated by the kernel.
2199  */
2200  ret = ec_rtdm_mmap(ctx, &io.process_data);
2201  if (ret < 0) {
2202  EC_MASTER_ERR(master, "Failed to map process data"
2203  " memory to user space (code %i).\n", ret);
2204  return ret;
2205  }
2206 #endif
2207  }
2208 
2209  io.process_data_size = ctx->process_data_size;
2210  }
2211  else
2212  {
2213  io.process_data = NULL;
2214  io.process_data_size = 0;
2215  }
2216 
2217 
2218  if (copy_to_user((void __user *) arg, &io,
2219  sizeof(ec_ioctl_master_activate_t)))
2220  return -EFAULT;
2221 
2222  return 0;
2223 }
2224 
2225 /*****************************************************************************/
2226 
2232  ec_master_t *master,
2233  void *arg,
2234  ec_ioctl_context_t *ctx
2235  )
2236 {
2237  ec_ioctl_master_activate_t io;
2238  ec_domain_t *domain;
2239  off_t offset;
2240  int ret;
2241 
2242  if (unlikely(!ctx->requested))
2243  return -EPERM;
2244 
2245 
2246  if (!ctx->process_data)
2247  {
2248  io.process_data = NULL;
2249 
2250  /* Get the sum of the domains' process data sizes. */
2251 
2252  ctx->process_data_size = 0;
2253 
2254  if (ec_lock_down_interruptible(&master->master_sem))
2255  return -EINTR;
2256 
2257  list_for_each_entry(domain, &master->domains, list) {
2258  ctx->process_data_size += ecrt_domain_size(domain);
2259  }
2260 
2261  ec_lock_up(&master->master_sem);
2262 
2263  if (ctx->process_data_size) {
2264  ctx->process_data = vmalloc(ctx->process_data_size);
2265  if (!ctx->process_data) {
2266  ctx->process_data_size = 0;
2267  return -ENOMEM;
2268  }
2269 
2270  /* Set the memory as external process data memory for the
2271  * domains.
2272  */
2273  offset = 0;
2274  list_for_each_entry(domain, &master->domains, list) {
2276  ctx->process_data + offset);
2277  offset += ecrt_domain_size(domain);
2278  }
2279 
2280 #ifdef EC_IOCTL_RTDM
2281  /* RTDM uses a different approach for memory-mapping, which has to be
2282  * initiated by the kernel.
2283  */
2284  ret = ec_rtdm_mmap(ctx, &io.process_data);
2285  if (ret < 0) {
2286  EC_MASTER_ERR(master, "Failed to map process data"
2287  " memory to user space (code %i).\n", ret);
2288  return ret;
2289  }
2290 #endif
2291  }
2292 
2293  io.process_data_size = ctx->process_data_size;
2294  }
2295  else
2296  {
2297  io.process_data = NULL;
2298  io.process_data_size = 0;
2299  }
2300 
2301 #ifndef EC_IOCTL_RTDM
2304 #endif
2305 
2306  ret = ecrt_master_activate(master);
2307  if (ret < 0)
2308  return ret;
2309 
2310  if (copy_to_user((void __user *) arg, &io,
2311  sizeof(ec_ioctl_master_activate_t)))
2312  return -EFAULT;
2313 
2314  return 0;
2315 }
2316 
2317 /*****************************************************************************/
2318 
2324  ec_master_t *master,
2325  void *arg,
2326  ec_ioctl_context_t *ctx
2327  )
2328 {
2329  if (unlikely(!ctx->requested))
2330  return -EPERM;
2331 
2333  return 0;
2334 }
2335 
2336 /*****************************************************************************/
2337 
2343  ec_master_t *master,
2344  void *arg,
2345  ec_ioctl_context_t *ctx
2346  )
2347 {
2348  if (unlikely(!ctx->requested))
2349  return -EPERM;
2350 
2351  ecrt_master_deactivate(master);
2352  return 0;
2353 }
2354 
2355 /*****************************************************************************/
2356 
2362  ec_master_t *master,
2363  void *arg,
2364  ec_ioctl_context_t *ctx
2365  )
2366 {
2367  size_t send_interval;
2368 
2369  if (unlikely(!ctx->requested)) {
2370  return -EPERM;
2371  }
2372 
2373  if (copy_from_user(&send_interval, (void __user *) arg,
2374  sizeof(send_interval))) {
2375  return -EFAULT;
2376  }
2377 
2378  if (ec_lock_down_interruptible(&master->master_sem))
2379  return -EINTR;
2380 
2381  ec_master_set_send_interval(master, send_interval);
2382 
2383  ec_lock_up(&master->master_sem);
2384  return 0;
2385 }
2386 
2387 /*****************************************************************************/
2388 
2394  ec_master_t *master,
2395  void *arg,
2396  ec_ioctl_context_t *ctx
2397  )
2398 {
2399  size_t sent_bytes;
2400 
2401  if (unlikely(!ctx->requested)) {
2402  return -EPERM;
2403  }
2404 
2405  /* Locking added as send is likely to be used by more than
2406  one application tasks */
2408  return -EINTR;
2409 
2410 #if defined(EC_RTDM) && defined(EC_EOE)
2411  sent_bytes = ecrt_master_send(master);
2412 #else
2413  if (master->send_cb != NULL) {
2414  master->send_cb(master->cb_data);
2415  sent_bytes = 0;
2416  } else
2417  sent_bytes = ecrt_master_send(master);
2418 #endif
2419 
2420  ec_ioctl_lock_up(&master->master_sem);
2421 
2422  if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) {
2423  return -EFAULT;
2424  }
2425 
2426  return 0;
2427 }
2428 
2429 /*****************************************************************************/
2430 
2436  ec_master_t *master,
2437  void *arg,
2438  ec_ioctl_context_t *ctx
2439  )
2440 {
2441  if (unlikely(!ctx->requested)) {
2442  return -EPERM;
2443  }
2444 
2445  /* Locking added as receive is likely to be used by more than
2446  one application tasks */
2448  return -EINTR;
2449 
2450 #if defined(EC_RTDM) && defined(EC_EOE)
2451  ecrt_master_receive(master);
2452 #else
2453  if (master->receive_cb != NULL)
2454  master->receive_cb(master->cb_data);
2455  else
2456  ecrt_master_receive(master);
2457 #endif
2458 
2459  ec_ioctl_lock_up(&master->master_sem);
2460 
2461  return 0;
2462 }
2463 
2464 /*****************************************************************************/
2465 
2466 #if defined(EC_RTDM) && defined(EC_EOE)
2467 
2472 static ATTRIBUTES int ec_ioctl_send_ext(
2473  ec_master_t *master,
2474  void *arg,
2475  ec_ioctl_context_t *ctx
2476  )
2477 {
2478  size_t sent_bytes;
2479 
2480  if (unlikely(!ctx->requested)) {
2481  return -EPERM;
2482  }
2483 
2484  sent_bytes = ecrt_master_send_ext(master);
2485 
2486  if (copy_to_user((void __user *) arg, &sent_bytes, sizeof(sent_bytes))) {
2487  return -EFAULT;
2488  }
2489 
2490  return 0;
2491 }
2492 
2493 #endif
2494 
2495 /*****************************************************************************/
2496 
2502  ec_master_t *master,
2503  void *arg,
2504  ec_ioctl_context_t *ctx
2505  )
2506 {
2507  ec_master_state_t data;
2508 
2509  ecrt_master_state(master, &data);
2510 
2511  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
2512  return -EFAULT;
2513 
2514  return 0;
2515 }
2516 
2517 /*****************************************************************************/
2518 
2524  ec_master_t *master,
2525  void *arg,
2526  ec_ioctl_context_t *ctx
2527  )
2528 {
2529  ec_ioctl_link_state_t ioctl;
2530  ec_master_link_state_t state;
2531  int ret;
2532 
2533  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
2534  return -EFAULT;
2535  }
2536 
2537  ret = ecrt_master_link_state(master, ioctl.dev_idx, &state);
2538  if (ret < 0) {
2539  return ret;
2540  }
2541 
2542  if (copy_to_user((void __user *) ioctl.state, &state, sizeof(state))) {
2543  return -EFAULT;
2544  }
2545 
2546  return 0;
2547 }
2548 
2549 /*****************************************************************************/
2550 
2556  ec_master_t *master,
2557  void *arg,
2558  ec_ioctl_context_t *ctx
2559  )
2560 {
2561  uint64_t time;
2562 
2563  if (unlikely(!ctx->requested))
2564  return -EPERM;
2565 
2566  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2567  return -EFAULT;
2568  }
2569 
2570  ecrt_master_application_time(master, time);
2571  return 0;
2572 }
2573 
2574 /*****************************************************************************/
2575 
2581  ec_master_t *master,
2582  void *arg,
2583  ec_ioctl_context_t *ctx
2584  )
2585 {
2586  if (unlikely(!ctx->requested)) {
2587  return -EPERM;
2588  }
2589 
2591  return 0;
2592 }
2593 
2594 /*****************************************************************************/
2595 
2601  ec_master_t *master,
2602  void *arg,
2603  ec_ioctl_context_t *ctx
2604  )
2605 {
2606  uint64_t time;
2607 
2608  if (unlikely(!ctx->requested))
2609  return -EPERM;
2610 
2611  if (copy_from_user(&time, (void __user *) arg, sizeof(time))) {
2612  return -EFAULT;
2613  }
2614 
2616  return 0;
2617 }
2618 
2619 /*****************************************************************************/
2620 
2626  ec_master_t *master,
2627  void *arg,
2628  ec_ioctl_context_t *ctx
2629  )
2630 {
2631  if (unlikely(!ctx->requested)) {
2632  return -EPERM;
2633  }
2634 
2636  return 0;
2637 }
2638 
2639 /*****************************************************************************/
2640 
2646  ec_master_t *master,
2647  void *arg,
2648  ec_ioctl_context_t *ctx
2649  )
2650 {
2651  uint32_t time;
2652  int ret;
2653 
2654  if (unlikely(!ctx->requested)) {
2655  return -EPERM;
2656  }
2657 
2658  ret = ecrt_master_reference_clock_time(master, &time);
2659  if (ret) {
2660  return ret;
2661  }
2662 
2663  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2664  return -EFAULT;
2665  }
2666 
2667  return 0;
2668 }
2669 
2670 /*****************************************************************************/
2671 
2677  ec_master_t *master,
2678  void *arg,
2679  ec_ioctl_context_t *ctx
2680  )
2681 {
2682  if (unlikely(!ctx->requested)) {
2683  return -EPERM;
2684  }
2685 
2687  return 0;
2688 }
2689 
2690 /*****************************************************************************/
2691 
2697  ec_master_t *master,
2698  void *arg,
2699  ec_ioctl_context_t *ctx
2700  )
2701 {
2702  uint64_t time;
2703  int ret;
2704 
2705  if (unlikely(!ctx->requested)) {
2706  return -EPERM;
2707  }
2708 
2709  ret = ecrt_master_64bit_reference_clock_time(master, &time);
2710  if (ret) {
2711  return ret;
2712  }
2713 
2714  if (copy_to_user((void __user *) arg, &time, sizeof(time))) {
2715  return -EFAULT;
2716  }
2717 
2718  return 0;
2719 }
2720 
2721 /*****************************************************************************/
2722 
2728  ec_master_t *master,
2729  void *arg,
2730  ec_ioctl_context_t *ctx
2731  )
2732 {
2733  if (unlikely(!ctx->requested)) {
2734  return -EPERM;
2735  }
2736 
2738  return 0;
2739 }
2740 
2741 /*****************************************************************************/
2742 
2748  ec_master_t *master,
2749  void *arg,
2750  ec_ioctl_context_t *ctx
2751  )
2752 {
2753  uint32_t time_diff;
2754 
2755  if (unlikely(!ctx->requested))
2756  return -EPERM;
2757 
2758  time_diff = ecrt_master_sync_monitor_process(master);
2759 
2760  if (copy_to_user((void __user *) arg, &time_diff, sizeof(time_diff)))
2761  return -EFAULT;
2762 
2763  return 0;
2764 }
2765 
2766 /*****************************************************************************/
2767 
2774  ec_master_t *master,
2775  void *arg,
2776  ec_ioctl_context_t *ctx
2777  )
2778 {
2779  unsigned long rt_slave_requests = (unsigned long) arg;
2780  int ret = 0;
2781 
2782  if (unlikely(!ctx->requested)) {
2783  ret = -EPERM;
2784  goto out_return;
2785  }
2786 
2787  if (ec_lock_down_interruptible(&master->master_sem)) {
2788  ret = -EINTR;
2789  goto out_return;
2790  }
2791 
2792  ecrt_master_rt_slave_requests(master, rt_slave_requests);
2793 
2794  ec_lock_up(&master->master_sem);
2795 
2796 out_return:
2797  return ret;
2798 }
2799 
2800 /*****************************************************************************/
2801 
2807  ec_master_t *master,
2808  void *arg,
2809  ec_ioctl_context_t *ctx
2810  )
2811 {
2812  if (unlikely(!ctx->requested)) {
2813  return -EPERM;
2814  }
2815 
2817 
2818  return 0;
2819 }
2820 
2821 /*****************************************************************************/
2822 
2828  ec_master_t *master,
2829  void *arg,
2830  ec_ioctl_context_t *ctx
2831  )
2832 {
2833  ec_lock_down(&master->master_sem);
2834  ecrt_master_reset(master);
2835  ec_lock_up(&master->master_sem);
2836  return 0;
2837 }
2838 
2839 /*****************************************************************************/
2840 
2846  ec_master_t *master,
2847  void *arg,
2848  ec_ioctl_context_t *ctx
2849  )
2850 {
2851  ec_ioctl_config_t data;
2852  ec_slave_config_t *sc;
2853  unsigned int i;
2854  int ret = 0;
2855 
2856  if (unlikely(!ctx->requested)) {
2857  ret = -EPERM;
2858  goto out_return;
2859  }
2860 
2861  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2862  ret = -EFAULT;
2863  goto out_return;
2864  }
2865 
2866  if (ec_lock_down_interruptible(&master->master_sem)) {
2867  ret = -EINTR;
2868  goto out_return;
2869  }
2870 
2871  if (!(sc = ec_master_get_config(master, data.config_index))) {
2872  ret = -ENOENT;
2873  goto out_up;
2874  }
2875 
2876  for (i = 0; i < EC_MAX_SYNC_MANAGERS; i++) {
2877  if (data.syncs[i].config_this) {
2878  ret = ecrt_slave_config_sync_manager(sc, i, data.syncs[i].dir,
2879  data.syncs[i].watchdog_mode);
2880  if (ret) {
2881  goto out_up;
2882  }
2883  }
2884  }
2885 
2886 out_up:
2887  ec_lock_up(&master->master_sem);
2888 out_return:
2889  return ret;
2890 }
2891 
2892 /*****************************************************************************/
2893 
2899  ec_master_t *master,
2900  void *arg,
2901  ec_ioctl_context_t *ctx
2902  )
2903 {
2904  ec_ioctl_config_t data;
2905  ec_slave_config_t *sc;
2906  int ret = 0;
2907 
2908  if (unlikely(!ctx->requested)) {
2909  ret = -EPERM;
2910  goto out_return;
2911  }
2912 
2913  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2914  ret = -EFAULT;
2915  goto out_return;
2916  }
2917 
2918  if (ec_lock_down_interruptible(&master->master_sem)) {
2919  ret = -EINTR;
2920  goto out_return;
2921  }
2922 
2923  if (!(sc = ec_master_get_config(master, data.config_index))) {
2924  ret = -ENOENT;
2925  goto out_up;
2926  }
2927 
2929  data.watchdog_divider, data.watchdog_intervals);
2930 
2931 out_up:
2932  ec_lock_up(&master->master_sem);
2933 out_return:
2934  return ret;
2935 }
2936 
2937 /*****************************************************************************/
2938 
2942  ec_master_t *master,
2943  void *arg,
2944  ec_ioctl_context_t *ctx
2945  )
2946 {
2947  ec_ioctl_config_t data;
2948  ec_slave_config_t *sc;
2949  int ret = 0;
2950 
2951  if (unlikely(!ctx->requested)) {
2952  ret = -EPERM;
2953  goto out_return;
2954  }
2955 
2956  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
2957  ret = -EFAULT;
2958  goto out_return;
2959  }
2960 
2961  if (ec_lock_down_interruptible(&master->master_sem)) {
2962  ret = -EINTR;
2963  goto out_return;
2964  }
2965 
2966  if (!(sc = ec_master_get_config(master, data.config_index))) {
2967  ret = -ENOENT;
2968  goto out_up;
2969  }
2970 
2972  data.allow_overlapping_pdos);
2973 
2974 out_up:
2975  ec_lock_up(&master->master_sem);
2976 out_return:
2977  return ret;
2978 }
2979 /*****************************************************************************/
2980 
2986  ec_master_t *master,
2987  void *arg,
2988  ec_ioctl_context_t *ctx
2989  )
2990 {
2991  ec_ioctl_config_pdo_t data;
2992  ec_slave_config_t *sc;
2993 
2994  if (unlikely(!ctx->requested))
2995  return -EPERM;
2996 
2997  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
2998  return -EFAULT;
2999 
3000  if (ec_lock_down_interruptible(&master->master_sem))
3001  return -EINTR;
3002 
3003  if (!(sc = ec_master_get_config(master, data.config_index))) {
3004  ec_lock_up(&master->master_sem);
3005  return -ENOENT;
3006  }
3007 
3008  ec_lock_up(&master->master_sem);
3010  return ecrt_slave_config_pdo_assign_add(sc, data.sync_index, data.index);
3011 }
3012 
3013 /*****************************************************************************/
3014 
3020  ec_master_t *master,
3021  void *arg,
3022  ec_ioctl_context_t *ctx
3023  )
3024 {
3025  ec_ioctl_config_pdo_t data;
3026  ec_slave_config_t *sc;
3027 
3028  if (unlikely(!ctx->requested))
3029  return -EPERM;
3030 
3031  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3032  return -EFAULT;
3033 
3034  if (ec_lock_down_interruptible(&master->master_sem))
3035  return -EINTR;
3036 
3037  if (!(sc = ec_master_get_config(master, data.config_index))) {
3038  ec_lock_up(&master->master_sem);
3039  return -ENOENT;
3040  }
3041 
3042  ec_lock_up(&master->master_sem);
3044  ecrt_slave_config_pdo_assign_clear(sc, data.sync_index);
3045  return 0;
3046 }
3047 
3048 /*****************************************************************************/
3049 
3055  ec_master_t *master,
3056  void *arg,
3057  ec_ioctl_context_t *ctx
3058  )
3059 {
3060  ec_ioctl_add_pdo_entry_t data;
3061  ec_slave_config_t *sc;
3062 
3063  if (unlikely(!ctx->requested))
3064  return -EPERM;
3065 
3066  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3067  return -EFAULT;
3068 
3069  if (ec_lock_down_interruptible(&master->master_sem))
3070  return -EINTR;
3071 
3072  if (!(sc = ec_master_get_config(master, data.config_index))) {
3073  ec_lock_up(&master->master_sem);
3074  return -ENOENT;
3075  }
3076 
3077  ec_lock_up(&master->master_sem);
3079  return ecrt_slave_config_pdo_mapping_add(sc, data.pdo_index,
3080  data.entry_index, data.entry_subindex, data.entry_bit_length);
3081 }
3082 
3083 /*****************************************************************************/
3084 
3090  ec_master_t *master,
3091  void *arg,
3092  ec_ioctl_context_t *ctx
3093  )
3094 {
3095  ec_ioctl_config_pdo_t data;
3096  ec_slave_config_t *sc;
3097 
3098  if (unlikely(!ctx->requested))
3099  return -EPERM;
3100 
3101  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3102  return -EFAULT;
3103 
3104  if (ec_lock_down_interruptible(&master->master_sem))
3105  return -EINTR;
3106 
3107  if (!(sc = ec_master_get_config(master, data.config_index))) {
3108  ec_lock_up(&master->master_sem);
3109  return -ENOENT;
3110  }
3111 
3112  ec_lock_up(&master->master_sem);
3114  ecrt_slave_config_pdo_mapping_clear(sc, data.index);
3115  return 0;
3116 }
3117 
3118 /*****************************************************************************/
3119 
3125  ec_master_t *master,
3126  void *arg,
3127  ec_ioctl_context_t *ctx
3128  )
3129 {
3130  ec_ioctl_reg_pdo_entry_t data;
3131  ec_slave_config_t *sc;
3132  ec_domain_t *domain;
3133  int ret;
3134 
3135  if (unlikely(!ctx->requested))
3136  return -EPERM;
3137 
3138  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3139  return -EFAULT;
3140 
3141  if (ec_lock_down_interruptible(&master->master_sem))
3142  return -EINTR;
3143 
3144  if (!(sc = ec_master_get_config(master, data.config_index))) {
3145  ec_lock_up(&master->master_sem);
3146  return -ENOENT;
3147  }
3148 
3149  if (!(domain = ec_master_find_domain(master, data.domain_index))) {
3150  ec_lock_up(&master->master_sem);
3151  return -ENOENT;
3152  }
3153 
3154  ec_lock_up(&master->master_sem);
3156  ret = ecrt_slave_config_reg_pdo_entry(sc, data.entry_index,
3157  data.entry_subindex, domain, &data.bit_position);
3158 
3159  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3160  return -EFAULT;
3161 
3162  return ret;
3163 }
3164 
3165 /*****************************************************************************/
3166 
3172  ec_master_t *master,
3173  void *arg,
3174  ec_ioctl_context_t *ctx
3175  )
3176 {
3177  ec_ioctl_reg_pdo_pos_t io;
3178  ec_slave_config_t *sc;
3179  ec_domain_t *domain;
3180  int ret;
3181 
3182  if (unlikely(!ctx->requested)) {
3183  return -EPERM;
3184  }
3185 
3186  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3187  return -EFAULT;
3188  }
3189 
3190  if (ec_lock_down_interruptible(&master->master_sem)) {
3191  return -EINTR;
3192  }
3193 
3194  if (!(sc = ec_master_get_config(master, io.config_index))) {
3195  ec_lock_up(&master->master_sem);
3196  return -ENOENT;
3197  }
3198 
3199  if (!(domain = ec_master_find_domain(master, io.domain_index))) {
3200  ec_lock_up(&master->master_sem);
3201  return -ENOENT;
3202  }
3203 
3204  ec_lock_up(&master->master_sem);
3206  ret = ecrt_slave_config_reg_pdo_entry_pos(sc, io.sync_index,
3207  io.pdo_pos, io.entry_pos, domain, &io.bit_position);
3208 
3209  if (copy_to_user((void __user *) arg, &io, sizeof(io)))
3210  return -EFAULT;
3211 
3212  return ret;
3213 }
3214 
3215 /*****************************************************************************/
3216 
3222  ec_master_t *master,
3223  void *arg,
3224  ec_ioctl_context_t *ctx
3225  )
3226 {
3227  ec_ioctl_config_t data;
3228  ec_slave_config_t *sc;
3229 
3230  if (unlikely(!ctx->requested))
3231  return -EPERM;
3232 
3233  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3234  return -EFAULT;
3235 
3236  if (ec_lock_down_interruptible(&master->master_sem))
3237  return -EINTR;
3238 
3239  if (!(sc = ec_master_get_config(master, data.config_index))) {
3240  ec_lock_up(&master->master_sem);
3241  return -ENOENT;
3242  }
3243 
3245  data.dc_sync[0].cycle_time,
3246  data.dc_sync[0].shift_time,
3247  data.dc_sync[1].cycle_time,
3248  data.dc_sync[1].shift_time);
3249 
3250  ec_lock_up(&master->master_sem);
3251 
3252  return 0;
3253 }
3254 
3255 /*****************************************************************************/
3256 
3262  ec_master_t *master,
3263  void *arg,
3264  ec_ioctl_context_t *ctx
3265  )
3266 {
3267  ec_ioctl_sc_sdo_t data;
3268  ec_slave_config_t *sc;
3269  uint8_t *sdo_data = NULL;
3270  int ret;
3271 
3272  if (unlikely(!ctx->requested))
3273  return -EPERM;
3274 
3275  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3276  return -EFAULT;
3277 
3278  if (!data.size)
3279  return -EINVAL;
3280 
3281  if (!(sdo_data = kmalloc(data.size, GFP_KERNEL))) {
3282  return -ENOMEM;
3283  }
3284 
3285  if (copy_from_user(sdo_data, (void __user *) data.data, data.size)) {
3286  kfree(sdo_data);
3287  return -EFAULT;
3288  }
3289 
3290  if (ec_lock_down_interruptible(&master->master_sem)) {
3291  kfree(sdo_data);
3292  return -EINTR;
3293  }
3294 
3295  if (!(sc = ec_master_get_config(master, data.config_index))) {
3296  ec_lock_up(&master->master_sem);
3297  kfree(sdo_data);
3298  return -ENOENT;
3299  }
3300 
3301  ec_lock_up(&master->master_sem);
3303  if (data.complete_access) {
3305  data.index, sdo_data, data.size);
3306  } else {
3307  ret = ecrt_slave_config_sdo(sc, data.index, data.subindex, sdo_data,
3308  data.size);
3309  }
3310  kfree(sdo_data);
3311  return ret;
3312 }
3313 
3314 /*****************************************************************************/
3315 
3321  ec_master_t *master,
3322  void *arg,
3323  ec_ioctl_context_t *ctx
3324  )
3325 {
3326  ec_ioctl_sc_emerg_t io;
3327  ec_slave_config_t *sc;
3328  int ret;
3329 
3330  if (unlikely(!ctx->requested))
3331  return -EPERM;
3332 
3333  if (copy_from_user(&io, (void __user *) arg, sizeof(io)))
3334  return -EFAULT;
3335 
3336  if (ec_lock_down_interruptible(&master->master_sem)) {
3337  return -EINTR;
3338  }
3339 
3340  if (!(sc = ec_master_get_config(master, io.config_index))) {
3341  ec_lock_up(&master->master_sem);
3342  return -ENOENT;
3343  }
3344 
3345  ret = ecrt_slave_config_emerg_size(sc, io.size);
3346 
3347  ec_lock_up(&master->master_sem);
3348 
3349  return ret;
3350 }
3351 
3352 /*****************************************************************************/
3353 
3359  ec_master_t *master,
3360  void *arg,
3361  ec_ioctl_context_t *ctx
3362  )
3363 {
3364  ec_ioctl_sc_emerg_t io;
3365  ec_slave_config_t *sc;
3366  u8 msg[EC_COE_EMERGENCY_MSG_SIZE];
3367  int ret;
3368 
3369  if (unlikely(!ctx->requested)) {
3370  return -EPERM;
3371  }
3372 
3373  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3374  return -EFAULT;
3375  }
3376 
3377  /* no locking of master_sem needed, because configuration will not be
3378  * deleted in the meantime. */
3379 
3380  if (!(sc = ec_master_get_config(master, io.config_index))) {
3381  return -ENOENT;
3382  }
3383 
3384  ret = ecrt_slave_config_emerg_pop(sc, msg);
3385  if (ret < 0) {
3386  return ret;
3387  }
3388 
3389  if (copy_to_user((void __user *) io.target, msg, sizeof(msg))) {
3390  return -EFAULT;
3391  }
3392 
3393  return ret;
3394 }
3395 
3396 /*****************************************************************************/
3397 
3403  ec_master_t *master,
3404  void *arg,
3405  ec_ioctl_context_t *ctx
3406  )
3407 {
3408  ec_ioctl_sc_emerg_t io;
3409  ec_slave_config_t *sc;
3410 
3411  if (unlikely(!ctx->requested)) {
3412  return -EPERM;
3413  }
3414 
3415  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3416  return -EFAULT;
3417  }
3418 
3419  /* no locking of master_sem needed, because configuration will not be
3420  * deleted in the meantime. */
3421 
3422  if (!(sc = ec_master_get_config(master, io.config_index))) {
3423  return -ENOENT;
3424  }
3425 
3426  return ecrt_slave_config_emerg_clear(sc);
3427 }
3428 
3429 /*****************************************************************************/
3430 
3436  ec_master_t *master,
3437  void *arg,
3438  ec_ioctl_context_t *ctx
3439  )
3440 {
3441  ec_ioctl_sc_emerg_t io;
3442  ec_slave_config_t *sc;
3443  int ret;
3444 
3445  if (unlikely(!ctx->requested)) {
3446  return -EPERM;
3447  }
3448 
3449  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3450  return -EFAULT;
3451  }
3452 
3453  /* no locking of master_sem needed, because configuration will not be
3454  * deleted in the meantime. */
3455 
3456  if (!(sc = ec_master_get_config(master, io.config_index))) {
3457  return -ENOENT;
3458  }
3459 
3461  if (ret < 0) {
3462  return ret;
3463  }
3464 
3465  io.overruns = ret;
3466 
3467  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3468  return -EFAULT;
3469  }
3470 
3471  return 0;
3472 }
3473 
3474 /*****************************************************************************/
3475 
3481  ec_master_t *master,
3482  void *arg,
3483  ec_ioctl_context_t *ctx
3484  )
3485 {
3486  ec_ioctl_sdo_request_t data;
3487  ec_slave_config_t *sc;
3488  ec_sdo_request_t *req;
3489 
3490  if (unlikely(!ctx->requested))
3491  return -EPERM;
3492 
3493  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3494  return -EFAULT;
3495  }
3496 
3497  data.request_index = 0;
3498 
3499  if (ec_lock_down_interruptible(&master->master_sem))
3500  return -EINTR;
3501 
3502  sc = ec_master_get_config(master, data.config_index);
3503  if (!sc) {
3504  ec_lock_up(&master->master_sem);
3505  return -ENOENT;
3506  }
3507 
3508  list_for_each_entry(req, &sc->sdo_requests, list) {
3509  data.request_index++;
3510  }
3511 
3512  ec_lock_up(&master->master_sem);
3514  req = ecrt_slave_config_create_sdo_request_err(sc, data.sdo_index,
3515  data.sdo_subindex, data.complete_access, data.size);
3516  if (IS_ERR(req))
3517  return PTR_ERR(req);
3518 
3519  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3520  return -EFAULT;
3521 
3522  return 0;
3523 }
3524 
3525 /*****************************************************************************/
3526 
3532  ec_master_t *master,
3533  void *arg,
3534  ec_ioctl_context_t *ctx
3535  )
3536 {
3537  ec_ioctl_foe_request_t data;
3538  ec_slave_config_t *sc;
3539  ec_foe_request_t *req;
3540 
3541  if (unlikely(!ctx->requested))
3542  return -EPERM;
3543 
3544  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3545  return -EFAULT;
3546  }
3547 
3548  data.request_index = 0;
3549 
3550  if (ec_lock_down_interruptible(&master->master_sem))
3551  return -EINTR;
3552 
3553  sc = ec_master_get_config(master, data.config_index);
3554  if (!sc) {
3555  ec_lock_up(&master->master_sem);
3556  return -ENOENT;
3557  }
3558 
3559  list_for_each_entry(req, &sc->foe_requests, list) {
3560  data.request_index++;
3561  }
3562 
3563  ec_lock_up(&master->master_sem);
3565  req = ecrt_slave_config_create_foe_request_err(sc, data.size);
3566  if (IS_ERR(req))
3567  return PTR_ERR(req);
3568 
3569  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3570  return -EFAULT;
3571 
3572  return 0;
3573 }
3574 
3575 /*****************************************************************************/
3576 
3582  ec_master_t *master,
3583  void *arg,
3584  ec_ioctl_context_t *ctx
3585  )
3586 {
3587  ec_ioctl_reg_request_t io;
3588  ec_slave_config_t *sc;
3589  ec_reg_request_t *reg;
3590 
3591  if (unlikely(!ctx->requested)) {
3592  return -EPERM;
3593  }
3594 
3595  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
3596  return -EFAULT;
3597  }
3598 
3599  io.request_index = 0;
3600 
3601  if (ec_lock_down_interruptible(&master->master_sem)) {
3602  return -EINTR;
3603  }
3604 
3605  sc = ec_master_get_config(master, io.config_index);
3606  if (!sc) {
3607  ec_lock_up(&master->master_sem);
3608  return -ENOENT;
3609  }
3610 
3611  list_for_each_entry(reg, &sc->reg_requests, list) {
3612  io.request_index++;
3613  }
3614 
3615  ec_lock_up(&master->master_sem);
3617  reg = ecrt_slave_config_create_reg_request_err(sc, io.mem_size);
3618  if (IS_ERR(reg)) {
3619  return PTR_ERR(reg);
3620  }
3621 
3622  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
3623  return -EFAULT;
3624  }
3625 
3626  return 0;
3627 }
3628 
3629 /*****************************************************************************/
3630 
3636  ec_master_t *master,
3637  void *arg,
3638  ec_ioctl_context_t *ctx
3639  )
3640 {
3641  ec_ioctl_voe_t data;
3642  ec_slave_config_t *sc;
3643  ec_voe_handler_t *voe;
3644 
3645  if (unlikely(!ctx->requested))
3646  return -EPERM;
3647 
3648  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3649  return -EFAULT;
3650  }
3651 
3652  data.voe_index = 0;
3653 
3654  if (ec_lock_down_interruptible(&master->master_sem))
3655  return -EINTR;
3656 
3657  sc = ec_master_get_config(master, data.config_index);
3658  if (!sc) {
3659  ec_lock_up(&master->master_sem);
3660  return -ENOENT;
3661  }
3662 
3663  list_for_each_entry(voe, &sc->voe_handlers, list) {
3664  data.voe_index++;
3665  }
3666 
3667  ec_lock_up(&master->master_sem);
3669  voe = ecrt_slave_config_create_voe_handler_err(sc, data.size);
3670  if (IS_ERR(voe))
3671  return PTR_ERR(voe);
3672 
3673  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
3674  return -EFAULT;
3675 
3676  return 0;
3677 }
3678 
3679 /*****************************************************************************/
3680 
3686  ec_master_t *master,
3687  void *arg,
3688  ec_ioctl_context_t *ctx
3689  )
3690 {
3691  ec_ioctl_sc_state_t data;
3692  const ec_slave_config_t *sc;
3694 
3695  if (unlikely(!ctx->requested))
3696  return -EPERM;
3697 
3698  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3699  return -EFAULT;
3700  }
3701 
3702  /* no locking of master_sem needed, because sc will not be deleted in the
3703  * meantime. */
3704 
3705  if (!(sc = ec_master_get_config_const(master, data.config_index))) {
3706  return -ENOENT;
3707  }
3708 
3709  ecrt_slave_config_state(sc, &state);
3710 
3711  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3712  return -EFAULT;
3713 
3714  return 0;
3715 }
3716 
3717 /*****************************************************************************/
3718 
3724  ec_master_t *master,
3725  void *arg,
3726  ec_ioctl_context_t *ctx
3727  )
3728 {
3729  ec_ioctl_sc_idn_t ioctl;
3730  ec_slave_config_t *sc;
3731  uint8_t *data = NULL;
3732  int ret;
3733 
3734  if (unlikely(!ctx->requested))
3735  return -EPERM;
3736 
3737  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl)))
3738  return -EFAULT;
3739 
3740  if (!ioctl.size)
3741  return -EINVAL;
3742 
3743  if (!(data = kmalloc(ioctl.size, GFP_KERNEL))) {
3744  return -ENOMEM;
3745  }
3746 
3747  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.size)) {
3748  kfree(data);
3749  return -EFAULT;
3750  }
3751 
3752  if (ec_lock_down_interruptible(&master->master_sem)) {
3753  kfree(data);
3754  return -EINTR;
3755  }
3756 
3757  if (!(sc = ec_master_get_config(master, ioctl.config_index))) {
3758  ec_lock_up(&master->master_sem);
3759  kfree(data);
3760  return -ENOENT;
3761  }
3762 
3763  ec_lock_up(&master->master_sem);
3765  ret = ecrt_slave_config_idn(
3766  sc, ioctl.drive_no, ioctl.idn, ioctl.al_state, data, ioctl.size);
3767  kfree(data);
3768  return ret;
3769 }
3770 
3771 /*****************************************************************************/
3772 
3778  ec_master_t *master,
3779  void *arg,
3780  ec_ioctl_context_t *ctx
3781  )
3782 {
3783  const ec_domain_t *domain;
3784 
3785  if (unlikely(!ctx->requested)) {
3786  return -EPERM;
3787  }
3788 
3789  if (ec_lock_down_interruptible(&master->master_sem)) {
3790  return -EINTR;
3791  }
3792 
3793  list_for_each_entry(domain, &master->domains, list) {
3794  if (domain->index == (unsigned long) arg) {
3795  size_t size = ecrt_domain_size(domain);
3796  ec_lock_up(&master->master_sem);
3797  return size;
3798  }
3799  }
3800 
3801  ec_lock_up(&master->master_sem);
3802  return -ENOENT;
3803 }
3804 
3805 /*****************************************************************************/
3806 
3812  ec_master_t *master,
3813  void *arg,
3814  ec_ioctl_context_t *ctx
3815  )
3816 {
3817  int offset = 0;
3818  const ec_domain_t *domain;
3819 
3820  if (unlikely(!ctx->requested))
3821  return -EPERM;
3822 
3823  if (ec_lock_down_interruptible(&master->master_sem)) {
3824  return -EINTR;
3825  }
3826 
3827  list_for_each_entry(domain, &master->domains, list) {
3828  if (domain->index == (unsigned long) arg) {
3829  ec_lock_up(&master->master_sem);
3830  return offset;
3831  }
3832  offset += ecrt_domain_size(domain);
3833  }
3834 
3835  ec_lock_up(&master->master_sem);
3836  return -ENOENT;
3837 }
3838 
3839 /*****************************************************************************/
3840 
3846  ec_master_t *master,
3847  void *arg,
3848  ec_ioctl_context_t *ctx
3849  )
3850 {
3851  ec_domain_t *domain;
3852 
3853  if (unlikely(!ctx->requested))
3854  return -EPERM;
3855 
3856  /* Locking added as domain processing is likely to be used by more than
3857  one application tasks */
3859  return -EINTR;
3860  }
3861 
3862  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3863  ec_ioctl_lock_up(&master->master_sem);
3864  return -ENOENT;
3865  }
3866 
3867  ecrt_domain_process(domain);
3868  ec_ioctl_lock_up(&master->master_sem);
3869  return 0;
3870 }
3871 
3872 /*****************************************************************************/
3873 
3879  ec_master_t *master,
3880  void *arg,
3881  ec_ioctl_context_t *ctx
3882  )
3883 {
3884  ec_domain_t *domain;
3885 
3886  if (unlikely(!ctx->requested))
3887  return -EPERM;
3888 
3889  /* Locking added as domain queing is likely to be used by more than
3890  one application tasks */
3892  return -EINTR;
3893 
3894  if (!(domain = ec_master_find_domain(master, (unsigned long) arg))) {
3895  ec_ioctl_lock_up(&master->master_sem);
3896  return -ENOENT;
3897  }
3898 
3899  ecrt_domain_queue(domain);
3900 
3901  ec_ioctl_lock_up(&master->master_sem);
3902 
3903  return 0;
3904 }
3905 
3906 /*****************************************************************************/
3907 
3913  ec_master_t *master,
3914  void *arg,
3915  ec_ioctl_context_t *ctx
3916  )
3917 {
3918  ec_ioctl_domain_state_t data;
3919  const ec_domain_t *domain;
3920  ec_domain_state_t state;
3921 
3922  if (unlikely(!ctx->requested))
3923  return -EPERM;
3924 
3925  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
3926  return -EFAULT;
3927  }
3928 
3929  /* no locking of master_sem needed, because domain will not be deleted in
3930  * the meantime. */
3931 
3932  if (!(domain = ec_master_find_domain_const(master, data.domain_index))) {
3933  return -ENOENT;
3934  }
3935 
3936  ecrt_domain_state(domain, &state);
3937 
3938  if (copy_to_user((void __user *) data.state, &state, sizeof(state)))
3939  return -EFAULT;
3940 
3941  return 0;
3942 }
3943 
3944 /*****************************************************************************/
3945 
3951  ec_master_t *master,
3952  void *arg,
3953  ec_ioctl_context_t *ctx
3954  )
3955 {
3956  ec_ioctl_sdo_request_t data;
3957  ec_slave_config_t *sc;
3958  ec_sdo_request_t *req;
3959 
3960  if (unlikely(!ctx->requested))
3961  return -EPERM;
3962 
3963  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
3964  return -EFAULT;
3965 
3966  /* no locking of master_sem needed, because neither sc nor req will not be
3967  * deleted in the meantime. */
3968 
3969  if (!(sc = ec_master_get_config(master, data.config_index))) {
3970  return -ENOENT;
3971  }
3972 
3973  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
3974  return -ENOENT;
3975  }
3976 
3977  if (data.complete_access) {
3978  ecrt_sdo_request_index_complete(req, data.sdo_index);
3979  } else {
3980  ecrt_sdo_request_index(req, data.sdo_index, data.sdo_subindex);
3981  }
3982  return 0;
3983 }
3984 
3985 /*****************************************************************************/
3986 
3992  ec_master_t *master,
3993  void *arg,
3994  ec_ioctl_context_t *ctx
3995  )
3996 {
3997  ec_ioctl_sdo_request_t data;
3998  ec_slave_config_t *sc;
3999  ec_sdo_request_t *req;
4000 
4001  if (unlikely(!ctx->requested))
4002  return -EPERM;
4003 
4004  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4005  return -EFAULT;
4006 
4007  /* no locking of master_sem needed, because neither sc nor req will not be
4008  * deleted in the meantime. */
4009 
4010  if (!(sc = ec_master_get_config(master, data.config_index))) {
4011  return -ENOENT;
4012  }
4013 
4014  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
4015  return -ENOENT;
4016  }
4017 
4018  ecrt_sdo_request_timeout(req, data.timeout);
4019  return 0;
4020 }
4021 
4022 /*****************************************************************************/
4023 
4029  ec_master_t *master,
4030  void *arg,
4031  ec_ioctl_context_t *ctx
4032  )
4033 {
4034  ec_ioctl_sdo_request_t data;
4035  ec_slave_config_t *sc;
4036  ec_sdo_request_t *req;
4037 
4038  if (unlikely(!ctx->requested))
4039  return -EPERM;
4040 
4041  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4042  return -EFAULT;
4043 
4044  /* no locking of master_sem needed, because neither sc nor req will not be
4045  * deleted in the meantime. */
4046 
4047  if (!(sc = ec_master_get_config(master, data.config_index))) {
4048  return -ENOENT;
4049  }
4050 
4051  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
4052  return -ENOENT;
4053  }
4054 
4055  data.state = ecrt_sdo_request_state(req);
4056  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
4057  data.size = ecrt_sdo_request_data_size(req);
4058  else
4059  data.size = 0;
4060 
4061  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
4062  return -EFAULT;
4063 
4064  return 0;
4065 }
4066 
4067 /*****************************************************************************/
4068 
4074  ec_master_t *master,
4075  void *arg,
4076  ec_ioctl_context_t *ctx
4077  )
4078 {
4079  ec_ioctl_sdo_request_t data;
4080  ec_slave_config_t *sc;
4081  ec_sdo_request_t *req;
4082 
4083  if (unlikely(!ctx->requested))
4084  return -EPERM;
4085 
4086  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4087  return -EFAULT;
4088 
4089  /* no locking of master_sem needed, because neither sc nor req will not be
4090  * deleted in the meantime. */
4091 
4092  if (!(sc = ec_master_get_config(master, data.config_index))) {
4093  return -ENOENT;
4094  }
4095 
4096  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
4097  return -ENOENT;
4098  }
4099 
4100  ecrt_sdo_request_read(req);
4101  return 0;
4102 }
4103 
4104 /*****************************************************************************/
4105 
4111  ec_master_t *master,
4112  void *arg,
4113  ec_ioctl_context_t *ctx
4114  )
4115 {
4116  ec_ioctl_sdo_request_t data;
4117  ec_slave_config_t *sc;
4118  ec_sdo_request_t *req;
4119  int ret;
4120 
4121  if (unlikely(!ctx->requested))
4122  return -EPERM;
4123 
4124  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4125  return -EFAULT;
4126 
4127  if (!data.size) {
4128  EC_MASTER_ERR(master, "SDO download: Data size may not be zero!\n");
4129  return -EINVAL;
4130  }
4131 
4132  /* no locking of master_sem needed, because neither sc nor req will not be
4133  * deleted in the meantime. */
4134 
4135  if (!(sc = ec_master_get_config(master, data.config_index))) {
4136  return -ENOENT;
4137  }
4138 
4139  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
4140  return -ENOENT;
4141  }
4142 
4143  ret = ec_sdo_request_alloc(req, data.size);
4144  if (ret)
4145  return ret;
4146 
4147  if (copy_from_user(req->data, (void __user *) data.data, data.size))
4148  return -EFAULT;
4149 
4150  req->data_size = data.size;
4152  return 0;
4153 }
4154 
4155 /*****************************************************************************/
4156 
4162  ec_master_t *master,
4163  void *arg,
4164  ec_ioctl_context_t *ctx
4165  )
4166 {
4167  ec_ioctl_sdo_request_t data;
4168  ec_slave_config_t *sc;
4169  ec_sdo_request_t *req;
4170 
4171  if (unlikely(!ctx->requested))
4172  return -EPERM;
4173 
4174  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4175  return -EFAULT;
4176 
4177  /* no locking of master_sem needed, because neither sc nor req will not be
4178  * deleted in the meantime. */
4179 
4180  if (!(sc = ec_master_get_config(master, data.config_index))) {
4181  return -ENOENT;
4182  }
4183 
4184  if (!(req = ec_slave_config_find_sdo_request(sc, data.request_index))) {
4185  return -ENOENT;
4186  }
4187 
4188  if (copy_to_user((void __user *) data.data, ecrt_sdo_request_data(req),
4190  return -EFAULT;
4191 
4192  return 0;
4193 }
4194 
4195 /*****************************************************************************/
4196 
4202  ec_master_t *master,
4203  void *arg,
4204  ec_ioctl_context_t *ctx
4205  )
4206 {
4207  ec_ioctl_foe_request_t data;
4208  ec_slave_config_t *sc;
4209  ec_foe_request_t *req;
4210 
4211  if (unlikely(!ctx->requested))
4212  return -EPERM;
4213 
4214  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4215  return -EFAULT;
4216 
4217  /* no locking of master_sem needed, because neither sc nor req will not be
4218  * deleted in the meantime. */
4219 
4220  if (!(sc = ec_master_get_config(master, data.config_index))) {
4221  return -ENOENT;
4222  }
4223 
4224  if (!(req = ec_slave_config_find_foe_request(sc, data.request_index))) {
4225  return -ENOENT;
4226  }
4227 
4228  ecrt_foe_request_file(req, data.file_name, data.password);
4229  return 0;
4230 }
4231 
4232 /*****************************************************************************/
4233 
4239  ec_master_t *master,
4240  void *arg,
4241  ec_ioctl_context_t *ctx
4242  )
4243 {
4244  ec_ioctl_foe_request_t data;
4245  ec_slave_config_t *sc;
4246  ec_foe_request_t *req;
4247 
4248  if (unlikely(!ctx->requested))
4249  return -EPERM;
4250 
4251  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4252  return -EFAULT;
4253 
4254  /* no locking of master_sem needed, because neither sc nor req will not be
4255  * deleted in the meantime. */
4256 
4257  if (!(sc = ec_master_get_config(master, data.config_index))) {
4258  return -ENOENT;
4259  }
4260 
4261  if (!(req = ec_slave_config_find_foe_request(sc, data.request_index))) {
4262  return -ENOENT;
4263  }
4264 
4265  ecrt_foe_request_timeout(req, data.timeout);
4266  return 0;
4267 }
4268 
4269 /*****************************************************************************/
4270 
4276  ec_master_t *master,
4277  void *arg,
4278  ec_ioctl_context_t *ctx
4279  )
4280 {
4281  ec_ioctl_foe_request_t data;
4282  ec_slave_config_t *sc;
4283  ec_foe_request_t *req;
4284 
4285  if (unlikely(!ctx->requested))
4286  return -EPERM;
4287 
4288  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4289  return -EFAULT;
4290 
4291  /* no locking of master_sem needed, because neither sc nor req will not be
4292  * deleted in the meantime. */
4293 
4294  if (!(sc = ec_master_get_config(master, data.config_index))) {
4295  return -ENOENT;
4296  }
4297 
4298  if (!(req = ec_slave_config_find_foe_request(sc, data.request_index))) {
4299  return -ENOENT;
4300  }
4301 
4302  data.state = ecrt_foe_request_state(req);
4303  data.progress = ecrt_foe_request_progress(req);
4304  if (data.state == EC_REQUEST_SUCCESS && req->dir == EC_DIR_INPUT)
4305  data.size = ecrt_foe_request_data_size(req);
4306  else
4307  data.size = 0;
4308  data.result = req->result;
4309  data.error_code = req->error_code;
4310 
4311  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
4312  return -EFAULT;
4313 
4314  return 0;
4315 }
4316 
4317 /*****************************************************************************/
4318 
4324  ec_master_t *master,
4325  void *arg,
4326  ec_ioctl_context_t *ctx
4327  )
4328 {
4329  ec_ioctl_foe_request_t data;
4330  ec_slave_config_t *sc;
4331  ec_foe_request_t *req;
4332 
4333  if (unlikely(!ctx->requested))
4334  return -EPERM;
4335 
4336  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4337  return -EFAULT;
4338 
4339  /* no locking of master_sem needed, because neither sc nor req will not be
4340  * deleted in the meantime. */
4341 
4342  if (!(sc = ec_master_get_config(master, data.config_index))) {
4343  return -ENOENT;
4344  }
4345 
4346  if (!(req = ec_slave_config_find_foe_request(sc, data.request_index))) {
4347  return -ENOENT;
4348  }
4349 
4350  ecrt_foe_request_read(req);
4351  return 0;
4352 }
4353 
4354 /*****************************************************************************/
4355 
4361  ec_master_t *master,
4362  void *arg,
4363  ec_ioctl_context_t *ctx
4364  )
4365 {
4366  ec_ioctl_foe_request_t data;
4367  ec_slave_config_t *sc;
4368  ec_foe_request_t *req;
4369  int ret;
4370 
4371  if (unlikely(!ctx->requested))
4372  return -EPERM;
4373 
4374  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4375  return -EFAULT;
4376 
4377  /* no locking of master_sem needed, because neither sc nor req will not be
4378  * deleted in the meantime. */
4379 
4380  if (!(sc = ec_master_get_config(master, data.config_index))) {
4381  return -ENOENT;
4382  }
4383 
4384  if (!(req = ec_slave_config_find_foe_request(sc, data.request_index))) {
4385  return -ENOENT;
4386  }
4387 
4388  ret = ec_foe_request_alloc(req, data.size);
4389  if (ret)
4390  return ret;
4391 
4392  if (copy_from_user(ecrt_foe_request_data(req), (void __user *) data.data, data.size))
4393  return -EFAULT;
4394 
4395  ecrt_foe_request_write(req, data.size);
4396  return 0;
4397 }
4398 
4399 /*****************************************************************************/
4400 
4406  ec_master_t *master,
4407  void *arg,
4408  ec_ioctl_context_t *ctx
4409  )
4410 {
4411  ec_ioctl_foe_request_t data;
4412  ec_slave_config_t *sc;
4413  ec_foe_request_t *req;
4414 
4415  if (unlikely(!ctx->requested))
4416  return -EPERM;
4417 
4418  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4419  return -EFAULT;
4420 
4421  /* no locking of master_sem needed, because neither sc nor req will not be
4422  * deleted in the meantime. */
4423 
4424  if (!(sc = ec_master_get_config(master, data.config_index))) {
4425  return -ENOENT;
4426  }
4427 
4428  if (!(req = ec_slave_config_find_foe_request(sc, data.request_index))) {
4429  return -ENOENT;
4430  }
4431 
4432  if (copy_to_user((void __user *) data.data, ecrt_foe_request_data(req),
4434  return -EFAULT;
4435 
4436  return 0;
4437 }
4438 
4439 /*****************************************************************************/
4440 
4446  ec_master_t *master,
4447  void *arg,
4448  ec_ioctl_context_t *ctx
4449  )
4450 {
4451  ec_ioctl_reg_request_t io;
4452  ec_slave_config_t *sc;
4453  ec_reg_request_t *reg;
4454 
4455  if (unlikely(!ctx->requested)) {
4456  return -EPERM;
4457  }
4458 
4459  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4460  return -EFAULT;
4461  }
4462 
4463  if (io.mem_size <= 0) {
4464  return 0;
4465  }
4466 
4467  /* no locking of master_sem needed, because neither sc nor reg will not be
4468  * deleted in the meantime. */
4469 
4470  if (!(sc = ec_master_get_config(master, io.config_index))) {
4471  return -ENOENT;
4472  }
4473 
4474  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4475  return -ENOENT;
4476  }
4477 
4478  if (copy_to_user((void __user *) io.data, ecrt_reg_request_data(reg),
4479  min(reg->mem_size, io.mem_size))) {
4480  return -EFAULT;
4481  }
4482 
4483  return 0;
4484 }
4485 
4486 /*****************************************************************************/
4487 
4493  ec_master_t *master,
4494  void *arg,
4495  ec_ioctl_context_t *ctx
4496  )
4497 {
4498  ec_ioctl_reg_request_t io;
4499  ec_slave_config_t *sc;
4500  ec_reg_request_t *reg;
4501 
4502  if (unlikely(!ctx->requested)) {
4503  return -EPERM;
4504  }
4505 
4506  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4507  return -EFAULT;
4508  }
4509 
4510  /* no locking of master_sem needed, because neither sc nor reg will not be
4511  * deleted in the meantime. */
4512 
4513  if (!(sc = ec_master_get_config(master, io.config_index))) {
4514  return -ENOENT;
4515  }
4516 
4517  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4518  return -ENOENT;
4519  }
4520 
4521  io.state = ecrt_reg_request_state(reg);
4522  io.new_data = io.state == EC_REQUEST_SUCCESS &&
4523  (reg->dir == EC_DIR_INPUT || reg->dir == EC_DIR_BOTH);
4524 
4525  if (copy_to_user((void __user *) arg, &io, sizeof(io))) {
4526  return -EFAULT;
4527  }
4528 
4529  return 0;
4530 }
4531 
4532 /*****************************************************************************/
4533 
4539  ec_master_t *master,
4540  void *arg,
4541  ec_ioctl_context_t *ctx
4542  )
4543 {
4544  ec_ioctl_reg_request_t io;
4545  ec_slave_config_t *sc;
4546  ec_reg_request_t *reg;
4547 
4548  if (unlikely(!ctx->requested)) {
4549  return -EPERM;
4550  }
4551 
4552  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4553  return -EFAULT;
4554  }
4555 
4556  /* no locking of master_sem needed, because neither sc nor reg will not be
4557  * deleted in the meantime. */
4558 
4559  if (!(sc = ec_master_get_config(master, io.config_index))) {
4560  return -ENOENT;
4561  }
4562 
4563  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4564  return -ENOENT;
4565  }
4566 
4567  if (io.transfer_size > reg->mem_size) {
4568  return -EOVERFLOW;
4569  }
4570 
4571  if (copy_from_user(reg->data, (void __user *) io.data,
4572  io.transfer_size)) {
4573  return -EFAULT;
4574  }
4575 
4576  ecrt_reg_request_write(reg, io.address, io.transfer_size);
4577  return 0;
4578 }
4579 
4580 /*****************************************************************************/
4581 
4587  ec_master_t *master,
4588  void *arg,
4589  ec_ioctl_context_t *ctx
4590  )
4591 {
4592  ec_ioctl_reg_request_t io;
4593  ec_slave_config_t *sc;
4594  ec_reg_request_t *reg;
4595 
4596  if (unlikely(!ctx->requested)) {
4597  return -EPERM;
4598  }
4599 
4600  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4601  return -EFAULT;
4602  }
4603 
4604  /* no locking of master_sem needed, because neither sc nor reg will not be
4605  * deleted in the meantime. */
4606 
4607  if (!(sc = ec_master_get_config(master, io.config_index))) {
4608  return -ENOENT;
4609  }
4610 
4611  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4612  return -ENOENT;
4613  }
4614 
4615  if (io.transfer_size > reg->mem_size) {
4616  return -EOVERFLOW;
4617  }
4618 
4619  ecrt_reg_request_read(reg, io.address, io.transfer_size);
4620  return 0;
4621 }
4622 
4623 /*****************************************************************************/
4624 
4630  ec_master_t *master,
4631  void *arg,
4632  ec_ioctl_context_t *ctx
4633  )
4634 {
4635  ec_ioctl_reg_request_t io;
4636  ec_slave_config_t *sc;
4637  ec_reg_request_t *reg;
4638 
4639  if (unlikely(!ctx->requested)) {
4640  return -EPERM;
4641  }
4642 
4643  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4644  return -EFAULT;
4645  }
4646 
4647  /* no locking of master_sem needed, because neither sc nor reg will not be
4648  * deleted in the meantime. */
4649 
4650  if (!(sc = ec_master_get_config(master, io.config_index))) {
4651  return -ENOENT;
4652  }
4653 
4654  if (!(reg = ec_slave_config_find_reg_request(sc, io.request_index))) {
4655  return -ENOENT;
4656  }
4657 
4658  if (io.transfer_size > reg->mem_size) {
4659  return -EOVERFLOW;
4660  }
4661 
4662  if (copy_from_user(reg->data, (void __user *) io.data,
4663  io.transfer_size)) {
4664  return -EFAULT;
4665  }
4666 
4667  ecrt_reg_request_readwrite(reg, io.address, io.transfer_size);
4668  return 0;
4669 }
4670 
4671 /*****************************************************************************/
4672 
4678  ec_master_t *master,
4679  void *arg,
4680  ec_ioctl_context_t *ctx
4681  )
4682 {
4683  ec_ioctl_voe_t data;
4684  ec_slave_config_t *sc;
4685  ec_voe_handler_t *voe;
4686  uint32_t vendor_id;
4687  uint16_t vendor_type;
4688 
4689  if (unlikely(!ctx->requested))
4690  return -EPERM;
4691 
4692  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4693  return -EFAULT;
4694 
4695  if (get_user(vendor_id, data.vendor_id))
4696  return -EFAULT;
4697 
4698  if (get_user(vendor_type, data.vendor_type))
4699  return -EFAULT;
4700 
4701  /* no locking of master_sem needed, because neither sc nor voe will not be
4702  * deleted in the meantime. */
4703 
4704  if (!(sc = ec_master_get_config(master, data.config_index))) {
4705  return -ENOENT;
4706  }
4707 
4708  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4709  return -ENOENT;
4710  }
4711 
4712  ecrt_voe_handler_send_header(voe, vendor_id, vendor_type);
4713  return 0;
4714 }
4715 
4716 /*****************************************************************************/
4717 
4723  ec_master_t *master,
4724  void *arg,
4725  ec_ioctl_context_t *ctx
4726  )
4727 {
4728  ec_ioctl_voe_t data;
4729  ec_slave_config_t *sc;
4730  ec_voe_handler_t *voe;
4731  uint32_t vendor_id;
4732  uint16_t vendor_type;
4733 
4734  if (unlikely(!ctx->requested))
4735  return -EPERM;
4736 
4737  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4738  return -EFAULT;
4739 
4740  /* no locking of master_sem needed, because neither sc nor voe will not be
4741  * deleted in the meantime. */
4742 
4743  if (!(sc = ec_master_get_config(master, data.config_index))) {
4744  return -ENOENT;
4745  }
4746 
4747  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4748  return -ENOENT;
4749  }
4750 
4751  ecrt_voe_handler_received_header(voe, &vendor_id, &vendor_type);
4752 
4753  if (likely(data.vendor_id))
4754  if (put_user(vendor_id, data.vendor_id))
4755  return -EFAULT;
4756 
4757  if (likely(data.vendor_type))
4758  if (put_user(vendor_type, data.vendor_type))
4759  return -EFAULT;
4760 
4761  return 0;
4762 }
4763 
4764 /*****************************************************************************/
4765 
4771  ec_master_t *master,
4772  void *arg,
4773  ec_ioctl_context_t *ctx
4774  )
4775 {
4776  ec_ioctl_voe_t data;
4777  ec_slave_config_t *sc;
4778  ec_voe_handler_t *voe;
4779 
4780  if (unlikely(!ctx->requested))
4781  return -EPERM;
4782 
4783  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4784  return -EFAULT;
4785 
4786  /* no locking of master_sem needed, because neither sc nor voe will not be
4787  * deleted in the meantime. */
4788 
4789  if (!(sc = ec_master_get_config(master, data.config_index))) {
4790  return -ENOENT;
4791  }
4792 
4793  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4794  return -ENOENT;
4795  }
4796 
4797  ecrt_voe_handler_read(voe);
4798  return 0;
4799 }
4800 
4801 /*****************************************************************************/
4802 
4808  ec_master_t *master,
4809  void *arg,
4810  ec_ioctl_context_t *ctx
4811  )
4812 {
4813  ec_ioctl_voe_t data;
4814  ec_slave_config_t *sc;
4815  ec_voe_handler_t *voe;
4816 
4817  if (unlikely(!ctx->requested))
4818  return -EPERM;
4819 
4820  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4821  return -EFAULT;
4822 
4823  /* no locking of master_sem needed, because neither sc nor voe will not be
4824  * deleted in the meantime. */
4825 
4826  if (!(sc = ec_master_get_config(master, data.config_index))) {
4827  return -ENOENT;
4828  }
4829 
4830  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4831  return -ENOENT;
4832  }
4833 
4835  return 0;
4836 }
4837 
4838 /*****************************************************************************/
4839 
4845  ec_master_t *master,
4846  void *arg,
4847  ec_ioctl_context_t *ctx
4848  )
4849 {
4850  ec_ioctl_voe_t data;
4851  ec_slave_config_t *sc;
4852  ec_voe_handler_t *voe;
4853 
4854  if (unlikely(!ctx->requested))
4855  return -EPERM;
4856 
4857  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4858  return -EFAULT;
4859 
4860  /* no locking of master_sem needed, because neither sc nor voe will not be
4861  * deleted in the meantime. */
4862 
4863  if (!(sc = ec_master_get_config(master, data.config_index))) {
4864  return -ENOENT;
4865  }
4866 
4867  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4868  return -ENOENT;
4869  }
4870 
4871  if (data.size) {
4872  if (data.size > ec_voe_handler_mem_size(voe))
4873  return -EOVERFLOW;
4874 
4875  if (copy_from_user(ecrt_voe_handler_data(voe),
4876  (void __user *) data.data, data.size))
4877  return -EFAULT;
4878  }
4879 
4880  ecrt_voe_handler_write(voe, data.size);
4881  return 0;
4882 }
4883 
4884 /*****************************************************************************/
4885 
4891  ec_master_t *master,
4892  void *arg,
4893  ec_ioctl_context_t *ctx
4894  )
4895 {
4896  ec_ioctl_voe_t data;
4897  ec_slave_config_t *sc;
4898  ec_voe_handler_t *voe;
4899 
4900  if (unlikely(!ctx->requested))
4901  return -EPERM;
4902 
4903  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4904  return -EFAULT;
4905 
4906  /* no locking of master_sem needed, because neither sc nor voe will not be
4907  * deleted in the meantime. */
4908 
4909  if (!(sc = ec_master_get_config(master, data.config_index))) {
4910  return -ENOENT;
4911  }
4912 
4913  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4914  return -ENOENT;
4915  }
4916 
4917  data.state = ecrt_voe_handler_execute(voe);
4918  if (data.state == EC_REQUEST_SUCCESS && voe->dir == EC_DIR_INPUT)
4919  data.size = ecrt_voe_handler_data_size(voe);
4920  else
4921  data.size = 0;
4922 
4923  if (copy_to_user((void __user *) arg, &data, sizeof(data)))
4924  return -EFAULT;
4925 
4926  return 0;
4927 }
4928 
4929 /*****************************************************************************/
4930 
4936  ec_master_t *master,
4937  void *arg,
4938  ec_ioctl_context_t *ctx
4939  )
4940 {
4941  ec_ioctl_voe_t data;
4942  ec_slave_config_t *sc;
4943  ec_voe_handler_t *voe;
4944 
4945  if (unlikely(!ctx->requested))
4946  return -EPERM;
4947 
4948  if (copy_from_user(&data, (void __user *) arg, sizeof(data)))
4949  return -EFAULT;
4950 
4951  /* no locking of master_sem needed, because neither sc nor voe will not be
4952  * deleted in the meantime. */
4953 
4954  if (!(sc = ec_master_get_config(master, data.config_index))) {
4955  return -ENOENT;
4956  }
4957 
4958  if (!(voe = ec_slave_config_find_voe_handler(sc, data.voe_index))) {
4959  return -ENOENT;
4960  }
4961 
4962  if (copy_to_user((void __user *) data.data, ecrt_voe_handler_data(voe),
4964  return -EFAULT;
4965 
4966  return 0;
4967 }
4968 
4969 /*****************************************************************************/
4970 
4976  ec_master_t *master,
4977  void *arg
4978  )
4979 {
4980  ec_ioctl_slave_foe_t io;
4981  ec_foe_request_t request;
4982  ec_slave_t *slave;
4983  int ret;
4984 
4985  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
4986  return -EFAULT;
4987  }
4988 
4989  ec_foe_request_init(&request);
4990  ret = ec_foe_request_alloc(&request, io.buffer_size);
4991  if (ret) {
4992  ec_foe_request_clear(&request);
4993  return ret;
4994  }
4995 
4996  ecrt_foe_request_file(&request, io.file_name, io.password);
4997  ecrt_foe_request_read(&request);
4998 
4999  if (ec_lock_down_interruptible(&master->master_sem)) {
5000  ec_foe_request_clear(&request);
5001  return -EINTR;
5002  }
5003 
5004  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
5005  ec_lock_up(&master->master_sem);
5006  ec_foe_request_clear(&request);
5007  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
5008  io.slave_position);
5009  return -EINVAL;
5010  }
5011 
5012  EC_SLAVE_DBG(slave, 1, "Scheduling FoE read request.\n");
5013 
5014  // schedule request.
5015  list_add_tail(&request.list, &slave->foe_requests);
5016 
5017  ec_lock_up(&master->master_sem);
5018 
5019  // wait for processing through FSM
5020  if (wait_event_interruptible(master->request_queue,
5021  request.state != EC_INT_REQUEST_QUEUED)) {
5022  // interrupted by signal
5023  ec_lock_down(&master->master_sem);
5024  if (request.state == EC_INT_REQUEST_QUEUED) {
5025  list_del(&request.list);
5026  ec_lock_up(&master->master_sem);
5027  ec_foe_request_clear(&request);
5028  return -EINTR;
5029  }
5030  // request already processing: interrupt not possible.
5031  ec_lock_up(&master->master_sem);
5032  }
5033 
5034  // wait until master FSM has finished processing
5035  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
5036 
5037  io.result = request.result;
5038  io.error_code = request.error_code;
5039 
5040  if (request.state != EC_INT_REQUEST_SUCCESS) {
5041  io.data_size = 0;
5042  ret = -EIO;
5043  } else {
5044  if (request.data_size > io.buffer_size) {
5045  EC_SLAVE_ERR(slave, "%s(): Buffer too small.\n", __func__);
5046  ec_foe_request_clear(&request);
5047  return -EOVERFLOW;
5048  }
5049  io.data_size = request.data_size;
5050  if (copy_to_user((void __user *) io.buffer,
5051  request.buffer, io.data_size)) {
5052  ec_foe_request_clear(&request);
5053  return -EFAULT;
5054  }
5055  ret = 0;
5056  }
5057 
5058  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
5059  ret = -EFAULT;
5060  }
5061 
5062  ec_foe_request_clear(&request);
5063  return ret;
5064 }
5065 
5066 /*****************************************************************************/
5067 
5073  ec_master_t *master,
5074  void *arg
5075  )
5076 {
5077  ec_ioctl_slave_foe_t io;
5078  ec_foe_request_t request;
5079  ec_slave_t *slave;
5080  int ret;
5081 
5082  if (copy_from_user(&io, (void __user *) arg, sizeof(io))) {
5083  return -EFAULT;
5084  }
5085 
5086  ec_foe_request_init(&request);
5087 
5088  ret = ec_foe_request_alloc(&request, io.buffer_size);
5089  if (ret) {
5090  ec_foe_request_clear(&request);
5091  return ret;
5092  }
5093 
5094  if (copy_from_user(request.buffer,
5095  (void __user *) io.buffer, io.buffer_size)) {
5096  ec_foe_request_clear(&request);
5097  return -EFAULT;
5098  }
5099 
5100  ecrt_foe_request_file(&request, io.file_name, io.password);
5101  ecrt_foe_request_write(&request, io.buffer_size);
5102 
5103  if (ec_lock_down_interruptible(&master->master_sem)) {
5104  ec_foe_request_clear(&request);
5105  return -EINTR;
5106  }
5107 
5108  if (!(slave = ec_master_find_slave(master, 0, io.slave_position))) {
5109  ec_lock_up(&master->master_sem);
5110  EC_MASTER_ERR(master, "Slave %u does not exist!\n",
5111  io.slave_position);
5112  ec_foe_request_clear(&request);
5113  return -EINVAL;
5114  }
5115 
5116  EC_SLAVE_DBG(slave, 1, "Scheduling FoE write request.\n");
5117 
5118  // schedule FoE write request.
5119  list_add_tail(&request.list, &slave->foe_requests);
5120 
5121  ec_lock_up(&master->master_sem);
5122 
5123  // wait for processing through FSM
5124  if (wait_event_interruptible(master->request_queue,
5125  request.state != EC_INT_REQUEST_QUEUED)) {
5126  // interrupted by signal
5127  ec_lock_down(&master->master_sem);
5128  if (request.state == EC_INT_REQUEST_QUEUED) {
5129  // abort request
5130  list_del(&request.list);
5131  ec_lock_up(&master->master_sem);
5132  ec_foe_request_clear(&request);
5133  return -EINTR;
5134  }
5135  ec_lock_up(&master->master_sem);
5136  }
5137 
5138  // wait until master FSM has finished processing
5139  wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
5140 
5141  io.result = request.result;
5142  io.error_code = request.error_code;
5143 
5144  ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
5145 
5146  if (__copy_to_user((void __user *) arg, &io, sizeof(io))) {
5147  ret = -EFAULT;
5148  }
5149 
5150  ec_foe_request_clear(&request);
5151  return ret;
5152 }
5153 
5154 /*****************************************************************************/
5155 
5161  ec_master_t *master,
5162  void *arg
5163  )
5164 {
5165  ec_ioctl_slave_soe_read_t ioctl;
5166  u8 *data;
5167  int retval;
5168 
5169  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
5170  return -EFAULT;
5171  }
5172 
5173  data = kmalloc(ioctl.mem_size, GFP_KERNEL);
5174  if (!data) {
5175  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
5176  ioctl.mem_size);
5177  return -ENOMEM;
5178  }
5179 
5180  retval = ecrt_master_read_idn(master, ioctl.slave_position,
5181  ioctl.drive_no, ioctl.idn, data, ioctl.mem_size, &ioctl.data_size,
5182  &ioctl.error_code);
5183  if (retval) {
5184  kfree(data);
5185  return retval;
5186  }
5187 
5188  if (copy_to_user((void __user *) ioctl.data,
5189  data, ioctl.data_size)) {
5190  kfree(data);
5191  return -EFAULT;
5192  }
5193  kfree(data);
5194 
5195  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
5196  retval = -EFAULT;
5197  }
5198 
5199  EC_MASTER_DBG(master, 1, "Finished SoE read request.\n");
5200  return retval;
5201 }
5202 
5203 /*****************************************************************************/
5204 
5210  ec_master_t *master,
5211  void *arg
5212  )
5213 {
5214  ec_ioctl_slave_soe_write_t ioctl;
5215  u8 *data;
5216  int retval;
5217 
5218  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
5219  return -EFAULT;
5220  }
5221 
5222  data = kmalloc(ioctl.data_size, GFP_KERNEL);
5223  if (!data) {
5224  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of IDN data.\n",
5225  ioctl.data_size);
5226  return -ENOMEM;
5227  }
5228  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
5229  kfree(data);
5230  return -EFAULT;
5231  }
5232 
5233  retval = ecrt_master_write_idn(master, ioctl.slave_position,
5234  ioctl.drive_no, ioctl.idn, data, ioctl.data_size,
5235  &ioctl.error_code);
5236  kfree(data);
5237  if (retval) {
5238  return retval;
5239  }
5240 
5241  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
5242  retval = -EFAULT;
5243  }
5244 
5245  EC_MASTER_DBG(master, 1, "Finished SoE write request.\n");
5246  return retval;
5247 }
5248 
5249 /*****************************************************************************/
5255  ec_master_t *master,
5256  void *arg
5257  )
5258 {
5259  ec_ioctl_slave_dict_upload_t data;
5260  int ret;
5261 
5262  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
5263  return -EFAULT;
5264  }
5265 
5266  ret = ec_master_dict_upload(master, data.slave_position);
5267 
5268  return ret;
5269 }
5270 
5271 /*****************************************************************************/
5272 
5273 #ifdef EC_EOE
5274 
5280  ec_master_t *master,
5281  void *arg,
5282  ec_ioctl_context_t *ctx
5283  )
5284 {
5285  int ret;
5286  ec_ioctl_eoe_if_t data;
5287 
5288  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
5289  return -EFAULT;
5290  }
5291 
5292  ret = ecrt_master_eoe_addif(master, data.alias, data.position);
5293 
5294  return ret;
5295 }
5296 
5297 /*****************************************************************************/
5298 
5304  ec_master_t *master,
5305  void *arg,
5306  ec_ioctl_context_t *ctx
5307  )
5308 {
5309  int ret;
5310  ec_ioctl_eoe_if_t data;
5311 
5312  if (copy_from_user(&data, (void __user *) arg, sizeof(data))) {
5313  return -EFAULT;
5314  }
5315 
5316  ret = ecrt_master_eoe_delif(master, data.alias, data.position);
5317 
5318  return ret;
5319 }
5320 
5321 #endif
5322 
5323 /*****************************************************************************/
5324 
5330  ec_master_t *master,
5331  void *arg,
5332  ec_ioctl_context_t *ctx
5333  )
5334 {
5335  ec_ioctl_mbox_gateway_t ioctl;
5336  u8 *data;
5337  int retval;
5338 
5339  if (copy_from_user(&ioctl, (void __user *) arg, sizeof(ioctl))) {
5340  return -EFAULT;
5341  }
5342 
5343  // ensure the incoming data will be at least the size of the mailbox header
5344  if (ioctl.data_size < EC_MBOX_HEADER_SIZE) {
5345  return -EFAULT;
5346  }
5347 
5348  // ensure the incoming data fits into the max buffer size
5349  if (ioctl.data_size > ioctl.buff_size) {
5350  return -EFAULT;
5351  }
5352 
5353  data = kmalloc(ioctl.buff_size, GFP_KERNEL);
5354  if (!data) {
5355  EC_MASTER_ERR(master, "Failed to allocate %zu bytes of"
5356  " mailbox gateway data.\n", ioctl.buff_size);
5357  return -ENOMEM;
5358  }
5359  if (copy_from_user(data, (void __user *) ioctl.data, ioctl.data_size)) {
5360  kfree(data);
5361  return -EFAULT;
5362  }
5363 
5364  // send the mailbox packet
5365  retval = ec_master_mbox_gateway(master, data,
5366  &ioctl.data_size, ioctl.buff_size);
5367  if (retval) {
5368  kfree(data);
5369  return retval;
5370  }
5371 
5372  if (copy_to_user((void __user *) ioctl.data,
5373  data, ioctl.data_size)) {
5374  kfree(data);
5375  return -EFAULT;
5376  }
5377  kfree(data);
5378 
5379  if (__copy_to_user((void __user *) arg, &ioctl, sizeof(ioctl))) {
5380  retval = -EFAULT;
5381  }
5382 
5383  EC_MASTER_DBG(master, 1, "Finished Mailbox Gateway request.\n");
5384  return retval;
5385 }
5386 
5387 /*****************************************************************************/
5388 
5391 #ifdef EC_IOCTL_RTDM
5392 #define EC_IOCTL ec_ioctl_rtdm
5393 #else
5394 #define EC_IOCTL ec_ioctl
5395 #endif
5396 
5402  ec_master_t *master,
5403  ec_ioctl_context_t *ctx,
5404  unsigned int cmd,
5405  void *arg
5406  )
5407 {
5408 #if DEBUG_LATENCY
5409  cycles_t a = get_cycles(), b;
5410  unsigned int t;
5411 #endif
5412  int ret;
5413 
5414  switch (cmd) {
5415  case EC_IOCTL_MODULE:
5416  ret = ec_ioctl_module(arg);
5417  break;
5418  case EC_IOCTL_MASTER:
5419  ret = ec_ioctl_master(master, arg);
5420  break;
5421  case EC_IOCTL_SLAVE:
5422  ret = ec_ioctl_slave(master, arg);
5423  break;
5424  case EC_IOCTL_SLAVE_SYNC:
5425  ret = ec_ioctl_slave_sync(master, arg);
5426  break;
5427  case EC_IOCTL_SLAVE_SYNC_PDO:
5428  ret = ec_ioctl_slave_sync_pdo(master, arg);
5429  break;
5430  case EC_IOCTL_SLAVE_SYNC_PDO_ENTRY:
5431  ret = ec_ioctl_slave_sync_pdo_entry(master, arg);
5432  break;
5433  case EC_IOCTL_DOMAIN:
5434  ret = ec_ioctl_domain(master, arg);
5435  break;
5436  case EC_IOCTL_DOMAIN_FMMU:
5437  ret = ec_ioctl_domain_fmmu(master, arg);
5438  break;
5439  case EC_IOCTL_DOMAIN_DATA:
5440  ret = ec_ioctl_domain_data(master, arg);
5441  break;
5442  case EC_IOCTL_PCAP_DATA:
5443  ret = ec_ioctl_pcap_data(master, arg);
5444  break;
5445  case EC_IOCTL_MASTER_DEBUG:
5446  if (!ctx->writable) {
5447  ret = -EPERM;
5448  break;
5449  }
5450  ret = ec_ioctl_master_debug(master, arg);
5451  break;
5452  case EC_IOCTL_MASTER_RESCAN:
5453  if (!ctx->writable) {
5454  ret = -EPERM;
5455  break;
5456  }
5457  ret = ec_ioctl_master_rescan(master, arg);
5458  break;
5459  case EC_IOCTL_SLAVE_STATE:
5460  if (!ctx->writable) {
5461  ret = -EPERM;
5462  break;
5463  }
5464  ret = ec_ioctl_slave_state(master, arg);
5465  break;
5466  case EC_IOCTL_SLAVE_REBOOT:
5467  if (!ctx->writable) {
5468  ret = -EPERM;
5469  break;
5470  }
5471  ret = ec_ioctl_slave_reboot(master, arg);
5472  break;
5473  case EC_IOCTL_SLAVE_SDO:
5474  ret = ec_ioctl_slave_sdo(master, arg);
5475  break;
5476  case EC_IOCTL_SLAVE_SDO_ENTRY:
5477  ret = ec_ioctl_slave_sdo_entry(master, arg);
5478  break;
5479  case EC_IOCTL_SLAVE_SDO_UPLOAD:
5480  ret = ec_ioctl_slave_sdo_upload(master, arg);
5481  break;
5482  case EC_IOCTL_SLAVE_SDO_DOWNLOAD:
5483  if (!ctx->writable) {
5484  ret = -EPERM;
5485  break;
5486  }
5487  ret = ec_ioctl_slave_sdo_download(master, arg);
5488  break;
5489  case EC_IOCTL_SLAVE_SII_READ:
5490  ret = ec_ioctl_slave_sii_read(master, arg);
5491  break;
5492  case EC_IOCTL_SLAVE_SII_WRITE:
5493  if (!ctx->writable) {
5494  ret = -EPERM;
5495  break;
5496  }
5497  ret = ec_ioctl_slave_sii_write(master, arg);
5498  break;
5499  case EC_IOCTL_SLAVE_REG_READ:
5500  ret = ec_ioctl_slave_reg_read(master, arg);
5501  break;
5502  case EC_IOCTL_SLAVE_REG_WRITE:
5503  if (!ctx->writable) {
5504  ret = -EPERM;
5505  break;
5506  }
5507  ret = ec_ioctl_slave_reg_write(master, arg);
5508  break;
5509  case EC_IOCTL_SLAVE_REG_READWRITE:
5510  if (!ctx->writable) {
5511  ret = -EPERM;
5512  break;
5513  }
5514  ret = ec_ioctl_slave_reg_readwrite(master, arg);
5515  break;
5516  case EC_IOCTL_SLAVE_FOE_READ:
5517  ret = ec_ioctl_slave_foe_read(master, arg);
5518  break;
5519  case EC_IOCTL_SLAVE_FOE_WRITE:
5520  if (!ctx->writable) {
5521  ret = -EPERM;
5522  break;
5523  }
5524  ret = ec_ioctl_slave_foe_write(master, arg);
5525  break;
5526  case EC_IOCTL_SLAVE_SOE_READ:
5527  ret = ec_ioctl_slave_soe_read(master, arg);
5528  break;
5529 #ifdef EC_EOE
5530  case EC_IOCTL_SLAVE_EOE_IP_PARAM:
5531  if (!ctx->writable) {
5532  ret = -EPERM;
5533  break;
5534  }
5535  ret = ec_ioctl_slave_eoe_ip_param(master, arg);
5536  break;
5537 #endif
5538  case EC_IOCTL_SLAVE_SOE_WRITE:
5539  if (!ctx->writable) {
5540  ret = -EPERM;
5541  break;
5542  }
5543  ret = ec_ioctl_slave_soe_write(master, arg);
5544  break;
5545  case EC_IOCTL_CONFIG:
5546  ret = ec_ioctl_config(master, arg);
5547  break;
5548  case EC_IOCTL_CONFIG_PDO:
5549  ret = ec_ioctl_config_pdo(master, arg);
5550  break;
5551  case EC_IOCTL_CONFIG_PDO_ENTRY:
5552  ret = ec_ioctl_config_pdo_entry(master, arg);
5553  break;
5554  case EC_IOCTL_CONFIG_SDO:
5555  ret = ec_ioctl_config_sdo(master, arg);
5556  break;
5557  case EC_IOCTL_CONFIG_IDN:
5558  ret = ec_ioctl_config_idn(master, arg);
5559  break;
5560 #ifdef EC_EOE
5561  case EC_IOCTL_EOE_HANDLER:
5562  ret = ec_ioctl_eoe_handler(master, arg);
5563  break;
5564 #endif
5565  case EC_IOCTL_REQUEST:
5566  if (!ctx->writable) {
5567  ret = -EPERM;
5568  break;
5569  }
5570  ret = ec_ioctl_request(master, arg, ctx);
5571  break;
5572 #if defined(EC_RTDM) && defined(EC_EOE)
5573  case EC_IOCTL_EOE_IS_OPEN:
5574  ret = ec_ioctl_eoe_is_open(master, arg, ctx);
5575  break;
5576  case EC_IOCTL_EOE_PROCESS:
5577  ret = ec_ioctl_eoe_process(master, arg, ctx);
5578  break;
5579 #endif
5580  case EC_IOCTL_CREATE_DOMAIN:
5581  if (!ctx->writable) {
5582  ret = -EPERM;
5583  break;
5584  }
5585  ret = ec_ioctl_create_domain(master, arg, ctx);
5586  break;
5587  case EC_IOCTL_CREATE_SLAVE_CONFIG:
5588  if (!ctx->writable) {
5589  ret = -EPERM;
5590  break;
5591  }
5592  ret = ec_ioctl_create_slave_config(master, arg, ctx);
5593  break;
5594  case EC_IOCTL_SELECT_REF_CLOCK:
5595  if (!ctx->writable) {
5596  ret = -EPERM;
5597  break;
5598  }
5599  ret = ec_ioctl_select_ref_clock(master, arg, ctx);
5600  break;
5601  case EC_IOCTL_SETUP_DOMAIN_MEMORY:
5602  if (!ctx->writable) {
5603  ret = -EPERM;
5604  break;
5605  }
5606  ret = ec_ioctl_setup_domain_memory(master, arg, ctx);
5607  break;
5608  case EC_IOCTL_ACTIVATE:
5609  if (!ctx->writable) {
5610  ret = -EPERM;
5611  break;
5612  }
5613  ret = ec_ioctl_activate(master, arg, ctx);
5614  break;
5615  case EC_IOCTL_DEACTIVATE_SLAVES:
5616  if (!ctx->writable) {
5617  ret = -EPERM;
5618  break;
5619  }
5620  ret = ec_ioctl_deactivate_slaves(master, arg, ctx);
5621  break;
5622  case EC_IOCTL_DEACTIVATE:
5623  if (!ctx->writable) {
5624  ret = -EPERM;
5625  break;
5626  }
5627  ret = ec_ioctl_deactivate(master, arg, ctx);
5628  break;
5629  case EC_IOCTL_SEND:
5630  if (!ctx->writable) {
5631  ret = -EPERM;
5632  break;
5633  }
5634  ret = ec_ioctl_send(master, arg, ctx);
5635  break;
5636  case EC_IOCTL_RECEIVE:
5637  if (!ctx->writable) {
5638  ret = -EPERM;
5639  break;
5640  }
5641  ret = ec_ioctl_receive(master, arg, ctx);
5642  break;
5643 #if defined(EC_RTDM) && defined(EC_EOE)
5644  case EC_IOCTL_SEND_EXT:
5645  if (!ctx->writable) {
5646  ret = -EPERM;
5647  break;
5648  }
5649  ret = ec_ioctl_send_ext(master, arg, ctx);
5650  break;
5651 #endif
5652  case EC_IOCTL_MASTER_STATE:
5653  ret = ec_ioctl_master_state(master, arg, ctx);
5654  break;
5655  case EC_IOCTL_MASTER_LINK_STATE:
5656  ret = ec_ioctl_master_link_state(master, arg, ctx);
5657  break;
5658  case EC_IOCTL_APP_TIME:
5659  if (!ctx->writable) {
5660  ret = -EPERM;
5661  break;
5662  }
5663  ret = ec_ioctl_app_time(master, arg, ctx);
5664  break;
5665  case EC_IOCTL_SYNC_REF:
5666  if (!ctx->writable) {
5667  ret = -EPERM;
5668  break;
5669  }
5670  ret = ec_ioctl_sync_ref(master, arg, ctx);
5671  break;
5672  case EC_IOCTL_SYNC_REF_TO:
5673  if (!ctx->writable) {
5674  ret = -EPERM;
5675  break;
5676  }
5677  ret = ec_ioctl_sync_ref_to(master, arg, ctx);
5678  break;
5679  case EC_IOCTL_SYNC_SLAVES:
5680  if (!ctx->writable) {
5681  ret = -EPERM;
5682  break;
5683  }
5684  ret = ec_ioctl_sync_slaves(master, arg, ctx);
5685  break;
5686  case EC_IOCTL_REF_CLOCK_TIME:
5687  if (!ctx->writable) {
5688  ret = -EPERM;
5689  break;
5690  }
5691  ret = ec_ioctl_ref_clock_time(master, arg, ctx);
5692  break;
5693  case EC_IOCTL_64_REF_CLK_TIME_QUEUE:
5694  if (!ctx->writable) {
5695  ret = -EPERM;
5696  break;
5697  }
5698  ret = ec_ioctl_64bit_ref_clock_time_queue(master, arg, ctx);
5699  break;
5700  case EC_IOCTL_64_REF_CLK_TIME:
5701  if (!ctx->writable) {
5702  ret = -EPERM;
5703  break;
5704  }
5705  ret = ec_ioctl_64bit_ref_clock_time(master, arg, ctx);
5706  break;
5707  case EC_IOCTL_SYNC_MON_QUEUE:
5708  if (!ctx->writable) {
5709  ret = -EPERM;
5710  break;
5711  }
5712  ret = ec_ioctl_sync_mon_queue(master, arg, ctx);
5713  break;
5714  case EC_IOCTL_SYNC_MON_PROCESS:
5715  if (!ctx->writable) {
5716  ret = -EPERM;
5717  break;
5718  }
5719  ret = ec_ioctl_sync_mon_process(master, arg, ctx);
5720  break;
5721  case EC_IOCTL_RT_SLAVE_REQUESTS:
5722  if (!ctx->writable) {
5723  ret = -EPERM;
5724  break;
5725  }
5726  ret = ec_ioctl_rt_slave_requests(master, arg, ctx);
5727  break;
5728  case EC_IOCTL_EXEC_SLAVE_REQUESTS:
5729  if (!ctx->writable) {
5730  ret = -EPERM;
5731  break;
5732  }
5733  ret = ec_ioctl_exec_slave_requests(master, arg, ctx);
5734  break;
5735  case EC_IOCTL_RESET:
5736  if (!ctx->writable) {
5737  ret = -EPERM;
5738  break;
5739  }
5740  ret = ec_ioctl_reset(master, arg, ctx);
5741  break;
5742  case EC_IOCTL_SC_SYNC:
5743  if (!ctx->writable) {
5744  ret = -EPERM;
5745  break;
5746  }
5747  ret = ec_ioctl_sc_sync(master, arg, ctx);
5748  break;
5749  case EC_IOCTL_SC_WATCHDOG:
5750  if (!ctx->writable) {
5751  ret = -EPERM;
5752  break;
5753  }
5754  ret = ec_ioctl_sc_watchdog(master, arg, ctx);
5755  break;
5756  case EC_IOCTL_SC_OVERLAPPING_IO:
5757  if (!ctx->writable) {
5758  ret = -EPERM;
5759  break;
5760  }
5761  ret = ec_ioctl_sc_allow_overlapping_pdos(master, arg, ctx);
5762  break;
5763  case EC_IOCTL_SC_ADD_PDO:
5764  if (!ctx->writable) {
5765  ret = -EPERM;
5766  break;
5767  }
5768  ret = ec_ioctl_sc_add_pdo(master, arg, ctx);
5769  break;
5770  case EC_IOCTL_SC_CLEAR_PDOS:
5771  if (!ctx->writable) {
5772  ret = -EPERM;
5773  break;
5774  }
5775  ret = ec_ioctl_sc_clear_pdos(master, arg, ctx);
5776  break;
5777  case EC_IOCTL_SC_ADD_ENTRY:
5778  if (!ctx->writable) {
5779  ret = -EPERM;
5780  break;
5781  }
5782  ret = ec_ioctl_sc_add_entry(master, arg, ctx);
5783  break;
5784  case EC_IOCTL_SC_CLEAR_ENTRIES:
5785  if (!ctx->writable) {
5786  ret = -EPERM;
5787  break;
5788  }
5789  ret = ec_ioctl_sc_clear_entries(master, arg, ctx);
5790  break;
5791  case EC_IOCTL_SC_REG_PDO_ENTRY:
5792  if (!ctx->writable) {
5793  ret = -EPERM;
5794  break;
5795  }
5796  ret = ec_ioctl_sc_reg_pdo_entry(master, arg, ctx);
5797  break;
5798  case EC_IOCTL_SC_REG_PDO_POS:
5799  if (!ctx->writable) {
5800  ret = -EPERM;
5801  break;
5802  }
5803  ret = ec_ioctl_sc_reg_pdo_pos(master, arg, ctx);
5804  break;
5805  case EC_IOCTL_SC_DC:
5806  if (!ctx->writable) {
5807  ret = -EPERM;
5808  break;
5809  }
5810  ret = ec_ioctl_sc_dc(master, arg, ctx);
5811  break;
5812  case EC_IOCTL_SC_SDO:
5813  if (!ctx->writable) {
5814  ret = -EPERM;
5815  break;
5816  }
5817  ret = ec_ioctl_sc_sdo(master, arg, ctx);
5818  break;
5819  case EC_IOCTL_SC_EMERG_SIZE:
5820  if (!ctx->writable) {
5821  ret = -EPERM;
5822  break;
5823  }
5824  ret = ec_ioctl_sc_emerg_size(master, arg, ctx);
5825  break;
5826  case EC_IOCTL_SC_EMERG_POP:
5827  if (!ctx->writable) {
5828  ret = -EPERM;
5829  break;
5830  }
5831  ret = ec_ioctl_sc_emerg_pop(master, arg, ctx);
5832  break;
5833  case EC_IOCTL_SC_EMERG_CLEAR:
5834  if (!ctx->writable) {
5835  ret = -EPERM;
5836  break;
5837  }
5838  ret = ec_ioctl_sc_emerg_clear(master, arg, ctx);
5839  break;
5840  case EC_IOCTL_SC_EMERG_OVERRUNS:
5841  ret = ec_ioctl_sc_emerg_overruns(master, arg, ctx);
5842  break;
5843  case EC_IOCTL_SC_SDO_REQUEST:
5844  if (!ctx->writable) {
5845  ret = -EPERM;
5846  break;
5847  }
5848  ret = ec_ioctl_sc_create_sdo_request(master, arg, ctx);
5849  break;
5850  case EC_IOCTL_SC_FOE_REQUEST:
5851  if (!ctx->writable) {
5852  ret = -EPERM;
5853  break;
5854  }
5855  ret = ec_ioctl_sc_create_foe_request(master, arg, ctx);
5856  break;
5857  case EC_IOCTL_SC_REG_REQUEST:
5858  if (!ctx->writable) {
5859  ret = -EPERM;
5860  break;
5861  }
5862  ret = ec_ioctl_sc_create_reg_request(master, arg, ctx);
5863  break;
5864  case EC_IOCTL_SC_VOE:
5865  if (!ctx->writable) {
5866  ret = -EPERM;
5867  break;
5868  }
5869  ret = ec_ioctl_sc_create_voe_handler(master, arg, ctx);
5870  break;
5871  case EC_IOCTL_SC_STATE:
5872  ret = ec_ioctl_sc_state(master, arg, ctx);
5873  break;
5874  case EC_IOCTL_SC_IDN:
5875  if (!ctx->writable) {
5876  ret = -EPERM;
5877  break;
5878  }
5879  ret = ec_ioctl_sc_idn(master, arg, ctx);
5880  break;
5881  case EC_IOCTL_DOMAIN_SIZE:
5882  ret = ec_ioctl_domain_size(master, arg, ctx);
5883  break;
5884  case EC_IOCTL_DOMAIN_OFFSET:
5885  ret = ec_ioctl_domain_offset(master, arg, ctx);
5886  break;
5887  case EC_IOCTL_DOMAIN_PROCESS:
5888  if (!ctx->writable) {
5889  ret = -EPERM;
5890  break;
5891  }
5892  ret = ec_ioctl_domain_process(master, arg, ctx);
5893  break;
5894  case EC_IOCTL_DOMAIN_QUEUE:
5895  if (!ctx->writable) {
5896  ret = -EPERM;
5897  break;
5898  }
5899  ret = ec_ioctl_domain_queue(master, arg, ctx);
5900  break;
5901  case EC_IOCTL_DOMAIN_STATE:
5902  ret = ec_ioctl_domain_state(master, arg, ctx);
5903  break;
5904  case EC_IOCTL_SDO_REQUEST_INDEX:
5905  if (!ctx->writable) {
5906  ret = -EPERM;
5907  break;
5908  }
5909  ret = ec_ioctl_sdo_request_index(master, arg, ctx);
5910  break;
5911  case EC_IOCTL_SDO_REQUEST_TIMEOUT:
5912  if (!ctx->writable) {
5913  ret = -EPERM;
5914  break;
5915  }
5916  ret = ec_ioctl_sdo_request_timeout(master, arg, ctx);
5917  break;
5918  case EC_IOCTL_SDO_REQUEST_STATE:
5919  ret = ec_ioctl_sdo_request_state(master, arg, ctx);
5920  break;
5921  case EC_IOCTL_SDO_REQUEST_READ:
5922  if (!ctx->writable) {
5923  ret = -EPERM;
5924  break;
5925  }
5926  ret = ec_ioctl_sdo_request_read(master, arg, ctx);
5927  break;
5928  case EC_IOCTL_SDO_REQUEST_WRITE:
5929  if (!ctx->writable) {
5930  ret = -EPERM;
5931  break;
5932  }
5933  ret = ec_ioctl_sdo_request_write(master, arg, ctx);
5934  break;
5935  case EC_IOCTL_SDO_REQUEST_DATA:
5936  ret = ec_ioctl_sdo_request_data(master, arg, ctx);
5937  break;
5938  case EC_IOCTL_FOE_REQUEST_FILE:
5939  if (!ctx->writable) {
5940  ret = -EPERM;
5941  break;
5942  }
5943  ret = ec_ioctl_foe_request_file(master, arg, ctx);
5944  break;
5945  case EC_IOCTL_FOE_REQUEST_TIMEOUT:
5946  if (!ctx->writable) {
5947  ret = -EPERM;
5948  break;
5949  }
5950  ret = ec_ioctl_foe_request_timeout(master, arg, ctx);
5951  break;
5952  case EC_IOCTL_FOE_REQUEST_STATE:
5953  ret = ec_ioctl_foe_request_state(master, arg, ctx);
5954  break;
5955  case EC_IOCTL_FOE_REQUEST_READ:
5956  if (!ctx->writable) {
5957  ret = -EPERM;
5958  break;
5959  }
5960  ret = ec_ioctl_foe_request_read(master, arg, ctx);
5961  break;
5962  case EC_IOCTL_FOE_REQUEST_WRITE:
5963  if (!ctx->writable) {
5964  ret = -EPERM;
5965  break;
5966  }
5967  ret = ec_ioctl_foe_request_write(master, arg, ctx);
5968  break;
5969  case EC_IOCTL_FOE_REQUEST_DATA:
5970  ret = ec_ioctl_foe_request_data(master, arg, ctx);
5971  break;
5972  case EC_IOCTL_REG_REQUEST_DATA:
5973  ret = ec_ioctl_reg_request_data(master, arg, ctx);
5974  break;
5975  case EC_IOCTL_REG_REQUEST_STATE:
5976  ret = ec_ioctl_reg_request_state(master, arg, ctx);
5977  break;
5978  case EC_IOCTL_REG_REQUEST_WRITE:
5979  if (!ctx->writable) {
5980  ret = -EPERM;
5981  break;
5982  }
5983  ret = ec_ioctl_reg_request_write(master, arg, ctx);
5984  break;
5985  case EC_IOCTL_REG_REQUEST_READ:
5986  if (!ctx->writable) {
5987  ret = -EPERM;
5988  break;
5989  }
5990  ret = ec_ioctl_reg_request_read(master, arg, ctx);
5991  break;
5992  case EC_IOCTL_REG_REQUEST_READWRITE:
5993  if (!ctx->writable) {
5994  ret = -EPERM;
5995  break;
5996  }
5997  ret = ec_ioctl_reg_request_readwrite(master, arg, ctx);
5998  break;
5999  case EC_IOCTL_VOE_SEND_HEADER:
6000  if (!ctx->writable) {
6001  ret = -EPERM;
6002  break;
6003  }
6004  ret = ec_ioctl_voe_send_header(master, arg, ctx);
6005  break;
6006  case EC_IOCTL_VOE_REC_HEADER:
6007  ret = ec_ioctl_voe_rec_header(master, arg, ctx);
6008  break;
6009  case EC_IOCTL_VOE_READ:
6010  if (!ctx->writable) {
6011  ret = -EPERM;
6012  break;
6013  }
6014  ret = ec_ioctl_voe_read(master, arg, ctx);
6015  break;
6016  case EC_IOCTL_VOE_READ_NOSYNC:
6017  if (!ctx->writable) {
6018  ret = -EPERM;
6019  break;
6020  }
6021  ret = ec_ioctl_voe_read_nosync(master, arg, ctx);
6022  break;
6023  case EC_IOCTL_VOE_WRITE:
6024  if (!ctx->writable) {
6025  ret = -EPERM;
6026  break;
6027  }
6028  ret = ec_ioctl_voe_write(master, arg, ctx);
6029  break;
6030  case EC_IOCTL_VOE_EXEC:
6031  if (!ctx->writable) {
6032  ret = -EPERM;
6033  break;
6034  }
6035  ret = ec_ioctl_voe_exec(master, arg, ctx);
6036  break;
6037  case EC_IOCTL_VOE_DATA:
6038  ret = ec_ioctl_voe_data(master, arg, ctx);
6039  break;
6040  case EC_IOCTL_SET_SEND_INTERVAL:
6041  if (!ctx->writable) {
6042  ret = -EPERM;
6043  break;
6044  }
6045  ret = ec_ioctl_set_send_interval(master, arg, ctx);
6046  break;
6047  case EC_IOCTL_SLAVE_DICT_UPLOAD:
6048  ret = ec_ioctl_slave_dict_upload(master, arg);
6049  break;
6050 #ifdef EC_EOE
6051  case EC_IOCTL_EOE_ADDIF:
6052  if (!ctx->writable) {
6053  ret = -EPERM;
6054  break;
6055  }
6056  ret = ec_ioctl_eoe_addif(master, arg, ctx);
6057  break;
6058  case EC_IOCTL_EOE_DELIF:
6059  if (!ctx->writable) {
6060  ret = -EPERM;
6061  break;
6062  }
6063  ret = ec_ioctl_eoe_delif(master, arg, ctx);
6064  break;
6065 #endif
6066  case EC_IOCTL_MBOX_GATEWAY:
6067  if (!ctx->writable) {
6068  ret = -EPERM;
6069  break;
6070  }
6071  ret = ec_ioctl_mbox_gateway(master, arg, ctx);
6072  break;
6073  default:
6074  ret = -ENOTTY;
6075  break;
6076  }
6077 
6078 #if DEBUG_LATENCY
6079  b = get_cycles();
6080  t = (unsigned int) ((b - a) * 1000LL) / cpu_khz;
6081  if (t > 50) {
6082  EC_MASTER_WARN(master, "ioctl(0x%02x) took %u us.\n",
6083  _IOC_NR(cmd), t);
6084  }
6085 #endif
6086 
6087  return ret;
6088 }
6089 
6090 /*****************************************************************************/
unsigned int tx_ring_size
Transmit ring size.
Definition: ethernet.h:96
ec_request_state_t ecrt_foe_request_state(const ec_foe_request_t *req)
Get the current state of the FoE request.
Definition: foe_request.c:229
static ATTRIBUTES int ec_ioctl_eoe_delif(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
delete an EOE interface
Definition: rtdm-ioctl.c:5303
size_t ecrt_domain_size(const ec_domain_t *domain)
Returns the current size of the domain&#39;s process data.
Definition: domain.c:503
ec_sii_general_flags_t general_flags
General flags.
Definition: slave.h:186
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
ec_internal_request_state_t state
Request state.
Definition: reg_request.h:56
uint16_t offset
SII word offset.
Definition: fsm_master.h:55
uint16_t ring_position
Ring position.
Definition: slave.h:221
uint32_t revision_number
Revision number.
Definition: slave.h:162
static ATTRIBUTES int ec_ioctl_slave_sii_write(ec_master_t *master, void *arg)
Write a slave&#39;s SII.
Definition: rtdm-ioctl.c:1152
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
uint8_t upstream_port
Index of master-facing port.
Definition: slave.h:232
static ATTRIBUTES int ec_ioctl_voe_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation.
Definition: rtdm-ioctl.c:4770
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: rtdm-ioctl.c:3811
static ATTRIBUTES int ec_ioctl_domain_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the domain.
Definition: rtdm-ioctl.c:3878
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
Definition: slave.c:889
void ecrt_sdo_request_index_complete(ec_sdo_request_t *req, uint16_t index)
Set the SDO index and prepare for complete-access.
Definition: sdo_request.c:195
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
Definition: slave.h:164
static ATTRIBUTES int ec_ioctl_foe_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an FoE write operation.
Definition: rtdm-ioctl.c:4360
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:142
uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
Processes the DC synchrony monitoring datagram.
Definition: master.c:3448
ec_sdo_request_t * ecrt_slave_config_create_sdo_request_err(ec_slave_config_t *sc, uint16_t index, uint8_t subindex, uint8_t complete, size_t size)
Same as ecrt_slave_config_create_sdo_request(), but with ERR_PTR() return value.
uint32_t tx_counter
octets transmitted during last second
Definition: ethernet.h:104
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:562
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
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
#define ec_ioctl_lock_down_interruptible(p)
Ioctl locking is disabled for RTDM as the RT app needs to use RTAI locks.
Definition: rtdm-ioctl.c:66
size_t ecrt_foe_request_data_size(const ec_foe_request_t *req)
Returns the data size.
Definition: foe_request.c:220
FMMU configuration.
Definition: fmmu_config.h:46
static ATTRIBUTES int ec_ioctl_sdo_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO read operation.
Definition: rtdm-ioctl.c:4073
void * pcap_curr_data
pcap debug output current memory pointer
Definition: master.h:314
u64 tx_count
Number of frames sent.
Definition: master.h:164
struct list_head sii_requests
SII write requests.
Definition: master.h:334
void ecrt_master_sync_slave_clocks(ec_master_t *master)
Queues the DC clock drift compensation datagram for sending.
Definition: master.c:3397
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:496
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.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Definition: slave.h:108
CANopen SDO entry.
Definition: sdo_entry.h:54
static ATTRIBUTES int ec_ioctl_config_idn(ec_master_t *master, void *arg)
Get slave configuration IDN information.
Definition: rtdm-ioctl.c:1736
static ATTRIBUTES int ec_ioctl_config_pdo(ec_master_t *master, void *arg)
Get slave configuration PDO information.
Definition: rtdm-ioctl.c:1551
size_t data_size
Size of the process data.
Definition: domain.h:61
uint8_t tx_fragment_number
number of the fragment
Definition: ethernet.h:102
ec_slave_t * slave
pointer to the corresponding slave
Definition: ethernet.h:75
unsigned int tx_ring_count
Transmit ring count.
Definition: ethernet.h:95
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: master.h:181
static ATTRIBUTES int ec_ioctl_sc_sdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an SDO.
Definition: rtdm-ioctl.c:3261
static ATTRIBUTES int ec_ioctl_sc_emerg_overruns(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the number of emergency overruns.
Definition: rtdm-ioctl.c:3435
ec_internal_request_state_t state
State of the request.
Definition: fsm_master.h:58
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:2327
static ATTRIBUTES int ec_ioctl_deactivate_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the slaves.
Definition: rtdm-ioctl.c:2323
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:693
static ATTRIBUTES int ec_ioctl_exec_slave_requests(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Call to process slave requests explicitly from application.
Definition: rtdm-ioctl.c:2806
void * pcap_data
pcap debug output memory pointer
Definition: master.h:313
struct list_head foe_requests
List of FoE requests.
Definition: slave_config.h:147
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:3324
static ATTRIBUTES int ec_ioctl_eoe_addif(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
add an EOE interface
Definition: rtdm-ioctl.c:5279
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
Definition: slave.h:231
void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
Sets the application time.
Definition: master.c:3340
static ATTRIBUTES int ec_ioctl_sc_emerg_pop(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get an emergency message from the ring.
Definition: rtdm-ioctl.c:3358
void ec_foe_request_init(ec_foe_request_t *req)
FoE request constructor.
Definition: foe_request.c:56
int ec_fsm_slave_is_ready(const ec_fsm_slave_t *fsm)
Returns, if the FSM is currently not busy and ready to execute.
Definition: fsm_slave.c:681
size_t rx_skb_size
size of the allocated socket buffer memory
Definition: ethernet.h:88
CANopen SDO request.
Definition: sdo_request.h:48
ec_slave_state_t current_state
Current application state.
Definition: slave.h:237
size_t tx_offset
number of octets sent
Definition: ethernet.h:103
static ATTRIBUTES int ec_ioctl_domain_data(ec_master_t *master, void *arg)
Get domain data.
Definition: rtdm-ioctl.c:647
#define ec_master_num_devices(MASTER)
Number of Ethernet devices.
Definition: master.h:359
#define EC_RATE_COUNT
Number of statistic rate intervals to maintain.
Definition: globals.h:71
size_t nwords
Number of words.
Definition: fsm_master.h:56
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
size_t mem_size
Size of data memory.
Definition: reg_request.h:50
uint32_t product_code
Slave product code.
Definition: slave_config.h:126
ec_slave_port_link_t link
Port link status.
Definition: slave.h:141
static ATTRIBUTES int ec_ioctl_pcap_data(ec_master_t *master, void *arg)
Get pcap data.
Definition: rtdm-ioctl.c:692
static ATTRIBUTES int ec_ioctl_foe_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an FoE read operation.
Definition: rtdm-ioctl.c:4323
void ec_master_internal_receive_cb(void *cb_data)
Internal receiving callback.
Definition: master.c:692
uint16_t position
Index after alias.
Definition: slave_config.h:123
static ATTRIBUTES int ec_ioctl_master_rescan(ec_master_t *master, void *arg)
Issue a bus scan.
Definition: rtdm-ioctl.c:780
static ATTRIBUTES int ec_ioctl_sc_clear_pdos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the PDO assignment.
Definition: rtdm-ioctl.c:3019
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:2278
unsigned int rescan_required
A bus rescan is required.
Definition: fsm_master.h:82
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:3286
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:452
uint32_t serial_number
Serial number.
Definition: slave.h:163
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:120
ec_sii_coe_details_t coe_details
CoE detail flags.
Definition: slave.h:185
char * order
Order number.
Definition: slave.h:182
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:2406
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:2445
uint16_t index
SDO index.
Definition: sdo_request.h:50
size_t ecrt_master_send_ext(ec_master_t *master)
Sends non-application datagrams.
Definition: master.c:3087
u64 dc_ref_time
Common reference timestamp for DC start times.
Definition: master.h:250
static ATTRIBUTES int ec_ioctl_voe_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reads the received VoE data.
Definition: rtdm-ioctl.c:4935
static ATTRIBUTES int ec_ioctl_set_send_interval(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set max.
Definition: rtdm-ioctl.c:2361
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:335
ec_internal_request_state_t state
Request state.
Definition: soe_request.h:58
unsigned int tx_queue_active
kernel netif queue started
Definition: ethernet.h:99
size_t data_size
Size of FoE data.
Definition: foe_request.h:54
static ATTRIBUTES int ec_ioctl_sc_clear_entries(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clears the mapping of a PDO.
Definition: rtdm-ioctl.c:3089
uint16_t alias
Slave alias.
Definition: slave_config.h:122
static ATTRIBUTES int ec_ioctl_receive(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Receive frames.
Definition: rtdm-ioctl.c:2435
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: rtdm-ioctl.c:3054
struct list_head domains
List of domains.
Definition: master.h:244
static ATTRIBUTES int ec_ioctl_slave_sync_pdo(ec_master_t *master, void *arg)
Get slave sync manager PDO information.
Definition: rtdm-ioctl.c:403
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: rtdm-ioctl.c:3950
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:925
ec_fsm_slave_t fsm
Slave state machine.
Definition: slave.h:282
struct list_head reg_requests
Register access requests.
Definition: slave.h:275
static ATTRIBUTES int ec_ioctl_sync_mon_queue(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Queue the sync monitoring datagram.
Definition: rtdm-ioctl.c:2727
uint8_t drive_no
Drive number.
Definition: soe_request.h:50
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: rtdm-ioctl.c:3991
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_setup_domain_memory(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets up domain memory.
Definition: rtdm-ioctl.c:2145
int16_t current_on_ebus
Power consumption in mA.
Definition: slave.h:187
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:2262
uint8_t link_state
device link state
Definition: device.h:97
static ATTRIBUTES int ec_ioctl_slave_reboot(ec_master_t *master, void *arg)
Reboot a slave (if supported).
Definition: rtdm-ioctl.c:830
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
static ATTRIBUTES int ec_ioctl_foe_request_timeout(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an FoE request&#39;s timeout.
Definition: rtdm-ioctl.c:4238
static ATTRIBUTES int ec_ioctl_ref_clock_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the system time of the reference clock.
Definition: rtdm-ioctl.c:2645
ec_master_t * ecrt_request_master_err(unsigned int)
Request a master.
Definition: module.c:544
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
Definition: slave.h:167
void ecrt_foe_request_timeout(ec_foe_request_t *req, uint32_t timeout)
Set the request timeout.
Definition: foe_request.c:179
void ecrt_foe_request_write(ec_foe_request_t *req, size_t data_size)
Prepares a write request (master to slave).
Definition: foe_request.c:281
const uint8_t * macs[EC_MAX_NUM_DEVICES]
Device MAC addresses.
Definition: master.h:220
void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
Reads the current master state.
Definition: master.c:3300
u64 rx_count
Number of frames received.
Definition: device.h:111
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:148
wait_queue_head_t request_queue
Wait queue for external requests from user space.
Definition: master.h:338
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.
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: rtdm-ioctl.c:4492
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:510
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:3384
void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
Set the timeout for an SDO request.
Definition: sdo_request.c:204
unsigned int sync_count
Number of sync managers.
Definition: slave.h:191
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: rtdm-ioctl.c:2696
struct list_head list
List head.
Definition: fsm_master.h:53
SII write request.
Definition: fsm_master.h:52
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:2759
uint32_t tx_rate
transmit rate (bps)
Definition: ethernet.h:105
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
Definition: slave.h:169
static ATTRIBUTES int ec_ioctl_sc_create_sdo_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an SDO request.
Definition: rtdm-ioctl.c:3480
static ATTRIBUTES int ec_ioctl_sc_add_pdo(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Add a PDO to the assignment.
Definition: rtdm-ioctl.c:2985
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:2342
void ecrt_slave_config_dc(ec_slave_config_t *sc, uint16_t assign_activate, uint32_t sync0_cycle_time, int32_t sync0_shift_time, uint32_t sync1_cycle_time, int32_t sync1_shift_time)
Configure distributed clocks.
Definition: slave_config.c:990
static ATTRIBUTES int ec_ioctl_slave_reg_read(ec_master_t *master, void *arg)
Read a slave&#39;s registers.
Definition: rtdm-ioctl.c:1240
static ATTRIBUTES int ec_ioctl_sc_dc(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the DC AssignActivate word and the sync signal times.
Definition: rtdm-ioctl.c:3221
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
Definition: slave.h:170
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: device.h:123
uint8_t * ecrt_sdo_request_data(ec_sdo_request_t *req)
Access to the SDO request&#39;s data.
Definition: sdo_request.c:211
uint8_t rx_expected_fragment
next expected fragment number
Definition: ethernet.h:89
size_t ecrt_foe_request_progress(const ec_foe_request_t *req)
Returns the progress of the current transfer.
Definition: foe_request.c:254
ec_direction_t dir
Direction.
Definition: sdo_request.h:60
PDO entry description.
Definition: pdo_entry.h:48
EtherCAT master structure.
uint8_t * data
Memory for the process data.
Definition: domain.h:62
int ecrt_master_64bit_reference_clock_time(ec_master_t *master, uint64_t *time)
Get the 64bit dc reference slave clock time.
Definition: master.c:3417
void * cb_data
Current callback data.
Definition: master.h:327
uint8_t file_name[255]
FoE filename.
Definition: foe_request.h:71
ec_sync_signal_t dc_sync[EC_SYNC_SIGNAL_COUNT]
DC sync signals.
Definition: slave_config.h:143
static ATTRIBUTES int ec_ioctl_master_link_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the link state.
Definition: rtdm-ioctl.c:2523
uint16_t index
PDO index.
Definition: pdo.h:51
int ecrt_master_sdo_upload_complete(ec_master_t *master, uint16_t slave_position, uint16_t index, 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 via complete access.
Definition: master.c:3711
#define EC_MASTER_DBG(master, level, fmt, args...)
Convenience macro for printing master-specific debug messages to syslog.
Definition: master.h:106
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
Definition: slave.h:166
static ATTRIBUTES int ec_ioctl_sync_mon_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Processes the sync monitoring datagram.
Definition: rtdm-ioctl.c:2747
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
ec_slave_t * slave
EtherCAT slave.
Definition: fsm_master.h:54
uint16_t index
PDO entry index.
Definition: pdo_entry.h:50
EtherCAT slave.
Definition: slave.h:214
static ATTRIBUTES int ec_ioctl_voe_exec(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Executes the VoE state machine.
Definition: rtdm-ioctl.c:4890
ec_lock_t device_sem
Device semaphore.
Definition: master.h:226
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:232
static ATTRIBUTES int ec_ioctl_mbox_gateway(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process an EtherCAT Mailbox Gateway message.
Definition: rtdm-ioctl.c:5329
unsigned int tx_next_to_use
index of frames added to the ring
Definition: ethernet.h:97
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:269
static ATTRIBUTES int ec_ioctl_slave_sdo_entry(ec_master_t *master, void *arg)
Get slave SDO entry information.
Definition: rtdm-ioctl.c:919
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
pcap global header
Definition: device.h:147
int ec_master_debug_level(ec_master_t *master, unsigned int level)
Set the debug level.
Definition: master.c:2470
Slave configuration state.
Definition: ecrt.h:318
static ATTRIBUTES int ec_ioctl_reg_request_read(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register read operation.
Definition: rtdm-ioctl.c:4586
static ATTRIBUTES int ec_ioctl_slave_reg_write(ec_master_t *master, void *arg)
Write a slave&#39;s registers.
Definition: rtdm-ioctl.c:1319
s32 tx_frame_rates[EC_RATE_COUNT]
Transmit rates in frames/s for different statistics cycle periods.
Definition: master.h:175
ec_sii_image_t * sii_image
Current complete SII image.
Definition: slave.h:267
s32 rx_byte_rates[EC_RATE_COUNT]
Receive rates in byte/s for different statistics cycle periods.
Definition: master.h:183
void ecrt_foe_request_read(ec_foe_request_t *req)
Prepares a read request (slave to master).
Definition: foe_request.c:265
Ethernet over EtherCAT (EoE)
ec_sync_config_t sync_configs[EC_MAX_SYNC_MANAGERS]
Sync manager configurations.
Definition: slave_config.h:138
ec_device_stats_t device_stats
Device statistics.
Definition: master.h:227
static ATTRIBUTES int ec_ioctl_sdo_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an SDO write operation.
Definition: rtdm-ioctl.c:4110
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
ec_master_phase_t phase
Master phase.
Definition: master.h:231
static ATTRIBUTES int ec_ioctl_slave_reg_readwrite(ec_master_t *master, void *arg)
Read & Write a slave&#39;s registers.
Definition: rtdm-ioctl.c:1404
Domain state.
Definition: ecrt.h:426
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: rtdm-ioctl.c:2676
static ATTRIBUTES int ec_ioctl_slave_eoe_ip_param(ec_master_t *master, void *arg)
Request EoE IP parameter setting.
Definition: rtdm-ioctl.c:1881
static ATTRIBUTES int ec_ioctl_master_debug(ec_master_t *master, void *arg)
Set master debug level.
Definition: rtdm-ioctl.c:766
static ATTRIBUTES int ec_ioctl_reset(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Reset configuration.
Definition: rtdm-ioctl.c:2827
static ATTRIBUTES int ec_ioctl_voe_rec_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets the received VoE header.
Definition: rtdm-ioctl.c:4722
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
static ATTRIBUTES int ec_ioctl_sdo_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read SDO data.
Definition: rtdm-ioctl.c:4161
static ATTRIBUTES int ec_ioctl_foe_request_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Gets an FoE request&#39;s state.
Definition: rtdm-ioctl.c:4275
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:128
struct list_head sdo_requests
List of SDO requests.
Definition: slave_config.h:146
EtherCAT device.
Definition: device.h:90
uint16_t mailbox_protocols
Supported mailbox protocols.
Definition: slave.h:172
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:2391
uint8_t * ecrt_foe_request_data(ec_foe_request_t *req)
Returns a pointer to the request&#39;s data.
Definition: foe_request.c:207
Access rights in OP.
Definition: globals.h:230
size_t data_size
Size of SDO data.
Definition: soe_request.h:55
static ATTRIBUTES int ec_ioctl_reg_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read register data.
Definition: rtdm-ioctl.c:4445
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
static ATTRIBUTES int ec_ioctl_slave_sdo_upload(ec_master_t *master, void *arg)
Upload SDO.
Definition: rtdm-ioctl.c:999
unsigned int ec_master_domain_count(const ec_master_t *master)
Get the number of domains.
Definition: master.c:2357
ec_slave_dc_range_t base_dc_range
DC range.
Definition: slave.h:258
uint8_t bit_length
entry length in bit
Definition: pdo_entry.h:53
Sync manager.
Definition: sync.h:47
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
Definition: slave.h:168
static ATTRIBUTES int ec_ioctl_sync_ref(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: rtdm-ioctl.c:2580
unsigned int tx_next_to_clean
index of frames being used from the ring
Definition: ethernet.h:98
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
Definition: slave.h:256
s32 loss_rates[EC_RATE_COUNT]
Frame loss rates for different statistics cycle periods.
Definition: master.h:185
static ATTRIBUTES int ec_ioctl_module(void *arg)
Get module information.
Definition: rtdm-ioctl.c:93
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
Definition: slave.h:262
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:3176
unsigned long rate_jiffies
time of last rate output
Definition: ethernet.h:82
unsigned int slave_count
Number of slaves on the bus.
Definition: master.h:240
unsigned int scan_busy
Current scan state.
Definition: master.h:265
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:326
uint16_t dc_assign_activate
Vendor-specific AssignActivate word.
Definition: slave_config.h:142
s32 rx_frame_rates[EC_RATE_COUNT]
Receive rates in frames/s for different statistics cycle periods.
Definition: master.h:178
unsigned int have_mbox_lock
flag to track if we have the mbox lock
Definition: ethernet.h:83
unsigned int index
Index (just a number).
Definition: domain.h:58
void ecrt_reg_request_readwrite(ec_reg_request_t *reg, uint16_t address, size_t size)
Schedule a register read-write operation.
Definition: reg_request.c:122
void ec_slave_request_reboot(ec_slave_t *slave)
Request a slave reboot (some slaves will ignore this).
Definition: slave.c:450
s32 tx_byte_rates[EC_RATE_COUNT]
Transmit rates in byte/s for different statistics cycle periods.
Definition: device.h:126
Main device.
Definition: globals.h:237
#define ATTRIBUTES
Optional compiler attributes fo ioctl() functions.
Definition: rtdm-ioctl.c:57
uint16_t watchdog_intervals
Process data watchdog intervals (see spec.
Definition: slave_config.h:130
static ATTRIBUTES int ec_ioctl_slave_sdo_download(ec_master_t *master, void *arg)
Download SDO.
Definition: rtdm-ioctl.c:1051
ec_slave_port_desc_t desc
Port descriptors.
Definition: slave.h:140
#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_master(ec_master_t *master, void *arg)
Get master information.
Definition: rtdm-ioctl.c:114
static ATTRIBUTES int ec_ioctl_sc_emerg_clear(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Clear the emergency ring.
Definition: rtdm-ioctl.c:3402
Vendor specific over EtherCAT handler.
Definition: voe_handler.h:49
unsigned int active
Master has been activated.
Definition: master.h:232
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_sc_reg_pdo_pos(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry by its position.
Definition: rtdm-ioctl.c:3171
static ATTRIBUTES int ec_ioctl_foe_request_file(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets an FoE request&#39;s FoE filename and password.
Definition: rtdm-ioctl.c:4201
void ecrt_master_exec_slave_requests(ec_master_t *master)
Explicit call to process slave requests.
Definition: master.c:3975
unsigned int ec_slave_config_sdo_count(const ec_slave_config_t *sc)
Get the number of SDO configurations.
Definition: slave_config.c:430
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:867
uint32_t error_code
Error code from an FoE Error Request.
Definition: foe_request.h:70
u64 rx_bytes
Number of bytes received.
Definition: device.h:116
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:3628
uint8_t has_dc_system_time
The slave supports the DC system time register.
Definition: slave.h:259
static ATTRIBUTES int ec_ioctl_reg_request_readwrite(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register read-write operation.
Definition: rtdm-ioctl.c:4629
Values read and written by the master.
Definition: ecrt.h:440
#define EC_IOCTL
ioctl() function to use.
Definition: rtdm-ioctl.c:5394
u64 tx_count
Number of frames sent.
Definition: device.h:109
static ATTRIBUTES int ec_ioctl_domain_process(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Process the domain.
Definition: rtdm-ioctl.c:3845
unsigned int ec_domain_fmmu_count(const ec_domain_t *domain)
Get the number of FMMU configurations of the domain.
Definition: domain.c:408
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: rtdm-ioctl.c:2941
#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
static ATTRIBUTES int ec_ioctl_select_ref_clock(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Select the DC reference clock.
Definition: rtdm-ioctl.c:2104
struct list_head list
List item.
Definition: foe_request.h:51
void ecrt_foe_request_file(ec_foe_request_t *req, const char *file_name, uint32_t password)
Selects a new file for the request.
Definition: foe_request.c:191
uint8_t control_register
Control register value.
Definition: sync.h:51
static ATTRIBUTES int ec_ioctl_voe_read_nosync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE read operation without sending a sync message first.
Definition: rtdm-ioctl.c:4807
static ATTRIBUTES int ec_ioctl_config_pdo_entry(ec_master_t *master, void *arg)
Get slave configuration PDO entry information.
Definition: rtdm-ioctl.c:1607
Values read by the master.
Definition: ecrt.h:439
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
ec_foe_error_t result
FoE request abort code.
Definition: foe_request.h:69
static ATTRIBUTES int ec_ioctl_domain_fmmu(ec_master_t *master, void *arg)
Get domain FMMU information.
Definition: rtdm-ioctl.c:595
Access rights in SAFEOP.
Definition: globals.h:229
static ATTRIBUTES int ec_ioctl_domain(ec_master_t *master, void *arg)
Get domain information.
Definition: rtdm-ioctl.c:550
uint16_t data_type
Data type.
Definition: sdo_entry.h:58
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: rtdm-ioctl.c:2898
static ATTRIBUTES int ec_ioctl_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Request the master from userspace.
Definition: rtdm-ioctl.c:1965
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:225
struct list_head configs
List of slave configurations.
Definition: master.h:243
ec_slave_t * slave
Slave pointer.
Definition: slave_config.h:135
static ATTRIBUTES int ec_ioctl_sync_ref_to(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the reference clock.
Definition: rtdm-ioctl.c:2600
unsigned int opened
net_device is opened
Definition: ethernet.h:81
static ATTRIBUTES int ec_ioctl_create_slave_config(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a slave configuration.
Definition: rtdm-ioctl.c:2058
uint16_t watchdog_divider
Watchdog divider as a number of 40ns intervals (see spec.
Definition: slave_config.h:128
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:518
static ATTRIBUTES int ec_ioctl_domain_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the domain state.
Definition: rtdm-ioctl.c:3912
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:4641
#define EC_MBOX_HEADER_SIZE
Mailbox header size.
Definition: globals.h:100
ec_foe_request_t * ec_slave_config_find_foe_request(ec_slave_config_t *sc, unsigned int pos)
Finds an FoE handler via its position in the list.
Definition: slave_config.c:540
#define EC_SLAVE_INFO(slave, fmt, args...)
Convenience macro for printing slave-specific information to syslog.
Definition: slave.h:63
static ATTRIBUTES int ec_ioctl_master_state(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Get the master state.
Definition: rtdm-ioctl.c:2501
void ecrt_master_sync_monitor_queue(ec_master_t *master)
Queues the DC synchrony monitoring datagram for sending.
Definition: master.c:3440
void ecrt_master_deactivate_slaves(ec_master_t *master)
Deactivates the slaves distributed clocks and sends the slaves into PREOP.
Definition: master.c:2889
static ATTRIBUTES int ec_ioctl_sync_slaves(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sync the slave clocks.
Definition: rtdm-ioctl.c: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
off_t rx_skb_offset
current write pointer in the socket buffer
Definition: ethernet.h:87
ec_direction_t dir
Direction.
Definition: foe_request.h:61
uint16_t working_counter[EC_MAX_NUM_DEVICES]
Last working counter values.
Definition: domain.h:68
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:845
uint32_t logical_base_address
Logical offset address of the process data.
Definition: domain.h:64
unsigned int ec_eoe_tx_queued_frames(const ec_eoe_t *eoe)
Definition: ethernet.c:540
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:741
ec_watchdog_mode_t watchdog_mode
Watchdog mode.
Definition: sync_config.h:48
struct net_device_stats stats
device statistics
Definition: ethernet.h:80
char * name
PDO name.
Definition: pdo.h:53
static ATTRIBUTES int ec_ioctl_config_sdo(ec_master_t *master, void *arg)
Get slave configuration SDO information.
Definition: rtdm-ioctl.c:1672
uint8_t subindex
SDO subindex.
Definition: sdo_request.h:51
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: rtdm-ioctl.c:3777
uint16_t expected_working_counter
Expected working counter.
Definition: domain.h:70
static ATTRIBUTES int ec_ioctl_rt_slave_requests(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Call to set whether processing slave requests explicitly from the application is active or not...
Definition: rtdm-ioctl.c:2773
uint8_t allow_overlapping_pdos
Allow input PDOs use the same frame space as output PDOs.
Definition: slave_config.h:133
static ATTRIBUTES int ec_ioctl_config(ec_master_t *master, void *arg)
Get slave configuration information.
Definition: rtdm-ioctl.c:1493
unsigned int ec_slave_config_idn_count(const ec_slave_config_t *sc)
Get the number of IDN configurations.
Definition: slave_config.c:474
u64 tx_errors
Number of transmit errors.
Definition: device.h:119
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:870
uint16_t effective_alias
Effective alias address.
Definition: slave.h:223
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:217
ec_internal_request_state_t state
Request state.
Definition: eoe_request.h:51
unsigned int tx_idle
Idle flag.
Definition: ethernet.h:106
static ATTRIBUTES int ec_ioctl_slave_sdo(ec_master_t *master, void *arg)
Get slave SDO information.
Definition: rtdm-ioctl.c:870
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:3870
struct list_head foe_requests
FoE requests.
Definition: slave.h:276
uint32_t rx_rate
receive rate (bps)
Definition: ethernet.h:91
ec_direction_t dir
Direction.
Definition: voe_handler.h:56
size_t buffer_size
Size of FoE data memory.
Definition: foe_request.h:53
u64 tx_bytes
Number of bytes sent.
Definition: master.h:169
static ATTRIBUTES int ec_ioctl_slave(ec_master_t *master, void *arg)
Get slave information.
Definition: rtdm-ioctl.c:216
int ecrt_master_activate(ec_master_t *master)
Finishes the configuration phase and prepares for cyclic operation.
Definition: master.c:2814
uint16_t ec_master_eoe_handler_count(const ec_master_t *master)
Get the number of EoE handlers.
Definition: master.c:2423
static ATTRIBUTES int ec_ioctl_slave_sync(ec_master_t *master, void *arg)
Get slave sync manager information.
Definition: rtdm-ioctl.c:339
ec_foe_request_t * ecrt_slave_config_create_foe_request_err(ec_slave_config_t *sc, size_t size)
Same as ecrt_slave_config_create_foe_request(), but with ERR_PTR() return value.
size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
Returns the current SDO data size.
Definition: sdo_request.c:218
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:778
struct sk_buff * rx_skb
current rx socket buffer
Definition: ethernet.h:86
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:2986
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:165
#define EC_MAX_PORTS
Maximum number of slave ports.
Definition: ecrt.h:217
static ATTRIBUTES int ec_ioctl_slave_soe_write(ec_master_t *master, void *arg)
Write an IDN to a slave via SoE.
Definition: rtdm-ioctl.c:5209
static ATTRIBUTES int ec_ioctl_slave_soe_read(ec_master_t *master, void *arg)
Read an SoE IDN.
Definition: rtdm-ioctl.c:5160
static void ec_ioctl_strcpy(char *target, const char *source)
Copies a string to an ioctl structure.
Definition: rtdm-ioctl.c:74
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:3459
static ATTRIBUTES int ec_ioctl_app_time(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the master DC application time.
Definition: rtdm-ioctl.c:2555
ec_slave_t * next_slave
Connected slaves.
Definition: slave.h:142
ec_direction_t dir
Direction.
Definition: reg_request.h:52
static ATTRIBUTES int ec_ioctl_slave_foe_read(ec_master_t *master, void *arg)
Read a file from a slave via FoE.
Definition: rtdm-ioctl.c:4975
uint32_t vendor_id
Slave vendor ID.
Definition: slave_config.h:125
uint32_t receive_time
Port receive times for delay measurement.
Definition: slave.h:143
uint8_t tx_frame_number
number of the transmitted frame
Definition: ethernet.h:101
uint8_t max_subindex
Maximum subindex.
Definition: sdo.h:55
void ec_master_reboot_slaves(ec_master_t *master)
Requests that all slaves on this master be rebooted (if supported).
Definition: master.c:1067
static ATTRIBUTES int ec_ioctl_sc_emerg_size(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Set the emergency ring buffer size.
Definition: rtdm-ioctl.c:3320
void ec_master_internal_send_cb(void *cb_data)
Internal sending callback.
Definition: master.c:678
char * image
Image name.
Definition: slave.h:181
ec_pdo_list_t pdos
Current PDO assignment.
Definition: sync.h:53
uint32_t rx_counter
octets received during last second
Definition: ethernet.h:90
static ATTRIBUTES int ec_ioctl_sc_idn(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configures an IDN.
Definition: rtdm-ioctl.c:3723
u64 app_time
Time of the last ecrt_master_sync() call.
Definition: master.h:249
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:436
uint16_t physical_start_address
Physical start address.
Definition: sync.h:49
uint8_t base_dc_supported
Distributed clocks are supported.
Definition: slave.h:257
u64 rx_count
Number of frames received.
Definition: master.h:166
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:670
void ecrt_master_deactivate(ec_master_t *master)
Deactivates the master.
Definition: master.c:2926
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:682
unsigned int ec_master_count(void)
Get the number of masters.
Definition: module.c:218
void ec_reg_request_clear(ec_reg_request_t *reg)
Register request destructor.
Definition: reg_request.c:73
static ATTRIBUTES int ec_ioctl_slave_sii_read(ec_master_t *master, void *arg)
Read a slave&#39;s SII.
Definition: rtdm-ioctl.c:1099
static ATTRIBUTES int ec_ioctl_slave_sync_pdo_entry(ec_master_t *master, void *arg)
Get slave sync manager PDO entry information.
Definition: rtdm-ioctl.c:471
char * group
Group name.
Definition: slave.h:180
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:643
unsigned int tries
Tries.
Definition: ethernet.h:108
static ATTRIBUTES int ec_ioctl_foe_request_data(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Read FoE data.
Definition: rtdm-ioctl.c:4405
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:3794
static ATTRIBUTES int ec_ioctl_reg_request_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts an register write operation.
Definition: rtdm-ioctl.c:4538
static ATTRIBUTES int ec_ioctl_sc_sync(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Configure a sync manager.
Definition: rtdm-ioctl.c:2845
EtherCAT slave configuration.
Definition: slave_config.h:118
static ATTRIBUTES int ec_ioctl_sc_reg_pdo_entry(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Registers a PDO entry.
Definition: rtdm-ioctl.c:3124
static ATTRIBUTES int ec_ioctl_send(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Send frames.
Definition: rtdm-ioctl.c:2393
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
unsigned long pcap_size
Pcap buffer size in bytes.
Definition: module.c:67
struct net_device * dev
pointer to the assigned net_device
Definition: device.h:93
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: rtdm-ioctl.c:3685
EtherCAT master character device IOCTL commands.
Request was processed successfully.
Definition: ecrt.h:540
EtherCAT slave configuration structure.
ec_sii_t sii
Extracted SII data.
Definition: slave.h:207
uint16_t idn
Sercos ID-Number.
Definition: soe_request.h:51
uint8_t write_access[EC_SDO_ENTRY_ACCESS_COUNT]
Write access.
Definition: sdo_entry.h:61
FoE request.
Definition: foe_request.h:50
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:3107
ec_device_index_t device_index
Index of device the slave responds on.
Definition: slave.h:217
uint8_t * ecrt_reg_request_data(ec_reg_request_t *reg)
Access to the register request&#39;s data.
Definition: reg_request.c:86
static ATTRIBUTES int ec_ioctl_voe_send_header(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Sets the VoE send header.
Definition: rtdm-ioctl.c:4677
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:3351
static ATTRIBUTES int ec_ioctl_voe_write(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Starts a VoE write operation.
Definition: rtdm-ioctl.c:4844
unsigned int index
Index.
Definition: master.h:203
unsigned int ec_master_config_count(const ec_master_t *master)
Get the number of slave configurations provided by the application.
Definition: master.c:2294
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
Reads the state of a domain.
Definition: domain.c:752
void ecrt_master_64bit_reference_clock_time_queue(ec_master_t *master)
Queues the 64bit dc reference slave clock time value datagram for sending.
Definition: master.c:3407
static ATTRIBUTES int ec_ioctl_sc_create_voe_handler(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a VoE handler.
Definition: rtdm-ioctl.c:3635
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.
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:723
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:161
void ecrt_domain_process(ec_domain_t *domain)
Determines the states of the domain&#39;s datagrams.
Definition: domain.c:534
static ATTRIBUTES int ec_ioctl_slave_foe_write(ec_master_t *master, void *arg)
Write a file to a slave via FoE.
Definition: rtdm-ioctl.c:5072
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:3543
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:71
static ATTRIBUTES int ec_ioctl_deactivate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Deactivates the master.
Definition: rtdm-ioctl.c:2342
ec_fsm_master_t fsm
Master state machine.
Definition: master.h:229
size_t nwords
Size of the SII contents in words.
Definition: slave.h:205
u64 rx_bytes
Number of bytes received.
Definition: master.h:171
Access rights in PREOP.
Definition: globals.h:228
void ecrt_domain_queue(ec_domain_t *domain)
(Re-)queues all domain datagrams in the master&#39;s datagram queue.
Definition: domain.c:722
static ATTRIBUTES int ec_ioctl_eoe_handler(ec_master_t *master, void *arg)
Get EoE handler information.
Definition: rtdm-ioctl.c:1802
uint8_t scan_required
Scan required.
Definition: slave.h:270
static ATTRIBUTES int ec_ioctl_slave_dict_upload(ec_master_t *master, void *arg)
Upload Dictionary.
Definition: rtdm-ioctl.c:5254
#define EC_COE_EMERGENCY_MSG_SIZE
Size of a CoE emergency message in byte.
Definition: ecrt.h:234
unsigned int error_flag
Stop processing after an error.
Definition: slave.h:239
ec_sync_t * syncs
SYNC MANAGER categories.
Definition: slave.h:190
static ATTRIBUTES int ec_ioctl_create_domain(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a domain.
Definition: rtdm-ioctl.c:2034
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
Definition: slave.h:171
unsigned int rx_idle
Idle flag.
Definition: ethernet.h:92
EtherCAT master.
Definition: master.h:202
struct list_head list
List item.
Definition: reg_request.h:49
struct list_head eoe_requests
EoE set IP parameter requests.
Definition: slave.h:278
void ecrt_master_sync_reference_clock(ec_master_t *master)
Queues the DC reference clock drift compensation datagram for sending.
Definition: master.c:3374
static ATTRIBUTES int ec_ioctl_slave_state(ec_master_t *master, void *arg)
Set slave state.
Definition: rtdm-ioctl.c:795
static ATTRIBUTES int ec_ioctl_activate(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Activates the master.
Definition: rtdm-ioctl.c:2231
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
Definition: ecrt.h:208
ec_device_t devices[EC_MAX_NUM_DEVICES]
EtherCAT devices.
Definition: master.h:219
u64 tx_bytes
Number of bytes sent.
Definition: device.h:114
static ATTRIBUTES int ec_ioctl_sc_create_reg_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create a register request.
Definition: rtdm-ioctl.c:3581
#define EC_SYNC_SIGNAL_COUNT
Number of DC sync signals.
Definition: globals.h:136
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:243
struct list_head list
List item.
Definition: eoe_request.h:50
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:57
char * name
Slave name.
Definition: slave.h:183
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:1052
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
EtherCAT domain.
Definition: domain.h:54
void(* send_cb)(void *)
Current send datagrams callback.
Definition: master.h:325
struct net_device * dev
net_device for virtual ethernet device
Definition: ethernet.h:79
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: rtdm-ioctl.c:4028
uint32_t vendor_id
Vendor ID.
Definition: slave.h:160
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:145
unsigned int queue_datagram
the datagram is ready for queuing
Definition: ethernet.h:77
void ecrt_sdo_request_index(ec_sdo_request_t *req, uint16_t index, uint8_t subindex)
Set the SDO index and subindex and prepare for non-complete-access.
Definition: sdo_request.c:187
ec_slave_t * dc_ref_clock
DC reference clock slave.
Definition: master.h:262
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:584
ec_master_t * master
EtherCAT master owning the domain.
Definition: domain.h:57
ec_internal_request_state_t state
FoE request state.
Definition: foe_request.h:64
unsigned int has_general
General category present.
Definition: slave.h:179
int ecrt_master_rt_slave_requests(ec_master_t *master, unsigned int rt_slave_requests)
Selects whether to process slave requests by the application or the master.
Definition: master.c:3954
void ecrt_master_receive(ec_master_t *master)
Fetches received frames from the hardware and processes the datagrams.
Definition: master.c:3035
static ATTRIBUTES int ec_ioctl_sc_create_foe_request(ec_master_t *master, void *arg, ec_ioctl_context_t *ctx)
Create an FoE request.
Definition: rtdm-ioctl.c:3531
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:426