144 init_waitqueue_head(&master->config_queue); |
144 init_waitqueue_head(&master->config_queue); |
145 |
145 |
146 INIT_LIST_HEAD(&master->datagram_queue); |
146 INIT_LIST_HEAD(&master->datagram_queue); |
147 master->datagram_index = 0; |
147 master->datagram_index = 0; |
148 |
148 |
|
149 INIT_LIST_HEAD(&master->ext_datagram_queue); |
|
150 init_MUTEX(&master->ext_queue_sem); |
|
151 |
149 INIT_LIST_HEAD(&master->domains); |
152 INIT_LIST_HEAD(&master->domains); |
150 |
153 |
151 master->debug_level = debug_level; |
154 master->debug_level = debug_level; |
152 master->stats.timeouts = 0; |
155 master->stats.timeouts = 0; |
153 master->stats.corrupted = 0; |
156 master->stats.corrupted = 0; |
161 master->eoe_thread = NULL; |
164 master->eoe_thread = NULL; |
162 INIT_LIST_HEAD(&master->eoe_handlers); |
165 INIT_LIST_HEAD(&master->eoe_handlers); |
163 #endif |
166 #endif |
164 |
167 |
165 init_MUTEX(&master->io_sem); |
168 init_MUTEX(&master->io_sem); |
166 master->request_cb = NULL; |
169 master->send_cb = NULL; |
167 master->release_cb = NULL; |
170 master->receive_cb = NULL; |
168 master->cb_data = NULL; |
171 master->app_send_cb = NULL; |
|
172 master->app_receive_cb = NULL; |
169 |
173 |
170 INIT_LIST_HEAD(&master->sii_requests); |
174 INIT_LIST_HEAD(&master->sii_requests); |
171 init_waitqueue_head(&master->sii_queue); |
175 init_waitqueue_head(&master->sii_queue); |
172 |
176 |
173 INIT_LIST_HEAD(&master->slave_sdo_requests); |
177 INIT_LIST_HEAD(&master->slave_sdo_requests); |
373 } |
377 } |
374 } |
378 } |
375 |
379 |
376 /*****************************************************************************/ |
380 /*****************************************************************************/ |
377 |
381 |
378 /** Internal locking callback. |
382 /** Internal sending callback. |
379 */ |
383 */ |
380 int ec_master_request_cb(void *data /**< callback data */) |
384 void ec_master_internal_send_cb( |
381 { |
385 ec_master_t *master /**< EtherCAT master. */ |
382 ec_master_t *master = (ec_master_t *) data; |
386 ) |
|
387 { |
383 down(&master->io_sem); |
388 down(&master->io_sem); |
384 return 0; |
389 ecrt_master_send_ext(master); |
385 } |
390 up(&master->io_sem); |
386 |
391 } |
387 /*****************************************************************************/ |
392 |
388 |
393 /*****************************************************************************/ |
389 /** Internal unlocking callback. |
394 |
390 */ |
395 /** Internal receiving callback. |
391 void ec_master_release_cb(void *data /**< callback data */) |
396 */ |
392 { |
397 void ec_master_internal_receive_cb( |
393 ec_master_t *master = (ec_master_t *) data; |
398 ec_master_t *master /**< EtherCAT master. */ |
|
399 ) |
|
400 { |
|
401 down(&master->io_sem); |
|
402 ecrt_master_receive(master); |
394 up(&master->io_sem); |
403 up(&master->io_sem); |
395 } |
404 } |
396 |
405 |
397 /*****************************************************************************/ |
406 /*****************************************************************************/ |
398 |
407 |
460 int ret; |
469 int ret; |
461 |
470 |
462 if (master->debug_level) |
471 if (master->debug_level) |
463 EC_DBG("ORPHANED -> IDLE.\n"); |
472 EC_DBG("ORPHANED -> IDLE.\n"); |
464 |
473 |
465 master->request_cb = ec_master_request_cb; |
474 master->send_cb = ec_master_internal_send_cb; |
466 master->release_cb = ec_master_release_cb; |
475 master->receive_cb = ec_master_internal_receive_cb; |
467 master->cb_data = master; |
|
468 |
476 |
469 master->phase = EC_IDLE; |
477 master->phase = EC_IDLE; |
470 ret = ec_master_thread_start(master, ec_master_idle_thread, |
478 ret = ec_master_thread_start(master, ec_master_idle_thread, |
471 "EtherCAT-IDLE"); |
479 "EtherCAT-IDLE"); |
472 if (ret) |
480 if (ret) |
562 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
570 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
563 } |
571 } |
564 #endif |
572 #endif |
565 |
573 |
566 master->phase = EC_OPERATION; |
574 master->phase = EC_OPERATION; |
567 master->ext_request_cb = NULL; |
575 master->app_send_cb = NULL; |
568 master->ext_release_cb = NULL; |
576 master->app_receive_cb = NULL; |
569 master->ext_cb_data = NULL; |
|
570 return ret; |
577 return ret; |
571 |
578 |
572 out_allow: |
579 out_allow: |
573 master->allow_scan = 1; |
580 master->allow_scan = 1; |
574 master->allow_config = 1; |
581 master->allow_config = 1; |
595 #ifdef EC_EOE |
602 #ifdef EC_EOE |
596 ec_master_eoe_stop(master); |
603 ec_master_eoe_stop(master); |
597 #endif |
604 #endif |
598 ec_master_thread_stop(master); |
605 ec_master_thread_stop(master); |
599 |
606 |
600 master->request_cb = ec_master_request_cb; |
607 master->send_cb = ec_master_internal_send_cb; |
601 master->release_cb = ec_master_release_cb; |
608 master->receive_cb = ec_master_internal_receive_cb; |
602 master->cb_data = master; |
|
603 |
609 |
604 down(&master->master_sem); |
610 down(&master->master_sem); |
605 ec_master_clear_domains(master); |
611 ec_master_clear_domains(master); |
606 ec_master_clear_slave_configs(master); |
612 ec_master_clear_slave_configs(master); |
607 up(&master->master_sem); |
613 up(&master->master_sem); |
644 |
650 |
645 /*****************************************************************************/ |
651 /*****************************************************************************/ |
646 |
652 |
647 /** Places a datagram in the datagram queue. |
653 /** Places a datagram in the datagram queue. |
648 */ |
654 */ |
649 void ec_master_queue_datagram(ec_master_t *master, /**< EtherCAT master */ |
655 void ec_master_queue_datagram( |
650 ec_datagram_t *datagram /**< datagram */ |
656 ec_master_t *master, /**< EtherCAT master */ |
651 ) |
657 ec_datagram_t *datagram /**< datagram */ |
|
658 ) |
652 { |
659 { |
653 ec_datagram_t *queued_datagram; |
660 ec_datagram_t *queued_datagram; |
654 |
661 |
655 // check, if the datagram is already queued |
662 // check, if the datagram is already queued |
656 list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { |
663 list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { |
663 } |
670 } |
664 } |
671 } |
665 |
672 |
666 list_add_tail(&datagram->queue, &master->datagram_queue); |
673 list_add_tail(&datagram->queue, &master->datagram_queue); |
667 datagram->state = EC_DATAGRAM_QUEUED; |
674 datagram->state = EC_DATAGRAM_QUEUED; |
|
675 } |
|
676 |
|
677 /*****************************************************************************/ |
|
678 |
|
679 /** Places a datagram in the non-application datagram queue. |
|
680 */ |
|
681 void ec_master_queue_datagram_ext( |
|
682 ec_master_t *master, /**< EtherCAT master */ |
|
683 ec_datagram_t *datagram /**< datagram */ |
|
684 ) |
|
685 { |
|
686 down(&master->ext_queue_sem); |
|
687 list_add_tail(&datagram->queue, &master->ext_datagram_queue); |
|
688 up(&master->ext_queue_sem); |
668 } |
689 } |
669 |
690 |
670 /*****************************************************************************/ |
691 /*****************************************************************************/ |
671 |
692 |
672 /** Sends the datagrams in the queue. |
693 /** Sends the datagrams in the queue. |
1046 } |
1067 } |
1047 |
1068 |
1048 if (list_empty(&master->eoe_handlers)) |
1069 if (list_empty(&master->eoe_handlers)) |
1049 return; |
1070 return; |
1050 |
1071 |
1051 if (!master->request_cb || !master->release_cb) { |
1072 if (!master->send_cb || !master->receive_cb) { |
1052 EC_WARN("No EoE processing because of missing locking callbacks!\n"); |
1073 EC_WARN("No EoE processing because of missing callbacks!\n"); |
1053 return; |
1074 return; |
1054 } |
1075 } |
1055 |
1076 |
1056 EC_INFO("Starting EoE thread.\n"); |
1077 EC_INFO("Starting EoE thread.\n"); |
1057 master->eoe_thread = kthread_run(ec_master_eoe_thread, master, |
1078 master->eoe_thread = kthread_run(ec_master_eoe_thread, master, |
1107 } |
1128 } |
1108 if (none_open) |
1129 if (none_open) |
1109 goto schedule; |
1130 goto schedule; |
1110 |
1131 |
1111 // receive datagrams |
1132 // receive datagrams |
1112 if (master->request_cb(master->cb_data)) |
1133 master->receive_cb(master); |
1113 goto schedule; |
|
1114 |
|
1115 ecrt_master_receive(master); |
|
1116 master->release_cb(master->cb_data); |
|
1117 |
1134 |
1118 // actual EoE processing |
1135 // actual EoE processing |
1119 sth_to_send = 0; |
1136 sth_to_send = 0; |
1120 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1137 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1121 ec_eoe_run(eoe); |
1138 ec_eoe_run(eoe); |
1126 all_idle = 0; |
1143 all_idle = 0; |
1127 } |
1144 } |
1128 } |
1145 } |
1129 |
1146 |
1130 if (sth_to_send) { |
1147 if (sth_to_send) { |
1131 // send datagrams |
|
1132 if (master->request_cb(master->cb_data)) { |
|
1133 goto schedule; |
|
1134 } |
|
1135 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1148 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1136 ec_eoe_queue(eoe); |
1149 ec_eoe_queue(eoe); |
1137 } |
1150 } |
1138 ecrt_master_send(master); |
1151 // (try to) send datagrams |
1139 master->release_cb(master->cb_data); |
1152 down(&master->ext_queue_sem); |
|
1153 master->send_cb(master); |
|
1154 up(&master->ext_queue_sem); |
1140 } |
1155 } |
1141 |
1156 |
1142 schedule: |
1157 schedule: |
1143 if (all_idle) { |
1158 if (all_idle) { |
1144 set_current_state(TASK_INTERRUPTIBLE); |
1159 set_current_state(TASK_INTERRUPTIBLE); |
1639 if (master->debug_level) |
1654 if (master->debug_level) |
1640 EC_DBG("FSM datagram is %x.\n", (unsigned int) &master->fsm_datagram); |
1655 EC_DBG("FSM datagram is %x.\n", (unsigned int) &master->fsm_datagram); |
1641 |
1656 |
1642 master->injection_seq_fsm = 0; |
1657 master->injection_seq_fsm = 0; |
1643 master->injection_seq_rt = 0; |
1658 master->injection_seq_rt = 0; |
1644 master->request_cb = master->ext_request_cb; |
1659 |
1645 master->release_cb = master->ext_release_cb; |
1660 master->send_cb = master->app_send_cb; |
1646 master->cb_data = master->ext_cb_data; |
1661 master->receive_cb = master->app_receive_cb; |
1647 |
1662 |
1648 ret = ec_master_thread_start(master, ec_master_operation_thread, |
1663 ret = ec_master_thread_start(master, ec_master_operation_thread, |
1649 "EtherCAT-OP"); |
1664 "EtherCAT-OP"); |
1650 if (ret < 0) { |
1665 if (ret < 0) { |
1651 EC_ERR("Failed to start master thread!\n"); |
1666 EC_ERR("Failed to start master thread!\n"); |
1733 master->frames_timed_out = frames_timed_out; |
1748 master->frames_timed_out = frames_timed_out; |
1734 } |
1749 } |
1735 |
1750 |
1736 /*****************************************************************************/ |
1751 /*****************************************************************************/ |
1737 |
1752 |
|
1753 void ecrt_master_send_ext(ec_master_t *master) |
|
1754 { |
|
1755 ec_datagram_t *datagram, *next; |
|
1756 |
|
1757 list_for_each_entry_safe(datagram, next, &master->ext_datagram_queue, |
|
1758 queue) { |
|
1759 list_del(&datagram->queue); |
|
1760 ec_master_queue_datagram(master, datagram); |
|
1761 } |
|
1762 |
|
1763 ecrt_master_send(master); |
|
1764 } |
|
1765 |
|
1766 /*****************************************************************************/ |
|
1767 |
1738 /** Same as ecrt_master_slave_config(), but with ERR_PTR() return value. |
1768 /** Same as ecrt_master_slave_config(), but with ERR_PTR() return value. |
1739 */ |
1769 */ |
1740 ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *master, |
1770 ec_slave_config_t *ecrt_master_slave_config_err(ec_master_t *master, |
1741 uint16_t alias, uint16_t position, uint32_t vendor_id, |
1771 uint16_t alias, uint16_t position, uint32_t vendor_id, |
1742 uint32_t product_code) |
1772 uint32_t product_code) |
1803 return IS_ERR(sc) ? NULL : sc; |
1833 return IS_ERR(sc) ? NULL : sc; |
1804 } |
1834 } |
1805 |
1835 |
1806 /*****************************************************************************/ |
1836 /*****************************************************************************/ |
1807 |
1837 |
1808 void ecrt_master_callbacks(ec_master_t *master, int (*request_cb)(void *), |
1838 void ecrt_master_callbacks(ec_master_t *master, |
1809 void (*release_cb)(void *), void *cb_data) |
1839 void (*send_cb)(ec_master_t *), void (*receive_cb)(ec_master_t *)) |
1810 { |
1840 { |
1811 if (master->debug_level) |
1841 if (master->debug_level) |
1812 EC_DBG("ecrt_master_callbacks(master = 0x%x, request_cb = 0x%x, " |
1842 EC_DBG("ecrt_master_callbacks(master = 0x%x, send_cb = 0x%x, " |
1813 " release_cb = 0x%x, cb_data = 0x%x)\n", (u32) master, |
1843 " receive_cb = 0x%x)\n", (u32) master, (u32) send_cb, |
1814 (u32) request_cb, (u32) release_cb, (u32) cb_data); |
1844 (u32) receive_cb); |
1815 |
1845 |
1816 master->ext_request_cb = request_cb; |
1846 master->app_send_cb = send_cb; |
1817 master->ext_release_cb = release_cb; |
1847 master->app_receive_cb = receive_cb; |
1818 master->ext_cb_data = cb_data; |
|
1819 } |
1848 } |
1820 |
1849 |
1821 /*****************************************************************************/ |
1850 /*****************************************************************************/ |
1822 |
1851 |
1823 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) |
1852 void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) |
1860 /** \cond */ |
1889 /** \cond */ |
1861 |
1890 |
1862 EXPORT_SYMBOL(ecrt_master_create_domain); |
1891 EXPORT_SYMBOL(ecrt_master_create_domain); |
1863 EXPORT_SYMBOL(ecrt_master_activate); |
1892 EXPORT_SYMBOL(ecrt_master_activate); |
1864 EXPORT_SYMBOL(ecrt_master_send); |
1893 EXPORT_SYMBOL(ecrt_master_send); |
|
1894 EXPORT_SYMBOL(ecrt_master_send_ext); |
1865 EXPORT_SYMBOL(ecrt_master_receive); |
1895 EXPORT_SYMBOL(ecrt_master_receive); |
1866 EXPORT_SYMBOL(ecrt_master_callbacks); |
1896 EXPORT_SYMBOL(ecrt_master_callbacks); |
1867 EXPORT_SYMBOL(ecrt_master_slave_config); |
1897 EXPORT_SYMBOL(ecrt_master_slave_config); |
1868 EXPORT_SYMBOL(ecrt_master_state); |
1898 EXPORT_SYMBOL(ecrt_master_state); |
1869 EXPORT_SYMBOL(ecrt_master_application_time); |
1899 EXPORT_SYMBOL(ecrt_master_application_time); |