in core/recovery/ocp_recovery_device.c [363:447]
int ocp_recovery_device_write_request (const struct ocp_recovery_device *device,
const union ocp_recovery_device_cmd_buffer *data, size_t length)
{
int status = OCP_RECOVERY_DEVICE_RO_COMMAND;
if ((device == NULL) || (data == NULL)) {
return OCP_RECOVERY_DEVICE_INVALID_ARGUMENT;
}
switch (device->state->active_cmd) {
case OCP_RECOVERY_DEVICE_NO_COMMAND:
status = OCP_RECOVERY_DEVICE_NO_ACTIVE_COMMAND;
break;
case OCP_RECOVERY_CMD_RESET:
if (length == sizeof (struct ocp_recovery_reset)) {
status = ocp_recovery_device_write_reset (device, &data->reset);
}
else if (length > sizeof (struct ocp_recovery_reset)) {
status = OCP_RECOVERY_DEVICE_EXTRA_CMD_BYTES;
}
else {
status = OCP_RECOVERY_DEVICE_CMD_INCOMPLETE;
}
break;
case OCP_RECOVERY_CMD_RECOVERY_CTRL:
if (length == sizeof (struct ocp_recovery_recovery_ctrl)) {
status = ocp_recovery_device_write_recovery_ctrl (device, &data->recovery_ctrl);
}
else if (length > sizeof (struct ocp_recovery_recovery_ctrl)) {
status = OCP_RECOVERY_DEVICE_EXTRA_CMD_BYTES;
}
else {
status = OCP_RECOVERY_DEVICE_CMD_INCOMPLETE;
}
break;
case OCP_RECOVERY_CMD_INDIRECT_CTRL:
if (length == sizeof (struct ocp_recovery_indirect_ctrl)) {
status = ocp_recovery_device_write_indirect_ctrl (device, &data->indirect_ctrl);
}
else if (length > sizeof (struct ocp_recovery_indirect_ctrl)) {
status = OCP_RECOVERY_DEVICE_EXTRA_CMD_BYTES;
}
else {
status = OCP_RECOVERY_DEVICE_CMD_INCOMPLETE;
}
break;
case OCP_RECOVERY_CMD_INDIRECT_DATA:
status = ocp_recovery_device_write_indirect_data (device, &data->indirect_data, length);
break;
case OCP_RECOVERY_CMD_VENDOR:
status = OCP_RECOVERY_DEVICE_UNSUPPORTED;
break;
}
/* Update the protocol status in the case of an error. */
switch (status) {
case 0:
/* Successful command. */
break;
case OCP_RECOVERY_DEVICE_UNSUPPORTED:
case OCP_RECOVERY_DEVICE_RO_COMMAND:
device->state->protocol_status = OCP_RECOVERY_DEVICE_STATUS_PROTO_UNSUPPORTED_CMD;
break;
case OCP_RECOVERY_DEVICE_UNSUPPORTED_PARAM:
case OCP_RECOVERY_DEVICE_UNSUPPORTED_CMS:
device->state->protocol_status = OCP_RECOVERY_DEVICE_STATUS_PROTO_UNSUPPORTED_PARAM;
break;
case OCP_RECOVERY_DEVICE_CMD_INCOMPLETE:
case OCP_RECOVERY_DEVICE_EXTRA_CMD_BYTES:
device->state->protocol_status = OCP_RECOVERY_DEVICE_STATUS_PROTO_LENGTH_ERROR;
break;
}
device->state->active_cmd = OCP_RECOVERY_DEVICE_NO_COMMAND;
return status;
}