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
00030
00031
00032
00033
00039
00040
00041 #include <linux/module.h>
00042 #include <linux/delay.h>
00043
00044 #include "globals.h"
00045 #include "slave.h"
00046 #include "datagram.h"
00047 #include "master.h"
00048
00049
00050
00051 extern const ec_code_msg_t al_status_messages[];
00052
00053
00054
00055 int ec_slave_fetch_categories(ec_slave_t *);
00056 ssize_t ec_show_slave_attribute(struct kobject *, struct attribute *, char *);
00057 ssize_t ec_store_slave_attribute(struct kobject *, struct attribute *,
00058 const char *, size_t);
00059
00060
00061
00064 EC_SYSFS_READ_ATTR(ring_position);
00065 EC_SYSFS_READ_ATTR(advanced_position);
00066 EC_SYSFS_READ_ATTR(vendor_name);
00067 EC_SYSFS_READ_ATTR(product_name);
00068 EC_SYSFS_READ_ATTR(product_desc);
00069 EC_SYSFS_READ_ATTR(name);
00070 EC_SYSFS_READ_ATTR(type);
00071 EC_SYSFS_READ_WRITE_ATTR(state);
00072 EC_SYSFS_READ_WRITE_ATTR(eeprom);
00073
00074 static struct attribute *def_attrs[] = {
00075 &attr_ring_position,
00076 &attr_advanced_position,
00077 &attr_vendor_name,
00078 &attr_product_name,
00079 &attr_product_desc,
00080 &attr_name,
00081 &attr_type,
00082 &attr_state,
00083 &attr_eeprom,
00084 NULL,
00085 };
00086
00087 static struct sysfs_ops sysfs_ops = {
00088 .show = ec_show_slave_attribute,
00089 .store = ec_store_slave_attribute
00090 };
00091
00092 static struct kobj_type ktype_ec_slave = {
00093 .release = ec_slave_clear,
00094 .sysfs_ops = &sysfs_ops,
00095 .default_attrs = def_attrs
00096 };
00097
00100
00101
00107 int ec_slave_init(ec_slave_t *slave,
00108 ec_master_t *master,
00109 uint16_t ring_position,
00110 uint16_t station_address
00111 )
00112 {
00113 unsigned int i;
00114
00115 slave->ring_position = ring_position;
00116 slave->station_address = station_address;
00117
00118
00119 memset(&slave->kobj, 0x00, sizeof(struct kobject));
00120 kobject_init(&slave->kobj);
00121 slave->kobj.ktype = &ktype_ec_slave;
00122 slave->kobj.parent = &master->kobj;
00123 if (kobject_set_name(&slave->kobj, "slave%03i", slave->ring_position)) {
00124 EC_ERR("Failed to set kobject name.\n");
00125 kobject_put(&slave->kobj);
00126 return -1;
00127 }
00128
00129 slave->master = master;
00130 slave->coupler_index = 0;
00131 slave->coupler_subindex = 0xFFFF;
00132 slave->base_type = 0;
00133 slave->base_revision = 0;
00134 slave->base_build = 0;
00135 slave->base_fmmu_count = 0;
00136 slave->base_sync_count = 0;
00137 slave->sii_alias = 0;
00138 slave->sii_vendor_id = 0;
00139 slave->sii_product_code = 0;
00140 slave->sii_revision_number = 0;
00141 slave->sii_serial_number = 0;
00142 slave->sii_rx_mailbox_offset = 0;
00143 slave->sii_rx_mailbox_size = 0;
00144 slave->sii_tx_mailbox_offset = 0;
00145 slave->sii_tx_mailbox_size = 0;
00146 slave->sii_mailbox_protocols = 0;
00147 slave->type = NULL;
00148 slave->registered = 0;
00149 slave->fmmu_count = 0;
00150 slave->eeprom_data = NULL;
00151 slave->eeprom_size = 0;
00152 slave->eeprom_group = NULL;
00153 slave->eeprom_image = NULL;
00154 slave->eeprom_order = NULL;
00155 slave->eeprom_name = NULL;
00156 slave->requested_state = EC_SLAVE_STATE_UNKNOWN;
00157 slave->current_state = EC_SLAVE_STATE_UNKNOWN;
00158 slave->error_flag = 0;
00159 slave->online = 1;
00160 slave->new_eeprom_data = NULL;
00161 slave->new_eeprom_size = 0;
00162
00163 INIT_LIST_HEAD(&slave->eeprom_strings);
00164 INIT_LIST_HEAD(&slave->eeprom_syncs);
00165 INIT_LIST_HEAD(&slave->eeprom_pdos);
00166 INIT_LIST_HEAD(&slave->sdo_dictionary);
00167 INIT_LIST_HEAD(&slave->varsize_fields);
00168
00169 for (i = 0; i < 4; i++) {
00170 slave->dl_link[i] = 0;
00171 slave->dl_loop[i] = 0;
00172 slave->dl_signal[i] = 0;
00173 slave->sii_physical_layer[i] = 0xFF;
00174 }
00175
00176 return 0;
00177 }
00178
00179
00180
00185 void ec_slave_clear(struct kobject *kobj )
00186 {
00187 ec_slave_t *slave;
00188 ec_eeprom_string_t *string, *next_str;
00189 ec_eeprom_sync_t *sync, *next_sync;
00190 ec_eeprom_pdo_t *pdo, *next_pdo;
00191 ec_eeprom_pdo_entry_t *entry, *next_ent;
00192 ec_sdo_t *sdo, *next_sdo;
00193 ec_sdo_entry_t *en, *next_en;
00194 ec_varsize_t *var, *next_var;
00195
00196 slave = container_of(kobj, ec_slave_t, kobj);
00197
00198
00199 list_for_each_entry_safe(string, next_str, &slave->eeprom_strings, list) {
00200 list_del(&string->list);
00201 kfree(string);
00202 }
00203
00204
00205 list_for_each_entry_safe(sync, next_sync, &slave->eeprom_syncs, list) {
00206 list_del(&sync->list);
00207 kfree(sync);
00208 }
00209
00210
00211 list_for_each_entry_safe(pdo, next_pdo, &slave->eeprom_pdos, list) {
00212 list_del(&pdo->list);
00213 if (pdo->name) kfree(pdo->name);
00214
00215
00216 list_for_each_entry_safe(entry, next_ent, &pdo->entries, list) {
00217 list_del(&entry->list);
00218 if (entry->name) kfree(entry->name);
00219 kfree(entry);
00220 }
00221
00222 kfree(pdo);
00223 }
00224
00225 if (slave->eeprom_group) kfree(slave->eeprom_group);
00226 if (slave->eeprom_image) kfree(slave->eeprom_image);
00227 if (slave->eeprom_order) kfree(slave->eeprom_order);
00228 if (slave->eeprom_name) kfree(slave->eeprom_name);
00229
00230
00231 list_for_each_entry_safe(sdo, next_sdo, &slave->sdo_dictionary, list) {
00232 list_del(&sdo->list);
00233 if (sdo->name) kfree(sdo->name);
00234
00235
00236 list_for_each_entry_safe(en, next_en, &sdo->entries, list) {
00237 list_del(&en->list);
00238 kfree(en);
00239 }
00240 kfree(sdo);
00241 }
00242
00243
00244 list_for_each_entry_safe(var, next_var, &slave->varsize_fields, list) {
00245 list_del(&var->list);
00246 kfree(var);
00247 }
00248
00249 if (slave->eeprom_data) kfree(slave->eeprom_data);
00250 if (slave->new_eeprom_data) kfree(slave->new_eeprom_data);
00251 }
00252
00253
00254
00260 int ec_slave_fetch(ec_slave_t *slave )
00261 {
00262 ec_datagram_t *datagram;
00263 unsigned int i;
00264 uint16_t dl_status;
00265
00266 datagram = &slave->master->simple_datagram;
00267
00268
00269 if (ec_datagram_nprd(datagram, slave->station_address, 0x0000, 6))
00270 return -1;
00271 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00272 EC_ERR("Reading base data from slave %i failed!\n",
00273 slave->ring_position);
00274 return -1;
00275 }
00276
00277 slave->base_type = EC_READ_U8 (datagram->data);
00278 slave->base_revision = EC_READ_U8 (datagram->data + 1);
00279 slave->base_build = EC_READ_U16(datagram->data + 2);
00280 slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4);
00281 slave->base_sync_count = EC_READ_U8 (datagram->data + 5);
00282
00283 if (slave->base_fmmu_count > EC_MAX_FMMUS)
00284 slave->base_fmmu_count = EC_MAX_FMMUS;
00285
00286
00287 if (ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2))
00288 return -1;
00289 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00290 EC_ERR("Reading DL status from slave %i failed!\n",
00291 slave->ring_position);
00292 return -1;
00293 }
00294
00295 dl_status = EC_READ_U16(datagram->data);
00296 for (i = 0; i < 4; i++) {
00297 slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0;
00298 slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0;
00299 slave->dl_signal[i] = dl_status & (1 << (9 + i * 2)) ? 1 : 0;
00300 }
00301
00302
00303 if (ec_slave_sii_read16(slave, 0x0004, &slave->sii_alias))
00304 return -1;
00305 if (ec_slave_sii_read32(slave, 0x0008, &slave->sii_vendor_id))
00306 return -1;
00307 if (ec_slave_sii_read32(slave, 0x000A, &slave->sii_product_code))
00308 return -1;
00309 if (ec_slave_sii_read32(slave, 0x000C, &slave->sii_revision_number))
00310 return -1;
00311 if (ec_slave_sii_read32(slave, 0x000E, &slave->sii_serial_number))
00312 return -1;
00313 if (ec_slave_sii_read16(slave, 0x0018, &slave->sii_rx_mailbox_offset))
00314 return -1;
00315 if (ec_slave_sii_read16(slave, 0x0019, &slave->sii_rx_mailbox_size))
00316 return -1;
00317 if (ec_slave_sii_read16(slave, 0x001A, &slave->sii_tx_mailbox_offset))
00318 return -1;
00319 if (ec_slave_sii_read16(slave, 0x001B, &slave->sii_tx_mailbox_size))
00320 return -1;
00321 if (ec_slave_sii_read16(slave, 0x001C, &slave->sii_mailbox_protocols))
00322 return -1;
00323
00324 if (unlikely(ec_slave_fetch_categories(slave))) {
00325 EC_ERR("Failed to fetch category data!\n");
00326 return -1;
00327 }
00328
00329 return 0;
00330 }
00331
00332
00333
00339 int ec_slave_sii_read16(ec_slave_t *slave,
00341 uint16_t offset,
00343 uint16_t *target
00345 )
00346 {
00347 ec_datagram_t *datagram;
00348 cycles_t start, end, timeout;
00349
00350 datagram = &slave->master->simple_datagram;
00351
00352
00353 if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6))
00354 return -1;
00355 EC_WRITE_U8 (datagram->data, 0x00);
00356 EC_WRITE_U8 (datagram->data + 1, 0x01);
00357 EC_WRITE_U32(datagram->data + 2, offset);
00358 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00359 EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
00360 return -1;
00361 }
00362
00363 start = get_cycles();
00364 timeout = (cycles_t) 100 * cpu_khz;
00365
00366 while (1)
00367 {
00368 udelay(10);
00369
00370 if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
00371 return -1;
00372 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00373 EC_ERR("Getting SII-read status failed on slave %i!\n",
00374 slave->ring_position);
00375 return -1;
00376 }
00377
00378 end = get_cycles();
00379
00380
00381 if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) {
00382 *target = EC_READ_U16(datagram->data + 6);
00383 return 0;
00384 }
00385
00386 if (unlikely((end - start) >= timeout)) {
00387 EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
00388 return -1;
00389 }
00390 }
00391 }
00392
00393
00394
00400 int ec_slave_sii_read32(ec_slave_t *slave,
00402 uint16_t offset,
00404 uint32_t *target
00406 )
00407 {
00408 ec_datagram_t *datagram;
00409 cycles_t start, end, timeout;
00410
00411 datagram = &slave->master->simple_datagram;
00412
00413
00414 if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6))
00415 return -1;
00416 EC_WRITE_U8 (datagram->data, 0x00);
00417 EC_WRITE_U8 (datagram->data + 1, 0x01);
00418 EC_WRITE_U32(datagram->data + 2, offset);
00419 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00420 EC_ERR("SII-read failed on slave %i!\n", slave->ring_position);
00421 return -1;
00422 }
00423
00424 start = get_cycles();
00425 timeout = (cycles_t) 100 * cpu_khz;
00426
00427 while (1)
00428 {
00429 udelay(10);
00430
00431 if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
00432 return -1;
00433 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00434 EC_ERR("Getting SII-read status failed on slave %i!\n",
00435 slave->ring_position);
00436 return -1;
00437 }
00438
00439 end = get_cycles();
00440
00441
00442 if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) {
00443 *target = EC_READ_U32(datagram->data + 6);
00444 return 0;
00445 }
00446
00447 if (unlikely((end - start) >= timeout)) {
00448 EC_ERR("SII-read. Slave %i timed out!\n", slave->ring_position);
00449 return -1;
00450 }
00451 }
00452 }
00453
00454
00455
00461 int ec_slave_sii_write16(ec_slave_t *slave,
00463 uint16_t offset,
00465 uint16_t value
00467 )
00468 {
00469 ec_datagram_t *datagram;
00470 cycles_t start, end, timeout;
00471
00472 datagram = &slave->master->simple_datagram;
00473
00474 EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n",
00475 slave->ring_position, offset, value);
00476
00477
00478 if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 8))
00479 return -1;
00480 EC_WRITE_U8 (datagram->data, 0x01);
00481 EC_WRITE_U8 (datagram->data + 1, 0x02);
00482 EC_WRITE_U32(datagram->data + 2, offset);
00483 EC_WRITE_U16(datagram->data + 6, value);
00484 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00485 EC_ERR("SII-write failed on slave %i!\n", slave->ring_position);
00486 return -1;
00487 }
00488
00489 start = get_cycles();
00490 timeout = (cycles_t) 100 * cpu_khz;
00491
00492 while (1)
00493 {
00494 udelay(10);
00495
00496 if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 2))
00497 return -1;
00498 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00499 EC_ERR("Getting SII-write status failed on slave %i!\n",
00500 slave->ring_position);
00501 return -1;
00502 }
00503
00504 end = get_cycles();
00505
00506
00507 if (likely((EC_READ_U8(datagram->data + 1) & 0x82) == 0)) {
00508 if (EC_READ_U8(datagram->data + 1) & 0x40) {
00509 EC_ERR("SII-write failed!\n");
00510 return -1;
00511 }
00512 else {
00513 EC_INFO("SII-write succeeded!\n");
00514 return 0;
00515 }
00516 }
00517
00518 if (unlikely((end - start) >= timeout)) {
00519 EC_ERR("SII-write: Slave %i timed out!\n", slave->ring_position);
00520 return -1;
00521 }
00522 }
00523 }
00524
00525
00526
00533 int ec_slave_fetch_categories(ec_slave_t *slave )
00534 {
00535 uint16_t word_offset, cat_type, word_count;
00536 uint32_t value;
00537 uint8_t *cat_data;
00538 unsigned int i;
00539
00540 word_offset = 0x0040;
00541
00542 if (!(cat_data = (uint8_t *) kmalloc(0x10000, GFP_ATOMIC))) {
00543 EC_ERR("Failed to allocate 64k bytes for category data.\n");
00544 return -1;
00545 }
00546
00547 while (1) {
00548
00549 if (ec_slave_sii_read32(slave, word_offset, &value)) {
00550 EC_ERR("Unable to read category header.\n");
00551 goto out_free;
00552 }
00553
00554
00555 if ((value & 0xFFFF) == 0xFFFF) break;
00556
00557 cat_type = value & 0x7FFF;
00558 word_count = (value >> 16) & 0xFFFF;
00559
00560
00561 for (i = 0; i < word_count; i++) {
00562 if (ec_slave_sii_read32(slave, word_offset + 2 + i, &value)) {
00563 EC_ERR("Unable to read category data word %i.\n", i);
00564 goto out_free;
00565 }
00566
00567 cat_data[i * 2] = (value >> 0) & 0xFF;
00568 cat_data[i * 2 + 1] = (value >> 8) & 0xFF;
00569
00570
00571 if (i + 1 < word_count) {
00572 i++;
00573 cat_data[i * 2] = (value >> 16) & 0xFF;
00574 cat_data[i * 2 + 1] = (value >> 24) & 0xFF;
00575 }
00576 }
00577
00578 switch (cat_type)
00579 {
00580 case 0x000A:
00581 if (ec_slave_fetch_strings(slave, cat_data))
00582 goto out_free;
00583 break;
00584 case 0x001E:
00585 if (ec_slave_fetch_general(slave, cat_data))
00586 goto out_free;
00587 break;
00588 case 0x0028:
00589 break;
00590 case 0x0029:
00591 if (ec_slave_fetch_sync(slave, cat_data, word_count))
00592 goto out_free;
00593 break;
00594 case 0x0032:
00595 if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_TX_PDO))
00596 goto out_free;
00597 break;
00598 case 0x0033:
00599 if (ec_slave_fetch_pdo(slave, cat_data, word_count, EC_RX_PDO))
00600 goto out_free;
00601 break;
00602 default:
00603 EC_WARN("Unknown category type 0x%04X in slave %i.\n",
00604 cat_type, slave->ring_position);
00605 }
00606
00607 word_offset += 2 + word_count;
00608 }
00609
00610 kfree(cat_data);
00611 return 0;
00612
00613 out_free:
00614 kfree(cat_data);
00615 return -1;
00616 }
00617
00618
00619
00625 int ec_slave_fetch_strings(ec_slave_t *slave,
00626 const uint8_t *data
00627 )
00628 {
00629 unsigned int string_count, i;
00630 size_t size;
00631 off_t offset;
00632 ec_eeprom_string_t *string;
00633
00634 string_count = data[0];
00635 offset = 1;
00636 for (i = 0; i < string_count; i++) {
00637 size = data[offset];
00638
00639 if (!(string = (ec_eeprom_string_t *)
00640 kmalloc(sizeof(ec_eeprom_string_t) + size + 1, GFP_ATOMIC))) {
00641 EC_ERR("Failed to allocate string memory.\n");
00642 return -1;
00643 }
00644 string->size = size;
00645
00646 string->data = (char *) string + sizeof(ec_eeprom_string_t);
00647 memcpy(string->data, data + offset + 1, size);
00648 string->data[size] = 0x00;
00649 list_add_tail(&string->list, &slave->eeprom_strings);
00650 offset += 1 + size;
00651 }
00652
00653 return 0;
00654 }
00655
00656
00657
00663 int ec_slave_fetch_general(ec_slave_t *slave,
00664 const uint8_t *data
00665 )
00666 {
00667 unsigned int i;
00668
00669 if (ec_slave_locate_string(slave, data[0], &slave->eeprom_group))
00670 return -1;
00671 if (ec_slave_locate_string(slave, data[1], &slave->eeprom_image))
00672 return -1;
00673 if (ec_slave_locate_string(slave, data[2], &slave->eeprom_order))
00674 return -1;
00675 if (ec_slave_locate_string(slave, data[3], &slave->eeprom_name))
00676 return -1;
00677
00678 for (i = 0; i < 4; i++)
00679 slave->sii_physical_layer[i] =
00680 (data[4] & (0x03 << (i * 2))) >> (i * 2);
00681
00682 return 0;
00683 }
00684
00685
00686
00692 int ec_slave_fetch_sync(ec_slave_t *slave,
00693 const uint8_t *data,
00694 size_t word_count
00695 )
00696 {
00697 unsigned int sync_count, i;
00698 ec_eeprom_sync_t *sync;
00699
00700 sync_count = word_count / 4;
00701
00702 for (i = 0; i < sync_count; i++, data += 8) {
00703 if (!(sync = (ec_eeprom_sync_t *)
00704 kmalloc(sizeof(ec_eeprom_sync_t), GFP_ATOMIC))) {
00705 EC_ERR("Failed to allocate Sync-Manager memory.\n");
00706 return -1;
00707 }
00708
00709 sync->index = i;
00710 sync->physical_start_address = *((uint16_t *) (data + 0));
00711 sync->length = *((uint16_t *) (data + 2));
00712 sync->control_register = data[4];
00713 sync->enable = data[6];
00714
00715 list_add_tail(&sync->list, &slave->eeprom_syncs);
00716 }
00717
00718 return 0;
00719 }
00720
00721
00722
00728 int ec_slave_fetch_pdo(ec_slave_t *slave,
00729 const uint8_t *data,
00730 size_t word_count,
00731 ec_pdo_type_t pdo_type
00732 )
00733 {
00734 ec_eeprom_pdo_t *pdo;
00735 ec_eeprom_pdo_entry_t *entry;
00736 unsigned int entry_count, i;
00737
00738 while (word_count >= 4) {
00739 if (!(pdo = (ec_eeprom_pdo_t *)
00740 kmalloc(sizeof(ec_eeprom_pdo_t), GFP_ATOMIC))) {
00741 EC_ERR("Failed to allocate PDO memory.\n");
00742 return -1;
00743 }
00744
00745 INIT_LIST_HEAD(&pdo->entries);
00746 pdo->type = pdo_type;
00747
00748 pdo->index = *((uint16_t *) data);
00749 entry_count = data[2];
00750 pdo->sync_manager = data[3];
00751 pdo->name = NULL;
00752 ec_slave_locate_string(slave, data[5], &pdo->name);
00753
00754 list_add_tail(&pdo->list, &slave->eeprom_pdos);
00755
00756 word_count -= 4;
00757 data += 8;
00758
00759 for (i = 0; i < entry_count; i++) {
00760 if (!(entry = (ec_eeprom_pdo_entry_t *)
00761 kmalloc(sizeof(ec_eeprom_pdo_entry_t), GFP_ATOMIC))) {
00762 EC_ERR("Failed to allocate PDO entry memory.\n");
00763 return -1;
00764 }
00765
00766 entry->index = *((uint16_t *) data);
00767 entry->subindex = data[2];
00768 entry->name = NULL;
00769 ec_slave_locate_string(slave, data[3], &entry->name);
00770 entry->bit_length = data[5];
00771
00772 list_add_tail(&entry->list, &pdo->entries);
00773
00774 word_count -= 4;
00775 data += 8;
00776 }
00777 }
00778
00779 return 0;
00780 }
00781
00782
00783
00790 int ec_slave_locate_string(ec_slave_t *slave,
00791 unsigned int index,
00792 char **ptr
00793 )
00794 {
00795 ec_eeprom_string_t *string;
00796 char *err_string;
00797
00798
00799 if (*ptr) {
00800 kfree(*ptr);
00801 *ptr = NULL;
00802 }
00803
00804
00805 if (!index) return 0;
00806
00807
00808 list_for_each_entry(string, &slave->eeprom_strings, list) {
00809 if (--index) continue;
00810
00811 if (!(*ptr = (char *) kmalloc(string->size + 1, GFP_ATOMIC))) {
00812 EC_ERR("Unable to allocate string memory.\n");
00813 return -1;
00814 }
00815 memcpy(*ptr, string->data, string->size + 1);
00816 return 0;
00817 }
00818
00819 EC_WARN("String %i not found in slave %i.\n", index, slave->ring_position);
00820
00821 err_string = "(string not found)";
00822
00823 if (!(*ptr = (char *) kmalloc(strlen(err_string) + 1, GFP_ATOMIC))) {
00824 EC_ERR("Unable to allocate string memory.\n");
00825 return -1;
00826 }
00827
00828 memcpy(*ptr, err_string, strlen(err_string) + 1);
00829 return 0;
00830 }
00831
00832
00833
00838 void ec_slave_state_ack(ec_slave_t *slave,
00839 uint8_t state
00840 )
00841 {
00842 ec_datagram_t *datagram;
00843 cycles_t start, end, timeout;
00844
00845 datagram = &slave->master->simple_datagram;
00846
00847 if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) return;
00848 EC_WRITE_U16(datagram->data, state | EC_ACK);
00849 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00850 EC_WARN("Acknowledge sending failed on slave %i!\n",
00851 slave->ring_position);
00852 return;
00853 }
00854
00855 start = get_cycles();
00856 timeout = (cycles_t) 100 * cpu_khz;
00857
00858 while (1) {
00859 udelay(100);
00860
00861 if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2))
00862 return;
00863 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00864 slave->current_state = EC_SLAVE_STATE_UNKNOWN;
00865 EC_WARN("Acknowledge checking failed on slave %i!\n",
00866 slave->ring_position);
00867 return;
00868 }
00869
00870 end = get_cycles();
00871
00872 if (EC_READ_U8(datagram->data) == state) {
00873 slave->current_state = state;
00874 EC_INFO("Acknowleged state 0x%02X on slave %i.\n", state,
00875 slave->ring_position);
00876 return;
00877 }
00878
00879 if (end - start >= timeout) {
00880 slave->current_state = EC_SLAVE_STATE_UNKNOWN;
00881 EC_WARN("Failed to acknowledge state 0x%02X on slave %i"
00882 " - Timeout!\n", state, slave->ring_position);
00883 return;
00884 }
00885 }
00886 }
00887
00888
00889
00896 void ec_slave_read_al_status_code(ec_slave_t *slave )
00897 {
00898 ec_datagram_t *datagram;
00899 uint16_t code;
00900 const ec_code_msg_t *al_msg;
00901
00902 datagram = &slave->master->simple_datagram;
00903
00904 if (ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2)) return;
00905 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00906 EC_WARN("Failed to read AL status code on slave %i!\n",
00907 slave->ring_position);
00908 return;
00909 }
00910
00911 if (!(code = EC_READ_U16(datagram->data))) return;
00912
00913 for (al_msg = al_status_messages; al_msg->code; al_msg++) {
00914 if (al_msg->code == code) {
00915 EC_ERR("AL status message 0x%04X: \"%s\".\n",
00916 al_msg->code, al_msg->message);
00917 return;
00918 }
00919 }
00920
00921 EC_ERR("Unknown AL status code 0x%04X.\n", code);
00922 }
00923
00924
00925
00931 int ec_slave_state_change(ec_slave_t *slave,
00932 uint8_t state
00933 )
00934 {
00935 ec_datagram_t *datagram;
00936 cycles_t start, end, timeout;
00937
00938 datagram = &slave->master->simple_datagram;
00939
00940 slave->requested_state = state;
00941
00942 if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2))
00943 return -1;
00944 EC_WRITE_U16(datagram->data, state);
00945 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00946 EC_ERR("Failed to set state 0x%02X on slave %i!\n",
00947 state, slave->ring_position);
00948 return -1;
00949 }
00950
00951 start = get_cycles();
00952 timeout = (cycles_t) 10 * cpu_khz;
00953
00954 while (1)
00955 {
00956 udelay(100);
00957
00958 if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2))
00959 return -1;
00960 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
00961 slave->current_state = EC_SLAVE_STATE_UNKNOWN;
00962 EC_ERR("Failed to check state 0x%02X on slave %i!\n",
00963 state, slave->ring_position);
00964 return -1;
00965 }
00966
00967 end = get_cycles();
00968
00969 if (unlikely(EC_READ_U8(datagram->data) & 0x10)) {
00970
00971 EC_ERR("Failed to set state 0x%02X - Slave %i refused state change"
00972 " (code 0x%02X)!\n", state, slave->ring_position,
00973 EC_READ_U8(datagram->data));
00974 slave->current_state = EC_READ_U8(datagram->data);
00975 state = slave->current_state & 0x0F;
00976 ec_slave_read_al_status_code(slave);
00977 ec_slave_state_ack(slave, state);
00978 return -1;
00979 }
00980
00981 if (likely(EC_READ_U8(datagram->data) == (state & 0x0F))) {
00982 slave->current_state = state;
00983 return 0;
00984 }
00985
00986 if (unlikely((end - start) >= timeout)) {
00987 slave->current_state = EC_SLAVE_STATE_UNKNOWN;
00988 EC_ERR("Failed to check state 0x%02X of slave %i - Timeout!\n",
00989 state, slave->ring_position);
00990 return -1;
00991 }
00992 }
00993 }
00994
00995
00996
01009 int ec_slave_prepare_fmmu(ec_slave_t *slave,
01010 const ec_domain_t *domain,
01011 const ec_sync_t *sync
01012 )
01013 {
01014 unsigned int i;
01015
01016
01017 for (i = 0; i < slave->fmmu_count; i++)
01018 if (slave->fmmus[i].domain == domain && slave->fmmus[i].sync == sync)
01019 return 0;
01020
01021
01022
01023 if (slave->fmmu_count >= slave->base_fmmu_count) {
01024 EC_ERR("Slave %i FMMU limit reached!\n", slave->ring_position);
01025 return -1;
01026 }
01027
01028 slave->fmmus[slave->fmmu_count].domain = domain;
01029 slave->fmmus[slave->fmmu_count].sync = sync;
01030 slave->fmmus[slave->fmmu_count].logical_start_address = 0;
01031 slave->fmmu_count++;
01032 slave->registered = 1;
01033
01034 return 0;
01035 }
01036
01037
01038
01047 void ec_slave_print(const ec_slave_t *slave,
01048 unsigned int verbosity
01049 )
01050 {
01051 ec_eeprom_sync_t *sync;
01052 ec_eeprom_pdo_t *pdo;
01053 ec_eeprom_pdo_entry_t *pdo_entry;
01054 ec_sdo_t *sdo;
01055 ec_sdo_entry_t *sdo_entry;
01056 int first, i;
01057
01058 if (slave->type) {
01059 EC_INFO("%i) %s %s: %s\n", slave->ring_position,
01060 slave->type->vendor_name, slave->type->product_name,
01061 slave->type->description);
01062 }
01063 else {
01064 EC_INFO("%i) UNKNOWN SLAVE: vendor 0x%08X, product 0x%08X\n",
01065 slave->ring_position, slave->sii_vendor_id,
01066 slave->sii_product_code);
01067 }
01068
01069 if (!verbosity) return;
01070
01071 EC_INFO(" Station address: 0x%04X\n", slave->station_address);
01072
01073 EC_INFO(" Data link status:\n");
01074 for (i = 0; i < 4; i++) {
01075 EC_INFO(" Port %i (", i);
01076 switch (slave->sii_physical_layer[i]) {
01077 case 0x00:
01078 printk("EBUS");
01079 break;
01080 case 0x01:
01081 printk("100BASE-TX");
01082 break;
01083 case 0x02:
01084 printk("100BASE-FX");
01085 break;
01086 default:
01087 printk("unknown");
01088 }
01089 printk(")\n");
01090 EC_INFO(" link %s, loop %s, %s\n",
01091 slave->dl_link[i] ? "up" : "down",
01092 slave->dl_loop[i] ? "closed" : "open",
01093 slave->dl_signal[i] ? "signal detected" : "no signal");
01094 }
01095
01096 EC_INFO(" Base information:\n");
01097 EC_INFO(" Type %u, revision %i, build %i\n",
01098 slave->base_type, slave->base_revision, slave->base_build);
01099 EC_INFO(" Supported FMMUs: %i, sync managers: %i\n",
01100 slave->base_fmmu_count, slave->base_sync_count);
01101
01102 if (slave->sii_mailbox_protocols) {
01103 EC_INFO(" Mailbox communication:\n");
01104 EC_INFO(" RX mailbox: 0x%04X/%i, TX mailbox: 0x%04X/%i\n",
01105 slave->sii_rx_mailbox_offset, slave->sii_rx_mailbox_size,
01106 slave->sii_tx_mailbox_offset, slave->sii_tx_mailbox_size);
01107 EC_INFO(" Supported protocols: ");
01108
01109 first = 1;
01110 if (slave->sii_mailbox_protocols & EC_MBOX_AOE) {
01111 printk("AoE");
01112 first = 0;
01113 }
01114 if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
01115 if (!first) printk(", ");
01116 printk("EoE");
01117 first = 0;
01118 }
01119 if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
01120 if (!first) printk(", ");
01121 printk("CoE");
01122 first = 0;
01123 }
01124 if (slave->sii_mailbox_protocols & EC_MBOX_FOE) {
01125 if (!first) printk(", ");
01126 printk("FoE");
01127 first = 0;
01128 }
01129 if (slave->sii_mailbox_protocols & EC_MBOX_SOE) {
01130 if (!first) printk(", ");
01131 printk("SoE");
01132 first = 0;
01133 }
01134 if (slave->sii_mailbox_protocols & EC_MBOX_VOE) {
01135 if (!first) printk(", ");
01136 printk("VoE");
01137 }
01138 printk("\n");
01139 }
01140
01141 EC_INFO(" EEPROM data:\n");
01142
01143 EC_INFO(" EEPROM content size: %i Bytes\n", slave->eeprom_size);
01144
01145 if (slave->sii_alias)
01146 EC_INFO(" Configured station alias: 0x%04X (%i)\n",
01147 slave->sii_alias, slave->sii_alias);
01148
01149 EC_INFO(" Vendor-ID: 0x%08X, Product code: 0x%08X\n",
01150 slave->sii_vendor_id, slave->sii_product_code);
01151 EC_INFO(" Revision number: 0x%08X, Serial number: 0x%08X\n",
01152 slave->sii_revision_number, slave->sii_serial_number);
01153
01154 if (slave->eeprom_group)
01155 EC_INFO(" Group: %s\n", slave->eeprom_group);
01156 if (slave->eeprom_image)
01157 EC_INFO(" Image: %s\n", slave->eeprom_image);
01158 if (slave->eeprom_order)
01159 EC_INFO(" Order#: %s\n", slave->eeprom_order);
01160 if (slave->eeprom_name)
01161 EC_INFO(" Name: %s\n", slave->eeprom_name);
01162
01163 if (!list_empty(&slave->eeprom_syncs)) {
01164 EC_INFO(" Sync-Managers:\n");
01165 list_for_each_entry(sync, &slave->eeprom_syncs, list) {
01166 EC_INFO(" %i: 0x%04X, length %i, control 0x%02X, %s\n",
01167 sync->index, sync->physical_start_address,
01168 sync->length, sync->control_register,
01169 sync->enable ? "enable" : "disable");
01170 }
01171 }
01172
01173 list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
01174 EC_INFO(" %s \"%s\" (0x%04X), -> Sync-Manager %i\n",
01175 pdo->type == EC_RX_PDO ? "RXPDO" : "TXPDO",
01176 pdo->name ? pdo->name : "???",
01177 pdo->index, pdo->sync_manager);
01178
01179 list_for_each_entry(pdo_entry, &pdo->entries, list) {
01180 EC_INFO(" \"%s\" 0x%04X:%X, %i Bit\n",
01181 pdo_entry->name ? pdo_entry->name : "???",
01182 pdo_entry->index, pdo_entry->subindex,
01183 pdo_entry->bit_length);
01184 }
01185 }
01186
01187 if (verbosity < 2) return;
01188
01189 if (!list_empty(&slave->sdo_dictionary)) {
01190 EC_INFO(" SDO-Dictionary:\n");
01191 list_for_each_entry(sdo, &slave->sdo_dictionary, list) {
01192 EC_INFO(" 0x%04X \"%s\"\n", sdo->index,
01193 sdo->name ? sdo->name : "");
01194 EC_INFO(" Object code: 0x%02X\n", sdo->object_code);
01195 list_for_each_entry(sdo_entry, &sdo->entries, list) {
01196 EC_INFO(" 0x%04X:%i \"%s\", type 0x%04X, %i bits\n",
01197 sdo->index, sdo_entry->subindex,
01198 sdo_entry->name ? sdo_entry->name : "",
01199 sdo_entry->data_type, sdo_entry->bit_length);
01200 }
01201 }
01202 }
01203 }
01204
01205
01206
01212 int ec_slave_check_crc(ec_slave_t *slave )
01213 {
01214 ec_datagram_t *datagram;
01215
01216 datagram = &slave->master->simple_datagram;
01217
01218 if (ec_datagram_nprd(datagram, slave->station_address, 0x0300, 4))
01219 return -1;
01220 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
01221 EC_WARN("Reading CRC fault counters failed on slave %i!\n",
01222 slave->ring_position);
01223 return -1;
01224 }
01225
01226 if (!EC_READ_U32(datagram->data)) return 0;
01227
01228 if (EC_READ_U8(datagram->data))
01229 EC_WARN("%3i RX-error%s on slave %i, channel A.\n",
01230 EC_READ_U8(datagram->data),
01231 EC_READ_U8(datagram->data) == 1 ? "" : "s",
01232 slave->ring_position);
01233 if (EC_READ_U8(datagram->data + 1))
01234 EC_WARN("%3i invalid frame%s on slave %i, channel A.\n",
01235 EC_READ_U8(datagram->data + 1),
01236 EC_READ_U8(datagram->data + 1) == 1 ? "" : "s",
01237 slave->ring_position);
01238 if (EC_READ_U8(datagram->data + 2))
01239 EC_WARN("%3i RX-error%s on slave %i, channel B.\n",
01240 EC_READ_U8(datagram->data + 2),
01241 EC_READ_U8(datagram->data + 2) == 1 ? "" : "s",
01242 slave->ring_position);
01243 if (EC_READ_U8(datagram->data + 3))
01244 EC_WARN("%3i invalid frame%s on slave %i, channel B.\n",
01245 EC_READ_U8(datagram->data + 3),
01246 EC_READ_U8(datagram->data + 3) == 1 ? "" : "s",
01247 slave->ring_position);
01248
01249
01250 if (ec_datagram_npwr(datagram, slave->station_address, 0x0300, 4))
01251 return -1;
01252 EC_WRITE_U32(datagram->data, 0x00000000);
01253 if (unlikely(ec_master_simple_io(slave->master, datagram))) {
01254 EC_WARN("Resetting CRC fault counters failed on slave %i!\n",
01255 slave->ring_position);
01256 return -1;
01257 }
01258
01259 return 0;
01260 }
01261
01262
01263
01269 ssize_t ec_slave_write_eeprom(ec_slave_t *slave,
01270 const uint8_t *data,
01271 size_t size
01272 )
01273 {
01274 uint16_t word_size, cat_type, cat_size;
01275 const uint16_t *data_words, *next_header;
01276 uint16_t *new_data;
01277
01278 if (!slave->master->eeprom_write_enable) {
01279 EC_ERR("Writing EEPROMs not allowed! Enable via"
01280 " eeprom_write_enable SysFS entry.\n");
01281 return -1;
01282 }
01283
01284 if (slave->master->mode != EC_MASTER_MODE_IDLE) {
01285 EC_ERR("Writing EEPROMs only allowed in idle mode!\n");
01286 return -1;
01287 }
01288
01289 if (slave->new_eeprom_data) {
01290 EC_ERR("Slave %i already has a pending EEPROM write operation!\n",
01291 slave->ring_position);
01292 return -1;
01293 }
01294
01295
01296
01297 if (size % 2) {
01298 EC_ERR("EEPROM size is odd! Dropping.\n");
01299 return -1;
01300 }
01301
01302 data_words = (const uint16_t *) data;
01303 word_size = size / 2;
01304
01305 if (word_size < 0x0041) {
01306 EC_ERR("EEPROM data too short! Dropping.\n");
01307 return -1;
01308 }
01309
01310 next_header = data_words + 0x0040;
01311 cat_type = EC_READ_U16(next_header);
01312 while (cat_type != 0xFFFF) {
01313 cat_type = EC_READ_U16(next_header);
01314 cat_size = EC_READ_U16(next_header + 1);
01315 if ((next_header + cat_size + 2) - data_words >= word_size) {
01316 EC_ERR("EEPROM data seems to be corrupted! Dropping.\n");
01317 return -1;
01318 }
01319 next_header += cat_size + 2;
01320 cat_type = EC_READ_U16(next_header);
01321 }
01322
01323
01324
01325 if (!(new_data = (uint16_t *) kmalloc(word_size * 2, GFP_KERNEL))) {
01326 EC_ERR("Unable to allocate memory for new EEPROM data!\n");
01327 return -1;
01328 }
01329 memcpy(new_data, data, size);
01330
01331 slave->new_eeprom_size = word_size;
01332 slave->new_eeprom_data = new_data;
01333
01334 EC_INFO("EEPROM writing scheduled for slave %i, %i words.\n",
01335 slave->ring_position, word_size);
01336 return 0;
01337 }
01338
01339
01340
01346 ssize_t ec_show_slave_attribute(struct kobject *kobj,
01347 struct attribute *attr,
01348 char *buffer
01349 )
01350 {
01351 ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
01352
01353 if (attr == &attr_ring_position) {
01354 return sprintf(buffer, "%i\n", slave->ring_position);
01355 }
01356 else if (attr == &attr_advanced_position) {
01357 return sprintf(buffer, "%i:%i\n", slave->coupler_index,
01358 slave->coupler_subindex);
01359 }
01360 else if (attr == &attr_vendor_name) {
01361 if (slave->type)
01362 return sprintf(buffer, "%s\n", slave->type->vendor_name);
01363 }
01364 else if (attr == &attr_product_name) {
01365 if (slave->type)
01366 return sprintf(buffer, "%s\n", slave->type->product_name);
01367 }
01368 else if (attr == &attr_product_desc) {
01369 if (slave->type)
01370 return sprintf(buffer, "%s\n", slave->type->description);
01371 }
01372 else if (attr == &attr_name) {
01373 if (slave->eeprom_name)
01374 return sprintf(buffer, "%s\n", slave->eeprom_name);
01375 }
01376 else if (attr == &attr_type) {
01377 if (slave->type) {
01378 if (slave->type->special == EC_TYPE_BUS_COUPLER)
01379 return sprintf(buffer, "coupler\n");
01380 else if (slave->type->special == EC_TYPE_INFRA)
01381 return sprintf(buffer, "infrastructure\n");
01382 else
01383 return sprintf(buffer, "normal\n");
01384 }
01385 }
01386 else if (attr == &attr_state) {
01387 switch (slave->current_state) {
01388 case EC_SLAVE_STATE_INIT:
01389 return sprintf(buffer, "INIT\n");
01390 case EC_SLAVE_STATE_PREOP:
01391 return sprintf(buffer, "PREOP\n");
01392 case EC_SLAVE_STATE_SAVEOP:
01393 return sprintf(buffer, "SAVEOP\n");
01394 case EC_SLAVE_STATE_OP:
01395 return sprintf(buffer, "OP\n");
01396 default:
01397 return sprintf(buffer, "UNKNOWN\n");
01398 }
01399 }
01400 else if (attr == &attr_eeprom) {
01401 if (slave->eeprom_data) {
01402 if (slave->eeprom_size > PAGE_SIZE) {
01403 EC_ERR("EEPROM contents of slave %i exceed 1 page (%i/%i).\n",
01404 slave->ring_position, slave->eeprom_size,
01405 (int) PAGE_SIZE);
01406 }
01407 else {
01408 memcpy(buffer, slave->eeprom_data, slave->eeprom_size);
01409 return slave->eeprom_size;
01410 }
01411 }
01412 }
01413
01414 return 0;
01415 }
01416
01417
01418
01424 ssize_t ec_store_slave_attribute(struct kobject *kobj,
01425 struct attribute *attr,
01426 const char *buffer,
01427 size_t size
01428 )
01429 {
01430 ec_slave_t *slave = container_of(kobj, ec_slave_t, kobj);
01431
01432 if (attr == &attr_state) {
01433 if (!strcmp(buffer, "INIT\n"))
01434 slave->requested_state = EC_SLAVE_STATE_INIT;
01435 else if (!strcmp(buffer, "PREOP\n"))
01436 slave->requested_state = EC_SLAVE_STATE_PREOP;
01437 else if (!strcmp(buffer, "SAVEOP\n"))
01438 slave->requested_state = EC_SLAVE_STATE_SAVEOP;
01439 else if (!strcmp(buffer, "OP\n"))
01440 slave->requested_state = EC_SLAVE_STATE_OP;
01441 else {
01442 EC_ERR("Invalid slave state \"%s\"!\n", buffer);
01443 return -EINVAL;
01444 }
01445
01446 EC_INFO("Accepted new state %s for slave %i.\n",
01447 buffer, slave->ring_position);
01448 slave->error_flag = 0;
01449 return size;
01450 }
01451 else if (attr == &attr_eeprom) {
01452 if (!ec_slave_write_eeprom(slave, buffer, size))
01453 return size;
01454 }
01455
01456 return -EINVAL;
01457 }
01458
01459
01460
01465 size_t ec_slave_calc_sync_size(const ec_slave_t *slave,
01466 const ec_sync_t *sync
01467 )
01468 {
01469 unsigned int i, found;
01470 const ec_field_t *field;
01471 const ec_varsize_t *var;
01472 size_t size;
01473
01474
01475 if (sync->size) return sync->size;
01476
01477
01478
01479 size = 0;
01480 for (i = 0; (field = sync->fields[i]); i++) {
01481 found = 0;
01482 list_for_each_entry(var, &slave->varsize_fields, list) {
01483 if (var->field != field) continue;
01484 size += var->size;
01485 found = 1;
01486 }
01487
01488 if (!found) {
01489 EC_WARN("Variable data field \"%s\" of slave %i has no size"
01490 " information!\n", field->name, slave->ring_position);
01491 }
01492 }
01493 return size;
01494 }
01495
01496
01497
01503 uint16_t ec_slave_calc_eeprom_sync_size(const ec_slave_t *slave,
01505 const ec_eeprom_sync_t *sync
01507 )
01508 {
01509 ec_eeprom_pdo_t *pdo;
01510 ec_eeprom_pdo_entry_t *pdo_entry;
01511 unsigned int bit_size;
01512
01513 if (sync->length) return sync->length;
01514
01515 bit_size = 0;
01516 list_for_each_entry(pdo, &slave->eeprom_pdos, list) {
01517 if (pdo->sync_manager != sync->index) continue;
01518
01519 list_for_each_entry(pdo_entry, &pdo->entries, list) {
01520 bit_size += pdo_entry->bit_length;
01521 }
01522 }
01523
01524 if (bit_size % 8)
01525 return bit_size / 8 + 1;
01526 else
01527 return bit_size / 8;
01528 }
01529
01530
01531
01532
01533
01540 int ecrt_slave_write_alias(ec_slave_t *slave,
01541 uint16_t alias
01542 )
01543 {
01544 return ec_slave_sii_write16(slave, 0x0004, alias);
01545 }
01546
01547
01548
01554 int ecrt_slave_field_size(ec_slave_t *slave,
01555 const char *field_name,
01556 unsigned int field_index,
01557 size_t size
01558 )
01559 {
01560 unsigned int i, j, field_counter;
01561 const ec_sync_t *sync;
01562 const ec_field_t *field;
01563 ec_varsize_t *var;
01564
01565 if (!slave->type) {
01566 EC_ERR("Slave %i has no type information!\n", slave->ring_position);
01567 return -1;
01568 }
01569
01570 field_counter = 0;
01571 for (i = 0; (sync = slave->type->sync_managers[i]); i++) {
01572 for (j = 0; (field = sync->fields[j]); j++) {
01573 if (!strcmp(field->name, field_name)) {
01574 if (field_counter++ == field_index) {
01575
01576 if (field->size) {
01577 EC_ERR("Field \"%s\"[%i] of slave %i has no variable"
01578 " size!\n", field->name, field_index,
01579 slave->ring_position);
01580 return -1;
01581 }
01582
01583 list_for_each_entry(var, &slave->varsize_fields, list) {
01584 if (var->field == field) {
01585 EC_WARN("Resizing field \"%s\"[%i] of slave %i.\n",
01586 field->name, field_index,
01587 slave->ring_position);
01588 var->size = size;
01589 return 0;
01590 }
01591 }
01592
01593 if (!(var = kmalloc(sizeof(ec_varsize_t), GFP_KERNEL))) {
01594 EC_ERR("Failed to allocate memory for varsize_t!\n");
01595 return -1;
01596 }
01597 var->field = field;
01598 var->size = size;
01599 list_add_tail(&var->list, &slave->varsize_fields);
01600 return 0;
01601 }
01602 }
01603 }
01604 }
01605
01606 EC_ERR("Slave %i (\"%s %s\") has no field \"%s\"[%i]!\n",
01607 slave->ring_position, slave->type->vendor_name,
01608 slave->type->product_name, field_name, field_index);
01609 return -1;
01610 }
01611
01612
01613
01616 EXPORT_SYMBOL(ecrt_slave_write_alias);
01617 EXPORT_SYMBOL(ecrt_slave_field_size);
01618
01621