Exemple #1
0
/**
* @brief This method finishes the construction of the SCSI data associated
         with a request for the  ATA information vital product data (VPD) page.
         The ATA device signature is written into the data response from the
         task fle registers after issuing a Execute Device Diagnostic command.
*
* @param[in]  sequence This parameter specifies the translator sequence
*             object to be utilized during data translation.
* @param[out] scsi_io This parameter specifies the user IO request for
*             which to construct the ATA information page.
* @param[in]  ata_io This parameter specifies the ATA payload
*             buffer location and size to be translated.
*
* @return none
*/
void sati_inquiry_ata_information_finish_translation(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   void                       * scsi_io,
   void                       * ata_io
)
{
   U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
   U32 offset;

   //SATA transport
   sati_set_data_byte(sequence, scsi_io, 36, 0x34);
   sati_set_data_byte(sequence, scsi_io, 37, 0x00);
   sati_set_data_byte(sequence, scsi_io, 38, (U8) sati_get_ata_status(register_fis));
   sati_set_data_byte(sequence, scsi_io, 39, (U8) sati_get_ata_error(register_fis));
   sati_set_data_byte(sequence, scsi_io, 40, sati_get_ata_lba_low(register_fis));
   sati_set_data_byte(sequence, scsi_io, 41, sati_get_ata_lba_mid(register_fis));
   sati_set_data_byte(sequence, scsi_io, 42, sati_get_ata_lba_high(register_fis));
   sati_set_data_byte(sequence, scsi_io, 43, sati_get_ata_device(register_fis));
   sati_set_data_byte(sequence, scsi_io, 44, sati_get_ata_lba_low_ext(register_fis));
   sati_set_data_byte(sequence, scsi_io, 45, sati_get_ata_lba_mid_ext(register_fis));
   sati_set_data_byte(sequence, scsi_io, 46, sati_get_ata_lba_high_ext(register_fis));
   sati_set_data_byte(sequence, scsi_io, 47, 0x00);
   sati_set_data_byte(sequence, scsi_io, 48, sati_get_ata_sector_count(register_fis));
   sati_set_data_byte(sequence, scsi_io, 49, sati_get_ata_sector_count_exp(register_fis));

   for(offset = 50; offset < 56; offset++)
   {
      sati_set_data_byte(sequence, scsi_io, offset, 0x00);
   }

   sequence->state = SATI_SEQUENCE_STATE_FINAL;
}
Exemple #2
0
/**
 * @brief This method will construct the sense data buffer in the user's
 *        sense data buffer location.  Additionally, it will set the user's
 *        SCSI status.
 *
 * @param[in]     sequence This parameter specifies the translation sequence
 *                for which to construct the sense data.
 * @param[in]     register_fis This parameter specifies the fis from which
 *                to get the data.
 * @param[in,out] scsi_io This parameter specifies the user's IO request
 *                for which to construct the sense data.
 * @param[in]     scsi_status This parameter specifies the SCSI status
 *                value for the user's IO request.
 * @param[in]     sense_key This parameter specifies the sense key to
 *                be set for the user's IO request.
 * @param[in]     additional_sense_code This parameter specifies the
 *                additional sense code (ASC) key to be set for the user's
 *                IO request.
 * @param[in]     additional_sense_code_qualifier This parameter specifies
 *                the additional sense code qualifier (ASCQ) key to be set
 *                for the user's IO request.
 *
 * @return none
 */
static
void sati_passthrough_construct_sense(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   U8                         * register_fis,
   void                       * scsi_io,
   U8                           scsi_status,
   U8                           sense_key,
   U8                           additional_sense_code,
   U8                           additional_sense_code_qualifier
)
{
   U8                    * sense_data;
   U32                     sense_len;
   U8                    * cdb;
   unsigned char           sector_count_upper;
   unsigned char           lba_upper;

#ifdef SATI_TRANSPORT_SUPPORTS_SAS
   SCI_SSP_RESPONSE_IU_T * rsp_iu = (SCI_SSP_RESPONSE_IU_T*)
                                    sati_cb_get_response_iu_address(scsi_io);

   sati_scsi_common_response_iu_construct(
      rsp_iu,
      scsi_status,
      SCSI_FIXED_SENSE_DATA_BASE_LENGTH,
      SCSI_RESPONSE_DATA_PRES_SENSE_DATA
   );

   sense_data                   = (U8*) rsp_iu->data;
   sense_len                    = SSP_RESPONSE_IU_MAX_DATA * 4;  // dwords to bytes
#else
   sense_data = sati_cb_get_sense_data_address(scsi_io);
   sense_len  = sati_cb_get_sense_data_length(scsi_io);
#endif // SATI_TRANSPORT_SUPPORTS_SAS

   sati_scsi_sense_data_construct(
      sequence,
      scsi_io,
      scsi_status,
      sense_key,
      additional_sense_code,
      additional_sense_code_qualifier
   );

   cdb = sati_cb_get_cdb_address(scsi_io);

   if (sati_get_ata_sector_count_ext(register_fis) != 0) {
      sector_count_upper = 1;
   } else {
       sector_count_upper = 0;
   }

   if (sati_get_ata_lba_high_ext(register_fis) != 0 ||
       sati_get_ata_lba_mid_ext(register_fis) != 0 ||
       sati_get_ata_lba_low_ext(register_fis) != 0) {
      lba_upper = 1;
   } else {
       lba_upper = 0;
   }

   // Information section
   sati_set_sense_data_byte(sense_data, sense_len, 3,  (U8)sati_get_ata_error(register_fis));
   sati_set_sense_data_byte(sense_data, sense_len, 4,  (U8)sati_get_ata_status(register_fis));
   sati_set_sense_data_byte(sense_data, sense_len, 5,  sati_get_ata_device(register_fis));
   sati_set_sense_data_byte(sense_data, sense_len, 6,  sati_get_ata_sector_count(register_fis));

   // Command specific section
   sati_set_sense_data_byte(sense_data, sense_len, 8,  (PASSTHROUGH_CDB_EXTEND(cdb) << 7) | (sector_count_upper << 6) | (lba_upper << 5));
   sati_set_sense_data_byte(sense_data, sense_len, 9,  sati_get_ata_lba_high(register_fis));
   sati_set_sense_data_byte(sense_data, sense_len, 10, sati_get_ata_lba_mid(register_fis));
   sati_set_sense_data_byte(sense_data, sense_len, 11, sati_get_ata_lba_low(register_fis));

   sequence->is_sense_response_set = TRUE;
}
/**
 * @brief This method will translate the response to the SATI Request Sense
 *        translation. ATA_Check_Power_Mode and ATA_SMART_Return_Status will
 *        be translated into a SCSI sense data response.
 *
 * @return SATI_STATUS Indicates if the response translation succeeded.
 *
 */
SATI_STATUS sati_request_sense_translate_response(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   void                       * scsi_io,
   void                       * ata_io
)
{
   U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
   U32 mid_register;
   U32 high_register;
   U32 sector_count;
   SATI_STATUS status = SATI_FAILURE;

   if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
   {
      sati_scsi_sense_data_construct(
         sequence,
         scsi_io,
         SCSI_STATUS_CHECK_CONDITION,
         SCSI_SENSE_ABORTED_COMMAND,
         SCSI_ASC_NO_ADDITIONAL_SENSE ,
         SCSI_ASCQ_NO_ADDITIONAL_SENSE
      );
      status = SATI_FAILURE_CHECK_RESPONSE_DATA;
   }
   else
   {
      switch(sequence->type)
      {
         case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS:

            mid_register = sati_get_ata_lba_mid(register_fis);
            high_register = sati_get_ata_lba_high(register_fis);
            if(mid_register == ATA_MID_REGISTER_THRESHOLD_EXCEEDED
               && high_register == ATA_HIGH_REGISTER_THRESHOLD_EXCEEDED)
            {
               sati_request_sense_data_response_construct(
                  sequence,
                  scsi_io,
                  SCSI_SENSE_NO_SENSE,
                  SCSI_ASC_HARDWARE_IMPENDING_FAILURE,
                  SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE
               );
               status = SATI_COMPLETE;
            }
            else
            {
               sati_request_sense_data_response_construct(
                  sequence,
                  scsi_io,
                  SCSI_SENSE_NO_SENSE,
                  SCSI_ASC_NO_ADDITIONAL_SENSE,
                  SCSI_ASCQ_NO_ADDITIONAL_SENSE
               );
               status = SATI_COMPLETE;
            }
         break;

         case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE:

            sector_count = sati_get_ata_sector_count(register_fis);

            switch(sector_count)
            {
                case ATA_STANDBY_POWER_MODE:
                   sati_request_sense_data_response_construct(
                      sequence,
                      scsi_io,
                      SCSI_SENSE_NO_SENSE,
                      SCSI_ASC_POWER_STATE_CHANGE,
                      SCSI_ASCQ_POWER_STATE_CHANGE_TO_STANDBY
                   );
                   status = SATI_COMPLETE;
                break;

                case ATA_IDLE_POWER_MODE:
                   sati_request_sense_data_response_construct(
                      sequence,
                      scsi_io,
                      SCSI_SENSE_NO_SENSE,
                      SCSI_ASC_POWER_STATE_CHANGE,
                      SCSI_ASCQ_POWER_STATE_CHANGE_TO_IDLE
                   );
                   status = SATI_COMPLETE;
                break;

                case ATA_ACTIVE_POWER_MODE:
                   sati_request_sense_data_response_construct(
                      sequence,
                      scsi_io,
                      SCSI_SENSE_NO_SENSE,
                      SCSI_ASC_NO_ADDITIONAL_SENSE,
                      SCSI_ASCQ_NO_ADDITIONAL_SENSE
                   );
                   status = SATI_COMPLETE;
                break;

                default:
                break;
             }
         break;

         default:
            sati_request_sense_data_response_construct(
               sequence,
               scsi_io,
               SCSI_SENSE_NO_SENSE,
               SCSI_ASC_NO_ADDITIONAL_SENSE,
               SCSI_ASCQ_NO_ADDITIONAL_SENSE
            );
            status = SATI_COMPLETE;
      }
   }

   return status;
}