401 |
401 |
402 cat_type = EC_READ_U16(fsm->fsm_sii.value); |
402 cat_type = EC_READ_U16(fsm->fsm_sii.value); |
403 cat_size = EC_READ_U16(fsm->fsm_sii.value + 2); |
403 cat_size = EC_READ_U16(fsm->fsm_sii.value + 2); |
404 |
404 |
405 if (cat_type != 0xFFFF) { // not the last category |
405 if (cat_type != 0xFFFF) { // not the last category |
406 fsm->sii_offset += cat_size + 2; |
406 off_t next_offset = 2UL + fsm->sii_offset + cat_size; |
407 if (fsm->sii_offset >= EC_MAX_EEPROM_SIZE) { |
407 if (next_offset >= EC_MAX_EEPROM_SIZE) { |
408 EC_WARN("EEPROM size of slave %i exceeds" |
408 EC_WARN("EEPROM size of slave %i exceeds" |
409 " %i words (0xffff limiter missing?).\n", |
409 " %u words (0xffff limiter missing?).\n", |
410 slave->ring_position, EC_MAX_EEPROM_SIZE); |
410 slave->ring_position, EC_MAX_EEPROM_SIZE); |
411 slave->eeprom_size = EC_FIRST_EEPROM_CATEGORY_OFFSET * 2; |
411 slave->eeprom_size = EC_FIRST_EEPROM_CATEGORY_OFFSET * 2; |
412 goto alloc_eeprom; |
412 goto alloc_eeprom; |
413 } |
413 } |
|
414 fsm->sii_offset = next_offset; |
414 ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, |
415 ec_fsm_sii_read(&fsm->fsm_sii, slave, fsm->sii_offset, |
415 EC_FSM_SII_NODE); |
416 EC_FSM_SII_NODE); |
416 ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately |
417 ec_fsm_sii_exec(&fsm->fsm_sii); // execute state immediately |
417 return; |
418 return; |
418 } |
419 } |
419 |
420 |
420 slave->eeprom_size = (fsm->sii_offset + 1) * 2; |
421 slave->eeprom_size = (fsm->sii_offset + 1) * 2; |
421 |
422 |
422 alloc_eeprom: |
423 alloc_eeprom: |
423 if (slave->eeprom_data) { |
424 if (slave->eeprom_data) { |
424 EC_INFO("Freeing old EEPROM data on slave %i...\n", |
425 EC_WARN("Freeing old EEPROM data on slave %i...\n", |
425 slave->ring_position); |
426 slave->ring_position); |
426 kfree(slave->eeprom_data); |
427 kfree(slave->eeprom_data); |
427 } |
428 } |
428 |
429 |
429 if (!(slave->eeprom_data = |
430 if (!(slave->eeprom_data = |
430 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) { |
431 (uint8_t *) kmalloc(slave->eeprom_size, GFP_ATOMIC))) { |
|
432 EC_ERR("Failed to allocate %u bytes of EEPROM data for slave %u.\n", |
|
433 slave->eeprom_size, slave->ring_position); |
431 slave->eeprom_size = 0; |
434 slave->eeprom_size = 0; |
432 slave->error_flag = 1; |
435 slave->error_flag = 1; |
433 fsm->state = ec_fsm_slave_state_error; |
436 fsm->state = ec_fsm_slave_state_error; |
434 EC_ERR("Failed to allocate EEPROM data for slave %u.\n", |
|
435 slave->ring_position); |
|
436 return; |
437 return; |
437 } |
438 } |
438 |
439 |
439 // Start fetching EEPROM contents |
440 // Start fetching EEPROM contents |
440 |
441 |
507 EC_READ_U16(slave->eeprom_data + 2 * 0x001B); |
508 EC_READ_U16(slave->eeprom_data + 2 * 0x001B); |
508 slave->sii_mailbox_protocols = |
509 slave->sii_mailbox_protocols = |
509 EC_READ_U16(slave->eeprom_data + 2 * 0x001C); |
510 EC_READ_U16(slave->eeprom_data + 2 * 0x001C); |
510 |
511 |
511 if (eeprom_word_size < EC_FIRST_EEPROM_CATEGORY_OFFSET + 1) { |
512 if (eeprom_word_size < EC_FIRST_EEPROM_CATEGORY_OFFSET + 1) { |
512 EC_ERR("Unexpected end of EEPROM data in slave %u.\n", |
513 EC_ERR("Unexpected end of EEPROM data in slave %u:" |
|
514 " First category header missing.\n", |
513 slave->ring_position); |
515 slave->ring_position); |
514 goto end; |
516 goto end; |
515 } |
517 } |
516 |
518 |
517 // evaluate category data |
519 // evaluate category data |
520 while (EC_READ_U16(cat_word) != 0xFFFF) { |
522 while (EC_READ_U16(cat_word) != 0xFFFF) { |
521 |
523 |
522 // type and size words must fit |
524 // type and size words must fit |
523 if (cat_word + 2 - (uint16_t *) slave->eeprom_data |
525 if (cat_word + 2 - (uint16_t *) slave->eeprom_data |
524 > eeprom_word_size) { |
526 > eeprom_word_size) { |
525 EC_ERR("Unexpected end of EEPROM data in slave %u.\n", |
527 EC_ERR("Unexpected end of EEPROM data in slave %u:" |
|
528 " Category header incomplete.\n", |
526 slave->ring_position); |
529 slave->ring_position); |
527 goto end; |
530 goto end; |
528 } |
531 } |
529 |
532 |
530 cat_type = EC_READ_U16(cat_word) & 0x7FFF; |
533 cat_type = EC_READ_U16(cat_word) & 0x7FFF; |
531 cat_size = EC_READ_U16(cat_word + 1); |
534 cat_size = EC_READ_U16(cat_word + 1); |
532 cat_word += 2; |
535 cat_word += 2; |
533 |
536 |
534 if (cat_word + cat_size - (uint16_t *) slave->eeprom_data |
537 if (cat_word + cat_size - (uint16_t *) slave->eeprom_data |
535 > eeprom_word_size) { |
538 > eeprom_word_size) { |
536 EC_WARN("Unexpected end of EEPROM data in slave %u.\n", |
539 EC_WARN("Unexpected end of EEPROM data in slave %u:" |
|
540 " Category data incomplete.\n", |
537 slave->ring_position); |
541 slave->ring_position); |
538 goto end; |
542 goto end; |
539 } |
543 } |
540 |
544 |
541 switch (cat_type) { |
545 switch (cat_type) { |
572 cat_type, slave->ring_position); |
576 cat_type, slave->ring_position); |
573 } |
577 } |
574 |
578 |
575 cat_word += cat_size; |
579 cat_word += cat_size; |
576 if (cat_word - (uint16_t *) slave->eeprom_data >= eeprom_word_size) { |
580 if (cat_word - (uint16_t *) slave->eeprom_data >= eeprom_word_size) { |
577 EC_WARN("Unexpected end of EEPROM data in slave %u.\n", |
581 EC_WARN("Unexpected end of EEPROM data in slave %u:" |
|
582 " Next category header missing.\n", |
578 slave->ring_position); |
583 slave->ring_position); |
579 goto end; |
584 goto end; |
580 } |
585 } |
581 } |
586 } |
582 |
587 |