955 return; |
955 return; |
956 } |
956 } |
957 |
957 |
958 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
958 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
959 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
959 (EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response |
960 EC_SLAVE_ERR(slave, "SDO information error response while" |
960 EC_SLAVE_WARN(slave, "SDO information error response while" |
961 " fetching SDO entry 0x%04X:%02X!\n", |
961 " fetching SDO entry 0x%04X:%02X!\n", |
962 sdo->index, fsm->subindex); |
962 sdo->index, fsm->subindex); |
963 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
963 ec_canopen_abort_msg(slave, EC_READ_U32(data + 6)); |
964 fsm->state = ec_fsm_coe_error; |
964 |
965 return; |
965 /* There may be gaps in the subindices, so try to continue with next |
966 } |
966 * subindex. */ |
967 |
967 |
968 if (rec_size < 9) { |
968 } else { |
969 EC_SLAVE_ERR(slave, "Received corrupted SDO entry" |
969 |
970 " description response (size %zu).\n", rec_size); |
970 if (rec_size < 9) { |
971 fsm->state = ec_fsm_coe_error; |
971 EC_SLAVE_ERR(slave, "Received corrupted SDO entry" |
972 return; |
972 " description response (size %zu).\n", rec_size); |
973 } |
973 fsm->state = ec_fsm_coe_error; |
974 |
974 return; |
975 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
975 } |
976 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response |
976 |
977 EC_READ_U16(data + 6) != sdo->index || // SDO index |
977 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
978 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex |
978 (EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response |
979 if (fsm->slave->master->debug_level) { |
979 EC_READ_U16(data + 6) != sdo->index || // SDO index |
980 EC_SLAVE_DBG(slave, 1, "Invalid entry description response while" |
980 EC_READ_U8(data + 8) != fsm->subindex) { // SDO subindex |
981 " fetching SDO entry 0x%04X:%02X!\n", |
981 if (fsm->slave->master->debug_level) { |
982 sdo->index, fsm->subindex); |
982 EC_SLAVE_DBG(slave, 1, "Invalid entry description response" |
|
983 " while fetching SDO entry 0x%04X:%02X!\n", |
|
984 sdo->index, fsm->subindex); |
|
985 ec_print_data(data, rec_size); |
|
986 } |
|
987 // check for CoE response again |
|
988 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
989 fsm->retries = EC_FSM_RETRIES; |
|
990 fsm->state = ec_fsm_coe_dict_entry_check; |
|
991 return; |
|
992 } |
|
993 |
|
994 if (rec_size < 16) { |
|
995 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size); |
983 ec_print_data(data, rec_size); |
996 ec_print_data(data, rec_size); |
984 } |
|
985 // check for CoE response again |
|
986 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
987 fsm->retries = EC_FSM_RETRIES; |
|
988 fsm->state = ec_fsm_coe_dict_entry_check; |
|
989 return; |
|
990 } |
|
991 |
|
992 if (rec_size < 16) { |
|
993 EC_SLAVE_ERR(slave, "Invalid data size %zu!\n", rec_size); |
|
994 ec_print_data(data, rec_size); |
|
995 fsm->state = ec_fsm_coe_error; |
|
996 return; |
|
997 } |
|
998 |
|
999 data_size = rec_size - 16; |
|
1000 |
|
1001 if (!(entry = (ec_sdo_entry_t *) |
|
1002 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) { |
|
1003 EC_SLAVE_ERR(slave, "Failed to allocate entry!\n"); |
|
1004 fsm->state = ec_fsm_coe_error; |
|
1005 return; |
|
1006 } |
|
1007 |
|
1008 ec_sdo_entry_init(entry, sdo, fsm->subindex); |
|
1009 entry->data_type = EC_READ_U16(data + 10); |
|
1010 entry->bit_length = EC_READ_U16(data + 12); |
|
1011 |
|
1012 // read access rights |
|
1013 word = EC_READ_U16(data + 14); |
|
1014 entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001; |
|
1015 entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 1) & 0x0001; |
|
1016 entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001; |
|
1017 entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001; |
|
1018 entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = (word >> 4) & 0x0001; |
|
1019 entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001; |
|
1020 |
|
1021 if (data_size) { |
|
1022 uint8_t *desc; |
|
1023 if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) { |
|
1024 EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n"); |
|
1025 fsm->state = ec_fsm_coe_error; |
997 fsm->state = ec_fsm_coe_error; |
1026 return; |
998 return; |
1027 } |
999 } |
1028 memcpy(desc, data + 16, data_size); |
1000 |
1029 desc[data_size] = 0; |
1001 data_size = rec_size - 16; |
1030 entry->description = desc; |
1002 |
1031 } |
1003 if (!(entry = (ec_sdo_entry_t *) |
1032 |
1004 kmalloc(sizeof(ec_sdo_entry_t), GFP_KERNEL))) { |
1033 list_add_tail(&entry->list, &sdo->entries); |
1005 EC_SLAVE_ERR(slave, "Failed to allocate entry!\n"); |
|
1006 fsm->state = ec_fsm_coe_error; |
|
1007 return; |
|
1008 } |
|
1009 |
|
1010 ec_sdo_entry_init(entry, sdo, fsm->subindex); |
|
1011 entry->data_type = EC_READ_U16(data + 10); |
|
1012 entry->bit_length = EC_READ_U16(data + 12); |
|
1013 |
|
1014 // read access rights |
|
1015 word = EC_READ_U16(data + 14); |
|
1016 entry->read_access[EC_SDO_ENTRY_ACCESS_PREOP] = word & 0x0001; |
|
1017 entry->read_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = |
|
1018 (word >> 1) & 0x0001; |
|
1019 entry->read_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 2) & 0x0001; |
|
1020 entry->write_access[EC_SDO_ENTRY_ACCESS_PREOP] = (word >> 3) & 0x0001; |
|
1021 entry->write_access[EC_SDO_ENTRY_ACCESS_SAFEOP] = |
|
1022 (word >> 4) & 0x0001; |
|
1023 entry->write_access[EC_SDO_ENTRY_ACCESS_OP] = (word >> 5) & 0x0001; |
|
1024 |
|
1025 if (data_size) { |
|
1026 uint8_t *desc; |
|
1027 if (!(desc = kmalloc(data_size + 1, GFP_KERNEL))) { |
|
1028 EC_SLAVE_ERR(slave, "Failed to allocate SDO entry name!\n"); |
|
1029 fsm->state = ec_fsm_coe_error; |
|
1030 return; |
|
1031 } |
|
1032 memcpy(desc, data + 16, data_size); |
|
1033 desc[data_size] = 0; |
|
1034 entry->description = desc; |
|
1035 } |
|
1036 |
|
1037 list_add_tail(&entry->list, &sdo->entries); |
|
1038 } |
1034 |
1039 |
1035 if (fsm->subindex < sdo->max_subindex) { |
1040 if (fsm->subindex < sdo->max_subindex) { |
1036 fsm->subindex++; |
1041 fsm->subindex++; |
1037 |
1042 |
1038 data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10); |
1043 data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10); |