int ocp_recovery_device_write_request()

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;
}