156 master->frames_timed_out = 0; |
156 master->frames_timed_out = 0; |
157 |
157 |
158 master->thread = NULL; |
158 master->thread = NULL; |
159 |
159 |
160 #ifdef EC_EOE |
160 #ifdef EC_EOE |
161 init_timer(&master->eoe_timer); |
161 master->eoe_thread = NULL; |
162 master->eoe_timer.function = ec_master_eoe_run; |
|
163 master->eoe_timer.data = (unsigned long) master; |
|
164 master->eoe_running = 0; |
|
165 INIT_LIST_HEAD(&master->eoe_handlers); |
162 INIT_LIST_HEAD(&master->eoe_handlers); |
166 #endif |
163 #endif |
167 |
164 |
168 master->internal_lock = SPIN_LOCK_UNLOCKED; |
165 init_MUTEX(&master->io_sem); |
169 master->request_cb = NULL; |
166 master->request_cb = NULL; |
170 master->release_cb = NULL; |
167 master->release_cb = NULL; |
171 master->cb_data = NULL; |
168 master->cb_data = NULL; |
172 |
169 |
173 INIT_LIST_HEAD(&master->sii_requests); |
170 INIT_LIST_HEAD(&master->sii_requests); |
378 |
375 |
379 /*****************************************************************************/ |
376 /*****************************************************************************/ |
380 |
377 |
381 /** Internal locking callback. |
378 /** Internal locking callback. |
382 */ |
379 */ |
383 int ec_master_request_cb(void *master /**< callback data */) |
380 int ec_master_request_cb(void *data /**< callback data */) |
384 { |
381 { |
385 spin_lock(&((ec_master_t *) master)->internal_lock); |
382 ec_master_t *master = (ec_master_t *) data; |
|
383 down(&master->io_sem); |
386 return 0; |
384 return 0; |
387 } |
385 } |
388 |
386 |
389 /*****************************************************************************/ |
387 /*****************************************************************************/ |
390 |
388 |
391 /** Internal unlocking callback. |
389 /** Internal unlocking callback. |
392 */ |
390 */ |
393 void ec_master_release_cb(void *master /**< callback data */) |
391 void ec_master_release_cb(void *data /**< callback data */) |
394 { |
392 { |
395 spin_unlock(&((ec_master_t *) master)->internal_lock); |
393 ec_master_t *master = (ec_master_t *) data; |
|
394 up(&master->io_sem); |
396 } |
395 } |
397 |
396 |
398 /*****************************************************************************/ |
397 /*****************************************************************************/ |
399 |
398 |
400 /** Starts the master thread. |
399 /** Starts the master thread. |
1050 if (!master->request_cb || !master->release_cb) { |
1051 if (!master->request_cb || !master->release_cb) { |
1051 EC_WARN("No EoE processing because of missing locking callbacks!\n"); |
1052 EC_WARN("No EoE processing because of missing locking callbacks!\n"); |
1052 return; |
1053 return; |
1053 } |
1054 } |
1054 |
1055 |
1055 EC_INFO("Starting EoE processing.\n"); |
1056 EC_INFO("Starting EoE thread.\n"); |
1056 master->eoe_running = 1; |
1057 master->eoe_thread = kthread_run(ec_master_eoe_thread, master, |
1057 |
1058 "EtherCAT-EoE"); |
1058 // start EoE processing |
1059 if (IS_ERR(master->eoe_thread)) { |
1059 master->eoe_timer.expires = jiffies + 10; |
1060 int err = (int) PTR_ERR(master->eoe_thread); |
1060 add_timer(&master->eoe_timer); |
1061 EC_ERR("Failed to start EoE thread (error %i)!\n", err); |
|
1062 master->eoe_thread = NULL; |
|
1063 return; |
|
1064 } |
|
1065 |
|
1066 sched_setscheduler(master->eoe_thread, SCHED_NORMAL, ¶m); |
|
1067 set_user_nice(master->eoe_thread, 0); |
1061 } |
1068 } |
1062 |
1069 |
1063 /*****************************************************************************/ |
1070 /*****************************************************************************/ |
1064 |
1071 |
1065 /** Stops the Ethernet over EtherCAT processing. |
1072 /** Stops the Ethernet over EtherCAT processing. |
1066 */ |
1073 */ |
1067 void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */) |
1074 void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */) |
1068 { |
1075 { |
1069 if (!master->eoe_running) return; |
1076 if (master->eoe_thread) { |
1070 |
1077 EC_INFO("Stopping EoE thread.\n"); |
1071 EC_INFO("Stopping EoE processing.\n"); |
1078 |
1072 |
1079 kthread_stop(master->eoe_thread); |
1073 del_timer_sync(&master->eoe_timer); |
1080 master->eoe_thread = NULL; |
1074 master->eoe_running = 0; |
1081 EC_INFO("EoE thread exited.\n"); |
|
1082 } |
1075 } |
1083 } |
1076 |
1084 |
1077 /*****************************************************************************/ |
1085 /*****************************************************************************/ |
1078 |
1086 |
1079 /** Does the Ethernet over EtherCAT processing. |
1087 /** Does the Ethernet over EtherCAT processing. |
1080 */ |
1088 */ |
1081 void ec_master_eoe_run(unsigned long data /**< master pointer */) |
1089 static int ec_master_eoe_thread(void *priv_data) |
1082 { |
1090 { |
1083 ec_master_t *master = (ec_master_t *) data; |
1091 ec_master_t *master = (ec_master_t *) priv_data; |
1084 ec_eoe_t *eoe; |
1092 ec_eoe_t *eoe; |
1085 unsigned int none_open = 1; |
1093 unsigned int none_open, sth_to_send, all_idle; |
1086 unsigned long restart_jiffies; |
1094 |
1087 |
1095 if (master->debug_level) |
1088 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1096 EC_DBG("EoE thread running.\n"); |
1089 if (ec_eoe_is_open(eoe)) { |
1097 |
1090 none_open = 0; |
1098 while (!kthread_should_stop()) { |
1091 break; |
1099 none_open = 1; |
1092 } |
1100 all_idle = 1; |
1093 } |
1101 |
1094 if (none_open) |
1102 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1095 goto queue_timer; |
1103 if (ec_eoe_is_open(eoe)) { |
1096 |
1104 none_open = 0; |
1097 // receive datagrams |
1105 break; |
1098 if (master->request_cb(master->cb_data)) |
1106 } |
1099 goto queue_timer; |
1107 } |
|
1108 if (none_open) |
|
1109 goto schedule; |
|
1110 |
|
1111 // receive datagrams |
|
1112 if (master->request_cb(master->cb_data)) |
|
1113 goto schedule; |
|
1114 |
|
1115 ecrt_master_receive(master); |
|
1116 master->release_cb(master->cb_data); |
|
1117 |
|
1118 // actual EoE processing |
|
1119 sth_to_send = 0; |
|
1120 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
1121 ec_eoe_run(eoe); |
|
1122 if (eoe->queue_datagram) { |
|
1123 sth_to_send = 1; |
|
1124 } |
|
1125 if (!ec_eoe_is_idle(eoe)) { |
|
1126 all_idle = 0; |
|
1127 } |
|
1128 } |
|
1129 |
|
1130 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) { |
|
1136 ec_eoe_queue(eoe); |
|
1137 } |
|
1138 ecrt_master_send(master); |
|
1139 master->release_cb(master->cb_data); |
|
1140 } |
|
1141 |
|
1142 schedule: |
|
1143 if (all_idle) { |
|
1144 set_current_state(TASK_INTERRUPTIBLE); |
|
1145 schedule_timeout(1); |
|
1146 } else { |
|
1147 schedule(); |
|
1148 } |
|
1149 } |
1100 |
1150 |
1101 ecrt_master_receive(master); |
1151 if (master->debug_level) |
1102 master->release_cb(master->cb_data); |
1152 EC_DBG("EoE thread exiting...\n"); |
1103 |
1153 return 0; |
1104 // actual EoE processing |
|
1105 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
1106 ec_eoe_run(eoe); |
|
1107 } |
|
1108 |
|
1109 // send datagrams |
|
1110 if (master->request_cb(master->cb_data)) { |
|
1111 goto queue_timer; |
|
1112 } |
|
1113 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
1114 ec_eoe_queue(eoe); |
|
1115 } |
|
1116 ecrt_master_send(master); |
|
1117 master->release_cb(master->cb_data); |
|
1118 |
|
1119 queue_timer: |
|
1120 restart_jiffies = HZ / EC_EOE_FREQUENCY; |
|
1121 if (!restart_jiffies) restart_jiffies = 1; |
|
1122 master->eoe_timer.expires = jiffies + restart_jiffies; |
|
1123 add_timer(&master->eoe_timer); |
|
1124 } |
1154 } |
1125 #endif |
1155 #endif |
1126 |
1156 |
1127 /*****************************************************************************/ |
1157 /*****************************************************************************/ |
1128 |
1158 |