/**
 * @brief This method will translate the test unit ready SCSI command into
 *        an ATA CHECK POWER MODE command.
 *        For more information on the parameters passed to this method,
 *        please reference sati_translate_command().
 *
 * @return Indicate if the command translation succeeded.
 * @retval SCI_SUCCESS This is returned if the command translation was
 *         successful.
 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if the
 *         LBA field is not 0, the PMI bit is not 0.
 */
SATI_STATUS sati_test_unit_ready_translate_command(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   void                       * scsi_io,
   void                       * ata_io
)
{
   /**
    * SAT dictates:
    * - the device should be in a state to receive commands
    * - a stopped device should cause sense data.
    * - a format unit in progresss should cause sense data.
    * - a self-test in progress should cause sense data.
    * - a device fault occurred on previous request should cause sense data.
    * - handling the removable media feature set isn't supported according to
    *   SAT specifications.
    */
   if (sequence->device->state == SATI_DEVICE_STATE_STOPPED)
   {
      sati_scsi_sense_data_construct(
         sequence,
         scsi_io,
         SCSI_STATUS_CHECK_CONDITION,
         SCSI_SENSE_NOT_READY,
         SCSI_ASC_INITIALIZING_COMMAND_REQUIRED,
         SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED
      );
      return SATI_FAILURE_CHECK_RESPONSE_DATA;
   }
   else if (sequence->device->state
            == SATI_DEVICE_STATE_SELF_TEST_IN_PROGRESS)
   {
      sati_scsi_sense_data_construct(
         sequence,
         scsi_io,
         SCSI_STATUS_CHECK_CONDITION,
         SCSI_SENSE_NOT_READY,
         SCSI_ASC_LUN_SELF_TEST_IN_PROGRESS,
         SCSI_ASCQ_LUN_SELF_TEST_IN_PROGRESS
      );
      return SATI_FAILURE_CHECK_RESPONSE_DATA;
   }
   else if (sequence->device->state
            == SATI_DEVICE_STATE_FORMAT_UNIT_IN_PROGRESS)
   {
      sati_scsi_sense_data_construct(
         sequence,
         scsi_io,
         SCSI_STATUS_CHECK_CONDITION,
         SCSI_SENSE_NOT_READY,
         SCSI_ASC_LUN_FORMAT_IN_PROGRESS,
         SCSI_ASCQ_LUN_FORMAT_IN_PROGRESS
      );
      return SATI_FAILURE_CHECK_RESPONSE_DATA;
   }

   // The CDB is properly formed and the device is ready.
   sequence->type = SATI_SEQUENCE_TEST_UNIT_READY;

   sati_ata_check_power_mode_construct(ata_io, sequence);
   return SATI_SUCCESS;
}
/**
 * @brief This method will translate the SCSI request sense command
 *        into corresponding ATA commands.  Depending on supported and enabled
 *        capabilities like SMART, different ATA commands can be selected.
 *        For more information on the parameters passed to this method,
 *        please reference sati_translate_command().
 *
 * @return Indicates if the command translation succeeded.
 * @retval SATI_SUCCESS indicates that the translation was supported and occurred
 *         without error.
 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
 *         the SATII is processing a format unit commmand.
 * @retval SATI_COMPLETE indicates that the translation was supported, occurred without
 *         error, and no additional translation is necessary.
 */
SATI_STATUS sati_request_sense_translate_command(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   void                       * scsi_io,
   void                       * ata_io
)
{
   U8 * cdb = sati_cb_get_cdb_address(scsi_io);

   //check if SATI is processing format unit command
   switch(sequence->device->state)
   {
      case SATI_DEVICE_STATE_FORMAT_UNIT_IN_PROGRESS:
         sati_scsi_sense_data_construct(
            sequence,
            scsi_io,
            SCSI_STATUS_GOOD,
            SCSI_SENSE_NOT_READY,
            SCSI_ASC_LUN_FORMAT_IN_PROGRESS,
            SCSI_ASCQ_LUN_FORMAT_IN_PROGRESS
         );
         return SATI_COMPLETE;
      break;

      case SATI_DEVICE_STATE_UNIT_ATTENTION_CONDITION:
         sati_scsi_sense_data_construct(
            sequence,
            scsi_io,
            SCSI_STATUS_GOOD,
            SCSI_SENSE_UNIT_ATTENTION,
            sequence->device->unit_attention_asc,
            sequence->device->unit_attention_ascq
         );
         return SATI_COMPLETE;
      break;
      //sending sense data status Idle, this is set by start_stop_unit
      case SATI_DEVICE_STATE_IDLE:
         sati_scsi_sense_data_construct(
            sequence,
            scsi_io,
            SCSI_STATUS_GOOD,
            SCSI_SENSE_NO_SENSE,
            SCSI_ASC_POWER_STATE_CHANGE,
            SCSI_ASCQ_IDLE_CONDITION_ACTIVATE_BY_COMMAND
         );
         return SATI_COMPLETE;
      break;
      //sending sense data status Standby, this is set by start_stop_unit
      case SATI_DEVICE_STATE_STANDBY:
         sati_scsi_sense_data_construct(
            sequence,
            scsi_io,
            SCSI_STATUS_GOOD,
            SCSI_SENSE_NO_SENSE,
            SCSI_ASC_POWER_STATE_CHANGE,
            SCSI_ASCQ_STANDBY_CONDITION_ACTIVATE_BY_COMMAND
         );
         return SATI_COMPLETE;
      break;

      case SATI_DEVICE_STATE_STOPPED:
         sati_scsi_sense_data_construct(
            sequence,
            scsi_io,
            SCSI_STATUS_GOOD,
            SCSI_SENSE_NO_SENSE,
            SCSI_ASC_NO_ADDITIONAL_SENSE,
            SCSI_ASCQ_NO_ADDITIONAL_SENSE
         );
         return SATI_COMPLETE;
      break;

      default:
      break;
   }

   sequence->allocation_length = sati_get_cdb_byte(cdb, 4);

   //Check if the device has SMART support & SMART enabled
   if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT)
   {
       if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_ENABLE)
       {
            sati_ata_smart_return_status_construct(
                           ata_io,
                           sequence,
                           ATA_SMART_SUB_CMD_RETURN_STATUS
            );

            sequence->type = SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS;
            return SATI_SUCCESS;
        }
   }
   sati_ata_check_power_mode_construct(ata_io, sequence);
   sequence->type = SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE;
   return SATI_SUCCESS;
}