00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035
00036
00037 #include <linux/module.h>
00038
00039 #include "globals.h"
00040 #include "pdo.h"
00041 #include "slave_config.h"
00042 #include "master.h"
00043
00044 #include "pdo_list.h"
00045
00046
00047
00050 void ec_pdo_list_init(
00051 ec_pdo_list_t *pl
00052 )
00053 {
00054 INIT_LIST_HEAD(&pl->list);
00055 }
00056
00057
00058
00061 void ec_pdo_list_clear(ec_pdo_list_t *pl )
00062 {
00063 ec_pdo_list_clear_pdos(pl);
00064 }
00065
00066
00067
00070 void ec_pdo_list_clear_pdos(ec_pdo_list_t *pl )
00071 {
00072 ec_pdo_t *pdo, *next;
00073
00074 list_for_each_entry_safe(pdo, next, &pl->list, list) {
00075 list_del_init(&pdo->list);
00076 ec_pdo_clear(pdo);
00077 kfree(pdo);
00078 }
00079 }
00080
00081
00082
00087 uint16_t ec_pdo_list_total_size(
00088 const ec_pdo_list_t *pl
00089 )
00090 {
00091 unsigned int bit_size;
00092 const ec_pdo_t *pdo;
00093 const ec_pdo_entry_t *pdo_entry;
00094 uint16_t byte_size;
00095
00096 bit_size = 0;
00097 list_for_each_entry(pdo, &pl->list, list) {
00098 list_for_each_entry(pdo_entry, &pdo->entries, list) {
00099 bit_size += pdo_entry->bit_length;
00100 }
00101 }
00102
00103 if (bit_size % 8)
00104 byte_size = bit_size / 8 + 1;
00105 else
00106 byte_size = bit_size / 8;
00107
00108 return byte_size;
00109 }
00110
00111
00112
00117 ec_pdo_t *ec_pdo_list_add_pdo(
00118 ec_pdo_list_t *pl,
00119 uint16_t index
00120 )
00121 {
00122 ec_pdo_t *pdo;
00123
00124 if (!(pdo = (ec_pdo_t *) kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
00125 EC_ERR("Failed to allocate memory for PDO.\n");
00126 return ERR_PTR(-ENOMEM);
00127 }
00128
00129 ec_pdo_init(pdo);
00130 pdo->index = index;
00131 list_add_tail(&pdo->list, &pl->list);
00132 return pdo;
00133 }
00134
00135
00136
00141 int ec_pdo_list_add_pdo_copy(
00142 ec_pdo_list_t *pl,
00143 const ec_pdo_t *pdo
00144 )
00145 {
00146 ec_pdo_t *mapped_pdo;
00147 int ret;
00148
00149
00150 list_for_each_entry(mapped_pdo, &pl->list, list) {
00151 if (mapped_pdo->index != pdo->index) continue;
00152 EC_ERR("PDO 0x%04X is already mapped!\n", pdo->index);
00153 return -EEXIST;
00154 }
00155
00156 if (!(mapped_pdo = kmalloc(sizeof(ec_pdo_t), GFP_KERNEL))) {
00157 EC_ERR("Failed to allocate PDO memory.\n");
00158 return -ENOMEM;
00159 }
00160
00161 ret = ec_pdo_init_copy(mapped_pdo, pdo);
00162 if (ret < 0) {
00163 kfree(mapped_pdo);
00164 return ret;
00165 }
00166
00167 list_add_tail(&mapped_pdo->list, &pl->list);
00168 return 0;
00169 }
00170
00171
00172
00177 int ec_pdo_list_copy(
00178 ec_pdo_list_t *pl,
00179 const ec_pdo_list_t *other
00180 )
00181 {
00182 ec_pdo_t *other_pdo;
00183 int ret;
00184
00185 ec_pdo_list_clear_pdos(pl);
00186
00187
00188 list_for_each_entry(other_pdo, &other->list, list) {
00189 ret = ec_pdo_list_add_pdo_copy(pl, other_pdo);
00190 if (ret)
00191 return ret;
00192 }
00193
00194 return 0;
00195 }
00196
00197
00198
00207 int ec_pdo_list_equal(
00208 const ec_pdo_list_t *pl1,
00209 const ec_pdo_list_t *pl2
00210 )
00211 {
00212 const struct list_head *h1, *h2, *l1, *l2;
00213 const ec_pdo_t *p1, *p2;
00214
00215 h1 = l1 = &pl1->list;
00216 h2 = l2 = &pl2->list;
00217
00218 while (1) {
00219 l1 = l1->next;
00220 l2 = l2->next;
00221
00222 if ((l1 == h1) ^ (l2 == h2))
00223 return 0;
00224 if (l1 == h1)
00225 break;
00226
00227 p1 = list_entry(l1, ec_pdo_t, list);
00228 p2 = list_entry(l2, ec_pdo_t, list);
00229
00230 if (p1->index != p2->index)
00231 return 0;
00232 }
00233
00234 return 1;
00235 }
00236
00237
00238
00243 ec_pdo_t *ec_pdo_list_find_pdo(
00244 const ec_pdo_list_t *pl,
00245 uint16_t index
00246 )
00247 {
00248 ec_pdo_t *pdo;
00249
00250 list_for_each_entry(pdo, &pl->list, list) {
00251 if (pdo->index != index)
00252 continue;
00253 return pdo;
00254 }
00255
00256 return NULL;
00257 }
00258
00259
00260
00265 const ec_pdo_t *ec_pdo_list_find_pdo_const(
00266 const ec_pdo_list_t *pl,
00267 uint16_t index
00268 )
00269 {
00270 const ec_pdo_t *pdo;
00271
00272 list_for_each_entry(pdo, &pl->list, list) {
00273 if (pdo->index != index)
00274 continue;
00275 return pdo;
00276 }
00277
00278 return NULL;
00279 }
00280
00281
00282
00289 const ec_pdo_t *ec_pdo_list_find_pdo_by_pos_const(
00290 const ec_pdo_list_t *pl,
00291 unsigned int pos
00292 )
00293 {
00294 const ec_pdo_t *pdo;
00295
00296 list_for_each_entry(pdo, &pl->list, list) {
00297 if (pos--)
00298 continue;
00299 return pdo;
00300 }
00301
00302 return NULL;
00303 }
00304
00305
00306
00311 unsigned int ec_pdo_list_count(
00312 const ec_pdo_list_t *pl
00313 )
00314 {
00315 const ec_pdo_t *pdo;
00316 unsigned int num = 0;
00317
00318 list_for_each_entry(pdo, &pl->list, list) {
00319 num++;
00320 }
00321
00322 return num;
00323 }
00324
00325
00326
00329 void ec_pdo_list_print(
00330 const ec_pdo_list_t *pl
00331 )
00332 {
00333 const ec_pdo_t *pdo;
00334
00335 if (list_empty(&pl->list)) {
00336 printk("(none)");
00337 } else {
00338 list_for_each_entry(pdo, &pl->list, list) {
00339 printk("0x%04X", pdo->index);
00340 if (pdo->list.next != &pl->list)
00341 printk(" ");
00342 }
00343 }
00344 }
00345
00346