FreeBSD/sys/dev/isci/scil/sati_mode_select.c
/**
 * @brief This method will check the validity of parameter data of Power Condition mode
 *            page and issue multiple ATA set feature commands to complete the translation.
 *
 * @param[in] mode_select_process_state This parameter points to the processing state fields
 *            of current mode page.
 * @param[in] page_size This parameter specifies page size of current mode page.
 *
 * @return Indicate if the translation was successful.
 * @retval SATI_SUCCESS
 * @retval SATI_COMPLETE
 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
 */
@brief This method will check the validity of parameter data of Power Condition mode
page and issue multiple ATA set feature commands to complete the translation.

@param[in] mode_select_process_state This parameter points to the processing state fields
of current mode page.
@param[in] page_size This parameter specifies page size of current mode page.

@return Indicate if the translation was successful.
@brief This method will check the validity of parameter data of Power Condition mode page and issue multiple ATA set feature commands to complete the translation . @param [ in ] mode_select_process_state This parameter points to the processing state fields of current mode page . @param [ in ] page_size This parameter specifies page size of current mode page . @return Indicate if the translation was successful .
static
SATI_STATUS sati_mode_select_process_mode_page_power_condition(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   void * scsi_io,
   void * ata_io,
   U32 page_size
   )
{
   SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
   U8 current_mode_page[SCSI_MODE_PAGE_1A_LENGTH] = {0,0,0,0,0,0,0,0,0,0};
   U32 mode_page_offset;
   U32 index;
   U32 timer = 0;
   U16 count = 0;
   mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
   sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION;
   for(index = 0; index < SCSI_MODE_PAGE_1A_LENGTH; index++)
   {
      sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
   }
   if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
      (current_mode_page[1] != (SCSI_MODE_PAGE_1A_LENGTH - 2) ) ||
      ((current_mode_page[3] & SCSI_MODE_PAGE_POWER_CONDITION_IDLE)!= 0)
      )
   {
      return SATI_FAILURE_CHECK_RESPONSE_DATA;
   }
   if (current_mode_page[3] & SCSI_MODE_PAGE_POWER_CONDITION_STANDBY)
   {
      timer = (current_mode_page[8]<<24) + (current_mode_page[9]<<16) + (current_mode_page[10]<<8) + current_mode_page[11];
      if (sequence->device->capabilities & SATI_DEVICE_CAP_STANDBY_ENABLE)
      {
         if (timer == 0)
         {
            sati_ata_standby_immediate_construct(ata_io, sequence);
            sequence->command_specific_data.translated_command = ATA_STANDBY_IMMED;
         }
         else if ((timer > 0) && (timer <= 12000))
         {
            count = (U16)((timer -1) / 50) + 1;
            sati_ata_standby_construct(ata_io, sequence, count);
         }
         else if ((timer > 12000) && (timer <= 12600))
         {
            sati_ata_standby_construct(ata_io, sequence, 0xFC);
         }
         else if ((timer > 12600) && (timer <= 12750))
         {
            sati_ata_standby_construct(ata_io, sequence, 0xFF);
         }
         else if ((timer > 12750) && (timer < 18000))
         {
            sati_ata_standby_construct(ata_io, sequence, 0xF1);
         }
         else if ((timer >= 18000) && (timer <= 198000))
         {
            count = (U16)(timer / 18000) + 240;
            sati_ata_standby_construct(ata_io, sequence, count);
         }
         else
         {
            sati_ata_standby_construct(ata_io, sequence, 0xFD);
         }
         status = SATI_SUCCESS ;
      }
      else
      {
         status = SATI_FAILURE_CHECK_RESPONSE_DATA;
      }
   }
   else
   {
      status = SATI_COMPLETE;
   }
   sequence->command_specific_data.process_state.size_of_data_processed += page_size;
   sequence->command_specific_data.process_state.mode_page_offset += page_size;
   sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
   return status;
}
static SATI_STATUS sati_mode_select_process_mode_page_power_condition ( SATI_TRANSLATOR_SEQUENCE_T * sequence , void * scsi_io , void * ata_io , U32 page_size ) { SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA ; U8 current_mode_page [ SCSI_MODE_PAGE_1A_LENGTH ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ; U32 mode_page_offset ; U32 index ; U32 timer = 0 ; U16 count = 0 ; mode_page_offset = sequence -> command_specific_data . process_state . mode_page_offset ; sequence -> type = SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION ; for ( index = 0 ; index < SCSI_MODE_PAGE_1A_LENGTH ; index ++ ) { sati_get_data_byte ( sequence , scsi_io , mode_page_offset + index , & current_mode_page [ index ] ) ; } if ( ( ( current_mode_page [ 0 ] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK ) != 0 ) || ( current_mode_page [ 1 ] != ( SCSI_MODE_PAGE_1A_LENGTH - 2 ) ) || ( ( current_mode_page [ 3 ] & SCSI_MODE_PAGE_POWER_CONDITION_IDLE ) != 0 ) ) { return SATI_FAILURE_CHECK_RESPONSE_DATA ; } if ( current_mode_page [ 3 ] & SCSI_MODE_PAGE_POWER_CONDITION_STANDBY ) { timer = ( current_mode_page [ 8 ] << 24 ) + ( current_mode_page [ 9 ] << 16 ) + ( current_mode_page [ 10 ] << 8 ) + current_mode_page [ 11 ] ; if ( sequence -> device -> capabilities & SATI_DEVICE_CAP_STANDBY_ENABLE ) { if ( timer == 0 ) { sati_ata_standby_immediate_construct ( ata_io , sequence ) ; sequence -> command_specific_data . translated_command = ATA_STANDBY_IMMED ; } else if ( ( timer > 0 ) && ( timer <= 12000 ) ) { count = ( U16 ) ( ( timer - 1 ) / 50 ) + 1 ; sati_ata_standby_construct ( ata_io , sequence , count ) ; } else if ( ( timer > 12000 ) && ( timer <= 12600 ) ) { sati_ata_standby_construct ( ata_io , sequence , 0xFC ) ; } else if ( ( timer > 12600 ) && ( timer <= 12750 ) ) { sati_ata_standby_construct ( ata_io , sequence , 0xFF ) ; } else if ( ( timer > 12750 ) && ( timer < 18000 ) ) { sati_ata_standby_construct ( ata_io , sequence , 0xF1 ) ; } else if ( ( timer >= 18000 ) && ( timer <= 198000 ) ) { count = ( U16 ) ( timer / 18000 ) + 240 ; sati_ata_standby_construct ( ata_io , sequence , count ) ; } else { sati_ata_standby_construct ( ata_io , sequence , 0xFD ) ; } status = SATI_SUCCESS ; } else { status = SATI_FAILURE_CHECK_RESPONSE_DATA ; } } else { status = SATI_COMPLETE ; } sequence -> command_specific_data . process_state . size_of_data_processed += page_size ; sequence -> command_specific_data . process_state . mode_page_offset += page_size ; sequence -> command_specific_data . process_state . current_mode_page_processed = TRUE ; return status ; }
@brief This method will check the validity of parameter data of Power Condition mode
            page and issue multiple ATA set feature commands to complete the translation.
@brief This method will check the validity of parameter data of Power Condition mode page and issue multiple ATA set feature commands to complete the translation .
//SCSI_MODE_PAGE_1A_LENGTH 10 //Check for data validity //SPF(0b); Page length 0x0A; //parameter data passed in containing data that doesn't meet the SAT-2 requirement // STANDBY bit is set to 0, do nothing since the standby timer can't be set; // STANDBY bit is set to 1, translate the standby timer // SCSI_MODE_PAGE_POWER_CONDITION_STANDBY== 0x01 //If the ATA IDENTIFY DEVICE data word 49, bit 13 is set to one, //TPV=0 send ATA STANDBY_IMMEDIATE //1 to 12 000 INT((z - 1) / 50) + 1 //12 001 to 12 600 FCh //12 601 to 12 750 FFh //12 751 to 17 999 F1h //18 000 to 198 000 INT(z / 18 000) + 240 //All other values FDh //If the ATA IDENTIFY DEVICE data word 49, bit 13 is set to 0