981 return; |
981 return; |
982 } |
982 } |
983 |
983 |
984 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
984 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
985 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
985 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
986 EC_SLAVE_ERR(slave, "SDO information error response while" |
986 EC_SLAVE_WARN(slave, "SDO information error response while" |
987 " fetching SDO entry 0x%04X:%02X!\n", |
987 " fetching SDO entry 0x%04X:%02X!\n", |
988 sdo->index, fsm->subindex); |
988 sdo->index, fsm->subindex); |
989 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
989 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
990 fsm->state = ec_fsm_coe_error; |
990 |
991 return; |
991 /* There may be gaps in the subindices, so try to continue with next |
992 } |
992 * subindex. */ |
993 |
993 |
994 if (rec_size < 9) { |
994 } else { |
995 EC_SLAVE_ERR(slave, "Received corrupted SDO entry" |
995 |
996 " description response (size %zu).\n", rec_size); |
996 if (rec_size < 9) { |
997 fsm->state = ec_fsm_coe_error; |
997 EC_SLAVE_ERR(slave, "Received corrupted SDO entry" |
998 return; |
998 " description response (size %zu).\n", rec_size); |
999 } |
999 fsm->state = ec_fsm_coe_error; |
1000 |
1000 return; |
1001 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
1001 } |
1002 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response |
1002 |
1003 EC_READ_U16(data + 6) != sdo->index || // SDO index |
1003 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
1004 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex |
1004 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. resp. |
1005 if (fsm->slave->master->debug_level) { |
1005 EC_READ_U16(data + 6) != sdo->index || // SDO index |
1006 EC_SLAVE_DBG(slave, 1, "Invalid entry description response while" |
1006 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex |
1007 " fetching SDO entry 0x%04X:%02X!\n", |
1007 if (fsm->slave->master->debug_level) { |
1008 sdo->index, fsm->subindex); |
1008 EC_SLAVE_DBG(slave, 1, "Invalid entry description response" |
|
1009 " while fetching SDO entry 0x%04X:%02X!\n", |
|
1010 sdo->index, fsm->subindex); |
|
1011 ec_print_data(data, rec_size); |
|
1012 } |
|
1013 // check for CoE response again |
|
1014 ec_slave_mbox_prepare_check(slave, mbox); // can not fail. |
|
1015 fsm->retries = EC_FSM_RETRIES; |
|
1016 fsm->state = ec_fsm_coe_dict_entry_check; |
|
1017 return; |
|
1018 } |
|
1019 |
|
1020 if (rec_size < 16) { |
|
1021 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size); |
1009 ec_print_data(data, rec_size); |
1022 ec_print_data(data, rec_size); |
1010 } |
|
1011 // check for CoE response again |
|
1012 ec_slave_mbox_prepare_check(slave, mbox); // can not fail. |
|
1013 fsm->retries = EC_FSM_RETRIES; |
|
1014 fsm->state = ec_fsm_coe_dict_entry_check; |
|
1015 return; |
|
1016 } |
|
1017 |
|
1018 if (rec_size < 16) { |
|
1019 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size); |
|
1020 ec_print_data(data, rec_size); |
|
1021 fsm->state = ec_fsm_coe_error; |
|
1022 return; |
|
1023 } |
|
1024 |
|
1025 data_size = rec_size - 16; |
|
1026 |
|
1027 if (!(entry = (ec_sdo_entry_t *) |
|
1028 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) { |
|
1029 EC_SLAVE_ERR(slave, "Failed to allocate entry!\n"); |
|
1030 fsm->state = ec_fsm_coe_error; |
|
1031 return; |
|
1032 } |
|
1033 |
|
1034 ec_sdo_entry_init(entry, sdo, fsm->subindex); |
|
1035 entry->data_type = EC_READ_U16(data + 10); |
|
1036 entry->bit_length = EC_READ_U16(data + 12); |
|
1037 |
|
1038 // read access rights |
|
1039 word = EC_READ_U16(data + 14); |
|
1040 entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001; |
|
1041 entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 1) & 0x0001; |
|
1042 entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001; |
|
1043 entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001; |
|
1044 entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 4) & 0x0001; |
|
1045 entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001; |
|
1046 |
|
1047 if (data_size) { |
|
1048 uint8_t *desc; |
|
1049 if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) { |
|
1050 EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n"); |
|
1051 fsm->state = ec_fsm_coe_error; |
1023 fsm->state = ec_fsm_coe_error; |
1052 return; |
1024 return; |
1053 } |
1025 } |
1054 memcpy(desc, data + 16, data_size); |
1026 |
1055 desc[data_size] = 0; |
1027 data_size = rec_size - 16; |
1056 entry->description = desc; |
1028 |
1057 } |
1029 if (!(entry = (ec_sdo_entry_t *) |
1058 |
1030 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) { |
1059 list_add_tail(&entry->list, &sdo->entries); |
1031 EC_SLAVE_ERR(slave, "Failed to allocate entry!\n"); |
|
1032 fsm->state = ec_fsm_coe_error; |
|
1033 return; |
|
1034 } |
|
1035 |
|
1036 ec_sdo_entry_init(entry, sdo, fsm->subindex); |
|
1037 entry->data_type = EC_READ_U16(data + 10); |
|
1038 entry->bit_length = EC_READ_U16(data + 12); |
|
1039 |
|
1040 // read access rights |
|
1041 word = EC_READ_U16(data + 14); |
|
1042 entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001; |
|
1043 entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 1) & 0x0001; |
|
1044 entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001; |
|
1045 entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001; |
|
1046 entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 4) & 0x0001; |
|
1047 entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001; |
|
1048 |
|
1049 if (data_size) { |
|
1050 uint8_t *desc; |
|
1051 if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) { |
|
1052 EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n"); |
|
1053 fsm->state = ec_fsm_coe_error; |
|
1054 return; |
|
1055 } |
|
1056 memcpy(desc, data + 16, data_size); |
|
1057 desc[data_size] = 0; |
|
1058 entry->description = desc; |
|
1059 } |
|
1060 |
|
1061 list_add_tail(&entry->list, &sdo->entries); |
|
1062 } |
1060 |
1063 |
1061 if (fsm->subindex < sdo->max_subindex) { |
1064 if (fsm->subindex < sdo->max_subindex) { |
1062 fsm->subindex++; |
1065 fsm->subindex++; |
1063 |
1066 |
1064 data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10); |
1067 data = ec_slave_mbox_prepare_send(slave, mbox, 0x03, 10); |