83 ) |
83 ) |
84 { |
84 { |
85 master->index = index; |
85 master->index = index; |
86 master->reserved = 0; |
86 master->reserved = 0; |
87 |
87 |
|
88 init_MUTEX(&master->master_sem); |
|
89 |
88 master->main_mac = main_mac; |
90 master->main_mac = main_mac; |
89 master->backup_mac = backup_mac; |
91 master->backup_mac = backup_mac; |
90 init_MUTEX(&master->device_sem); |
92 init_MUTEX(&master->device_sem); |
91 |
93 |
92 master->phase = EC_ORPHANED; |
94 master->phase = EC_ORPHANED; |
358 */ |
360 */ |
359 int ec_master_enter_idle_phase( |
361 int ec_master_enter_idle_phase( |
360 ec_master_t *master /**< EtherCAT master */ |
362 ec_master_t *master /**< EtherCAT master */ |
361 ) |
363 ) |
362 { |
364 { |
|
365 if (master->debug_level) |
|
366 EC_DBG("ORPHANED -> IDLE.\n"); |
|
367 |
363 master->request_cb = ec_master_request_cb; |
368 master->request_cb = ec_master_request_cb; |
364 master->release_cb = ec_master_release_cb; |
369 master->release_cb = ec_master_release_cb; |
365 master->cb_data = master; |
370 master->cb_data = master; |
366 |
|
367 if (master->debug_level) |
|
368 EC_DBG("ORPHANED -> IDLE.\n"); |
|
369 |
371 |
370 master->phase = EC_IDLE; |
372 master->phase = EC_IDLE; |
371 if (ec_master_thread_start(master, ec_master_idle_thread)) { |
373 if (ec_master_thread_start(master, ec_master_idle_thread)) { |
372 master->phase = EC_ORPHANED; |
374 master->phase = EC_ORPHANED; |
373 return -1; |
375 return -1; |
389 |
391 |
390 #ifdef EC_EOE |
392 #ifdef EC_EOE |
391 ec_master_eoe_stop(master); |
393 ec_master_eoe_stop(master); |
392 #endif |
394 #endif |
393 ec_master_thread_stop(master); |
395 ec_master_thread_stop(master); |
|
396 |
|
397 down(&master->master_sem); |
394 ec_master_clear_slaves(master); |
398 ec_master_clear_slaves(master); |
|
399 up(&master->master_sem); |
395 } |
400 } |
396 |
401 |
397 /*****************************************************************************/ |
402 /*****************************************************************************/ |
398 |
403 |
399 /** Transition function from IDLE to OPERATION phase. |
404 /** Transition function from IDLE to OPERATION phase. |
455 if (ec_eoe_is_open(eoe)) |
460 if (ec_eoe_is_open(eoe)) |
456 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
461 ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP); |
457 } |
462 } |
458 #endif |
463 #endif |
459 |
464 |
460 if (master->debug_level) |
|
461 EC_DBG("Switching to operation phase.\n"); |
|
462 |
|
463 master->phase = EC_OPERATION; |
465 master->phase = EC_OPERATION; |
464 master->ext_request_cb = NULL; |
466 master->ext_request_cb = NULL; |
465 master->ext_release_cb = NULL; |
467 master->ext_release_cb = NULL; |
466 master->ext_cb_data = NULL; |
468 master->ext_cb_data = NULL; |
467 return 0; |
469 return 0; |
496 |
498 |
497 master->request_cb = ec_master_request_cb; |
499 master->request_cb = ec_master_request_cb; |
498 master->release_cb = ec_master_release_cb; |
500 master->release_cb = ec_master_release_cb; |
499 master->cb_data = master; |
501 master->cb_data = master; |
500 |
502 |
|
503 down(&master->master_sem); |
501 ec_master_clear_domains(master); |
504 ec_master_clear_domains(master); |
502 ec_master_clear_slave_configs(master); |
505 ec_master_clear_slave_configs(master); |
|
506 up(&master->master_sem); |
503 |
507 |
504 // set states for all slaves |
508 // set states for all slaves |
505 for (slave = master->slaves; |
509 for (slave = master->slaves; |
506 slave < master->slaves + master->slave_count; |
510 slave < master->slaves + master->slave_count; |
507 slave++) { |
511 slave++) { |
824 |
828 |
825 if (master->fsm_datagram.state == EC_DATAGRAM_SENT) |
829 if (master->fsm_datagram.state == EC_DATAGRAM_SENT) |
826 goto schedule; |
830 goto schedule; |
827 |
831 |
828 // execute master state machine |
832 // execute master state machine |
|
833 down(&master->master_sem); |
829 ec_fsm_master_exec(&master->fsm); |
834 ec_fsm_master_exec(&master->fsm); |
|
835 up(&master->master_sem); |
830 |
836 |
831 // queue and send |
837 // queue and send |
832 spin_lock_bh(&master->internal_lock); |
838 spin_lock_bh(&master->internal_lock); |
833 ec_master_queue_datagram(master, &master->fsm_datagram); |
839 ec_master_queue_datagram(master, &master->fsm_datagram); |
834 ecrt_master_send(master); |
840 ecrt_master_send(master); |
1144 if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { |
1152 if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { |
1145 EC_ERR("Error allocating domain memory!\n"); |
1153 EC_ERR("Error allocating domain memory!\n"); |
1146 return NULL; |
1154 return NULL; |
1147 } |
1155 } |
1148 |
1156 |
|
1157 down(&master->master_sem); |
|
1158 |
1149 if (list_empty(&master->domains)) { |
1159 if (list_empty(&master->domains)) { |
1150 index = 0; |
1160 index = 0; |
1151 } else { |
1161 } else { |
1152 last_domain = list_entry(master->domains.prev, ec_domain_t, list); |
1162 last_domain = list_entry(master->domains.prev, ec_domain_t, list); |
1153 index = last_domain->index + 1; |
1163 index = last_domain->index + 1; |
1154 } |
1164 } |
1155 |
1165 |
1156 ec_domain_init(domain, master, index); |
1166 ec_domain_init(domain, master, index); |
1157 list_add_tail(&domain->list, &master->domains); |
1167 list_add_tail(&domain->list, &master->domains); |
1158 |
1168 |
|
1169 up(&master->master_sem); |
|
1170 |
1159 return domain; |
1171 return domain; |
1160 } |
1172 } |
1161 |
1173 |
1162 /*****************************************************************************/ |
1174 /*****************************************************************************/ |
1163 |
1175 |
1164 int ecrt_master_activate(ec_master_t *master) |
1176 int ecrt_master_activate(ec_master_t *master) |
1165 { |
1177 { |
1166 uint32_t domain_offset; |
1178 uint32_t domain_offset; |
1167 ec_domain_t *domain; |
1179 ec_domain_t *domain; |
|
1180 |
|
1181 down(&master->master_sem); |
1168 |
1182 |
1169 // finish all domains |
1183 // finish all domains |
1170 domain_offset = 0; |
1184 domain_offset = 0; |
1171 list_for_each_entry(domain, &master->domains, list) { |
1185 list_for_each_entry(domain, &master->domains, list) { |
1172 if (ec_domain_finish(domain, domain_offset)) { |
1186 if (ec_domain_finish(domain, domain_offset)) { |
1173 EC_ERR("Failed to finish domain 0x%08X!\n", (u32) domain); |
1187 EC_ERR("Failed to finish domain 0x%08X!\n", (u32) domain); |
1174 return -1; |
1188 return -1; |
1175 } |
1189 } |
1176 domain_offset += domain->data_size; |
1190 domain_offset += domain->data_size; |
1177 } |
1191 } |
|
1192 |
|
1193 up(&master->master_sem); |
1178 |
1194 |
1179 // restart EoE process and master thread with new locking |
1195 // restart EoE process and master thread with new locking |
1180 #ifdef EC_EOE |
1196 #ifdef EC_EOE |
1181 ec_master_eoe_stop(master); |
1197 ec_master_eoe_stop(master); |
1182 #endif |
1198 #endif |
1325 } |
1341 } |
1326 |
1342 |
1327 ec_slave_config_init(sc, master, |
1343 ec_slave_config_init(sc, master, |
1328 alias, position, vendor_id, product_code); |
1344 alias, position, vendor_id, product_code); |
1329 |
1345 |
|
1346 |
|
1347 down(&master->master_sem); |
|
1348 |
1330 // try to find the addressed slave |
1349 // try to find the addressed slave |
1331 ec_slave_config_attach(sc); |
1350 ec_slave_config_attach(sc); |
1332 ec_slave_config_load_default_sync_config(sc); |
1351 ec_slave_config_load_default_sync_config(sc); |
1333 |
|
1334 list_add_tail(&sc->list, &master->configs); |
1352 list_add_tail(&sc->list, &master->configs); |
|
1353 |
|
1354 up(&master->master_sem); |
1335 } |
1355 } |
1336 |
1356 |
1337 return sc; |
1357 return sc; |
1338 } |
1358 } |
1339 |
1359 |