master/fsm_slave.c
changeset 744 b83392e8cd66
parent 742 03d2fe3d4a93
child 758 8fa6f825eb7d
equal deleted inserted replaced
743:5ee2c5ce9cca 744:b83392e8cd66
   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