00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00037
00038
00039 #include <linux/module.h>
00040 #include <linux/kernel.h>
00041 #include <linux/string.h>
00042 #include <linux/slab.h>
00043 #include <linux/delay.h>
00044 #include <linux/device.h>
00045 #include <linux/version.h>
00046 #include <linux/hrtimer.h>
00047 #include "globals.h"
00048 #include "slave.h"
00049 #include "slave_config.h"
00050 #include "device.h"
00051 #include "datagram.h"
00052 #ifdef EC_EOE
00053 #include "ethernet.h"
00054 #endif
00055 #include "master.h"
00056
00057
00058
00061 #define DEBUG_INJECT 0
00062
00065 #define FORCE_OUTPUT_CORRUPTED 0
00066
00067 #ifdef EC_HAVE_CYCLES
00068
00071 static cycles_t timeout_cycles;
00072
00075 static cycles_t ext_injection_timeout_cycles;
00076
00077 #else
00078
00081 static unsigned long timeout_jiffies;
00082
00085 static unsigned long ext_injection_timeout_jiffies;
00086
00087 #endif
00088
00091 const unsigned int rate_intervals[] = {
00092 1, 10, 60
00093 };
00094
00095
00096
00097 void ec_master_clear_slave_configs(ec_master_t *);
00098 void ec_master_clear_domains(ec_master_t *);
00099 static int ec_master_idle_thread(void *);
00100 static int ec_master_operation_thread(void *);
00101 #ifdef EC_EOE
00102 static int ec_master_eoe_thread(void *);
00103 #endif
00104 void ec_master_find_dc_ref_clock(ec_master_t *);
00105 void ec_master_clear_device_stats(ec_master_t *);
00106 void ec_master_update_device_stats(ec_master_t *);
00107
00108
00109
00112 void ec_master_init_static(void)
00113 {
00114 #ifdef EC_HAVE_CYCLES
00115 timeout_cycles = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000);
00116 ext_injection_timeout_cycles =
00117 (cycles_t) EC_SDO_INJECTION_TIMEOUT * (cpu_khz / 1000);
00118 #else
00119
00120 timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1);
00121 ext_injection_timeout_jiffies =
00122 max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1);
00123 #endif
00124 }
00125
00126
00127
00133 int ec_master_init(ec_master_t *master,
00134 unsigned int index,
00135 const uint8_t *main_mac,
00136 const uint8_t *backup_mac,
00137 dev_t device_number,
00138 struct class *class,
00139 unsigned int debug_level
00140 )
00141 {
00142 int ret;
00143 unsigned int dev_idx, i;
00144
00145 master->index = index;
00146 master->reserved = 0;
00147
00148 sema_init(&master->master_sem, 1);
00149
00150 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_MAX_NUM_DEVICES; dev_idx++) {
00151 master->macs[dev_idx] = NULL;
00152 }
00153
00154 master->macs[EC_DEVICE_MAIN] = main_mac;
00155
00156 #if EC_MAX_NUM_DEVICES > 1
00157 master->macs[EC_DEVICE_BACKUP] = backup_mac;
00158 master->num_devices = 1 + !ec_mac_is_zero(backup_mac);
00159 #else
00160 if (!ec_mac_is_zero(backup_mac)) {
00161 EC_MASTER_WARN(master, "Ignoring backup MAC address!");
00162 }
00163 #endif
00164
00165 ec_master_clear_device_stats(master);
00166
00167 sema_init(&master->device_sem, 1);
00168
00169 master->phase = EC_ORPHANED;
00170 master->active = 0;
00171 master->config_changed = 0;
00172 master->injection_seq_fsm = 0;
00173 master->injection_seq_rt = 0;
00174
00175 master->slaves = NULL;
00176 master->slave_count = 0;
00177
00178 INIT_LIST_HEAD(&master->configs);
00179 INIT_LIST_HEAD(&master->domains);
00180
00181 master->app_time = 0ULL;
00182 master->app_start_time = 0ULL;
00183 master->has_app_time = 0;
00184
00185 master->scan_busy = 0;
00186 master->allow_scan = 1;
00187 sema_init(&master->scan_sem, 1);
00188 init_waitqueue_head(&master->scan_queue);
00189
00190 master->config_busy = 0;
00191 sema_init(&master->config_sem, 1);
00192 init_waitqueue_head(&master->config_queue);
00193
00194 INIT_LIST_HEAD(&master->datagram_queue);
00195 master->datagram_index = 0;
00196
00197 INIT_LIST_HEAD(&master->ext_datagram_queue);
00198 sema_init(&master->ext_queue_sem, 1);
00199
00200 master->ext_ring_idx_rt = 0;
00201 master->ext_ring_idx_fsm = 0;
00202
00203
00204 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
00205 ec_datagram_t *datagram = &master->ext_datagram_ring[i];
00206 ec_datagram_init(datagram);
00207 snprintf(datagram->name, EC_DATAGRAM_NAME_SIZE, "ext-%u", i);
00208 }
00209
00210
00211 ec_master_set_send_interval(master, 1000000 / HZ);
00212
00213 master->fsm_slave = NULL;
00214 INIT_LIST_HEAD(&master->fsm_exec_list);
00215 master->fsm_exec_count = 0U;
00216
00217 master->debug_level = debug_level;
00218 master->stats.timeouts = 0;
00219 master->stats.corrupted = 0;
00220 master->stats.unmatched = 0;
00221 master->stats.output_jiffies = 0;
00222
00223 master->thread = NULL;
00224
00225 #ifdef EC_EOE
00226 master->eoe_thread = NULL;
00227 INIT_LIST_HEAD(&master->eoe_handlers);
00228 #endif
00229
00230 sema_init(&master->io_sem, 1);
00231 master->send_cb = NULL;
00232 master->receive_cb = NULL;
00233 master->cb_data = NULL;
00234 master->app_send_cb = NULL;
00235 master->app_receive_cb = NULL;
00236 master->app_cb_data = NULL;
00237
00238 INIT_LIST_HEAD(&master->sii_requests);
00239 INIT_LIST_HEAD(&master->emerg_reg_requests);
00240
00241 init_waitqueue_head(&master->request_queue);
00242
00243
00244 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
00245 dev_idx++) {
00246 ret = ec_device_init(&master->devices[dev_idx], master);
00247 if (ret < 0) {
00248 goto out_clear_devices;
00249 }
00250 }
00251
00252
00253 ec_datagram_init(&master->fsm_datagram);
00254 snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
00255 ret = ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE);
00256 if (ret < 0) {
00257 ec_datagram_clear(&master->fsm_datagram);
00258 EC_MASTER_ERR(master, "Failed to allocate FSM datagram.\n");
00259 goto out_clear_devices;
00260 }
00261
00262
00263 ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
00264
00265
00266 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
00267 ec_datagram_t *datagram = &master->ext_datagram_ring[i];
00268 ret = ec_datagram_prealloc(datagram, EC_MAX_DATA_SIZE);
00269 if (ret) {
00270 EC_MASTER_ERR(master, "Failed to allocate external"
00271 " datagram %u.\n", i);
00272 goto out_clear_ext_datagrams;
00273 }
00274 }
00275
00276
00277 ec_datagram_init(&master->ref_sync_datagram);
00278 snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE,
00279 "refsync");
00280 ret = ec_datagram_prealloc(&master->ref_sync_datagram, 4);
00281 if (ret < 0) {
00282 ec_datagram_clear(&master->ref_sync_datagram);
00283 EC_MASTER_ERR(master, "Failed to allocate reference"
00284 " synchronisation datagram.\n");
00285 goto out_clear_ext_datagrams;
00286 }
00287
00288
00289 ec_datagram_init(&master->sync_datagram);
00290 snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync");
00291 ret = ec_datagram_prealloc(&master->sync_datagram, 4);
00292 if (ret < 0) {
00293 ec_datagram_clear(&master->sync_datagram);
00294 EC_MASTER_ERR(master, "Failed to allocate"
00295 " synchronisation datagram.\n");
00296 goto out_clear_ref_sync;
00297 }
00298
00299
00300 ec_datagram_init(&master->sync_mon_datagram);
00301 snprintf(master->sync_mon_datagram.name, EC_DATAGRAM_NAME_SIZE,
00302 "syncmon");
00303 ret = ec_datagram_brd(&master->sync_mon_datagram, 0x092c, 4);
00304 if (ret < 0) {
00305 ec_datagram_clear(&master->sync_mon_datagram);
00306 EC_MASTER_ERR(master, "Failed to allocate sync"
00307 " monitoring datagram.\n");
00308 goto out_clear_sync;
00309 }
00310
00311 master->dc_ref_config = NULL;
00312 master->dc_ref_clock = NULL;
00313
00314
00315 ret = ec_cdev_init(&master->cdev, master, device_number);
00316 if (ret)
00317 goto out_clear_sync_mon;
00318
00319 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
00320 master->class_device = device_create(class, NULL,
00321 MKDEV(MAJOR(device_number), master->index), NULL,
00322 "EtherCAT%u", master->index);
00323 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
00324 master->class_device = device_create(class, NULL,
00325 MKDEV(MAJOR(device_number), master->index),
00326 "EtherCAT%u", master->index);
00327 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15)
00328 master->class_device = class_device_create(class, NULL,
00329 MKDEV(MAJOR(device_number), master->index), NULL,
00330 "EtherCAT%u", master->index);
00331 #else
00332 master->class_device = class_device_create(class,
00333 MKDEV(MAJOR(device_number), master->index), NULL,
00334 "EtherCAT%u", master->index);
00335 #endif
00336 if (IS_ERR(master->class_device)) {
00337 EC_MASTER_ERR(master, "Failed to create class device!\n");
00338 ret = PTR_ERR(master->class_device);
00339 goto out_clear_cdev;
00340 }
00341
00342 #ifdef EC_RTDM
00343
00344 ret = ec_rtdm_dev_init(&master->rtdm_dev, master);
00345 if (ret) {
00346 goto out_unregister_class_device;
00347 }
00348 #endif
00349
00350 return 0;
00351
00352 #ifdef EC_RTDM
00353 out_unregister_class_device:
00354 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
00355 device_unregister(master->class_device);
00356 #else
00357 class_device_unregister(master->class_device);
00358 #endif
00359 #endif
00360 out_clear_cdev:
00361 ec_cdev_clear(&master->cdev);
00362 out_clear_sync_mon:
00363 ec_datagram_clear(&master->sync_mon_datagram);
00364 out_clear_sync:
00365 ec_datagram_clear(&master->sync_datagram);
00366 out_clear_ref_sync:
00367 ec_datagram_clear(&master->ref_sync_datagram);
00368 out_clear_ext_datagrams:
00369 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
00370 ec_datagram_clear(&master->ext_datagram_ring[i]);
00371 }
00372 ec_fsm_master_clear(&master->fsm);
00373 ec_datagram_clear(&master->fsm_datagram);
00374 out_clear_devices:
00375 for (; dev_idx > 0; dev_idx--) {
00376 ec_device_clear(&master->devices[dev_idx - 1]);
00377 }
00378 return ret;
00379 }
00380
00381
00382
00385 void ec_master_clear(
00386 ec_master_t *master
00387 )
00388 {
00389 unsigned int dev_idx, i;
00390
00391 #ifdef EC_RTDM
00392 ec_rtdm_dev_clear(&master->rtdm_dev);
00393 #endif
00394
00395 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
00396 device_unregister(master->class_device);
00397 #else
00398 class_device_unregister(master->class_device);
00399 #endif
00400
00401 ec_cdev_clear(&master->cdev);
00402
00403 #ifdef EC_EOE
00404 ec_master_clear_eoe_handlers(master);
00405 #endif
00406 ec_master_clear_domains(master);
00407 ec_master_clear_slave_configs(master);
00408 ec_master_clear_slaves(master);
00409
00410 ec_datagram_clear(&master->sync_mon_datagram);
00411 ec_datagram_clear(&master->sync_datagram);
00412 ec_datagram_clear(&master->ref_sync_datagram);
00413
00414 for (i = 0; i < EC_EXT_RING_SIZE; i++) {
00415 ec_datagram_clear(&master->ext_datagram_ring[i]);
00416 }
00417
00418 ec_fsm_master_clear(&master->fsm);
00419 ec_datagram_clear(&master->fsm_datagram);
00420
00421 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
00422 dev_idx++) {
00423 ec_device_clear(&master->devices[dev_idx]);
00424 }
00425 }
00426
00427
00428
00429 #ifdef EC_EOE
00430
00432 void ec_master_clear_eoe_handlers(
00433 ec_master_t *master
00434 )
00435 {
00436 ec_eoe_t *eoe, *next;
00437
00438 list_for_each_entry_safe(eoe, next, &master->eoe_handlers, list) {
00439 list_del(&eoe->list);
00440 ec_eoe_clear(eoe);
00441 kfree(eoe);
00442 }
00443 }
00444 #endif
00445
00446
00447
00450 void ec_master_clear_slave_configs(ec_master_t *master)
00451 {
00452 ec_slave_config_t *sc, *next;
00453
00454 master->dc_ref_config = NULL;
00455 master->fsm.sdo_request = NULL;
00456
00457 list_for_each_entry_safe(sc, next, &master->configs, list) {
00458 list_del(&sc->list);
00459 ec_slave_config_clear(sc);
00460 kfree(sc);
00461 }
00462 }
00463
00464
00465
00468 void ec_master_clear_slaves(ec_master_t *master)
00469 {
00470 ec_slave_t *slave;
00471
00472 master->dc_ref_clock = NULL;
00473
00474
00475
00476
00477 while (!list_empty(&master->sii_requests)) {
00478 ec_sii_write_request_t *request =
00479 list_entry(master->sii_requests.next,
00480 ec_sii_write_request_t, list);
00481 list_del_init(&request->list);
00482 EC_MASTER_WARN(master, "Discarding SII request, slave %u about"
00483 " to be deleted.\n", request->slave->ring_position);
00484 request->state = EC_INT_REQUEST_FAILURE;
00485 wake_up_all(&master->request_queue);
00486 }
00487
00488 master->fsm_slave = NULL;
00489 INIT_LIST_HEAD(&master->fsm_exec_list);
00490 master->fsm_exec_count = 0;
00491
00492 for (slave = master->slaves;
00493 slave < master->slaves + master->slave_count;
00494 slave++) {
00495 ec_slave_clear(slave);
00496 }
00497
00498 if (master->slaves) {
00499 kfree(master->slaves);
00500 master->slaves = NULL;
00501 }
00502
00503 master->slave_count = 0;
00504 }
00505
00506
00507
00510 void ec_master_clear_domains(ec_master_t *master)
00511 {
00512 ec_domain_t *domain, *next;
00513
00514 list_for_each_entry_safe(domain, next, &master->domains, list) {
00515 list_del(&domain->list);
00516 ec_domain_clear(domain);
00517 kfree(domain);
00518 }
00519 }
00520
00521
00522
00525 void ec_master_clear_config(
00526 ec_master_t *master
00527 )
00528 {
00529 down(&master->master_sem);
00530 ec_master_clear_domains(master);
00531 ec_master_clear_slave_configs(master);
00532 up(&master->master_sem);
00533 }
00534
00535
00536
00539 void ec_master_internal_send_cb(
00540 void *cb_data
00541 )
00542 {
00543 ec_master_t *master = (ec_master_t *) cb_data;
00544 down(&master->io_sem);
00545 ecrt_master_send_ext(master);
00546 up(&master->io_sem);
00547 }
00548
00549
00550
00553 void ec_master_internal_receive_cb(
00554 void *cb_data
00555 )
00556 {
00557 ec_master_t *master = (ec_master_t *) cb_data;
00558 down(&master->io_sem);
00559 ecrt_master_receive(master);
00560 up(&master->io_sem);
00561 }
00562
00563
00564
00570 int ec_master_thread_start(
00571 ec_master_t *master,
00572 int (*thread_func)(void *),
00573 const char *name
00574 )
00575 {
00576 EC_MASTER_INFO(master, "Starting %s thread.\n", name);
00577 master->thread = kthread_run(thread_func, master, name);
00578 if (IS_ERR(master->thread)) {
00579 int err = (int) PTR_ERR(master->thread);
00580 EC_MASTER_ERR(master, "Failed to start master thread (error %i)!\n",
00581 err);
00582 master->thread = NULL;
00583 return err;
00584 }
00585
00586 return 0;
00587 }
00588
00589
00590
00593 void ec_master_thread_stop(
00594 ec_master_t *master
00595 )
00596 {
00597 unsigned long sleep_jiffies;
00598
00599 if (!master->thread) {
00600 EC_MASTER_WARN(master, "%s(): Already finished!\n", __func__);
00601 return;
00602 }
00603
00604 EC_MASTER_DBG(master, 1, "Stopping master thread.\n");
00605
00606 kthread_stop(master->thread);
00607 master->thread = NULL;
00608 EC_MASTER_INFO(master, "Master thread exited.\n");
00609
00610 if (master->fsm_datagram.state != EC_DATAGRAM_SENT) {
00611 return;
00612 }
00613
00614
00615 sleep_jiffies = max(HZ / 100, 1);
00616 schedule_timeout(sleep_jiffies);
00617 }
00618
00619
00620
00625 int ec_master_enter_idle_phase(
00626 ec_master_t *master
00627 )
00628 {
00629 int ret;
00630 ec_device_index_t dev_idx;
00631
00632 EC_MASTER_DBG(master, 1, "ORPHANED -> IDLE.\n");
00633
00634 master->send_cb = ec_master_internal_send_cb;
00635 master->receive_cb = ec_master_internal_receive_cb;
00636 master->cb_data = master;
00637
00638 master->phase = EC_IDLE;
00639
00640
00641 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
00642 dev_idx++) {
00643 master->fsm.slaves_responding[dev_idx] = 0;
00644 }
00645
00646 ret = ec_master_thread_start(master, ec_master_idle_thread,
00647 "EtherCAT-IDLE");
00648 if (ret)
00649 master->phase = EC_ORPHANED;
00650
00651 return ret;
00652 }
00653
00654
00655
00658 void ec_master_leave_idle_phase(ec_master_t *master )
00659 {
00660 EC_MASTER_DBG(master, 1, "IDLE -> ORPHANED.\n");
00661
00662 master->phase = EC_ORPHANED;
00663
00664 #ifdef EC_EOE
00665 ec_master_eoe_stop(master);
00666 #endif
00667 ec_master_thread_stop(master);
00668
00669 down(&master->master_sem);
00670 ec_master_clear_slaves(master);
00671 up(&master->master_sem);
00672
00673 ec_fsm_master_reset(&master->fsm);
00674 }
00675
00676
00677
00682 int ec_master_enter_operation_phase(
00683 ec_master_t *master
00684 )
00685 {
00686 int ret = 0;
00687 ec_slave_t *slave;
00688 #ifdef EC_EOE
00689 ec_eoe_t *eoe;
00690 #endif
00691
00692 EC_MASTER_DBG(master, 1, "IDLE -> OPERATION.\n");
00693
00694 down(&master->config_sem);
00695 if (master->config_busy) {
00696 up(&master->config_sem);
00697
00698
00699 ret = wait_event_interruptible(master->config_queue,
00700 !master->config_busy);
00701 if (ret) {
00702 EC_MASTER_INFO(master, "Finishing slave configuration"
00703 " interrupted by signal.\n");
00704 goto out_return;
00705 }
00706
00707 EC_MASTER_DBG(master, 1, "Waiting for pending slave"
00708 " configuration returned.\n");
00709 } else {
00710 up(&master->config_sem);
00711 }
00712
00713 down(&master->scan_sem);
00714 master->allow_scan = 0;
00715 if (!master->scan_busy) {
00716 up(&master->scan_sem);
00717 } else {
00718 up(&master->scan_sem);
00719
00720
00721 ret = wait_event_interruptible(master->scan_queue,
00722 !master->scan_busy);
00723 if (ret) {
00724 EC_MASTER_INFO(master, "Waiting for slave scan"
00725 " interrupted by signal.\n");
00726 goto out_allow;
00727 }
00728
00729 EC_MASTER_DBG(master, 1, "Waiting for pending"
00730 " slave scan returned.\n");
00731 }
00732
00733
00734 for (slave = master->slaves;
00735 slave < master->slaves + master->slave_count;
00736 slave++) {
00737 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
00738 }
00739
00740 #ifdef EC_EOE
00741
00742 list_for_each_entry(eoe, &master->eoe_handlers, list) {
00743 if (ec_eoe_is_open(eoe))
00744 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
00745 }
00746 #endif
00747
00748 master->phase = EC_OPERATION;
00749 master->app_send_cb = NULL;
00750 master->app_receive_cb = NULL;
00751 master->app_cb_data = NULL;
00752 return ret;
00753
00754 out_allow:
00755 master->allow_scan = 1;
00756 out_return:
00757 return ret;
00758 }
00759
00760
00761
00764 void ec_master_leave_operation_phase(
00765 ec_master_t *master
00766 )
00767 {
00768 if (master->active) {
00769 ecrt_master_deactivate(master);
00770 } else {
00771 ec_master_clear_config(master);
00772 }
00773
00774
00775 master->allow_scan = 1;
00776
00777 EC_MASTER_DBG(master, 1, "OPERATION -> IDLE.\n");
00778
00779 master->phase = EC_IDLE;
00780 }
00781
00782
00783
00786 void ec_master_inject_external_datagrams(
00787 ec_master_t *master
00788 )
00789 {
00790 ec_datagram_t *datagram;
00791 size_t queue_size = 0, new_queue_size = 0;
00792 #if DEBUG_INJECT
00793 unsigned int datagram_count = 0;
00794 #endif
00795
00796 if (master->ext_ring_idx_rt == master->ext_ring_idx_fsm) {
00797
00798 return;
00799 }
00800
00801 list_for_each_entry(datagram, &master->datagram_queue, queue) {
00802 if (datagram->state == EC_DATAGRAM_QUEUED) {
00803 queue_size += datagram->data_size;
00804 }
00805 }
00806
00807 #if DEBUG_INJECT
00808 EC_MASTER_DBG(master, 1, "Injecting datagrams, queue_size=%zu\n",
00809 queue_size);
00810 #endif
00811
00812 while (master->ext_ring_idx_rt != master->ext_ring_idx_fsm) {
00813 datagram = &master->ext_datagram_ring[master->ext_ring_idx_rt];
00814
00815 if (datagram->state != EC_DATAGRAM_INIT) {
00816
00817 master->ext_ring_idx_rt =
00818 (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
00819 continue;
00820 }
00821
00822 new_queue_size = queue_size + datagram->data_size;
00823 if (new_queue_size <= master->max_queue_size) {
00824 #if DEBUG_INJECT
00825 EC_MASTER_DBG(master, 1, "Injecting datagram %s"
00826 " size=%zu, queue_size=%zu\n", datagram->name,
00827 datagram->data_size, new_queue_size);
00828 datagram_count++;
00829 #endif
00830 #ifdef EC_HAVE_CYCLES
00831 datagram->cycles_sent = 0;
00832 #endif
00833 datagram->jiffies_sent = 0;
00834 ec_master_queue_datagram(master, datagram);
00835 queue_size = new_queue_size;
00836 }
00837 else if (datagram->data_size > master->max_queue_size) {
00838 datagram->state = EC_DATAGRAM_ERROR;
00839 EC_MASTER_ERR(master, "External datagram %s is too large,"
00840 " size=%zu, max_queue_size=%zu\n",
00841 datagram->name, datagram->data_size,
00842 master->max_queue_size);
00843 }
00844 else {
00845 #ifdef EC_HAVE_CYCLES
00846 cycles_t cycles_now = get_cycles();
00847
00848 if (cycles_now - datagram->cycles_sent
00849 > ext_injection_timeout_cycles)
00850 #else
00851 if (jiffies - datagram->jiffies_sent
00852 > ext_injection_timeout_jiffies)
00853 #endif
00854 {
00855 #if defined EC_RT_SYSLOG || DEBUG_INJECT
00856 unsigned int time_us;
00857 #endif
00858
00859 datagram->state = EC_DATAGRAM_ERROR;
00860
00861 #if defined EC_RT_SYSLOG || DEBUG_INJECT
00862 #ifdef EC_HAVE_CYCLES
00863 time_us = (unsigned int)
00864 ((cycles_now - datagram->cycles_sent) * 1000LL)
00865 / cpu_khz;
00866 #else
00867 time_us = (unsigned int)
00868 ((jiffies - datagram->jiffies_sent) * 1000000 / HZ);
00869 #endif
00870 EC_MASTER_ERR(master, "Timeout %u us: Injecting"
00871 " external datagram %s size=%zu,"
00872 " max_queue_size=%zu\n", time_us, datagram->name,
00873 datagram->data_size, master->max_queue_size);
00874 #endif
00875 }
00876 else {
00877 #if DEBUG_INJECT
00878 EC_MASTER_DBG(master, 1, "Deferred injecting"
00879 " external datagram %s size=%u, queue_size=%u\n",
00880 datagram->name, datagram->data_size, queue_size);
00881 #endif
00882 break;
00883 }
00884 }
00885
00886 master->ext_ring_idx_rt =
00887 (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
00888 }
00889
00890 #if DEBUG_INJECT
00891 EC_MASTER_DBG(master, 1, "Injected %u datagrams.\n", datagram_count);
00892 #endif
00893 }
00894
00895
00896
00900 void ec_master_set_send_interval(
00901 ec_master_t *master,
00902 unsigned int send_interval
00903 )
00904 {
00905 master->send_interval = send_interval;
00906 master->max_queue_size =
00907 (send_interval * 1000) / EC_BYTE_TRANSMISSION_TIME_NS;
00908 master->max_queue_size -= master->max_queue_size / 10;
00909 }
00910
00911
00912
00917 ec_datagram_t *ec_master_get_external_datagram(
00918 ec_master_t *master
00919 )
00920 {
00921 if ((master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE !=
00922 master->ext_ring_idx_rt) {
00923 ec_datagram_t *datagram =
00924 &master->ext_datagram_ring[master->ext_ring_idx_fsm];
00925 return datagram;
00926 }
00927 else {
00928 return NULL;
00929 }
00930 }
00931
00932
00933
00936 void ec_master_queue_datagram(
00937 ec_master_t *master,
00938 ec_datagram_t *datagram
00939 )
00940 {
00941 ec_datagram_t *queued_datagram;
00942
00943
00944
00945
00946
00947
00948
00949 list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
00950 if (queued_datagram == datagram) {
00951 datagram->skip_count++;
00952 #ifdef EC_RT_SYSLOG
00953 EC_MASTER_DBG(master, 1,
00954 "Datagram %p already queued (skipping).\n", datagram);
00955 #endif
00956 datagram->state = EC_DATAGRAM_QUEUED;
00957 return;
00958 }
00959 }
00960
00961 list_add_tail(&datagram->queue, &master->datagram_queue);
00962 datagram->state = EC_DATAGRAM_QUEUED;
00963 }
00964
00965
00966
00969 void ec_master_queue_datagram_ext(
00970 ec_master_t *master,
00971 ec_datagram_t *datagram
00972 )
00973 {
00974 down(&master->ext_queue_sem);
00975 list_add_tail(&datagram->queue, &master->ext_datagram_queue);
00976 up(&master->ext_queue_sem);
00977 }
00978
00979
00980
00984 void ec_master_send_datagrams(
00985 ec_master_t *master,
00986 ec_device_index_t device_index
00987 )
00988 {
00989 ec_datagram_t *datagram, *next;
00990 size_t datagram_size;
00991 uint8_t *frame_data, *cur_data = NULL;
00992 void *follows_word;
00993 #ifdef EC_HAVE_CYCLES
00994 cycles_t cycles_start, cycles_sent, cycles_end;
00995 #endif
00996 unsigned long jiffies_sent;
00997 unsigned int frame_count, more_datagrams_waiting;
00998 struct list_head sent_datagrams;
00999
01000 #ifdef EC_HAVE_CYCLES
01001 cycles_start = get_cycles();
01002 #endif
01003 frame_count = 0;
01004 INIT_LIST_HEAD(&sent_datagrams);
01005
01006 EC_MASTER_DBG(master, 2, "%s(device_index = %u)\n",
01007 __func__, device_index);
01008
01009 do {
01010 frame_data = NULL;
01011 follows_word = NULL;
01012 more_datagrams_waiting = 0;
01013
01014
01015 list_for_each_entry(datagram, &master->datagram_queue, queue) {
01016 if (datagram->state != EC_DATAGRAM_QUEUED ||
01017 datagram->device_index != device_index) {
01018 continue;
01019 }
01020
01021 if (!frame_data) {
01022
01023 frame_data =
01024 ec_device_tx_data(&master->devices[device_index]);
01025 cur_data = frame_data + EC_FRAME_HEADER_SIZE;
01026 }
01027
01028
01029 datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
01030 + EC_DATAGRAM_FOOTER_SIZE;
01031 if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
01032 more_datagrams_waiting = 1;
01033 break;
01034 }
01035
01036 list_add_tail(&datagram->sent, &sent_datagrams);
01037 datagram->index = master->datagram_index++;
01038
01039 EC_MASTER_DBG(master, 2, "Adding datagram 0x%02X\n",
01040 datagram->index);
01041
01042
01043 if (follows_word) {
01044 EC_WRITE_U16(follows_word,
01045 EC_READ_U16(follows_word) | 0x8000);
01046 }
01047
01048
01049 EC_WRITE_U8 (cur_data, datagram->type);
01050 EC_WRITE_U8 (cur_data + 1, datagram->index);
01051 memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
01052 EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
01053 EC_WRITE_U16(cur_data + 8, 0x0000);
01054 follows_word = cur_data + 6;
01055 cur_data += EC_DATAGRAM_HEADER_SIZE;
01056
01057
01058 memcpy(cur_data, datagram->data, datagram->data_size);
01059 cur_data += datagram->data_size;
01060
01061
01062 EC_WRITE_U16(cur_data, 0x0000);
01063 cur_data += EC_DATAGRAM_FOOTER_SIZE;
01064 }
01065
01066 if (list_empty(&sent_datagrams)) {
01067 EC_MASTER_DBG(master, 2, "nothing to send.\n");
01068 break;
01069 }
01070
01071
01072 EC_WRITE_U16(frame_data, ((cur_data - frame_data
01073 - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
01074
01075
01076 while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
01077 EC_WRITE_U8(cur_data++, 0x00);
01078
01079 EC_MASTER_DBG(master, 2, "frame size: %zu\n", cur_data - frame_data);
01080
01081
01082 ec_device_send(&master->devices[device_index],
01083 cur_data - frame_data);
01084 #ifdef EC_HAVE_CYCLES
01085 cycles_sent = get_cycles();
01086 #endif
01087 jiffies_sent = jiffies;
01088
01089
01090 list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
01091 datagram->state = EC_DATAGRAM_SENT;
01092 #ifdef EC_HAVE_CYCLES
01093 datagram->cycles_sent = cycles_sent;
01094 #endif
01095 datagram->jiffies_sent = jiffies_sent;
01096 list_del_init(&datagram->sent);
01097 }
01098
01099 frame_count++;
01100 }
01101 while (more_datagrams_waiting);
01102
01103 #ifdef EC_HAVE_CYCLES
01104 if (unlikely(master->debug_level > 1)) {
01105 cycles_end = get_cycles();
01106 EC_MASTER_DBG(master, 0, "%s()"
01107 " sent %u frames in %uus.\n", __func__, frame_count,
01108 (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
01109 }
01110 #endif
01111 }
01112
01113
01114
01121 void ec_master_receive_datagrams(
01122 ec_master_t *master,
01123 ec_device_t *device,
01124 const uint8_t *frame_data,
01125 size_t size
01126 )
01127 {
01128 size_t frame_size, data_size;
01129 uint8_t datagram_type, datagram_index;
01130 unsigned int cmd_follows, matched;
01131 const uint8_t *cur_data;
01132 ec_datagram_t *datagram;
01133
01134 if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
01135 if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
01136 EC_MASTER_DBG(master, 0, "Corrupted frame received"
01137 " on %s (size %zu < %u byte):\n",
01138 device->dev->name, size, EC_FRAME_HEADER_SIZE);
01139 ec_print_data(frame_data, size);
01140 }
01141 master->stats.corrupted++;
01142 #ifdef EC_RT_SYSLOG
01143 ec_master_output_stats(master);
01144 #endif
01145 return;
01146 }
01147
01148 cur_data = frame_data;
01149
01150
01151 frame_size = EC_READ_U16(cur_data) & 0x07FF;
01152 cur_data += EC_FRAME_HEADER_SIZE;
01153
01154 if (unlikely(frame_size > size)) {
01155 if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
01156 EC_MASTER_DBG(master, 0, "Corrupted frame received"
01157 " on %s (invalid frame size %zu for "
01158 "received size %zu):\n", device->dev->name,
01159 frame_size, size);
01160 ec_print_data(frame_data, size);
01161 }
01162 master->stats.corrupted++;
01163 #ifdef EC_RT_SYSLOG
01164 ec_master_output_stats(master);
01165 #endif
01166 return;
01167 }
01168
01169 cmd_follows = 1;
01170 while (cmd_follows) {
01171
01172 datagram_type = EC_READ_U8 (cur_data);
01173 datagram_index = EC_READ_U8 (cur_data + 1);
01174 data_size = EC_READ_U16(cur_data + 6) & 0x07FF;
01175 cmd_follows = EC_READ_U16(cur_data + 6) & 0x8000;
01176 cur_data += EC_DATAGRAM_HEADER_SIZE;
01177
01178 if (unlikely(cur_data - frame_data
01179 + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
01180 if (master->debug_level || FORCE_OUTPUT_CORRUPTED) {
01181 EC_MASTER_DBG(master, 0, "Corrupted frame received"
01182 " on %s (invalid data size %zu):\n",
01183 device->dev->name, data_size);
01184 ec_print_data(frame_data, size);
01185 }
01186 master->stats.corrupted++;
01187 #ifdef EC_RT_SYSLOG
01188 ec_master_output_stats(master);
01189 #endif
01190 return;
01191 }
01192
01193
01194 matched = 0;
01195 list_for_each_entry(datagram, &master->datagram_queue, queue) {
01196 if (datagram->index == datagram_index
01197 && datagram->state == EC_DATAGRAM_SENT
01198 && datagram->type == datagram_type
01199 && datagram->data_size == data_size) {
01200 matched = 1;
01201 break;
01202 }
01203 }
01204
01205
01206 if (!matched) {
01207 master->stats.unmatched++;
01208 #ifdef EC_RT_SYSLOG
01209 ec_master_output_stats(master);
01210 #endif
01211
01212 if (unlikely(master->debug_level > 0)) {
01213 EC_MASTER_DBG(master, 0, "UNMATCHED datagram:\n");
01214 ec_print_data(cur_data - EC_DATAGRAM_HEADER_SIZE,
01215 EC_DATAGRAM_HEADER_SIZE + data_size
01216 + EC_DATAGRAM_FOOTER_SIZE);
01217 #ifdef EC_DEBUG_RING
01218 ec_device_debug_ring_print(&master->devices[EC_DEVICE_MAIN]);
01219 #endif
01220 }
01221
01222 cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
01223 continue;
01224 }
01225
01226 if (datagram->type != EC_DATAGRAM_APWR &&
01227 datagram->type != EC_DATAGRAM_FPWR &&
01228 datagram->type != EC_DATAGRAM_BWR &&
01229 datagram->type != EC_DATAGRAM_LWR) {
01230
01231
01232 memcpy(datagram->data, cur_data, data_size);
01233 }
01234 cur_data += data_size;
01235
01236
01237 datagram->working_counter = EC_READ_U16(cur_data);
01238 cur_data += EC_DATAGRAM_FOOTER_SIZE;
01239
01240
01241 datagram->state = EC_DATAGRAM_RECEIVED;
01242 #ifdef EC_HAVE_CYCLES
01243 datagram->cycles_received =
01244 master->devices[EC_DEVICE_MAIN].cycles_poll;
01245 #endif
01246 datagram->jiffies_received =
01247 master->devices[EC_DEVICE_MAIN].jiffies_poll;
01248 list_del_init(&datagram->queue);
01249 }
01250 }
01251
01252
01253
01259 void ec_master_output_stats(ec_master_t *master )
01260 {
01261 if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) {
01262 master->stats.output_jiffies = jiffies;
01263
01264 if (master->stats.timeouts) {
01265 EC_MASTER_WARN(master, "%u datagram%s TIMED OUT!\n",
01266 master->stats.timeouts,
01267 master->stats.timeouts == 1 ? "" : "s");
01268 master->stats.timeouts = 0;
01269 }
01270 if (master->stats.corrupted) {
01271 EC_MASTER_WARN(master, "%u frame%s CORRUPTED!\n",
01272 master->stats.corrupted,
01273 master->stats.corrupted == 1 ? "" : "s");
01274 master->stats.corrupted = 0;
01275 }
01276 if (master->stats.unmatched) {
01277 EC_MASTER_WARN(master, "%u datagram%s UNMATCHED!\n",
01278 master->stats.unmatched,
01279 master->stats.unmatched == 1 ? "" : "s");
01280 master->stats.unmatched = 0;
01281 }
01282 }
01283 }
01284
01285
01286
01289 void ec_master_clear_device_stats(
01290 ec_master_t *master
01291 )
01292 {
01293 unsigned int i;
01294
01295
01296 master->device_stats.tx_count = 0;
01297 master->device_stats.last_tx_count = 0;
01298 master->device_stats.rx_count = 0;
01299 master->device_stats.last_rx_count = 0;
01300 master->device_stats.tx_bytes = 0;
01301 master->device_stats.last_tx_bytes = 0;
01302 master->device_stats.rx_bytes = 0;
01303 master->device_stats.last_rx_bytes = 0;
01304 master->device_stats.last_loss = 0;
01305
01306 for (i = 0; i < EC_RATE_COUNT; i++) {
01307 master->device_stats.tx_frame_rates[i] = 0;
01308 master->device_stats.tx_byte_rates[i] = 0;
01309 master->device_stats.loss_rates[i] = 0;
01310 }
01311 }
01312
01313
01314
01317 void ec_master_update_device_stats(
01318 ec_master_t *master
01319 )
01320 {
01321 ec_device_stats_t *s = &master->device_stats;
01322 s32 tx_frame_rate, rx_frame_rate, tx_byte_rate, rx_byte_rate, loss_rate;
01323 u64 loss;
01324 unsigned int i, dev_idx;
01325
01326
01327 if (likely(jiffies - s->jiffies < HZ)) {
01328 return;
01329 }
01330
01331 tx_frame_rate = (s->tx_count - s->last_tx_count) * 1000;
01332 rx_frame_rate = (s->rx_count - s->last_rx_count) * 1000;
01333 tx_byte_rate = s->tx_bytes - s->last_tx_bytes;
01334 rx_byte_rate = s->rx_bytes - s->last_rx_bytes;
01335 loss = s->tx_count - s->rx_count;
01336 loss_rate = (loss - s->last_loss) * 1000;
01337
01338
01339
01340
01341
01342 for (i = 0; i < EC_RATE_COUNT; i++) {
01343 s32 n = rate_intervals[i];
01344 s->tx_frame_rates[i] += (tx_frame_rate - s->tx_frame_rates[i]) / n;
01345 s->rx_frame_rates[i] += (rx_frame_rate - s->rx_frame_rates[i]) / n;
01346 s->tx_byte_rates[i] += (tx_byte_rate - s->tx_byte_rates[i]) / n;
01347 s->rx_byte_rates[i] += (rx_byte_rate - s->rx_byte_rates[i]) / n;
01348 s->loss_rates[i] += (loss_rate - s->loss_rates[i]) / n;
01349 }
01350
01351 s->last_tx_count = s->tx_count;
01352 s->last_rx_count = s->rx_count;
01353 s->last_tx_bytes = s->tx_bytes;
01354 s->last_rx_bytes = s->rx_bytes;
01355 s->last_loss = loss;
01356
01357 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
01358 dev_idx++) {
01359 ec_device_update_stats(&master->devices[dev_idx]);
01360 }
01361
01362 s->jiffies = jiffies;
01363 }
01364
01365
01366
01367 #ifdef EC_USE_HRTIMER
01368
01369
01370
01371
01372 static enum hrtimer_restart ec_master_nanosleep_wakeup(struct hrtimer *timer)
01373 {
01374 struct hrtimer_sleeper *t =
01375 container_of(timer, struct hrtimer_sleeper, timer);
01376 struct task_struct *task = t->task;
01377
01378 t->task = NULL;
01379 if (task)
01380 wake_up_process(task);
01381
01382 return HRTIMER_NORESTART;
01383 }
01384
01385
01386
01387 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
01388
01389
01390 static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer)
01391 {
01392 return timer->expires;
01393 }
01394
01395
01396
01397 static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
01398 {
01399 timer->expires = time;
01400 }
01401
01402 #endif
01403
01404
01405
01406 void ec_master_nanosleep(const unsigned long nsecs)
01407 {
01408 struct hrtimer_sleeper t;
01409 enum hrtimer_mode mode = HRTIMER_MODE_REL;
01410
01411 hrtimer_init(&t.timer, CLOCK_MONOTONIC, mode);
01412 t.timer.function = ec_master_nanosleep_wakeup;
01413 t.task = current;
01414 #ifdef CONFIG_HIGH_RES_TIMERS
01415 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
01416 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_RESTART;
01417 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
01418 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_NO_SOFTIRQ;
01419 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
01420 t.timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
01421 #endif
01422 #endif
01423 hrtimer_set_expires(&t.timer, ktime_set(0, nsecs));
01424
01425 do {
01426 set_current_state(TASK_INTERRUPTIBLE);
01427 hrtimer_start(&t.timer, hrtimer_get_expires(&t.timer), mode);
01428
01429 if (likely(t.task))
01430 schedule();
01431
01432 hrtimer_cancel(&t.timer);
01433 mode = HRTIMER_MODE_ABS;
01434
01435 } while (t.task && !signal_pending(current));
01436 }
01437
01438 #endif // EC_USE_HRTIMER
01439
01440
01441
01444 void ec_master_exec_slave_fsms(
01445 ec_master_t *master
01446 )
01447 {
01448 ec_datagram_t *datagram;
01449 ec_fsm_slave_t *fsm, *next;
01450 unsigned int count = 0;
01451
01452 list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
01453 if (!fsm->datagram) {
01454 EC_MASTER_WARN(master, "Slave %u FSM has zero datagram."
01455 "This is a bug!\n", fsm->slave->ring_position);
01456 list_del_init(&fsm->list);
01457 master->fsm_exec_count--;
01458 return;
01459 }
01460
01461 if (fsm->datagram->state == EC_DATAGRAM_INIT ||
01462 fsm->datagram->state == EC_DATAGRAM_QUEUED ||
01463 fsm->datagram->state == EC_DATAGRAM_SENT) {
01464
01465
01466 return;
01467 }
01468
01469 datagram = ec_master_get_external_datagram(master);
01470 if (!datagram) {
01471
01472 EC_MASTER_WARN(master, "No free datagram during"
01473 " slave FSM execution. This is a bug!\n");
01474 continue;
01475 }
01476
01477 #if DEBUG_INJECT
01478 EC_MASTER_DBG(master, 1, "Executing slave %u FSM.\n",
01479 fsm->slave->ring_position);
01480 #endif
01481 if (ec_fsm_slave_exec(fsm, datagram)) {
01482
01483 #if DEBUG_INJECT
01484 EC_MASTER_DBG(master, 1, "FSM consumed datagram %s\n",
01485 datagram->name);
01486 #endif
01487 master->ext_ring_idx_fsm =
01488 (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
01489 }
01490 else {
01491
01492 list_del_init(&fsm->list);
01493 master->fsm_exec_count--;
01494 #if DEBUG_INJECT
01495 EC_MASTER_DBG(master, 1, "FSM finished. %u remaining.\n",
01496 master->fsm_exec_count);
01497 #endif
01498 }
01499 }
01500
01501 while (master->fsm_exec_count < EC_EXT_RING_SIZE / 2
01502 && count < master->slave_count) {
01503
01504 if (ec_fsm_slave_is_ready(&master->fsm_slave->fsm)) {
01505 datagram = ec_master_get_external_datagram(master);
01506
01507 if (ec_fsm_slave_exec(&master->fsm_slave->fsm, datagram)) {
01508 master->ext_ring_idx_fsm =
01509 (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
01510 list_add_tail(&master->fsm_slave->fsm.list,
01511 &master->fsm_exec_list);
01512 master->fsm_exec_count++;
01513 #if DEBUG_INJECT
01514 EC_MASTER_DBG(master, 1, "New slave %u FSM"
01515 " consumed datagram %s, now %u FSMs in list.\n",
01516 master->fsm_slave->ring_position, datagram->name,
01517 master->fsm_exec_count);
01518 #endif
01519 }
01520 }
01521
01522 master->fsm_slave++;
01523 if (master->fsm_slave >= master->slaves + master->slave_count) {
01524 master->fsm_slave = master->slaves;
01525 }
01526 count++;
01527 }
01528 }
01529
01530
01531
01534 static int ec_master_idle_thread(void *priv_data)
01535 {
01536 ec_master_t *master = (ec_master_t *) priv_data;
01537 int fsm_exec;
01538 #ifdef EC_USE_HRTIMER
01539 size_t sent_bytes;
01540 #endif
01541
01542
01543 ec_master_set_send_interval(master, 1000000 / HZ);
01544
01545 EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
01546 " max data size=%zu\n", master->send_interval,
01547 master->max_queue_size);
01548
01549 while (!kthread_should_stop()) {
01550 ec_datagram_output_stats(&master->fsm_datagram);
01551
01552
01553 down(&master->io_sem);
01554 ecrt_master_receive(master);
01555 up(&master->io_sem);
01556
01557
01558 if (down_interruptible(&master->master_sem)) {
01559 break;
01560 }
01561
01562 fsm_exec = ec_fsm_master_exec(&master->fsm);
01563
01564 ec_master_exec_slave_fsms(master);
01565
01566 up(&master->master_sem);
01567
01568
01569 down(&master->io_sem);
01570 if (fsm_exec) {
01571 ec_master_queue_datagram(master, &master->fsm_datagram);
01572 }
01573 ecrt_master_send(master);
01574 #ifdef EC_USE_HRTIMER
01575 sent_bytes = master->devices[EC_DEVICE_MAIN].tx_skb[
01576 master->devices[EC_DEVICE_MAIN].tx_ring_index]->len;
01577 #endif
01578 up(&master->io_sem);
01579
01580 if (ec_fsm_master_idle(&master->fsm)) {
01581 #ifdef EC_USE_HRTIMER
01582 ec_master_nanosleep(master->send_interval * 1000);
01583 #else
01584 set_current_state(TASK_INTERRUPTIBLE);
01585 schedule_timeout(1);
01586 #endif
01587 } else {
01588 #ifdef EC_USE_HRTIMER
01589 ec_master_nanosleep(sent_bytes * EC_BYTE_TRANSMISSION_TIME_NS);
01590 #else
01591 schedule();
01592 #endif
01593 }
01594 }
01595
01596 EC_MASTER_DBG(master, 1, "Master IDLE thread exiting...\n");
01597
01598 return 0;
01599 }
01600
01601
01602
01605 static int ec_master_operation_thread(void *priv_data)
01606 {
01607 ec_master_t *master = (ec_master_t *) priv_data;
01608
01609 EC_MASTER_DBG(master, 1, "Operation thread running"
01610 " with fsm interval = %u us, max data size=%zu\n",
01611 master->send_interval, master->max_queue_size);
01612
01613 while (!kthread_should_stop()) {
01614 ec_datagram_output_stats(&master->fsm_datagram);
01615
01616 if (master->injection_seq_rt == master->injection_seq_fsm) {
01617
01618 ec_master_output_stats(master);
01619
01620
01621 if (down_interruptible(&master->master_sem)) {
01622 break;
01623 }
01624
01625 if (ec_fsm_master_exec(&master->fsm)) {
01626
01627
01628 master->injection_seq_fsm++;
01629 }
01630
01631 ec_master_exec_slave_fsms(master);
01632
01633 up(&master->master_sem);
01634 }
01635
01636 #ifdef EC_USE_HRTIMER
01637
01638 ec_master_nanosleep(master->send_interval * 1000);
01639 #else
01640 if (ec_fsm_master_idle(&master->fsm)) {
01641 set_current_state(TASK_INTERRUPTIBLE);
01642 schedule_timeout(1);
01643 }
01644 else {
01645 schedule();
01646 }
01647 #endif
01648 }
01649
01650 EC_MASTER_DBG(master, 1, "Master OP thread exiting...\n");
01651 return 0;
01652 }
01653
01654
01655
01656 #ifdef EC_EOE
01657
01659 void ec_master_eoe_start(ec_master_t *master )
01660 {
01661 struct sched_param param = { .sched_priority = 0 };
01662
01663 if (master->eoe_thread) {
01664 EC_MASTER_WARN(master, "EoE already running!\n");
01665 return;
01666 }
01667
01668 if (list_empty(&master->eoe_handlers))
01669 return;
01670
01671 if (!master->send_cb || !master->receive_cb) {
01672 EC_MASTER_WARN(master, "No EoE processing"
01673 " because of missing callbacks!\n");
01674 return;
01675 }
01676
01677 EC_MASTER_INFO(master, "Starting EoE thread.\n");
01678 master->eoe_thread = kthread_run(ec_master_eoe_thread, master,
01679 "EtherCAT-EoE");
01680 if (IS_ERR(master->eoe_thread)) {
01681 int err = (int) PTR_ERR(master->eoe_thread);
01682 EC_MASTER_ERR(master, "Failed to start EoE thread (error %i)!\n",
01683 err);
01684 master->eoe_thread = NULL;
01685 return;
01686 }
01687
01688 sched_setscheduler(master->eoe_thread, SCHED_NORMAL, ¶m);
01689 set_user_nice(master->eoe_thread, 0);
01690 }
01691
01692
01693
01696 void ec_master_eoe_stop(ec_master_t *master )
01697 {
01698 if (master->eoe_thread) {
01699 EC_MASTER_INFO(master, "Stopping EoE thread.\n");
01700
01701 kthread_stop(master->eoe_thread);
01702 master->eoe_thread = NULL;
01703 EC_MASTER_INFO(master, "EoE thread exited.\n");
01704 }
01705 }
01706
01707
01708
01711 static int ec_master_eoe_thread(void *priv_data)
01712 {
01713 ec_master_t *master = (ec_master_t *) priv_data;
01714 ec_eoe_t *eoe;
01715 unsigned int none_open, sth_to_send, all_idle;
01716
01717 EC_MASTER_DBG(master, 1, "EoE thread running.\n");
01718
01719 while (!kthread_should_stop()) {
01720 none_open = 1;
01721 all_idle = 1;
01722
01723 list_for_each_entry(eoe, &master->eoe_handlers, list) {
01724 if (ec_eoe_is_open(eoe)) {
01725 none_open = 0;
01726 break;
01727 }
01728 }
01729 if (none_open)
01730 goto schedule;
01731
01732
01733 master->receive_cb(master->cb_data);
01734
01735
01736 sth_to_send = 0;
01737 list_for_each_entry(eoe, &master->eoe_handlers, list) {
01738 ec_eoe_run(eoe);
01739 if (eoe->queue_datagram) {
01740 sth_to_send = 1;
01741 }
01742 if (!ec_eoe_is_idle(eoe)) {
01743 all_idle = 0;
01744 }
01745 }
01746
01747 if (sth_to_send) {
01748 list_for_each_entry(eoe, &master->eoe_handlers, list) {
01749 ec_eoe_queue(eoe);
01750 }
01751
01752 down(&master->ext_queue_sem);
01753 master->send_cb(master->cb_data);
01754 up(&master->ext_queue_sem);
01755 }
01756
01757 schedule:
01758 if (all_idle) {
01759 set_current_state(TASK_INTERRUPTIBLE);
01760 schedule_timeout(1);
01761 } else {
01762 schedule();
01763 }
01764 }
01765
01766 EC_MASTER_DBG(master, 1, "EoE thread exiting...\n");
01767 return 0;
01768 }
01769 #endif
01770
01771
01772
01775 void ec_master_attach_slave_configs(
01776 ec_master_t *master
01777 )
01778 {
01779 ec_slave_config_t *sc;
01780
01781 list_for_each_entry(sc, &master->configs, list) {
01782 ec_slave_config_attach(sc);
01783 }
01784 }
01785
01786
01787
01791 #define EC_FIND_SLAVE \
01792 do { \
01793 if (alias) { \
01794 for (; slave < master->slaves + master->slave_count; \
01795 slave++) { \
01796 if (slave->effective_alias == alias) \
01797 break; \
01798 } \
01799 if (slave == master->slaves + master->slave_count) \
01800 return NULL; \
01801 } \
01802 \
01803 slave += position; \
01804 if (slave < master->slaves + master->slave_count) { \
01805 return slave; \
01806 } else { \
01807 return NULL; \
01808 } \
01809 } while (0)
01810
01815 ec_slave_t *ec_master_find_slave(
01816 ec_master_t *master,
01817 uint16_t alias,
01818 uint16_t position
01819 )
01820 {
01821 ec_slave_t *slave = master->slaves;
01822 EC_FIND_SLAVE;
01823 }
01824
01831 const ec_slave_t *ec_master_find_slave_const(
01832 const ec_master_t *master,
01833 uint16_t alias,
01834 uint16_t position
01835 )
01836 {
01837 const ec_slave_t *slave = master->slaves;
01838 EC_FIND_SLAVE;
01839 }
01840
01841
01842
01847 unsigned int ec_master_config_count(
01848 const ec_master_t *master
01849 )
01850 {
01851 const ec_slave_config_t *sc;
01852 unsigned int count = 0;
01853
01854 list_for_each_entry(sc, &master->configs, list) {
01855 count++;
01856 }
01857
01858 return count;
01859 }
01860
01861
01862
01866 #define EC_FIND_CONFIG \
01867 do { \
01868 list_for_each_entry(sc, &master->configs, list) { \
01869 if (pos--) \
01870 continue; \
01871 return sc; \
01872 } \
01873 return NULL; \
01874 } while (0)
01875
01880 ec_slave_config_t *ec_master_get_config(
01881 const ec_master_t *master,
01882 unsigned int pos
01883 )
01884 {
01885 ec_slave_config_t *sc;
01886 EC_FIND_CONFIG;
01887 }
01888
01895 const ec_slave_config_t *ec_master_get_config_const(
01896 const ec_master_t *master,
01897 unsigned int pos
01898 )
01899 {
01900 const ec_slave_config_t *sc;
01901 EC_FIND_CONFIG;
01902 }
01903
01904
01905
01910 unsigned int ec_master_domain_count(
01911 const ec_master_t *master
01912 )
01913 {
01914 const ec_domain_t *domain;
01915 unsigned int count = 0;
01916
01917 list_for_each_entry(domain, &master->domains, list) {
01918 count++;
01919 }
01920
01921 return count;
01922 }
01923
01924
01925
01929 #define EC_FIND_DOMAIN \
01930 do { \
01931 list_for_each_entry(domain, &master->domains, list) { \
01932 if (index--) \
01933 continue; \
01934 return domain; \
01935 } \
01936 \
01937 return NULL; \
01938 } while (0)
01939
01944 ec_domain_t *ec_master_find_domain(
01945 ec_master_t *master,
01946 unsigned int index
01947 )
01948 {
01949 ec_domain_t *domain;
01950 EC_FIND_DOMAIN;
01951 }
01952
01959 const ec_domain_t *ec_master_find_domain_const(
01960 const ec_master_t *master,
01961 unsigned int index
01962 )
01963 {
01964 const ec_domain_t *domain;
01965 EC_FIND_DOMAIN;
01966 }
01967
01968
01969
01970 #ifdef EC_EOE
01971
01976 uint16_t ec_master_eoe_handler_count(
01977 const ec_master_t *master
01978 )
01979 {
01980 const ec_eoe_t *eoe;
01981 unsigned int count = 0;
01982
01983 list_for_each_entry(eoe, &master->eoe_handlers, list) {
01984 count++;
01985 }
01986
01987 return count;
01988 }
01989
01990
01991
01998 const ec_eoe_t *ec_master_get_eoe_handler_const(
01999 const ec_master_t *master,
02000 uint16_t index
02001 )
02002 {
02003 const ec_eoe_t *eoe;
02004
02005 list_for_each_entry(eoe, &master->eoe_handlers, list) {
02006 if (index--)
02007 continue;
02008 return eoe;
02009 }
02010
02011 return NULL;
02012 }
02013
02014 #endif
02015
02016
02017
02023 int ec_master_debug_level(
02024 ec_master_t *master,
02025 unsigned int level
02026 )
02027 {
02028 if (level > 2) {
02029 EC_MASTER_ERR(master, "Invalid debug level %u!\n", level);
02030 return -EINVAL;
02031 }
02032
02033 if (level != master->debug_level) {
02034 master->debug_level = level;
02035 EC_MASTER_INFO(master, "Master debug level set to %u.\n",
02036 master->debug_level);
02037 }
02038
02039 return 0;
02040 }
02041
02042
02043
02046 void ec_master_find_dc_ref_clock(
02047 ec_master_t *master
02048 )
02049 {
02050 ec_slave_t *slave, *ref = NULL;
02051
02052 if (master->dc_ref_config) {
02053
02054 slave = master->dc_ref_config->slave;
02055
02056 if (slave) {
02057 if (slave->base_dc_supported && slave->has_dc_system_time) {
02058 ref = slave;
02059 }
02060 else {
02061 EC_MASTER_WARN(master, "Slave %u can not act as a"
02062 " DC reference clock!", slave->ring_position);
02063 }
02064 }
02065 else {
02066 EC_MASTER_WARN(master, "DC reference clock config (%u-%u)"
02067 " has no slave attached!\n", master->dc_ref_config->alias,
02068 master->dc_ref_config->position);
02069 }
02070 }
02071 else {
02072
02073 for (slave = master->slaves;
02074 slave < master->slaves + master->slave_count;
02075 slave++) {
02076 if (slave->base_dc_supported && slave->has_dc_system_time) {
02077 ref = slave;
02078 break;
02079 }
02080 }
02081
02082 }
02083
02084 master->dc_ref_clock = ref;
02085
02086 if (ref) {
02087 EC_MASTER_INFO(master, "Using slave %u as DC reference clock.\n",
02088 ref->ring_position);
02089 }
02090 else {
02091 EC_MASTER_INFO(master, "No DC reference clock found.\n");
02092 }
02093
02094
02095
02096 ec_datagram_fpwr(&master->ref_sync_datagram,
02097 ref ? ref->station_address : 0xffff, 0x0910, 4);
02098 ec_datagram_frmw(&master->sync_datagram,
02099 ref ? ref->station_address : 0xffff, 0x0910, 4);
02100 }
02101
02102
02103
02108 int ec_master_calc_topology_rec(
02109 ec_master_t *master,
02110 ec_slave_t *port0_slave,
02111 unsigned int *slave_position
02112 )
02113 {
02114 ec_slave_t *slave = master->slaves + *slave_position;
02115 unsigned int port_index;
02116 int ret;
02117
02118 static const unsigned int next_table[EC_MAX_PORTS] = {
02119 3, 2, 0, 1
02120 };
02121
02122 slave->ports[0].next_slave = port0_slave;
02123
02124 port_index = 3;
02125 while (port_index != 0) {
02126 if (!slave->ports[port_index].link.loop_closed) {
02127 *slave_position = *slave_position + 1;
02128 if (*slave_position < master->slave_count) {
02129 slave->ports[port_index].next_slave =
02130 master->slaves + *slave_position;
02131 ret = ec_master_calc_topology_rec(master,
02132 slave, slave_position);
02133 if (ret) {
02134 return ret;
02135 }
02136 } else {
02137 return -1;
02138 }
02139 }
02140
02141 port_index = next_table[port_index];
02142 }
02143
02144 return 0;
02145 }
02146
02147
02148
02151 void ec_master_calc_topology(
02152 ec_master_t *master
02153 )
02154 {
02155 unsigned int slave_position = 0;
02156
02157 if (master->slave_count == 0)
02158 return;
02159
02160 if (ec_master_calc_topology_rec(master, NULL, &slave_position))
02161 EC_MASTER_ERR(master, "Failed to calculate bus topology.\n");
02162 }
02163
02164
02165
02168 void ec_master_calc_transmission_delays(
02169 ec_master_t *master
02170 )
02171 {
02172 ec_slave_t *slave;
02173
02174 for (slave = master->slaves;
02175 slave < master->slaves + master->slave_count;
02176 slave++) {
02177 ec_slave_calc_port_delays(slave);
02178 }
02179
02180 if (master->dc_ref_clock) {
02181 uint32_t delay = 0;
02182 ec_slave_calc_transmission_delays_rec(master->dc_ref_clock, &delay);
02183 }
02184 }
02185
02186
02187
02190 void ec_master_calc_dc(
02191 ec_master_t *master
02192 )
02193 {
02194
02195 ec_master_find_dc_ref_clock(master);
02196
02197
02198 ec_master_calc_topology(master);
02199
02200 ec_master_calc_transmission_delays(master);
02201 }
02202
02203
02204
02207 void ec_master_request_op(
02208 ec_master_t *master
02209 )
02210 {
02211 unsigned int i;
02212 ec_slave_t *slave;
02213
02214 if (!master->active)
02215 return;
02216
02217 EC_MASTER_DBG(master, 1, "Requesting OP...\n");
02218
02219
02220 for (i = 0; i < master->slave_count; i++) {
02221 slave = master->slaves + i;
02222 if (slave->config) {
02223 ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
02224 }
02225 }
02226
02227
02228 if (master->dc_ref_clock) {
02229 ec_slave_request_state(master->dc_ref_clock, EC_SLAVE_STATE_OP);
02230 }
02231 }
02232
02233
02234
02235
02236
02241 ec_domain_t *ecrt_master_create_domain_err(
02242 ec_master_t *master
02243 )
02244 {
02245 ec_domain_t *domain, *last_domain;
02246 unsigned int index;
02247
02248 EC_MASTER_DBG(master, 1, "ecrt_master_create_domain(master = 0x%p)\n",
02249 master);
02250
02251 if (!(domain =
02252 (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) {
02253 EC_MASTER_ERR(master, "Error allocating domain memory!\n");
02254 return ERR_PTR(-ENOMEM);
02255 }
02256
02257 down(&master->master_sem);
02258
02259 if (list_empty(&master->domains)) {
02260 index = 0;
02261 } else {
02262 last_domain = list_entry(master->domains.prev, ec_domain_t, list);
02263 index = last_domain->index + 1;
02264 }
02265
02266 ec_domain_init(domain, master, index);
02267 list_add_tail(&domain->list, &master->domains);
02268
02269 up(&master->master_sem);
02270
02271 EC_MASTER_DBG(master, 1, "Created domain %u.\n", domain->index);
02272
02273 return domain;
02274 }
02275
02276
02277
02278 ec_domain_t *ecrt_master_create_domain(
02279 ec_master_t *master
02280 )
02281 {
02282 ec_domain_t *d = ecrt_master_create_domain_err(master);
02283 return IS_ERR(d) ? NULL : d;
02284 }
02285
02286
02287
02288 int ecrt_master_activate(ec_master_t *master)
02289 {
02290 uint32_t domain_offset;
02291 ec_domain_t *domain;
02292 int ret;
02293 #ifdef EC_EOE
02294 int eoe_was_running;
02295 #endif
02296
02297 EC_MASTER_DBG(master, 1, "ecrt_master_activate(master = 0x%p)\n", master);
02298
02299 if (master->active) {
02300 EC_MASTER_WARN(master, "%s: Master already active!\n", __func__);
02301 return 0;
02302 }
02303
02304 down(&master->master_sem);
02305
02306
02307 domain_offset = 0;
02308 list_for_each_entry(domain, &master->domains, list) {
02309 ret = ec_domain_finish(domain, domain_offset);
02310 if (ret < 0) {
02311 up(&master->master_sem);
02312 EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain);
02313 return ret;
02314 }
02315 domain_offset += domain->data_size;
02316 }
02317
02318 up(&master->master_sem);
02319
02320
02321
02322 ec_master_thread_stop(master);
02323 #ifdef EC_EOE
02324 eoe_was_running = master->eoe_thread != NULL;
02325 ec_master_eoe_stop(master);
02326 #endif
02327
02328 EC_MASTER_DBG(master, 1, "FSM datagram is %p.\n", &master->fsm_datagram);
02329
02330 master->injection_seq_fsm = 0;
02331 master->injection_seq_rt = 0;
02332
02333 master->send_cb = master->app_send_cb;
02334 master->receive_cb = master->app_receive_cb;
02335 master->cb_data = master->app_cb_data;
02336
02337 #ifdef EC_EOE
02338 if (eoe_was_running) {
02339 ec_master_eoe_start(master);
02340 }
02341 #endif
02342 ret = ec_master_thread_start(master, ec_master_operation_thread,
02343 "EtherCAT-OP");
02344 if (ret < 0) {
02345 EC_MASTER_ERR(master, "Failed to start master thread!\n");
02346 return ret;
02347 }
02348
02349
02350 master->allow_scan = 1;
02351
02352 master->active = 1;
02353
02354
02355 master->config_changed = 1;
02356
02357 return 0;
02358 }
02359
02360
02361
02362 void ecrt_master_deactivate(ec_master_t *master)
02363 {
02364 ec_slave_t *slave;
02365 #ifdef EC_EOE
02366 ec_eoe_t *eoe;
02367 int eoe_was_running;
02368 #endif
02369
02370 EC_MASTER_DBG(master, 1, "%s(master = 0x%p)\n", __func__, master);
02371
02372 if (!master->active) {
02373 EC_MASTER_WARN(master, "%s: Master not active.\n", __func__);
02374 return;
02375 }
02376
02377 ec_master_thread_stop(master);
02378 #ifdef EC_EOE
02379 eoe_was_running = master->eoe_thread != NULL;
02380 ec_master_eoe_stop(master);
02381 #endif
02382
02383 master->send_cb = ec_master_internal_send_cb;
02384 master->receive_cb = ec_master_internal_receive_cb;
02385 master->cb_data = master;
02386
02387 ec_master_clear_config(master);
02388
02389 for (slave = master->slaves;
02390 slave < master->slaves + master->slave_count;
02391 slave++) {
02392
02393
02394 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
02395
02396
02397
02398
02399 slave->force_config = 1;
02400 }
02401
02402 #ifdef EC_EOE
02403
02404 list_for_each_entry(eoe, &master->eoe_handlers, list) {
02405 if (ec_eoe_is_open(eoe))
02406 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
02407 }
02408 #endif
02409
02410 master->app_time = 0ULL;
02411 master->app_start_time = 0ULL;
02412 master->has_app_time = 0;
02413
02414 #ifdef EC_EOE
02415 if (eoe_was_running) {
02416 ec_master_eoe_start(master);
02417 }
02418 #endif
02419 if (ec_master_thread_start(master, ec_master_idle_thread,
02420 "EtherCAT-IDLE")) {
02421 EC_MASTER_WARN(master, "Failed to restart master thread!\n");
02422 }
02423
02424
02425
02426 master->allow_scan = 0;
02427
02428 master->active = 0;
02429 }
02430
02431
02432
02433 void ecrt_master_send(ec_master_t *master)
02434 {
02435 ec_datagram_t *datagram, *n;
02436 ec_device_index_t dev_idx;
02437
02438 if (master->injection_seq_rt != master->injection_seq_fsm) {
02439
02440 ec_master_queue_datagram(master, &master->fsm_datagram);
02441 master->injection_seq_rt = master->injection_seq_fsm;
02442 }
02443
02444 ec_master_inject_external_datagrams(master);
02445
02446 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
02447 dev_idx++) {
02448 if (unlikely(!master->devices[dev_idx].link_state)) {
02449
02450 list_for_each_entry_safe(datagram, n,
02451 &master->datagram_queue, queue) {
02452 if (datagram->device_index == dev_idx) {
02453 datagram->state = EC_DATAGRAM_ERROR;
02454 list_del_init(&datagram->queue);
02455 }
02456 }
02457
02458 if (!master->devices[dev_idx].dev) {
02459 continue;
02460 }
02461
02462
02463 ec_device_poll(&master->devices[dev_idx]);
02464
02465
02466 ec_device_clear_stats(&master->devices[dev_idx]);
02467 continue;
02468 }
02469
02470
02471 ec_master_send_datagrams(master, dev_idx);
02472 }
02473 }
02474
02475
02476
02477 void ecrt_master_receive(ec_master_t *master)
02478 {
02479 unsigned int dev_idx;
02480 ec_datagram_t *datagram, *next;
02481
02482
02483 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
02484 dev_idx++) {
02485 ec_device_poll(&master->devices[dev_idx]);
02486 }
02487 ec_master_update_device_stats(master);
02488
02489
02490 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
02491 if (datagram->state != EC_DATAGRAM_SENT) continue;
02492
02493 #ifdef EC_HAVE_CYCLES
02494 if (master->devices[EC_DEVICE_MAIN].cycles_poll -
02495 datagram->cycles_sent > timeout_cycles) {
02496 #else
02497 if (master->devices[EC_DEVICE_MAIN].jiffies_poll -
02498 datagram->jiffies_sent > timeout_jiffies) {
02499 #endif
02500 list_del_init(&datagram->queue);
02501 datagram->state = EC_DATAGRAM_TIMED_OUT;
02502 master->stats.timeouts++;
02503
02504 #ifdef EC_RT_SYSLOG
02505 ec_master_output_stats(master);
02506
02507 if (unlikely(master->debug_level > 0)) {
02508 unsigned int time_us;
02509 #ifdef EC_HAVE_CYCLES
02510 time_us = (unsigned int)
02511 (master->devices[EC_DEVICE_MAIN].cycles_poll -
02512 datagram->cycles_sent) * 1000 / cpu_khz;
02513 #else
02514 time_us = (unsigned int)
02515 ((master->devices[EC_DEVICE_MAIN].jiffies_poll -
02516 datagram->jiffies_sent) * 1000000 / HZ);
02517 #endif
02518 EC_MASTER_DBG(master, 0, "TIMED OUT datagram %p,"
02519 " index %02X waited %u us.\n",
02520 datagram, datagram->index, time_us);
02521 }
02522 #endif
02523 }
02524 }
02525 }
02526
02527
02528
02529 void ecrt_master_send_ext(ec_master_t *master)
02530 {
02531 ec_datagram_t *datagram, *next;
02532
02533 list_for_each_entry_safe(datagram, next, &master->ext_datagram_queue,
02534 queue) {
02535 list_del(&datagram->queue);
02536 ec_master_queue_datagram(master, datagram);
02537 }
02538
02539 ecrt_master_send(master);
02540 }
02541
02542
02543
02546 ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *master,
02547 uint16_t alias, uint16_t position, uint32_t vendor_id,
02548 uint32_t product_code)
02549 {
02550 ec_slave_config_t *sc;
02551 unsigned int found = 0;
02552
02553
02554 EC_MASTER_DBG(master, 1, "ecrt_master_slave_config(master = 0x%p,"
02555 " alias = %u, position = %u, vendor_id = 0x%08x,"
02556 " product_code = 0x%08x)\n",
02557 master, alias, position, vendor_id, product_code);
02558
02559 list_for_each_entry(sc, &master->configs, list) {
02560 if (sc->alias == alias && sc->position == position) {
02561 found = 1;
02562 break;
02563 }
02564 }
02565
02566 if (found) {
02567 if (sc->vendor_id != vendor_id || sc->product_code != product_code) {
02568 EC_MASTER_ERR(master, "Slave type mismatch. Slave was"
02569 " configured as 0x%08X/0x%08X before. Now configuring"
02570 " with 0x%08X/0x%08X.\n", sc->vendor_id, sc->product_code,
02571 vendor_id, product_code);
02572 return ERR_PTR(-ENOENT);
02573 }
02574 } else {
02575 EC_MASTER_DBG(master, 1, "Creating slave configuration for %u:%u,"
02576 " 0x%08X/0x%08X.\n",
02577 alias, position, vendor_id, product_code);
02578
02579 if (!(sc = (ec_slave_config_t *) kmalloc(sizeof(ec_slave_config_t),
02580 GFP_KERNEL))) {
02581 EC_MASTER_ERR(master, "Failed to allocate memory"
02582 " for slave configuration.\n");
02583 return ERR_PTR(-ENOMEM);
02584 }
02585
02586 ec_slave_config_init(sc, master,
02587 alias, position, vendor_id, product_code);
02588
02589 down(&master->master_sem);
02590
02591
02592 ec_slave_config_attach(sc);
02593 ec_slave_config_load_default_sync_config(sc);
02594 list_add_tail(&sc->list, &master->configs);
02595
02596 up(&master->master_sem);
02597 }
02598
02599 return sc;
02600 }
02601
02602
02603
02604 ec_slave_config_t *ecrt_master_slave_config(ec_master_t *master,
02605 uint16_t alias, uint16_t position, uint32_t vendor_id,
02606 uint32_t product_code)
02607 {
02608 ec_slave_config_t *sc = ecrt_master_slave_config_err(master, alias,
02609 position, vendor_id, product_code);
02610 return IS_ERR(sc) ? NULL : sc;
02611 }
02612
02613
02614
02615 int ecrt_master_select_reference_clock(ec_master_t *master,
02616 ec_slave_config_t *sc)
02617 {
02618 if (sc) {
02619 ec_slave_t *slave = sc->slave;
02620
02621
02622 if (slave &&
02623 (!slave->base_dc_supported || !slave->has_dc_system_time)) {
02624 EC_MASTER_WARN(master, "Slave %u can not act as"
02625 " a reference clock!", slave->ring_position);
02626 }
02627 }
02628
02629 master->dc_ref_config = sc;
02630 return 0;
02631 }
02632
02633
02634
02635 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info)
02636 {
02637 EC_MASTER_DBG(master, 1, "ecrt_master(master = 0x%p,"
02638 " master_info = 0x%p)\n", master, master_info);
02639
02640 master_info->slave_count = master->slave_count;
02641 master_info->link_up = master->devices[EC_DEVICE_MAIN].link_state;
02642 master_info->scan_busy = master->scan_busy;
02643 master_info->app_time = master->app_time;
02644 return 0;
02645 }
02646
02647
02648
02649 int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
02650 ec_slave_info_t *slave_info)
02651 {
02652 const ec_slave_t *slave;
02653 unsigned int i;
02654 int ret = 0;
02655
02656 if (down_interruptible(&master->master_sem)) {
02657 return -EINTR;
02658 }
02659
02660 slave = ec_master_find_slave_const(master, 0, slave_position);
02661
02662 if (slave == NULL) {
02663 ret = -ENOENT;
02664 goto out_get_slave;
02665 }
02666
02667 slave_info->position = slave->ring_position;
02668 slave_info->vendor_id = slave->sii.vendor_id;
02669 slave_info->product_code = slave->sii.product_code;
02670 slave_info->revision_number = slave->sii.revision_number;
02671 slave_info->serial_number = slave->sii.serial_number;
02672 slave_info->alias = slave->effective_alias;
02673 slave_info->current_on_ebus = slave->sii.current_on_ebus;
02674
02675 for (i = 0; i < EC_MAX_PORTS; i++) {
02676 slave_info->ports[i].desc = slave->ports[i].desc;
02677 slave_info->ports[i].link.link_up = slave->ports[i].link.link_up;
02678 slave_info->ports[i].link.loop_closed =
02679 slave->ports[i].link.loop_closed;
02680 slave_info->ports[i].link.signal_detected =
02681 slave->ports[i].link.signal_detected;
02682 slave_info->ports[i].receive_time = slave->ports[i].receive_time;
02683 if (slave->ports[i].next_slave) {
02684 slave_info->ports[i].next_slave =
02685 slave->ports[i].next_slave->ring_position;
02686 } else {
02687 slave_info->ports[i].next_slave = 0xffff;
02688 }
02689 slave_info->ports[i].delay_to_next_dc =
02690 slave->ports[i].delay_to_next_dc;
02691 }
02692
02693 slave_info->al_state = slave->current_state;
02694 slave_info->error_flag = slave->error_flag;
02695 slave_info->sync_count = slave->sii.sync_count;
02696 slave_info->sdo_count = ec_slave_sdo_count(slave);
02697 if (slave->sii.name) {
02698 strncpy(slave_info->name, slave->sii.name, EC_MAX_STRING_LENGTH);
02699 } else {
02700 slave_info->name[0] = 0;
02701 }
02702
02703 out_get_slave:
02704 up(&master->master_sem);
02705
02706 return ret;
02707 }
02708
02709
02710
02711 void ecrt_master_callbacks(ec_master_t *master,
02712 void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data)
02713 {
02714 EC_MASTER_DBG(master, 1, "ecrt_master_callbacks(master = 0x%p,"
02715 " send_cb = 0x%p, receive_cb = 0x%p, cb_data = 0x%p)\n",
02716 master, send_cb, receive_cb, cb_data);
02717
02718 master->app_send_cb = send_cb;
02719 master->app_receive_cb = receive_cb;
02720 master->app_cb_data = cb_data;
02721 }
02722
02723
02724
02725 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state)
02726 {
02727 ec_device_index_t dev_idx;
02728
02729 state->slaves_responding = 0U;
02730 state->al_states = 0;
02731 state->link_up = 0U;
02732
02733 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
02734 dev_idx++) {
02735
02736 state->slaves_responding += master->fsm.slaves_responding[dev_idx];
02737
02738
02739 state->al_states |= master->fsm.slave_states[dev_idx];
02740
02741
02742 state->link_up |= master->devices[dev_idx].link_state;
02743 }
02744 }
02745
02746
02747
02748 int ecrt_master_link_state(const ec_master_t *master, unsigned int dev_idx,
02749 ec_master_link_state_t *state)
02750 {
02751 if (dev_idx >= ec_master_num_devices(master)) {
02752 return -EINVAL;
02753 }
02754
02755 state->slaves_responding = master->fsm.slaves_responding[dev_idx];
02756 state->al_states = master->fsm.slave_states[dev_idx];
02757 state->link_up = master->devices[dev_idx].link_state;
02758
02759 return 0;
02760 }
02761
02762
02763
02764 void ecrt_master_application_time(ec_master_t *master, uint64_t app_time)
02765 {
02766 master->app_time = app_time;
02767
02768 if (unlikely(!master->has_app_time)) {
02769 master->app_start_time = app_time;
02770 master->has_app_time = 1;
02771 }
02772 }
02773
02774
02775
02776 int ecrt_master_reference_clock_time(ec_master_t *master, uint32_t *time)
02777 {
02778 if (!master->dc_ref_clock) {
02779 return -ENXIO;
02780 }
02781
02782 if (master->sync_datagram.state != EC_DATAGRAM_RECEIVED) {
02783 return -EIO;
02784 }
02785
02786
02787 *time = EC_READ_U32(master->sync_datagram.data) -
02788 master->dc_ref_clock->transmission_delay;
02789
02790 return 0;
02791 }
02792
02793
02794
02795 void ecrt_master_sync_reference_clock(ec_master_t *master)
02796 {
02797 if (master->dc_ref_clock) {
02798 EC_WRITE_U32(master->ref_sync_datagram.data, master->app_time);
02799 ec_master_queue_datagram(master, &master->ref_sync_datagram);
02800 }
02801 }
02802
02803
02804
02805 void ecrt_master_sync_slave_clocks(ec_master_t *master)
02806 {
02807 if (master->dc_ref_clock) {
02808 ec_datagram_zero(&master->sync_datagram);
02809 ec_master_queue_datagram(master, &master->sync_datagram);
02810 }
02811 }
02812
02813
02814
02815 void ecrt_master_sync_monitor_queue(ec_master_t *master)
02816 {
02817 ec_datagram_zero(&master->sync_mon_datagram);
02818 ec_master_queue_datagram(master, &master->sync_mon_datagram);
02819 }
02820
02821
02822
02823 uint32_t ecrt_master_sync_monitor_process(ec_master_t *master)
02824 {
02825 if (master->sync_mon_datagram.state == EC_DATAGRAM_RECEIVED) {
02826 return EC_READ_U32(master->sync_mon_datagram.data) & 0x7fffffff;
02827 } else {
02828 return 0xffffffff;
02829 }
02830 }
02831
02832
02833
02834 int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
02835 uint16_t index, uint8_t subindex, uint8_t *data,
02836 size_t data_size, uint32_t *abort_code)
02837 {
02838 ec_sdo_request_t request;
02839 ec_slave_t *slave;
02840 int ret;
02841
02842 EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
02843 " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
02844 " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
02845 __func__, master, slave_position, index, subindex,
02846 data, data_size, abort_code);
02847
02848 if (!data_size) {
02849 EC_MASTER_ERR(master, "Zero data size!\n");
02850 return -EINVAL;
02851 }
02852
02853 ec_sdo_request_init(&request);
02854 ecrt_sdo_request_index(&request, index, subindex);
02855 ret = ec_sdo_request_alloc(&request, data_size);
02856 if (ret) {
02857 ec_sdo_request_clear(&request);
02858 return ret;
02859 }
02860
02861 memcpy(request.data, data, data_size);
02862 request.data_size = data_size;
02863 ecrt_sdo_request_write(&request);
02864
02865 if (down_interruptible(&master->master_sem)) {
02866 ec_sdo_request_clear(&request);
02867 return -EINTR;
02868 }
02869
02870 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
02871 up(&master->master_sem);
02872 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
02873 ec_sdo_request_clear(&request);
02874 return -EINVAL;
02875 }
02876
02877 EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request.\n");
02878
02879
02880 list_add_tail(&request.list, &slave->sdo_requests);
02881
02882 up(&master->master_sem);
02883
02884
02885 if (wait_event_interruptible(master->request_queue,
02886 request.state != EC_INT_REQUEST_QUEUED)) {
02887
02888 down(&master->master_sem);
02889 if (request.state == EC_INT_REQUEST_QUEUED) {
02890 list_del(&request.list);
02891 up(&master->master_sem);
02892 ec_sdo_request_clear(&request);
02893 return -EINTR;
02894 }
02895
02896 up(&master->master_sem);
02897 }
02898
02899
02900 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
02901
02902 *abort_code = request.abort_code;
02903
02904 if (request.state == EC_INT_REQUEST_SUCCESS) {
02905 ret = 0;
02906 } else if (request.errno) {
02907 ret = -request.errno;
02908 } else {
02909 ret = -EIO;
02910 }
02911
02912 ec_sdo_request_clear(&request);
02913 return ret;
02914 }
02915
02916
02917
02918 int ecrt_master_sdo_download_complete(ec_master_t *master,
02919 uint16_t slave_position, uint16_t index, uint8_t *data,
02920 size_t data_size, uint32_t *abort_code)
02921 {
02922 ec_sdo_request_t request;
02923 ec_slave_t *slave;
02924 int ret;
02925
02926 EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
02927 " slave_position = %u, index = 0x%04X,"
02928 " data = 0x%p, data_size = %zu, abort_code = 0x%p)\n",
02929 __func__, master, slave_position, index, data, data_size,
02930 abort_code);
02931
02932 if (!data_size) {
02933 EC_MASTER_ERR(master, "Zero data size!\n");
02934 return -EINVAL;
02935 }
02936
02937 ec_sdo_request_init(&request);
02938 ecrt_sdo_request_index(&request, index, 0);
02939 ret = ec_sdo_request_alloc(&request, data_size);
02940 if (ret) {
02941 ec_sdo_request_clear(&request);
02942 return ret;
02943 }
02944
02945 request.complete_access = 1;
02946 memcpy(request.data, data, data_size);
02947 request.data_size = data_size;
02948 ecrt_sdo_request_write(&request);
02949
02950 if (down_interruptible(&master->master_sem)) {
02951 ec_sdo_request_clear(&request);
02952 return -EINTR;
02953 }
02954
02955 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
02956 up(&master->master_sem);
02957 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
02958 ec_sdo_request_clear(&request);
02959 return -EINVAL;
02960 }
02961
02962 EC_SLAVE_DBG(slave, 1, "Scheduling SDO download request"
02963 " (complete access).\n");
02964
02965
02966 list_add_tail(&request.list, &slave->sdo_requests);
02967
02968 up(&master->master_sem);
02969
02970
02971 if (wait_event_interruptible(master->request_queue,
02972 request.state != EC_INT_REQUEST_QUEUED)) {
02973
02974 down(&master->master_sem);
02975 if (request.state == EC_INT_REQUEST_QUEUED) {
02976 list_del(&request.list);
02977 up(&master->master_sem);
02978 ec_sdo_request_clear(&request);
02979 return -EINTR;
02980 }
02981
02982 up(&master->master_sem);
02983 }
02984
02985
02986 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
02987
02988 *abort_code = request.abort_code;
02989
02990 if (request.state == EC_INT_REQUEST_SUCCESS) {
02991 ret = 0;
02992 } else if (request.errno) {
02993 ret = -request.errno;
02994 } else {
02995 ret = -EIO;
02996 }
02997
02998 ec_sdo_request_clear(&request);
02999 return ret;
03000 }
03001
03002
03003
03004 int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
03005 uint16_t index, uint8_t subindex, uint8_t *target,
03006 size_t target_size, size_t *result_size, uint32_t *abort_code)
03007 {
03008 ec_sdo_request_t request;
03009 ec_slave_t *slave;
03010 int ret = 0;
03011
03012 EC_MASTER_DBG(master, 1, "%s(master = 0x%p,"
03013 " slave_position = %u, index = 0x%04X, subindex = 0x%02X,"
03014 " target = 0x%p, target_size = %zu, result_size = 0x%p,"
03015 " abort_code = 0x%p)\n",
03016 __func__, master, slave_position, index, subindex,
03017 target, target_size, result_size, abort_code);
03018
03019 ec_sdo_request_init(&request);
03020 ecrt_sdo_request_index(&request, index, subindex);
03021 ecrt_sdo_request_read(&request);
03022
03023 if (down_interruptible(&master->master_sem)) {
03024 ec_sdo_request_clear(&request);
03025 return -EINTR;
03026 }
03027
03028 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
03029 up(&master->master_sem);
03030 ec_sdo_request_clear(&request);
03031 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
03032 return -EINVAL;
03033 }
03034
03035 EC_SLAVE_DBG(slave, 1, "Scheduling SDO upload request.\n");
03036
03037
03038 list_add_tail(&request.list, &slave->sdo_requests);
03039
03040 up(&master->master_sem);
03041
03042
03043 if (wait_event_interruptible(master->request_queue,
03044 request.state != EC_INT_REQUEST_QUEUED)) {
03045
03046 down(&master->master_sem);
03047 if (request.state == EC_INT_REQUEST_QUEUED) {
03048 list_del(&request.list);
03049 up(&master->master_sem);
03050 ec_sdo_request_clear(&request);
03051 return -EINTR;
03052 }
03053
03054 up(&master->master_sem);
03055 }
03056
03057
03058 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
03059
03060 *abort_code = request.abort_code;
03061
03062 if (request.state != EC_INT_REQUEST_SUCCESS) {
03063 *result_size = 0;
03064 if (request.errno) {
03065 ret = -request.errno;
03066 } else {
03067 ret = -EIO;
03068 }
03069 } else {
03070 if (request.data_size > target_size) {
03071 EC_MASTER_ERR(master, "Buffer too small.\n");
03072 ret = -EOVERFLOW;
03073 }
03074 else {
03075 memcpy(target, request.data, request.data_size);
03076 *result_size = request.data_size;
03077 ret = 0;
03078 }
03079 }
03080
03081 ec_sdo_request_clear(&request);
03082 return ret;
03083 }
03084
03085
03086
03087 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
03088 uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
03089 uint16_t *error_code)
03090 {
03091 ec_soe_request_t request;
03092 ec_slave_t *slave;
03093 int ret;
03094
03095 if (drive_no > 7) {
03096 EC_MASTER_ERR(master, "Invalid drive number!\n");
03097 return -EINVAL;
03098 }
03099
03100 ec_soe_request_init(&request);
03101 ec_soe_request_set_drive_no(&request, drive_no);
03102 ec_soe_request_set_idn(&request, idn);
03103
03104 ret = ec_soe_request_alloc(&request, data_size);
03105 if (ret) {
03106 ec_soe_request_clear(&request);
03107 return ret;
03108 }
03109
03110 memcpy(request.data, data, data_size);
03111 request.data_size = data_size;
03112 ec_soe_request_write(&request);
03113
03114 if (down_interruptible(&master->master_sem)) {
03115 ec_soe_request_clear(&request);
03116 return -EINTR;
03117 }
03118
03119 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
03120 up(&master->master_sem);
03121 EC_MASTER_ERR(master, "Slave %u does not exist!\n",
03122 slave_position);
03123 ec_soe_request_clear(&request);
03124 return -EINVAL;
03125 }
03126
03127 EC_SLAVE_DBG(slave, 1, "Scheduling SoE write request.\n");
03128
03129
03130 list_add_tail(&request.list, &slave->soe_requests);
03131
03132 up(&master->master_sem);
03133
03134
03135 if (wait_event_interruptible(master->request_queue,
03136 request.state != EC_INT_REQUEST_QUEUED)) {
03137
03138 down(&master->master_sem);
03139 if (request.state == EC_INT_REQUEST_QUEUED) {
03140
03141 list_del(&request.list);
03142 up(&master->master_sem);
03143 ec_soe_request_clear(&request);
03144 return -EINTR;
03145 }
03146 up(&master->master_sem);
03147 }
03148
03149
03150 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
03151
03152 if (error_code) {
03153 *error_code = request.error_code;
03154 }
03155 ret = request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
03156 ec_soe_request_clear(&request);
03157
03158 return ret;
03159 }
03160
03161
03162
03163 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
03164 uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
03165 size_t *result_size, uint16_t *error_code)
03166 {
03167 ec_soe_request_t request;
03168 ec_slave_t *slave;
03169 int ret;
03170
03171 if (drive_no > 7) {
03172 EC_MASTER_ERR(master, "Invalid drive number!\n");
03173 return -EINVAL;
03174 }
03175
03176 ec_soe_request_init(&request);
03177 ec_soe_request_set_drive_no(&request, drive_no);
03178 ec_soe_request_set_idn(&request, idn);
03179 ec_soe_request_read(&request);
03180
03181 if (down_interruptible(&master->master_sem)) {
03182 ec_soe_request_clear(&request);
03183 return -EINTR;
03184 }
03185
03186 if (!(slave = ec_master_find_slave(master, 0, slave_position))) {
03187 up(&master->master_sem);
03188 ec_soe_request_clear(&request);
03189 EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
03190 return -EINVAL;
03191 }
03192
03193 EC_SLAVE_DBG(slave, 1, "Scheduling SoE read request.\n");
03194
03195
03196 list_add_tail(&request.list, &slave->soe_requests);
03197
03198 up(&master->master_sem);
03199
03200
03201 if (wait_event_interruptible(master->request_queue,
03202 request.state != EC_INT_REQUEST_QUEUED)) {
03203
03204 down(&master->master_sem);
03205 if (request.state == EC_INT_REQUEST_QUEUED) {
03206 list_del(&request.list);
03207 up(&master->master_sem);
03208 ec_soe_request_clear(&request);
03209 return -EINTR;
03210 }
03211
03212 up(&master->master_sem);
03213 }
03214
03215
03216 wait_event(master->request_queue, request.state != EC_INT_REQUEST_BUSY);
03217
03218 if (error_code) {
03219 *error_code = request.error_code;
03220 }
03221
03222 if (request.state != EC_INT_REQUEST_SUCCESS) {
03223 if (result_size) {
03224 *result_size = 0;
03225 }
03226 ret = -EIO;
03227 } else {
03228 if (request.data_size > target_size) {
03229 EC_MASTER_ERR(master, "Buffer too small.\n");
03230 ret = -EOVERFLOW;
03231 }
03232 else {
03233 if (result_size) {
03234 *result_size = request.data_size;
03235 }
03236 memcpy(target, request.data, request.data_size);
03237 ret = 0;
03238 }
03239 }
03240
03241 ec_soe_request_clear(&request);
03242 return ret;
03243 }
03244
03245
03246
03247 void ecrt_master_reset(ec_master_t *master)
03248 {
03249 ec_slave_config_t *sc;
03250
03251 list_for_each_entry(sc, &master->configs, list) {
03252 if (sc->slave) {
03253 ec_slave_request_state(sc->slave, EC_SLAVE_STATE_OP);
03254 }
03255 }
03256 }
03257
03258
03259
03262 EXPORT_SYMBOL(ecrt_master_create_domain);
03263 EXPORT_SYMBOL(ecrt_master_activate);
03264 EXPORT_SYMBOL(ecrt_master_deactivate);
03265 EXPORT_SYMBOL(ecrt_master_send);
03266 EXPORT_SYMBOL(ecrt_master_send_ext);
03267 EXPORT_SYMBOL(ecrt_master_receive);
03268 EXPORT_SYMBOL(ecrt_master_callbacks);
03269 EXPORT_SYMBOL(ecrt_master);
03270 EXPORT_SYMBOL(ecrt_master_get_slave);
03271 EXPORT_SYMBOL(ecrt_master_slave_config);
03272 EXPORT_SYMBOL(ecrt_master_select_reference_clock);
03273 EXPORT_SYMBOL(ecrt_master_state);
03274 EXPORT_SYMBOL(ecrt_master_link_state);
03275 EXPORT_SYMBOL(ecrt_master_application_time);
03276 EXPORT_SYMBOL(ecrt_master_sync_reference_clock);
03277 EXPORT_SYMBOL(ecrt_master_sync_slave_clocks);
03278 EXPORT_SYMBOL(ecrt_master_reference_clock_time);
03279 EXPORT_SYMBOL(ecrt_master_sync_monitor_queue);
03280 EXPORT_SYMBOL(ecrt_master_sync_monitor_process);
03281 EXPORT_SYMBOL(ecrt_master_sdo_download);
03282 EXPORT_SYMBOL(ecrt_master_sdo_download_complete);
03283 EXPORT_SYMBOL(ecrt_master_sdo_upload);
03284 EXPORT_SYMBOL(ecrt_master_write_idn);
03285 EXPORT_SYMBOL(ecrt_master_read_idn);
03286 EXPORT_SYMBOL(ecrt_master_reset);
03287
03290