395 } |
395 } |
396 |
396 |
397 if (mbox_prot != 0x03) { // CoE |
397 if (mbox_prot != 0x03) { // CoE |
398 EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
398 EC_ERR("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
399 fsm->state = ec_fsm_coe_error; |
399 fsm->state = ec_fsm_coe_error; |
400 return; |
400 return; |
401 } |
401 } |
402 |
402 |
403 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
403 if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information |
404 (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response |
404 (EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response |
405 EC_ERR("SDO information error response at slave %i!\n", |
405 EC_ERR("SDO information error response at slave %i!\n", |
406 slave->ring_position); |
406 slave->ring_position); |
407 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
407 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
408 fsm->state = ec_fsm_coe_error; |
408 fsm->state = ec_fsm_coe_error; |
409 return; |
409 return; |
410 } |
410 } |
411 |
411 |
412 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
412 if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information |
413 (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response |
413 (EC_READ_U8 (data + 2) & 0x7F) != 0x02) { // Get OD List response |
414 EC_ERR("Invalid SDO list response at slave %i!\n", |
414 EC_ERR("Invalid SDO list response at slave %i!\n", |
415 slave->ring_position); |
415 slave->ring_position); |
416 ec_print_data(data, rec_size); |
416 ec_print_data(data, rec_size); |
417 fsm->state = ec_fsm_coe_error; |
417 fsm->state = ec_fsm_coe_error; |
418 return; |
418 return; |
419 } |
419 } |
420 |
420 |
421 if (rec_size < 8) { |
421 if (rec_size < 8) { |
422 EC_ERR("Invalid data size!\n"); |
422 EC_ERR("Invalid data size!\n"); |
423 ec_print_data(data, rec_size); |
423 ec_print_data(data, rec_size); |
424 fsm->state = ec_fsm_coe_error; |
424 fsm->state = ec_fsm_coe_error; |
425 return; |
425 return; |
426 } |
426 } |
427 |
427 |
428 sdo_count = (rec_size - 8) / 2; |
428 sdo_count = (rec_size - 8) / 2; |
429 |
429 |
430 for (i = 0; i < sdo_count; i++) { |
430 for (i = 0; i < sdo_count; i++) { |
1323 } |
1328 } |
1324 |
1329 |
1325 if (mbox_prot != 0x03) { // CoE |
1330 if (mbox_prot != 0x03) { // CoE |
1326 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
1331 EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); |
1327 fsm->state = ec_fsm_coe_error; |
1332 fsm->state = ec_fsm_coe_error; |
1328 return; |
1333 return; |
1329 } |
1334 } |
1330 |
1335 |
1331 if (rec_size < 10) { |
1336 if (rec_size < 3) { |
1332 EC_ERR("Received currupted SDO upload response!\n"); |
1337 EC_ERR("Received currupted SDO upload response (%u bytes)!\n", rec_size); |
1333 ec_print_data(data, rec_size); |
1338 ec_print_data(data, rec_size); |
1334 fsm->state = ec_fsm_coe_error; |
1339 fsm->state = ec_fsm_coe_error; |
1335 return; |
1340 return; |
1336 } |
1341 } |
1337 |
1342 |
1338 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request |
1343 if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request |
1339 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request |
1344 EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request |
1340 EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n", |
1345 EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n", |
1341 entry->sdo->index, entry->subindex, slave->ring_position); |
1346 entry->sdo->index, entry->subindex, slave->ring_position); |
1342 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
1347 if (rec_size >= 10) |
1343 fsm->state = ec_fsm_coe_error; |
1348 ec_canopen_abort_msg(EC_READ_U32(data + 6)); |
1344 return; |
1349 else |
1345 } |
1350 EC_ERR("No abort message.\n"); |
1346 |
1351 fsm->state = ec_fsm_coe_error; |
1347 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
1352 return; |
1348 EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response |
1353 } |
1349 EC_READ_U16(data + 3) != entry->sdo->index || // index |
1354 |
1350 EC_READ_U8 (data + 5) != entry->subindex) { // subindex |
1355 if (request->data) { |
1351 EC_ERR("SDO upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex); |
1356 kfree(request->data); |
1352 EC_ERR("Invalid SDO upload response at slave %i!\n", |
1357 request->data = NULL; |
1353 slave->ring_position); |
1358 } |
1354 ec_print_data(data, rec_size); |
1359 request->size = 0; |
1355 fsm->state = ec_fsm_coe_error; |
1360 |
1356 return; |
1361 // normal or expedited? |
1357 } |
|
1358 |
|
1359 data_size = rec_size - 10; |
|
1360 expedited = EC_READ_U8(data + 2) & 0x02; |
1362 expedited = EC_READ_U8(data + 2) & 0x02; |
1361 |
1363 |
1362 if (expedited) { |
1364 if (expedited) { |
|
1365 if (rec_size < 7) { |
|
1366 EC_ERR("Received currupted SDO expedited upload" |
|
1367 " response (only %u bytes)!\n", rec_size); |
|
1368 ec_print_data(data, rec_size); |
|
1369 fsm->state = ec_fsm_coe_error; |
|
1370 return; |
|
1371 } |
|
1372 |
|
1373 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
|
1374 EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response |
|
1375 EC_READ_U16(data + 3) != entry->sdo->index || // index |
|
1376 EC_READ_U8 (data + 5) != entry->subindex) { // subindex |
|
1377 EC_ERR("SDO upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex); |
|
1378 EC_ERR("Invalid SDO upload response at slave %i!\n", |
|
1379 slave->ring_position); |
|
1380 ec_print_data(data, rec_size); |
|
1381 fsm->state = ec_fsm_coe_error; |
|
1382 return; |
|
1383 } |
|
1384 |
1363 size_specified = EC_READ_U8(data + 2) & 0x01; |
1385 size_specified = EC_READ_U8(data + 2) & 0x01; |
1364 if (size_specified) { |
1386 if (size_specified) { |
1365 complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2); |
1387 complete_size = 4 - ((EC_READ_U8(data + 2) & 0x0C) >> 2); |
1366 } |
1388 } else { |
1367 else { |
|
1368 complete_size = 4; |
1389 complete_size = 4; |
1369 } |
1390 } |
1370 } |
1391 |
1371 else { |
1392 if (rec_size < 6 + complete_size) { |
1372 complete_size = EC_READ_U32(data + 6); |
1393 EC_ERR("Received currupted SDO expedited upload" |
1373 } |
1394 " response (only %u bytes)!\n", rec_size); |
1374 |
1395 ec_print_data(data, rec_size); |
1375 if (request->data) { |
1396 fsm->state = ec_fsm_coe_error; |
1376 kfree(request->data); |
1397 return; |
1377 request->data = NULL; |
1398 } |
1378 } |
1399 |
1379 request->size = 0; |
|
1380 |
|
1381 if (complete_size) { |
|
1382 if (!(request->data = (uint8_t *) |
1400 if (!(request->data = (uint8_t *) |
1383 kmalloc(complete_size + 1, GFP_ATOMIC))) { |
1401 kmalloc(complete_size + 1, GFP_ATOMIC))) { |
1384 EC_ERR("Failed to allocate %i bytes of SDO data!\n", |
1402 EC_ERR("Failed to allocate %i bytes of SDO data!\n", |
1385 complete_size); |
1403 complete_size); |
1386 fsm->state = ec_fsm_coe_error; |
1404 fsm->state = ec_fsm_coe_error; |
1387 return; |
1405 return; |
1388 } |
1406 } |
1389 request->data[complete_size] = 0x00; // just to be sure... |
1407 request->data[complete_size] = 0x00; // just to be sure... |
1390 } |
1408 |
1391 |
|
1392 if (expedited) { |
|
1393 memcpy(request->data, data + 6, complete_size); |
1409 memcpy(request->data, data + 6, complete_size); |
1394 request->size = complete_size; |
1410 request->size = complete_size; |
1395 } |
1411 |
1396 else { |
1412 } else { // normal |
|
1413 if (rec_size < 10) { |
|
1414 EC_ERR("Received currupted SDO normal upload" |
|
1415 " response (only %u bytes)!\n", rec_size); |
|
1416 ec_print_data(data, rec_size); |
|
1417 fsm->state = ec_fsm_coe_error; |
|
1418 return; |
|
1419 } |
|
1420 |
|
1421 if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response |
|
1422 EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response |
|
1423 EC_READ_U16(data + 3) != entry->sdo->index || // index |
|
1424 EC_READ_U8 (data + 5) != entry->subindex) { // subindex |
|
1425 EC_ERR("SDO upload 0x%04X:%X failed:\n", entry->sdo->index, entry->subindex); |
|
1426 EC_ERR("Invalid SDO upload response at slave %i!\n", |
|
1427 slave->ring_position); |
|
1428 ec_print_data(data, rec_size); |
|
1429 fsm->state = ec_fsm_coe_error; |
|
1430 return; |
|
1431 } |
|
1432 |
|
1433 data_size = rec_size - 10; |
|
1434 complete_size = EC_READ_U32(data + 6); |
|
1435 |
|
1436 if (!complete_size) { |
|
1437 EC_ERR("No complete size supplied!\n"); |
|
1438 ec_print_data(data, rec_size); |
|
1439 fsm->state = ec_fsm_coe_error; |
|
1440 return; |
|
1441 } |
|
1442 |
|
1443 if (!(request->data = (uint8_t *) |
|
1444 kmalloc(complete_size + 1, GFP_ATOMIC))) { |
|
1445 EC_ERR("Failed to allocate %i bytes of SDO data!\n", |
|
1446 complete_size); |
|
1447 fsm->state = ec_fsm_coe_error; |
|
1448 return; |
|
1449 } |
|
1450 request->data[complete_size] = 0x00; // just to be sure... |
|
1451 |
1397 memcpy(request->data, data + 10, data_size); |
1452 memcpy(request->data, data + 10, data_size); |
1398 request->size = data_size; |
1453 request->size = complete_size; |
1399 fsm->toggle = 0; |
1454 fsm->toggle = 0; |
1400 |
1455 |
1401 if (data_size < complete_size) { |
1456 if (data_size < complete_size) { |
1402 EC_WARN("SDO data incomplete (%i / %i).\n", |
1457 EC_WARN("SDO data incomplete (%i / %i).\n", |
1403 data_size, complete_size); |
1458 data_size, complete_size); |