218 ec_datagram_init(&master->fsm_datagram); |
219 ec_datagram_init(&master->fsm_datagram); |
219 snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm"); |
220 snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm"); |
220 ret = ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE); |
221 ret = ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE); |
221 if (ret < 0) { |
222 if (ret < 0) { |
222 ec_datagram_clear(&master->fsm_datagram); |
223 ec_datagram_clear(&master->fsm_datagram); |
223 EC_ERR("Failed to allocate FSM datagram.\n"); |
224 EC_MASTER_ERR(master, "Failed to allocate FSM datagram.\n"); |
224 goto out_clear_backup; |
225 goto out_clear_backup; |
225 } |
226 } |
226 |
227 |
227 // create state machine object |
228 // create state machine object |
228 ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram); |
229 ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram); |
231 ec_datagram_init(&master->ref_sync_datagram); |
232 ec_datagram_init(&master->ref_sync_datagram); |
232 snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "refsync"); |
233 snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "refsync"); |
233 ret = ec_datagram_apwr(&master->ref_sync_datagram, 0, 0x0910, 8); |
234 ret = ec_datagram_apwr(&master->ref_sync_datagram, 0, 0x0910, 8); |
234 if (ret < 0) { |
235 if (ret < 0) { |
235 ec_datagram_clear(&master->ref_sync_datagram); |
236 ec_datagram_clear(&master->ref_sync_datagram); |
236 EC_ERR("Failed to allocate reference synchronisation datagram.\n"); |
237 EC_MASTER_ERR(master, "Failed to allocate reference" |
|
238 " synchronisation datagram.\n"); |
237 goto out_clear_fsm; |
239 goto out_clear_fsm; |
238 } |
240 } |
239 |
241 |
240 // init sync datagram |
242 // init sync datagram |
241 ec_datagram_init(&master->sync_datagram); |
243 ec_datagram_init(&master->sync_datagram); |
242 snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync"); |
244 snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync"); |
243 ret = ec_datagram_prealloc(&master->sync_datagram, 4); |
245 ret = ec_datagram_prealloc(&master->sync_datagram, 4); |
244 if (ret < 0) { |
246 if (ret < 0) { |
245 ec_datagram_clear(&master->sync_datagram); |
247 ec_datagram_clear(&master->sync_datagram); |
246 EC_ERR("Failed to allocate synchronisation datagram.\n"); |
248 EC_MASTER_ERR(master, "Failed to allocate" |
|
249 " synchronisation datagram.\n"); |
247 goto out_clear_ref_sync; |
250 goto out_clear_ref_sync; |
248 } |
251 } |
249 |
252 |
250 // init sync monitor datagram |
253 // init sync monitor datagram |
251 ec_datagram_init(&master->sync_mon_datagram); |
254 ec_datagram_init(&master->sync_mon_datagram); |
252 snprintf(master->sync_mon_datagram.name, EC_DATAGRAM_NAME_SIZE, "syncmon"); |
255 snprintf(master->sync_mon_datagram.name, EC_DATAGRAM_NAME_SIZE, "syncmon"); |
253 ret = ec_datagram_brd(&master->sync_mon_datagram, 0x092c, 4); |
256 ret = ec_datagram_brd(&master->sync_mon_datagram, 0x092c, 4); |
254 if (ret < 0) { |
257 if (ret < 0) { |
255 ec_datagram_clear(&master->sync_mon_datagram); |
258 ec_datagram_clear(&master->sync_mon_datagram); |
256 EC_ERR("Failed to allocate sync monitoring datagram.\n"); |
259 EC_MASTER_ERR(master, "Failed to allocate sync" |
|
260 " monitoring datagram.\n"); |
257 goto out_clear_sync; |
261 goto out_clear_sync; |
258 } |
262 } |
259 |
263 |
260 ec_master_find_dc_ref_clock(master); |
264 ec_master_find_dc_ref_clock(master); |
261 |
265 |
384 |
388 |
385 master->dc_ref_clock = NULL; |
389 master->dc_ref_clock = NULL; |
386 |
390 |
387 // external requests are obsolete, so we wake pending waiters and remove |
391 // external requests are obsolete, so we wake pending waiters and remove |
388 // them from the list |
392 // them from the list |
389 // |
393 |
390 // SII requests |
394 while (!list_empty(&master->sii_requests)) { |
391 while (1) { |
395 ec_sii_write_request_t *request = |
392 ec_sii_write_request_t *request; |
396 list_entry(master->sii_requests.next, |
393 if (list_empty(&master->sii_requests)) |
397 ec_sii_write_request_t, list); |
394 break; |
|
395 // get first request |
|
396 request = list_entry(master->sii_requests.next, |
|
397 ec_sii_write_request_t, list); |
|
398 list_del_init(&request->list); // dequeue |
398 list_del_init(&request->list); // dequeue |
399 EC_INFO("Discarding SII request, slave %u does not exist anymore.\n", |
399 EC_MASTER_WARN(master, "Discarding SII request, slave %u about" |
400 request->slave->ring_position); |
400 " to be deleted.\n", request->slave->ring_position); |
401 request->state = EC_INT_REQUEST_FAILURE; |
401 request->state = EC_INT_REQUEST_FAILURE; |
402 wake_up(&master->sii_queue); |
402 wake_up(&master->sii_queue); |
403 } |
403 } |
404 |
404 |
405 // Register requests |
405 while (!list_empty(&master->reg_requests)) { |
406 while (1) { |
406 ec_reg_request_t *request = |
407 ec_reg_request_t *request; |
407 list_entry(master->reg_requests.next, ec_reg_request_t, list); |
408 if (list_empty(&master->reg_requests)) |
|
409 break; |
|
410 // get first request |
|
411 request = list_entry(master->reg_requests.next, |
|
412 ec_reg_request_t, list); |
|
413 list_del_init(&request->list); // dequeue |
408 list_del_init(&request->list); // dequeue |
414 EC_INFO("Discarding Reg request, slave %u does not exist anymore.\n", |
409 EC_MASTER_WARN(master, "Discarding register request, slave %u" |
415 request->slave->ring_position); |
410 " about to be deleted.\n", request->slave->ring_position); |
416 request->state = EC_INT_REQUEST_FAILURE; |
411 request->state = EC_INT_REQUEST_FAILURE; |
417 wake_up(&master->reg_queue); |
412 wake_up(&master->reg_queue); |
418 } |
413 } |
419 |
414 |
420 for (slave = master->slaves; |
415 for (slave = master->slaves; |
421 slave < master->slaves + master->slave_count; |
416 slave < master->slaves + master->slave_count; |
422 slave++) { |
417 slave++) { |
423 // SDO requests |
|
424 while (1) { |
|
425 ec_master_sdo_request_t *request; |
|
426 if (list_empty(&slave->slave_sdo_requests)) |
|
427 break; |
|
428 // get first request |
|
429 request = list_entry(slave->slave_sdo_requests.next, |
|
430 ec_master_sdo_request_t, list); |
|
431 list_del_init(&request->list); // dequeue |
|
432 EC_INFO("Discarding SDO request," |
|
433 " slave %u does not exist anymore.\n", |
|
434 slave->ring_position); |
|
435 request->req.state = EC_INT_REQUEST_FAILURE; |
|
436 wake_up(&slave->sdo_queue); |
|
437 } |
|
438 // FoE requests |
|
439 while (1) { |
|
440 ec_master_foe_request_t *request; |
|
441 if (list_empty(&slave->foe_requests)) |
|
442 break; |
|
443 // get first request |
|
444 request = list_entry(slave->foe_requests.next, |
|
445 ec_master_foe_request_t, list); |
|
446 list_del_init(&request->list); // dequeue |
|
447 EC_INFO("Discarding FoE request," |
|
448 " slave %u does not exist anymore.\n", |
|
449 slave->ring_position); |
|
450 request->req.state = EC_INT_REQUEST_FAILURE; |
|
451 wake_up(&slave->foe_queue); |
|
452 } |
|
453 // SoE requests |
|
454 while (1) { |
|
455 ec_master_soe_request_t *request; |
|
456 if (list_empty(&slave->soe_requests)) |
|
457 break; |
|
458 // get first request |
|
459 request = list_entry(slave->soe_requests.next, |
|
460 ec_master_soe_request_t, list); |
|
461 list_del_init(&request->list); // dequeue |
|
462 EC_INFO("Discarding SoE request," |
|
463 " slave %u does not exist anymore.\n", |
|
464 slave->ring_position); |
|
465 request->req.state = EC_INT_REQUEST_FAILURE; |
|
466 wake_up(&slave->soe_queue); |
|
467 } |
|
468 ec_slave_clear(slave); |
418 ec_slave_clear(slave); |
469 } |
419 } |
470 |
420 |
471 if (master->slaves) { |
421 if (master->slaves) { |
472 kfree(master->slaves); |
422 kfree(master->slaves); |
530 ec_master_t *master, /**< EtherCAT master */ |
480 ec_master_t *master, /**< EtherCAT master */ |
531 int (*thread_func)(void *), /**< thread function to start */ |
481 int (*thread_func)(void *), /**< thread function to start */ |
532 const char *name /**< Thread name. */ |
482 const char *name /**< Thread name. */ |
533 ) |
483 ) |
534 { |
484 { |
535 EC_INFO("Starting %s thread.\n", name); |
485 EC_MASTER_INFO(master, "Starting %s thread.\n", name); |
536 master->thread = kthread_run(thread_func, master, name); |
486 master->thread = kthread_run(thread_func, master, name); |
537 if (IS_ERR(master->thread)) { |
487 if (IS_ERR(master->thread)) { |
538 int err = (int) PTR_ERR(master->thread); |
488 int err = (int) PTR_ERR(master->thread); |
539 EC_ERR("Failed to start master thread (error %i)!\n", err); |
489 EC_MASTER_ERR(master, "Failed to start master thread (error %i)!\n", |
|
490 err); |
540 master->thread = NULL; |
491 master->thread = NULL; |
541 return err; |
492 return err; |
542 } |
493 } |
543 |
494 |
544 return 0; |
495 return 0; |
553 ) |
504 ) |
554 { |
505 { |
555 unsigned long sleep_jiffies; |
506 unsigned long sleep_jiffies; |
556 |
507 |
557 if (!master->thread) { |
508 if (!master->thread) { |
558 EC_WARN("ec_master_thread_stop(): Already finished!\n"); |
509 EC_MASTER_WARN(master, "%s(): Already finished!\n", __func__); |
559 return; |
510 return; |
560 } |
511 } |
561 |
512 |
562 if (master->debug_level) |
513 EC_MASTER_DBG(master, 1, "Stopping master thread.\n"); |
563 EC_DBG("Stopping master thread.\n"); |
|
564 |
514 |
565 kthread_stop(master->thread); |
515 kthread_stop(master->thread); |
566 master->thread = NULL; |
516 master->thread = NULL; |
567 EC_INFO("Master thread exited.\n"); |
517 EC_MASTER_INFO(master, "Master thread exited.\n"); |
568 |
518 |
569 if (master->fsm_datagram.state != EC_DATAGRAM_SENT) |
519 if (master->fsm_datagram.state != EC_DATAGRAM_SENT) |
570 return; |
520 return; |
571 |
521 |
572 // wait for FSM datagram |
522 // wait for FSM datagram |
631 ec_slave_t *slave; |
579 ec_slave_t *slave; |
632 #ifdef EC_EOE |
580 #ifdef EC_EOE |
633 ec_eoe_t *eoe; |
581 ec_eoe_t *eoe; |
634 #endif |
582 #endif |
635 |
583 |
636 if (master->debug_level) |
584 EC_MASTER_DBG(master, 1, "IDLE -> OPERATION.\n"); |
637 EC_DBG("IDLE -> OPERATION.\n"); |
|
638 |
585 |
639 down(&master->config_sem); |
586 down(&master->config_sem); |
640 master->allow_config = 0; // temporarily disable slave configuration |
587 master->allow_config = 0; // temporarily disable slave configuration |
641 if (master->config_busy) { |
588 if (master->config_busy) { |
642 up(&master->config_sem); |
589 up(&master->config_sem); |
643 |
590 |
644 // wait for slave configuration to complete |
591 // wait for slave configuration to complete |
645 ret = wait_event_interruptible(master->config_queue, |
592 ret = wait_event_interruptible(master->config_queue, |
646 !master->config_busy); |
593 !master->config_busy); |
647 if (ret) { |
594 if (ret) { |
648 EC_INFO("Finishing slave configuration interrupted by signal.\n"); |
595 EC_MASTER_INFO(master, "Finishing slave configuration" |
|
596 " interrupted by signal.\n"); |
649 goto out_allow; |
597 goto out_allow; |
650 } |
598 } |
651 |
599 |
652 if (master->debug_level) |
600 EC_MASTER_DBG(master, 1, "Waiting for pending slave" |
653 EC_DBG("Waiting for pending slave configuration returned.\n"); |
601 " configuration returned.\n"); |
654 } else { |
602 } else { |
655 up(&master->config_sem); |
603 up(&master->config_sem); |
656 } |
604 } |
657 |
605 |
658 down(&master->scan_sem); |
606 down(&master->scan_sem); |
663 up(&master->scan_sem); |
611 up(&master->scan_sem); |
664 |
612 |
665 // wait for slave scan to complete |
613 // wait for slave scan to complete |
666 ret = wait_event_interruptible(master->scan_queue, !master->scan_busy); |
614 ret = wait_event_interruptible(master->scan_queue, !master->scan_busy); |
667 if (ret) { |
615 if (ret) { |
668 EC_INFO("Waiting for slave scan interrupted by signal.\n"); |
616 EC_MASTER_INFO(master, "Waiting for slave scan" |
|
617 " interrupted by signal.\n"); |
669 goto out_allow; |
618 goto out_allow; |
670 } |
619 } |
671 |
620 |
672 if (master->debug_level) |
621 EC_MASTER_DBG(master, 1, "Waiting for pending" |
673 EC_DBG("Waiting for pending slave scan returned.\n"); |
622 " slave scan returned.\n"); |
674 } |
623 } |
675 |
624 |
676 // set states for all slaves |
625 // set states for all slaves |
677 for (slave = master->slaves; |
626 for (slave = master->slaves; |
678 slave < master->slaves + master->slave_count; |
627 slave < master->slaves + master->slave_count; |
737 queue) { |
685 queue) { |
738 queue_size += datagram->data_size; |
686 queue_size += datagram->data_size; |
739 if (queue_size <= master->max_queue_size) { |
687 if (queue_size <= master->max_queue_size) { |
740 list_del_init(&datagram->queue); |
688 list_del_init(&datagram->queue); |
741 #if DEBUG_INJECT |
689 #if DEBUG_INJECT |
742 if (master->debug_level) { |
690 EC_MASTER_DBG(master, 0, "Injecting external datagram %08x" |
743 EC_DBG("Injecting external datagram %08x size=%u," |
691 " size=%u, queue_size=%u\n", (unsigned int) datagram, |
744 " queue_size=%u\n", (unsigned int) datagram, |
692 datagram->data_size, queue_size); |
745 datagram->data_size, queue_size); |
|
746 } |
|
747 #endif |
693 #endif |
748 #ifdef EC_HAVE_CYCLES |
694 #ifdef EC_HAVE_CYCLES |
749 datagram->cycles_sent = 0; |
695 datagram->cycles_sent = 0; |
750 #endif |
696 #endif |
751 datagram->jiffies_sent = 0; |
697 datagram->jiffies_sent = 0; |
753 } |
699 } |
754 else { |
700 else { |
755 if (datagram->data_size > master->max_queue_size) { |
701 if (datagram->data_size > master->max_queue_size) { |
756 list_del_init(&datagram->queue); |
702 list_del_init(&datagram->queue); |
757 datagram->state = EC_DATAGRAM_ERROR; |
703 datagram->state = EC_DATAGRAM_ERROR; |
758 EC_ERR("External datagram %p is too large," |
704 EC_MASTER_ERR(master, "External datagram %p is too large," |
759 " size=%u, max_queue_size=%u\n", |
705 " size=%u, max_queue_size=%u\n", |
760 datagram, datagram->data_size, |
706 datagram, datagram->data_size, |
761 master->max_queue_size); |
707 master->max_queue_size); |
762 } else { |
708 } else { |
763 #ifdef EC_HAVE_CYCLES |
709 #ifdef EC_HAVE_CYCLES |
780 / cpu_khz; |
726 / cpu_khz; |
781 #else |
727 #else |
782 time_us = (unsigned int) |
728 time_us = (unsigned int) |
783 ((jiffies - datagram->jiffies_sent) * 1000000 / HZ); |
729 ((jiffies - datagram->jiffies_sent) * 1000000 / HZ); |
784 #endif |
730 #endif |
785 EC_ERR("Timeout %u us: injecting external datagram %p" |
731 EC_MASTER_ERR(master, "Timeout %u us: Injecting" |
786 " size=%u, max_queue_size=%u\n", |
732 " external datagram %p size=%u," |
787 time_us, datagram, |
733 " max_queue_size=%u\n", time_us, datagram, |
788 datagram->data_size, master->max_queue_size); |
734 datagram->data_size, master->max_queue_size); |
789 } |
735 } |
790 #if DEBUG_INJECT |
736 #if DEBUG_INJECT |
791 else if (master->debug_level) { |
737 else { |
792 EC_DBG("Deferred injecting of external datagram %p" |
738 EC_MASTER_DBG(master, 0, "Deferred injecting" |
|
739 " of external datagram %p" |
793 " size=%u, queue_size=%u\n", |
740 " size=%u, queue_size=%u\n", |
794 datagram, datagram->data_size, queue_size); |
741 datagram, datagram->data_size, queue_size); |
795 } |
742 } |
796 #endif |
743 #endif |
797 } |
744 } |
1061 ec_datagram_t *datagram; |
1002 ec_datagram_t *datagram; |
1062 ec_fmmu_config_t* domain_fmmu; |
1003 ec_fmmu_config_t* domain_fmmu; |
1063 |
1004 |
1064 if (unlikely(size < EC_FRAME_HEADER_SIZE)) { |
1005 if (unlikely(size < EC_FRAME_HEADER_SIZE)) { |
1065 if (master->debug_level) { |
1006 if (master->debug_level) { |
1066 EC_DBG("Corrupted frame received (size %zu < %u byte):\n", |
1007 EC_MASTER_DBG(master, 0, "Corrupted frame received" |
|
1008 " (size %zu < %u byte):\n", |
1067 size, EC_FRAME_HEADER_SIZE); |
1009 size, EC_FRAME_HEADER_SIZE); |
1068 ec_print_data(frame_data, size); |
1010 ec_print_data(frame_data, size); |
1069 } |
1011 } |
1070 master->stats.corrupted++; |
1012 master->stats.corrupted++; |
1071 ec_master_output_stats(master); |
1013 ec_master_output_stats(master); |
1078 frame_size = EC_READ_U16(cur_data) & 0x07FF; |
1020 frame_size = EC_READ_U16(cur_data) & 0x07FF; |
1079 cur_data += EC_FRAME_HEADER_SIZE; |
1021 cur_data += EC_FRAME_HEADER_SIZE; |
1080 |
1022 |
1081 if (unlikely(frame_size > size)) { |
1023 if (unlikely(frame_size > size)) { |
1082 if (master->debug_level) { |
1024 if (master->debug_level) { |
1083 EC_DBG("Corrupted frame received (invalid frame size %zu for " |
1025 EC_MASTER_DBG(master, 0, "Corrupted frame received" |
|
1026 " (invalid frame size %zu for " |
1084 "received size %zu):\n", frame_size, size); |
1027 "received size %zu):\n", frame_size, size); |
1085 ec_print_data(frame_data, size); |
1028 ec_print_data(frame_data, size); |
1086 } |
1029 } |
1087 master->stats.corrupted++; |
1030 master->stats.corrupted++; |
1088 ec_master_output_stats(master); |
1031 ec_master_output_stats(master); |
1099 cur_data += EC_DATAGRAM_HEADER_SIZE; |
1042 cur_data += EC_DATAGRAM_HEADER_SIZE; |
1100 |
1043 |
1101 if (unlikely(cur_data - frame_data |
1044 if (unlikely(cur_data - frame_data |
1102 + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) { |
1045 + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) { |
1103 if (master->debug_level) { |
1046 if (master->debug_level) { |
1104 EC_DBG("Corrupted frame received (invalid data size %zu):\n", |
1047 EC_MASTER_DBG(master, 0, "Corrupted frame received" |
1105 data_size); |
1048 " (invalid data size %zu):\n", data_size); |
1106 ec_print_data(frame_data, size); |
1049 ec_print_data(frame_data, size); |
1107 } |
1050 } |
1108 master->stats.corrupted++; |
1051 master->stats.corrupted++; |
1109 ec_master_output_stats(master); |
1052 ec_master_output_stats(master); |
1110 return; |
1053 return; |
1126 if (!matched) { |
1069 if (!matched) { |
1127 master->stats.unmatched++; |
1070 master->stats.unmatched++; |
1128 ec_master_output_stats(master); |
1071 ec_master_output_stats(master); |
1129 |
1072 |
1130 if (unlikely(master->debug_level > 0)) { |
1073 if (unlikely(master->debug_level > 0)) { |
1131 EC_DBG("UNMATCHED datagram:\n"); |
1074 EC_MASTER_DBG(master, 0, "UNMATCHED datagram:\n"); |
1132 ec_print_data(cur_data - EC_DATAGRAM_HEADER_SIZE, |
1075 ec_print_data(cur_data - EC_DATAGRAM_HEADER_SIZE, |
1133 EC_DATAGRAM_HEADER_SIZE + data_size |
1076 EC_DATAGRAM_HEADER_SIZE + data_size |
1134 + EC_DATAGRAM_FOOTER_SIZE); |
1077 + EC_DATAGRAM_FOOTER_SIZE); |
1135 #ifdef EC_DEBUG_RING |
1078 #ifdef EC_DEBUG_RING |
1136 ec_device_debug_ring_print(&master->main_device); |
1079 ec_device_debug_ring_print(&master->main_device); |
1190 { |
1133 { |
1191 if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) { |
1134 if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) { |
1192 master->stats.output_jiffies = jiffies; |
1135 master->stats.output_jiffies = jiffies; |
1193 |
1136 |
1194 if (master->stats.timeouts) { |
1137 if (master->stats.timeouts) { |
1195 EC_WARN("%u datagram%s TIMED OUT!\n", master->stats.timeouts, |
1138 EC_MASTER_WARN(master, "%u datagram%s TIMED OUT!\n", |
|
1139 master->stats.timeouts, |
1196 master->stats.timeouts == 1 ? "" : "s"); |
1140 master->stats.timeouts == 1 ? "" : "s"); |
1197 master->stats.timeouts = 0; |
1141 master->stats.timeouts = 0; |
1198 } |
1142 } |
1199 if (master->stats.corrupted) { |
1143 if (master->stats.corrupted) { |
1200 EC_WARN("%u frame%s CORRUPTED!\n", master->stats.corrupted, |
1144 EC_MASTER_WARN(master, "%u frame%s CORRUPTED!\n", |
|
1145 master->stats.corrupted, |
1201 master->stats.corrupted == 1 ? "" : "s"); |
1146 master->stats.corrupted == 1 ? "" : "s"); |
1202 master->stats.corrupted = 0; |
1147 master->stats.corrupted = 0; |
1203 } |
1148 } |
1204 if (master->stats.unmatched) { |
1149 if (master->stats.unmatched) { |
1205 EC_WARN("%u datagram%s UNMATCHED!\n", master->stats.unmatched, |
1150 EC_MASTER_WARN(master, "%u datagram%s UNMATCHED!\n", |
|
1151 master->stats.unmatched, |
1206 master->stats.unmatched == 1 ? "" : "s"); |
1152 master->stats.unmatched == 1 ? "" : "s"); |
1207 master->stats.unmatched = 0; |
1153 master->stats.unmatched = 0; |
1208 } |
1154 } |
1209 } |
1155 } |
1210 } |
1156 } |
1365 { |
1309 { |
1366 ec_master_t *master = (ec_master_t *) priv_data; |
1310 ec_master_t *master = (ec_master_t *) priv_data; |
1367 ec_slave_t *slave = NULL; |
1311 ec_slave_t *slave = NULL; |
1368 int fsm_exec; |
1312 int fsm_exec; |
1369 |
1313 |
1370 if (master->debug_level) |
1314 EC_MASTER_DBG(master, 1, "Operation thread running" |
1371 EC_DBG("Operation thread running with fsm interval = %d us," |
1315 " with fsm interval = %d us, max data size=%d\n", |
1372 " max data size=%d\n", |
1316 master->send_interval, master->max_queue_size); |
1373 master->send_interval, |
|
1374 master->max_queue_size); |
|
1375 |
1317 |
1376 while (!kthread_should_stop()) { |
1318 while (!kthread_should_stop()) { |
1377 ec_datagram_output_stats(&master->fsm_datagram); |
1319 ec_datagram_output_stats(&master->fsm_datagram); |
1378 |
1320 |
1379 if (master->injection_seq_rt == master->injection_seq_fsm) { |
1321 if (master->injection_seq_rt == master->injection_seq_fsm) { |
1424 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */) |
1365 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */) |
1425 { |
1366 { |
1426 struct sched_param param = { .sched_priority = 0 }; |
1367 struct sched_param param = { .sched_priority = 0 }; |
1427 |
1368 |
1428 if (master->eoe_thread) { |
1369 if (master->eoe_thread) { |
1429 EC_WARN("EoE already running!\n"); |
1370 EC_MASTER_WARN(master, "EoE already running!\n"); |
1430 return; |
1371 return; |
1431 } |
1372 } |
1432 |
1373 |
1433 if (list_empty(&master->eoe_handlers)) |
1374 if (list_empty(&master->eoe_handlers)) |
1434 return; |
1375 return; |
1435 |
1376 |
1436 if (!master->send_cb || !master->receive_cb) { |
1377 if (!master->send_cb || !master->receive_cb) { |
1437 EC_WARN("No EoE processing because of missing callbacks!\n"); |
1378 EC_MASTER_WARN(master, "No EoE processing" |
|
1379 " because of missing callbacks!\n"); |
1438 return; |
1380 return; |
1439 } |
1381 } |
1440 |
1382 |
1441 EC_INFO("Starting EoE thread.\n"); |
1383 EC_MASTER_INFO(master, "Starting EoE thread.\n"); |
1442 master->eoe_thread = kthread_run(ec_master_eoe_thread, master, |
1384 master->eoe_thread = kthread_run(ec_master_eoe_thread, master, |
1443 "EtherCAT-EoE"); |
1385 "EtherCAT-EoE"); |
1444 if (IS_ERR(master->eoe_thread)) { |
1386 if (IS_ERR(master->eoe_thread)) { |
1445 int err = (int) PTR_ERR(master->eoe_thread); |
1387 int err = (int) PTR_ERR(master->eoe_thread); |
1446 EC_ERR("Failed to start EoE thread (error %i)!\n", err); |
1388 EC_MASTER_ERR(master, "Failed to start EoE thread (error %i)!\n", |
|
1389 err); |
1447 master->eoe_thread = NULL; |
1390 master->eoe_thread = NULL; |
1448 return; |
1391 return; |
1449 } |
1392 } |
1450 |
1393 |
1451 sched_setscheduler(master->eoe_thread, SCHED_NORMAL, ¶m); |
1394 sched_setscheduler(master->eoe_thread, SCHED_NORMAL, ¶m); |
1928 ec_master_calc_topology(master); |
1870 ec_master_calc_topology(master); |
1929 |
1871 |
1930 ec_master_calc_transmission_delays(master); |
1872 ec_master_calc_transmission_delays(master); |
1931 } |
1873 } |
1932 |
1874 |
|
1875 /*****************************************************************************/ |
|
1876 |
|
1877 /** Request OP state for configured slaves. |
|
1878 */ |
|
1879 void ec_master_request_op( |
|
1880 ec_master_t *master /**< EtherCAT master. */ |
|
1881 ) |
|
1882 { |
|
1883 unsigned int i; |
|
1884 ec_slave_t *slave; |
|
1885 |
|
1886 if (!master->active) |
|
1887 return; |
|
1888 |
|
1889 EC_MASTER_DBG(master, 1, "Requesting OP...\n"); |
|
1890 |
|
1891 // request OP for all configured slaves |
|
1892 for (i = 0; i < master->slave_count; i++) { |
|
1893 slave = master->slaves + i; |
|
1894 if (slave->config) { |
|
1895 ec_slave_request_state(slave, EC_SLAVE_STATE_OP); |
|
1896 } |
|
1897 } |
|
1898 |
|
1899 // always set DC reference clock to OP |
|
1900 if (master->dc_ref_clock) { |
|
1901 ec_slave_request_state(master->dc_ref_clock, |
|
1902 EC_SLAVE_STATE_OP); |
|
1903 } |
|
1904 } |
|
1905 |
1933 /****************************************************************************** |
1906 /****************************************************************************** |
1934 * Application interface |
1907 * Application interface |
1935 *****************************************************************************/ |
1908 *****************************************************************************/ |
1936 |
1909 |
1937 /** Same as ecrt_master_create_domain(), but with ERR_PTR() return value. |
1910 /** Same as ecrt_master_create_domain(), but with ERR_PTR() return value. |
2006 domain_offset = 0; |
1977 domain_offset = 0; |
2007 list_for_each_entry(domain, &master->domains, list) { |
1978 list_for_each_entry(domain, &master->domains, list) { |
2008 ret = ec_domain_finish(domain, domain_offset); |
1979 ret = ec_domain_finish(domain, domain_offset); |
2009 if (ret < 0) { |
1980 if (ret < 0) { |
2010 up(&master->master_sem); |
1981 up(&master->master_sem); |
2011 EC_ERR("Failed to finish domain 0x%p!\n", domain); |
1982 EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain); |
2012 return ret; |
1983 return ret; |
2013 } |
1984 } |
2014 domain_offset += domain->data_size; |
1985 domain_offset += domain->data_size; |
2015 } |
1986 } |
2016 |
1987 |
2017 // always set DC reference clock to OP |
|
2018 if (master->dc_ref_clock) { |
|
2019 ec_slave_request_state(master->dc_ref_clock, EC_SLAVE_STATE_OP); |
|
2020 } |
|
2021 |
|
2022 up(&master->master_sem); |
1988 up(&master->master_sem); |
2023 |
1989 |
2024 // restart EoE process and master thread with new locking |
1990 // restart EoE process and master thread with new locking |
2025 |
1991 |
2026 ec_master_thread_stop(master); |
1992 ec_master_thread_stop(master); |
2027 #ifdef EC_EOE |
1993 #ifdef EC_EOE |
2028 eoe_was_running = master->eoe_thread != NULL; |
1994 eoe_was_running = master->eoe_thread != NULL; |
2029 ec_master_eoe_stop(master); |
1995 ec_master_eoe_stop(master); |
2030 #endif |
1996 #endif |
2031 |
1997 |
2032 if (master->debug_level) |
1998 EC_MASTER_DBG(master, 1, "FSM datagram is %p.\n", &master->fsm_datagram); |
2033 EC_DBG("FSM datagram is %p.\n", &master->fsm_datagram); |
|
2034 |
1999 |
2035 master->injection_seq_fsm = 0; |
2000 master->injection_seq_fsm = 0; |
2036 master->injection_seq_rt = 0; |
2001 master->injection_seq_rt = 0; |
2037 |
2002 |
2038 master->send_cb = master->app_send_cb; |
2003 master->send_cb = master->app_send_cb; |
2227 { |
2197 { |
2228 ec_slave_config_t *sc; |
2198 ec_slave_config_t *sc; |
2229 unsigned int found = 0; |
2199 unsigned int found = 0; |
2230 |
2200 |
2231 |
2201 |
2232 if (master->debug_level) |
2202 EC_MASTER_DBG(master, 1, "ecrt_master_slave_config(master = 0x%p," |
2233 EC_DBG("ecrt_master_slave_config(master = 0x%p, alias = %u, " |
2203 " alias = %u, position = %u, vendor_id = 0x%08x," |
2234 "position = %u, vendor_id = 0x%08x, product_code = 0x%08x)\n", |
2204 " product_code = 0x%08x)\n", |
2235 master, alias, position, vendor_id, product_code); |
2205 master, alias, position, vendor_id, product_code); |
2236 |
2206 |
2237 list_for_each_entry(sc, &master->configs, list) { |
2207 list_for_each_entry(sc, &master->configs, list) { |
2238 if (sc->alias == alias && sc->position == position) { |
2208 if (sc->alias == alias && sc->position == position) { |
2239 found = 1; |
2209 found = 1; |
2240 break; |
2210 break; |
2241 } |
2211 } |
2242 } |
2212 } |
2243 |
2213 |
2244 if (found) { // config with same alias/position already existing |
2214 if (found) { // config with same alias/position already existing |
2245 if (sc->vendor_id != vendor_id || sc->product_code != product_code) { |
2215 if (sc->vendor_id != vendor_id || sc->product_code != product_code) { |
2246 EC_ERR("Slave type mismatch. Slave was configured as" |
2216 EC_MASTER_ERR(master, "Slave type mismatch. Slave was" |
2247 " 0x%08X/0x%08X before. Now configuring with" |
2217 " configured as 0x%08X/0x%08X before. Now configuring" |
2248 " 0x%08X/0x%08X.\n", sc->vendor_id, sc->product_code, |
2218 " with 0x%08X/0x%08X.\n", sc->vendor_id, sc->product_code, |
2249 vendor_id, product_code); |
2219 vendor_id, product_code); |
2250 return ERR_PTR(-ENOENT); |
2220 return ERR_PTR(-ENOENT); |
2251 } |
2221 } |
2252 } else { |
2222 } else { |
2253 if (master->debug_level) |
2223 EC_MASTER_DBG(master, 1, "Creating slave configuration for %u:%u," |
2254 EC_DBG("Creating slave configuration for %u:%u, 0x%08X/0x%08X.\n", |
2224 " 0x%08X/0x%08X.\n", |
2255 alias, position, vendor_id, product_code); |
2225 alias, position, vendor_id, product_code); |
2256 |
2226 |
2257 if (!(sc = (ec_slave_config_t *) kmalloc(sizeof(ec_slave_config_t), |
2227 if (!(sc = (ec_slave_config_t *) kmalloc(sizeof(ec_slave_config_t), |
2258 GFP_KERNEL))) { |
2228 GFP_KERNEL))) { |
2259 EC_ERR("Failed to allocate memory for slave configuration.\n"); |
2229 EC_MASTER_ERR(master, "Failed to allocate memory" |
|
2230 " for slave configuration.\n"); |
2260 return ERR_PTR(-ENOMEM); |
2231 return ERR_PTR(-ENOMEM); |
2261 } |
2232 } |
2262 |
2233 |
2263 ec_slave_config_init(sc, master, |
2234 ec_slave_config_init(sc, master, |
2264 alias, position, vendor_id, product_code); |
2235 alias, position, vendor_id, product_code); |
2289 |
2260 |
2290 /*****************************************************************************/ |
2261 /*****************************************************************************/ |
2291 |
2262 |
2292 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info) |
2263 int ecrt_master(ec_master_t *master, ec_master_info_t *master_info) |
2293 { |
2264 { |
2294 if (master->debug_level) |
2265 EC_MASTER_DBG(master, 1, "ecrt_master(master = 0x%p," |
2295 EC_DBG("ecrt_master(master = 0x%p, master_info = 0x%p)\n", |
2266 " master_info = 0x%p)\n", master, master_info); |
2296 master, master_info); |
|
2297 |
2267 |
2298 master_info->slave_count = master->slave_count; |
2268 master_info->slave_count = master->slave_count; |
2299 master_info->link_up = master->main_device.link_state; |
2269 master_info->link_up = master->main_device.link_state; |
2300 master_info->scan_busy = master->scan_busy; |
2270 master_info->scan_busy = master->scan_busy; |
2301 master_info->app_time = master->app_time; |
2271 master_info->app_time = master->app_time; |
2340 /*****************************************************************************/ |
2310 /*****************************************************************************/ |
2341 |
2311 |
2342 void ecrt_master_callbacks(ec_master_t *master, |
2312 void ecrt_master_callbacks(ec_master_t *master, |
2343 void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data) |
2313 void (*send_cb)(void *), void (*receive_cb)(void *), void *cb_data) |
2344 { |
2314 { |
2345 if (master->debug_level) |
2315 EC_MASTER_DBG(master, 1, "ecrt_master_callbacks(master = 0x%p," |
2346 EC_DBG("ecrt_master_callbacks(master = 0x%p, send_cb = 0x%p, " |
2316 " send_cb = 0x%p, receive_cb = 0x%p, cb_data = 0x%p)\n", |
2347 " receive_cb = 0x%p, cb_data = 0x%p)\n", master, |
2317 master, send_cb, receive_cb, cb_data); |
2348 send_cb, receive_cb, cb_data); |
|
2349 |
2318 |
2350 master->app_send_cb = send_cb; |
2319 master->app_send_cb = send_cb; |
2351 master->app_receive_cb = receive_cb; |
2320 master->app_receive_cb = receive_cb; |
2352 master->app_cb_data = cb_data; |
2321 master->app_cb_data = cb_data; |
2353 } |
2322 } |