1 /****************************************************************************** |
1 /****************************************************************************** |
2 * |
2 * |
3 * $Id$ |
3 * $Id$ |
4 * |
4 * |
5 * Copyright (C) 2006-2008 Florian Pose, Ingenieurgemeinschaft IgH |
5 * Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH |
6 * |
6 * |
7 * This file is part of the IgH EtherCAT Master. |
7 * This file is part of the IgH EtherCAT Master. |
8 * |
8 * |
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
9 * The IgH EtherCAT Master is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU General Public License version 2, as |
10 * modify it under the terms of the GNU General Public License version 2, as |
84 sc->dc_sync[0].shift_time = 0x00000000; |
84 sc->dc_sync[0].shift_time = 0x00000000; |
85 sc->dc_sync[1].shift_time = 0x00000000; |
85 sc->dc_sync[1].shift_time = 0x00000000; |
86 |
86 |
87 INIT_LIST_HEAD(&sc->sdo_configs); |
87 INIT_LIST_HEAD(&sc->sdo_configs); |
88 INIT_LIST_HEAD(&sc->sdo_requests); |
88 INIT_LIST_HEAD(&sc->sdo_requests); |
|
89 INIT_LIST_HEAD(&sc->reg_requests); |
89 INIT_LIST_HEAD(&sc->voe_handlers); |
90 INIT_LIST_HEAD(&sc->voe_handlers); |
90 INIT_LIST_HEAD(&sc->soe_configs); |
91 INIT_LIST_HEAD(&sc->soe_configs); |
91 |
92 |
92 ec_coe_emerg_ring_init(&sc->emerg_ring, sc); |
93 ec_coe_emerg_ring_init(&sc->emerg_ring, sc); |
93 } |
94 } |
103 ) |
104 ) |
104 { |
105 { |
105 unsigned int i; |
106 unsigned int i; |
106 ec_sdo_request_t *req, *next_req; |
107 ec_sdo_request_t *req, *next_req; |
107 ec_voe_handler_t *voe, *next_voe; |
108 ec_voe_handler_t *voe, *next_voe; |
|
109 ec_reg_request_t *reg, *next_reg; |
108 ec_soe_request_t *soe, *next_soe; |
110 ec_soe_request_t *soe, *next_soe; |
109 |
111 |
110 ec_slave_config_detach(sc); |
112 ec_slave_config_detach(sc); |
111 |
113 |
112 // Free sync managers |
114 // Free sync managers |
123 // free all SDO requests |
125 // free all SDO requests |
124 list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) { |
126 list_for_each_entry_safe(req, next_req, &sc->sdo_requests, list) { |
125 list_del(&req->list); |
127 list_del(&req->list); |
126 ec_sdo_request_clear(req); |
128 ec_sdo_request_clear(req); |
127 kfree(req); |
129 kfree(req); |
|
130 } |
|
131 |
|
132 // free all register requests |
|
133 list_for_each_entry_safe(reg, next_reg, &sc->reg_requests, list) { |
|
134 list_del(®->list); |
|
135 ec_reg_request_clear(reg); |
|
136 kfree(reg); |
128 } |
137 } |
129 |
138 |
130 // free all VoE handlers |
139 // free all VoE handlers |
131 list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) { |
140 list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) { |
132 list_del(&voe->list); |
141 list_del(&voe->list); |
427 return NULL; |
436 return NULL; |
428 } |
437 } |
429 |
438 |
430 /*****************************************************************************/ |
439 /*****************************************************************************/ |
431 |
440 |
432 /** Finds a VoE handler via its position in the list. |
441 /** Finds a CoE handler via its position in the list. |
433 */ |
442 */ |
434 ec_sdo_request_t *ec_slave_config_find_sdo_request( |
443 ec_sdo_request_t *ec_slave_config_find_sdo_request( |
435 ec_slave_config_t *sc, /**< Slave configuration. */ |
444 ec_slave_config_t *sc, /**< Slave configuration. */ |
436 unsigned int pos /**< Position in the list. */ |
445 unsigned int pos /**< Position in the list. */ |
437 ) |
446 ) |
440 |
449 |
441 list_for_each_entry(req, &sc->sdo_requests, list) { |
450 list_for_each_entry(req, &sc->sdo_requests, list) { |
442 if (pos--) |
451 if (pos--) |
443 continue; |
452 continue; |
444 return req; |
453 return req; |
|
454 } |
|
455 |
|
456 return NULL; |
|
457 } |
|
458 |
|
459 /*****************************************************************************/ |
|
460 |
|
461 /** Finds a register handler via its position in the list. |
|
462 */ |
|
463 ec_reg_request_t *ec_slave_config_find_reg_request( |
|
464 ec_slave_config_t *sc, /**< Slave configuration. */ |
|
465 unsigned int pos /**< Position in the list. */ |
|
466 ) |
|
467 { |
|
468 ec_reg_request_t *reg; |
|
469 |
|
470 list_for_each_entry(reg, &sc->reg_requests, list) { |
|
471 if (pos--) |
|
472 continue; |
|
473 return reg; |
445 } |
474 } |
446 |
475 |
447 return NULL; |
476 return NULL; |
448 } |
477 } |
449 |
478 |
959 ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size) |
988 ec_slave_config_t *sc, uint16_t index, uint8_t subindex, size_t size) |
960 { |
989 { |
961 ec_sdo_request_t *s = ecrt_slave_config_create_sdo_request_err(sc, index, |
990 ec_sdo_request_t *s = ecrt_slave_config_create_sdo_request_err(sc, index, |
962 subindex, size); |
991 subindex, size); |
963 return IS_ERR(s) ? NULL : s; |
992 return IS_ERR(s) ? NULL : s; |
|
993 } |
|
994 |
|
995 /*****************************************************************************/ |
|
996 |
|
997 /** Same as ecrt_slave_config_create_reg_request(), but with ERR_PTR() return |
|
998 * value. |
|
999 */ |
|
1000 ec_reg_request_t *ecrt_slave_config_create_reg_request_err( |
|
1001 ec_slave_config_t *sc, size_t size) |
|
1002 { |
|
1003 ec_reg_request_t *reg; |
|
1004 int ret; |
|
1005 |
|
1006 EC_CONFIG_DBG(sc, 1, "%s(sc = 0x%p, size = %zu)\n", |
|
1007 __func__, sc, size); |
|
1008 |
|
1009 if (!(reg = (ec_reg_request_t *) |
|
1010 kmalloc(sizeof(ec_reg_request_t), GFP_KERNEL))) { |
|
1011 EC_CONFIG_ERR(sc, "Failed to allocate register request memory!\n"); |
|
1012 return ERR_PTR(-ENOMEM); |
|
1013 } |
|
1014 |
|
1015 ret = ec_reg_request_init(reg, size); |
|
1016 if (ret) { |
|
1017 kfree(reg); |
|
1018 return ERR_PTR(ret); |
|
1019 } |
|
1020 |
|
1021 down(&sc->master->master_sem); |
|
1022 list_add_tail(®->list, &sc->reg_requests); |
|
1023 up(&sc->master->master_sem); |
|
1024 |
|
1025 return reg; |
|
1026 } |
|
1027 |
|
1028 /*****************************************************************************/ |
|
1029 |
|
1030 ec_reg_request_t *ecrt_slave_config_create_reg_request( |
|
1031 ec_slave_config_t *sc, size_t size) |
|
1032 { |
|
1033 ec_reg_request_t *reg = |
|
1034 ecrt_slave_config_create_reg_request_err(sc, size); |
|
1035 return IS_ERR(reg) ? NULL : reg; |
964 } |
1036 } |
965 |
1037 |
966 /*****************************************************************************/ |
1038 /*****************************************************************************/ |
967 |
1039 |
968 /** Same as ecrt_slave_config_create_voe_handler(), but with ERR_PTR() return |
1040 /** Same as ecrt_slave_config_create_voe_handler(), but with ERR_PTR() return |
1099 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop); |
1171 EXPORT_SYMBOL(ecrt_slave_config_emerg_pop); |
1100 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear); |
1172 EXPORT_SYMBOL(ecrt_slave_config_emerg_clear); |
1101 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns); |
1173 EXPORT_SYMBOL(ecrt_slave_config_emerg_overruns); |
1102 EXPORT_SYMBOL(ecrt_slave_config_create_sdo_request); |
1174 EXPORT_SYMBOL(ecrt_slave_config_create_sdo_request); |
1103 EXPORT_SYMBOL(ecrt_slave_config_create_voe_handler); |
1175 EXPORT_SYMBOL(ecrt_slave_config_create_voe_handler); |
|
1176 EXPORT_SYMBOL(ecrt_slave_config_create_reg_request); |
1104 EXPORT_SYMBOL(ecrt_slave_config_state); |
1177 EXPORT_SYMBOL(ecrt_slave_config_state); |
1105 EXPORT_SYMBOL(ecrt_slave_config_idn); |
1178 EXPORT_SYMBOL(ecrt_slave_config_idn); |
1106 |
1179 |
1107 /** \endcond */ |
1180 /** \endcond */ |
1108 |
1181 |