FreeBSD/sys/dev/isci/scil/sati_atapi.c
//******************************************************************************
//* P U B L I C   M E T H O D S
//******************************************************************************
P U B L I C   M E T H O D S
P U B L I C M E T H O D S
SATI_STATUS sati_atapi_translate_command(
   SATI_TRANSLATOR_SEQUENCE_T * sequence,
   SATI_DEVICE_T              * sati_device,
   void                       * scsi_io,
   void                       * atapi_io
)
{
   SATI_STATUS   status;
   U8          * cdb = sati_cb_get_cdb_address(scsi_io);
   SATA_FIS_REG_H2D_T * register_fis =
      (SATA_FIS_REG_H2D_T *)sati_cb_get_h2d_register_fis_address(atapi_io);
   U8 io_direction = SATI_DATA_DIRECTION_IN;
   sequence->is_sense_response_set = FALSE;
   sequence->is_translate_response_required = FALSE;
   sequence->number_data_bytes_set = 0;
   sequence->device  = sati_device;
   sequence->command_specific_data.scratch = 0;
   sati_cb_get_data_direction(scsi_io, &io_direction);
   if (io_direction == SATI_DATA_DIRECTION_NONE)
      sequence->protocol = SAT_PROTOCOL_PACKET_NON_DATA;
   else if (io_direction == SATI_DATA_DIRECTION_IN)
      sequence->protocol = SAT_PROTOCOL_PACKET_DMA_DATA_IN;
   else if (io_direction == SATI_DATA_DIRECTION_OUT)
      sequence->protocol = SAT_PROTOCOL_PACKET_DMA_DATA_OUT;
   if  (sati_get_cdb_byte(cdb, 0) == SCSI_REPORT_LUNS)
   {
      status = sati_report_luns_translate_command(
                  sequence, scsi_io, atapi_io
               );
   }
   else if (sati_cb_get_lun(scsi_io) != 0)
   {
      sati_scsi_sense_data_construct(
         sequence,
         scsi_io,
         SCSI_STATUS_CHECK_CONDITION,
         SCSI_SENSE_ILLEGAL_REQUEST,
         SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED,
         0
      );
      status = SATI_FAILURE_CHECK_RESPONSE_DATA;
   }
   else
   {
      if (sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
      {  
         U8 request_sense_cdb[SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH] =
            {0x3, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
         sequence->protocol = SAT_PROTOCOL_PACKET_DMA_DATA_IN;
         memcpy(sequence->command_specific_data.sati_atapi_data.request_sense_cdb,
                request_sense_cdb,
                SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH
               );
      }
      register_fis->command = ATA_PACKET;
      register_fis->features |= ATA_PACKET_FEATURE_DMA;
      register_fis->fis_type = SATA_FIS_TYPE_REGH2D;
      register_fis->command_flag = 1;
      status = SATI_SUCCESS;
   }
   return status;
}
SATI_STATUS sati_atapi_translate_command ( SATI_TRANSLATOR_SEQUENCE_T * sequence , SATI_DEVICE_T * sati_device , void * scsi_io , void * atapi_io ) { SATI_STATUS status ; U8 * cdb = sati_cb_get_cdb_address ( scsi_io ) ; SATA_FIS_REG_H2D_T * register_fis = ( SATA_FIS_REG_H2D_T * ) sati_cb_get_h2d_register_fis_address ( atapi_io ) ; U8 io_direction = SATI_DATA_DIRECTION_IN ; sequence -> is_sense_response_set = FALSE ; sequence -> is_translate_response_required = FALSE ; sequence -> number_data_bytes_set = 0 ; sequence -> device = sati_device ; sequence -> command_specific_data . scratch = 0 ; sati_cb_get_data_direction ( scsi_io , & io_direction ) ; if ( io_direction == SATI_DATA_DIRECTION_NONE ) sequence -> protocol = SAT_PROTOCOL_PACKET_NON_DATA ; else if ( io_direction == SATI_DATA_DIRECTION_IN ) sequence -> protocol = SAT_PROTOCOL_PACKET_DMA_DATA_IN ; else if ( io_direction == SATI_DATA_DIRECTION_OUT ) sequence -> protocol = SAT_PROTOCOL_PACKET_DMA_DATA_OUT ; if ( sati_get_cdb_byte ( cdb , 0 ) == SCSI_REPORT_LUNS ) { status = sati_report_luns_translate_command ( sequence , scsi_io , atapi_io ) ; } else if ( sati_cb_get_lun ( scsi_io ) != 0 ) { sati_scsi_sense_data_construct ( sequence , scsi_io , SCSI_STATUS_CHECK_CONDITION , SCSI_SENSE_ILLEGAL_REQUEST , SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED , 0 ) ; status = SATI_FAILURE_CHECK_RESPONSE_DATA ; } else { if ( sequence -> state == SATI_SEQUENCE_STATE_INCOMPLETE ) { U8 request_sense_cdb [ SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH ] = { 0x3 , 0x0 , 0x0 , 0x0 , 0x12 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 } ; sequence -> protocol = SAT_PROTOCOL_PACKET_DMA_DATA_IN ; memcpy ( sequence -> command_specific_data . sati_atapi_data . request_sense_cdb , request_sense_cdb , SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH ) ; } register_fis -> command = ATA_PACKET ; register_fis -> features |= ATA_PACKET_FEATURE_DMA ; register_fis -> fis_type = SATA_FIS_TYPE_REGH2D ; register_fis -> command_flag = 1 ; status = SATI_SUCCESS ; } return status ; }
P U B L I C   M E T H O D S
P U B L I C M E T H O D S
//No sense response has been set for the translation sequence yet // Default to no translation response required //set sat protocol. // We don't send Report Luns command out. //Request Sense command is required. //set the sequence->protocol to DATA_IN anyway; //set the cdb for Request Sense using command_specific_data field. //build Packet Fis for any other command translation.