summaryrefslogtreecommitdiffstats
path: root/sys/dev/isci/scil/sati.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isci/scil/sati.c')
-rw-r--r--sys/dev/isci/scil/sati.c1250
1 files changed, 1250 insertions, 0 deletions
diff --git a/sys/dev/isci/scil/sati.c b/sys/dev/isci/scil/sati.c
new file mode 100644
index 0000000..17df017
--- /dev/null
+++ b/sys/dev/isci/scil/sati.c
@@ -0,0 +1,1250 @@
+/*-
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/**
+ * @file
+ * @brief This file contains all of the method implementations that
+ * can be utilized by a user to perform SCSI-to-ATA Translation.
+ * SATI adheres to the www.t10.org SAT specification.
+ *
+ * For situations where compliance is not observed, the SATI will
+ * return an error indication (most likely INVALID FIELD IN CDB sense data).
+ */
+
+#include <dev/isci/scil/sati.h>
+#include <dev/isci/scil/sati_callbacks.h>
+#include <dev/isci/scil/sati_util.h>
+#include <dev/isci/scil/sati_report_luns.h>
+#include <dev/isci/scil/sati_inquiry.h>
+#include <dev/isci/scil/sati_mode_sense_6.h>
+#include <dev/isci/scil/sati_mode_sense_10.h>
+#include <dev/isci/scil/sati_mode_select.h>
+#include <dev/isci/scil/sati_test_unit_ready.h>
+#include <dev/isci/scil/sati_read_capacity.h>
+#include <dev/isci/scil/sati_read.h>
+#include <dev/isci/scil/sati_write.h>
+#include <dev/isci/scil/sati_verify.h>
+#include <dev/isci/scil/sati_synchronize_cache.h>
+#include <dev/isci/scil/sati_lun_reset.h>
+#include <dev/isci/scil/sati_start_stop_unit.h>
+#include <dev/isci/scil/sati_request_sense.h>
+#include <dev/isci/scil/sati_write_long.h>
+#include <dev/isci/scil/sati_reassign_blocks.h>
+#include <dev/isci/scil/sati_log_sense.h>
+#include <dev/isci/scil/sati_abort_task_set.h>
+#include <dev/isci/scil/sati_unmap.h>
+#include <dev/isci/scil/sati_passthrough.h>
+#include <dev/isci/scil/sati_write_and_verify.h>
+#include <dev/isci/scil/sati_read_buffer.h>
+#include <dev/isci/scil/sati_write_buffer.h>
+#include <dev/isci/scil/intel_ata.h>
+#include <dev/isci/scil/intel_scsi.h>
+#include <dev/isci/scil/intel_sat.h>
+
+//******************************************************************************
+//* P R I V A T E M E T H O D S
+//******************************************************************************
+
+/**
+ * @brief This method performs the translation of ATA error register values
+ * into SCSI sense data.
+ * For more information on the parameter passed to this method please
+ * reference the sati_translate_response() method.
+ *
+ * @param[in] error This parameter specifies the contents of the ATA error
+ * register to be translated.
+ *
+ * @return none
+ */
+void sati_translate_error(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ void * scsi_io,
+ U8 error
+)
+{
+ if (error & ATA_ERROR_REG_NO_MEDIA_BIT)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_NOT_READY,
+ SCSI_ASC_MEDIUM_NOT_PRESENT,
+ SCSI_ASCQ_MEDIUM_NOT_PRESENT
+ );
+ }
+ else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_UNIT_ATTENTION,
+ SCSI_ASC_NOT_READY_TO_READY_CHANGE,
+ SCSI_ASCQ_NOT_READY_TO_READY_CHANGE
+ );
+ }
+ else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_UNIT_ATTENTION,
+ SCSI_ASC_MEDIUM_REMOVAL_REQUEST,
+ SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST
+ );
+ }
+ else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_LBA_OUT_OF_RANGE,
+ SCSI_ASCQ_LBA_OUT_OF_RANGE
+ );
+ }
+ else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT)
+ {
+ //Mark the Sequence state as a read error so more sense data
+ //can be returned later
+ sequence->state = SATI_SEQUENCE_STATE_READ_ERROR;
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_MEDIUM_ERROR,
+ SCSI_ASC_UNRECOVERED_READ_ERROR,
+ SCSI_ASCQ_UNRECOVERED_READ_ERROR
+ );
+ }
+ else if ( (sequence->data_direction == SATI_DATA_DIRECTION_OUT)
+ && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) )
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_DATA_PROTECT,
+ SCSI_ASC_WRITE_PROTECTED,
+ SCSI_ASCQ_WRITE_PROTECTED
+ );
+ }
+ else if (error & ATA_ERROR_REG_ICRC_BIT)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_ABORTED_COMMAND,
+ SCSI_ASC_IU_CRC_ERROR_DETECTED,
+ SCSI_ASCQ_IU_CRC_ERROR_DETECTED
+ );
+ }
+ else // (error & ATA_ERROR_REG_ABORT_BIT)
+ {
+ // The ABORT bit has the lowest precedence of all errors.
+ // As a result, it is at the bottom of the conditional
+ // statement.
+ 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
+ );
+ }
+}
+
+/**
+ * @brief This method translates the supplied ATA payload data into the
+ * corresponding SCSI data. This is necessary for SCSI commands
+ * that have well-defined payload data associated with them (e.g.
+ * READ CAPACITY).
+ *
+ * @param[in] sequence This parameter specifies the sequence
+ * data associated with the translation.
+ * @param[in] ata_io This parameter specifies the ATA payload
+ * buffer location and size to be translated.
+ * @param[out] scsi_output_data This parameter specifies the SCSI payload
+ * memory area into which the translator is to write.
+ *
+ * @return none
+ */
+static
+void sati_translate_data(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ void * ata_input_data,
+ void * scsi_io
+)
+{
+ // Update the device capabilities in the odd/crazy event something changed.
+ sati_device_update_capabilities(
+ sequence->device, (ATA_IDENTIFY_DEVICE_DATA_T*) ata_input_data
+ );
+
+ // Look at the first byte to determine the SCSI command to translate.
+ switch (sequence->type)
+ {
+#if !defined(DISABLE_SATI_INQUIRY)
+ case SATI_SEQUENCE_INQUIRY_STANDARD:
+ sati_inquiry_standard_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
+ sati_inquiry_serial_number_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
+ sati_inquiry_device_id_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
+ sati_inquiry_block_device_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
+ sati_inquiry_ata_information_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+#endif // !defined(DISABLE_SATI_INQUIRY)
+
+#if !defined(DISABLE_SATI_READ_CAPACITY)
+ case SATI_SEQUENCE_READ_CAPACITY_10:
+ sati_read_capacity_10_translate_data(sequence, ata_input_data, scsi_io);
+ break;
+
+ case SATI_SEQUENCE_READ_CAPACITY_16:
+ sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io);
+ break;
+#endif // !defined(DISABLE_SATI_READ_CAPACITY)
+
+#if !defined(DISABLE_SATI_MODE_SENSE)
+ case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
+ sati_mode_sense_6_caching_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
+ sati_mode_sense_6_informational_excp_control_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
+ sati_mode_sense_6_read_write_error_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
+ sati_mode_sense_6_disconnect_reconnect_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
+ sati_mode_sense_6_control_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
+ sati_mode_sense_6_all_pages_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
+ sati_mode_sense_6_power_condition_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
+ sati_mode_sense_10_power_condition_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
+ sati_mode_sense_10_caching_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
+ sati_mode_sense_10_informational_excp_control_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
+ sati_mode_sense_10_read_write_error_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT:
+ sati_mode_sense_10_disconnect_reconnect_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
+ sati_mode_sense_10_control_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+
+ case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES:
+ sati_mode_sense_10_all_pages_translate_data(
+ sequence, ata_input_data, scsi_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_MODE_SENSE)
+
+ default:
+ break;
+ }
+}
+
+//******************************************************************************
+//* P U B L I C M E T H O D S
+//******************************************************************************
+
+SATI_STATUS sati_translate_command(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ SATI_DEVICE_T * sati_device,
+ void * scsi_io,
+ void * ata_io
+)
+{
+ SATI_STATUS status = SATI_FAILURE;
+ U8 * cdb = sati_cb_get_cdb_address(scsi_io);
+
+ //No sense response has been set for the translation sequence yet
+ sequence->is_sense_response_set = FALSE;
+ // Default to no translation response required
+ sequence->is_translate_response_required = FALSE;
+ // Assign sati_device to sequence
+ sequence->device = sati_device;
+
+ /**
+ * Fail any I/O request with LUN != 0
+ */
+ 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
+ );
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ }
+
+ /**
+ * SAT dictates:
+ * - the NACA bit in the control byte (last byte) must be 0
+ */
+ if ( (sati_get_cdb_byte(cdb, sati_cb_get_cdb_length(scsi_io) - 1)
+ & SCSI_CONTROL_BYTE_NACA_BIT_ENABLE))
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_INVALID_FIELD_IN_CDB,
+ SCSI_ASCQ_INVALID_FIELD_IN_CDB
+ );
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ }
+
+ /**
+ * Per SAT "Error and sense reporting" section. All subsequent IOs after
+ * a device fault should receive INTERNAL TARGET FAILURE sense data.
+ */
+ if (sati_device->state == SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_HARDWARE_ERROR,
+ SCSI_ASC_INTERNAL_TARGET_FAILURE,
+ SCSI_ASCQ_INTERNAL_TARGET_FAILURE
+ );
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ }
+
+ if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
+ {
+ sequence->command_specific_data.scratch = 0;
+ sequence->number_data_bytes_set = 0;
+ }
+
+
+#ifdef SATI_TRANSPORT_SUPPORTS_SATA
+ {
+ U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
+ sati_set_sata_command_flag(register_fis);
+ sati_set_sata_fis_type(register_fis, SATA_FIS_TYPE_REGH2D);
+ }
+#endif // SATI_TRANSPORT_SUPPORTS_SATA
+
+ // Look at the first byte to determine the SCSI command to translate.
+ switch (sati_get_cdb_byte(cdb, 0))
+ {
+#if !defined(DISABLE_SATI_REPORT_LUNS)
+ case SCSI_REPORT_LUNS:
+ status = sati_report_luns_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_REPORT_LUNS)
+
+#if !defined(DISABLE_SATI_INQUIRY)
+ case SCSI_INQUIRY:
+ status = sati_inquiry_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_INQUIRY)
+
+#if !defined(DISABLE_SATI_MODE_SENSE)
+ case SCSI_MODE_SENSE_6:
+ status = sati_mode_sense_6_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+
+ case SCSI_MODE_SENSE_10:
+ status = sati_mode_sense_10_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_MODE_SENSE)
+
+#if !defined(DISABLE_SATI_MODE_SELECT)
+ case SCSI_MODE_SELECT_6:
+ status = sati_mode_select_6_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+
+ case SCSI_MODE_SELECT_10:
+ status = sati_mode_select_10_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_MODE_SELECT)
+
+#if !defined(DISABLE_SATI_TEST_UNIT_READY)
+ case SCSI_TEST_UNIT_READY:
+ status = sati_test_unit_ready_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
+
+#if !defined(DISABLE_SATI_READ_CAPACITY)
+ case SCSI_READ_CAPACITY_10:
+ status = sati_read_capacity_10_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+
+ case SCSI_SERVICE_ACTION_IN_16:
+ if ( (sati_get_cdb_byte(cdb, 1) & SCSI_SERVICE_ACTION_MASK)
+ == SCSI_SERVICE_ACTION_IN_CODES_READ_CAPACITY_16)
+ status = sati_read_capacity_16_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ else
+ status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ break;
+#endif // !defined(DISABLE_SATI_READ_CAPACITY)
+
+#if !defined(DISABLE_SATI_REQUEST_SENSE)
+ case SCSI_REQUEST_SENSE:
+ status = sati_request_sense_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_REQUEST_SENSE)
+
+ case SCSI_READ_6:
+ status = sati_read_6_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_READ_10:
+ status = sati_read_10_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_READ_12:
+ status = sati_read_12_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_READ_16:
+ status = sati_read_16_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_WRITE_6:
+ status = sati_write_6_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_WRITE_10:
+ status = sati_write_10_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_WRITE_12:
+ status = sati_write_12_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_WRITE_16:
+ status = sati_write_16_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+#if !defined(DISABLE_SATI_VERIFY)
+ case SCSI_VERIFY_10:
+ status = sati_verify_10_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_VERIFY_12:
+ status = sati_verify_12_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_VERIFY_16:
+ status = sati_verify_16_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_VERIFY)
+
+#if !defined(DISABLE_SATI_WRITE_AND_VERIFY) \
+ && !defined(DISABLE_SATI_VERIFY) \
+ && !defined(DISABLE_SATI_WRITE)
+
+ case SCSI_WRITE_AND_VERIFY_10:
+ status = sati_write_and_verify_10_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_WRITE_AND_VERIFY_12:
+ status = sati_write_and_verify_12_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_WRITE_AND_VERIFY_16:
+ status = sati_write_and_verify_16_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
+ // && !defined(DISABLE_SATI_VERIFY)
+ // && !defined(DISABLE_SATI_WRITE)
+
+#if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
+ case SCSI_REASSIGN_BLOCKS:
+ status = sati_reassign_blocks_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
+
+#if !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
+ case SCSI_SYNCHRONIZE_CACHE_10:
+ case SCSI_SYNCHRONIZE_CACHE_16:
+ status = sati_synchronize_cache_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_SYNCHRONIZE_CACHE)
+
+#if !defined(DISABLE_SATI_START_STOP_UNIT)
+ case SCSI_START_STOP_UNIT:
+ status = sati_start_stop_unit_translate_command(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_START_STOP_UNIT)
+
+#if !defined(DISABLE_SATI_WRITE_LONG)
+ case SCSI_WRITE_LONG_10:
+ case SCSI_WRITE_LONG_16:
+ status = sati_write_long_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_WRITE_LONG)
+
+#if !defined(DISABLE_SATI_LOG_SENSE)
+ case SCSI_LOG_SENSE:
+ status = sati_log_sense_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_LOG_SENSE)
+
+ case SCSI_PERSISTENT_RESERVE_IN:
+ case SCSI_PERSISTENT_RESERVE_OUT:
+ //These commands are not supported by SATI
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
+ SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE
+ );
+ //returning status now to keep sense data set above
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ break;
+
+#if !defined(DISABLE_SATI_UNMAP)
+ case SCSI_UNMAP:
+ status = sati_unmap_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif // !defined(DISABLE_SATI_UNMAP)
+
+#if !defined(DISABLE_SATI_ATA_PASSTHROUGH)
+ case SCSI_ATA_PASSTHRU_12:
+ status = sati_passthrough_12_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+ case SCSI_ATA_PASSTHRU_16:
+ status = sati_passthrough_16_translate_command(sequence, scsi_io, ata_io);
+ break;
+
+#endif // !define(DISABLE_SATI_ATA_PASSTHRU)
+
+#if !defined(DISABLE_SATI_READ_BUFFER)
+ case SCSI_READ_BUFFER:
+ status = sati_read_buffer_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif //!defined(DISABLE_SATI_READ_BUFFER)
+
+#if !defined(DISABLE_SATI_WRITE_BUFFER)
+ case SCSI_WRITE_BUFFER:
+ status = sati_write_buffer_translate_command(sequence, scsi_io, ata_io);
+ break;
+#endif //!defined(DISABLE_SATI_WRITE_BUFFER)
+ default:
+ status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ break;
+ }
+
+ if( (status == SATI_FAILURE_CHECK_RESPONSE_DATA) &&
+ !(sequence->is_sense_response_set) )
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_INVALID_FIELD_IN_CDB,
+ SCSI_ASCQ_INVALID_FIELD_IN_CDB
+ );
+ }
+ return status;
+}
+
+// -----------------------------------------------------------------------------
+
+#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
+SATI_STATUS sati_translate_task_management(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ SATI_DEVICE_T * sati_device,
+ void * scsi_task,
+ void * ata_io
+)
+{
+ SATI_STATUS status=SATI_FAILURE;
+ U8 task_function = sati_cb_get_task_function(scsi_task);
+
+ sequence->device = sati_device;
+
+ switch (task_function)
+ {
+ /**
+ * @todo We need to update the ABORT_TASK and ABORT_TASK_SET to be
+ * SAT compliant.
+ */
+ case SCSI_TASK_REQUEST_ABORT_TASK:
+ case SCSI_TASK_REQUEST_LOGICAL_UNIT_RESET:
+ status = sati_lun_reset_translate_command(sequence, scsi_task, ata_io);
+ break;
+
+ case SCSI_TASK_REQUEST_ABORT_TASK_SET:
+#if !defined(DISABLE_SATI_ABORT_TASK_SET)
+ status = sati_abort_task_set_translate_command(sequence, scsi_task, ata_io);
+#else
+ status = SATI_FAILURE;
+#endif
+ break;
+ default:
+ status = SATI_FAILURE;
+ break;
+ }
+
+ return status;
+}
+#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
+
+// -----------------------------------------------------------------------------
+#if !defined(DISABLE_SATI_INQUIRY) \
+ || !defined(DISABLE_SATI_READY_CAPACITY) \
+ || !defined(DISABLE_SATI_MODE_SENSE) \
+ || !defined(DISABLE_SATI_MODE_SELECT) \
+ || !defined(DISABLE_SATI_REASSIGN_BLOCKS) \
+ || !defined(DISABLE_SATI_START_STOP_UNIT) \
+ || !defined(DISABLE_SATI_REQUEST_SENSE) \
+ || !defined(DISABLE_SATI_WRITE_LONG) \
+ || !defined(DISABLE_SATI_LOG_SENSE) \
+ || !defined(DISABLE_SATI_UNMAP)
+
+static
+SATI_STATUS sati_check_data_io(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence
+)
+{
+ if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
+ {
+ return SATI_SEQUENCE_INCOMPLETE;
+ }
+ else if(sequence->number_data_bytes_set < sequence->allocation_length)
+ {
+ return SATI_COMPLETE_IO_DONE_EARLY;
+ }
+ else
+ {
+ return SATI_COMPLETE;
+ }
+}
+#endif // !defined(DISABLE_SATI_INQUIRY)
+ // || !defined(DISABLE_SATI_READY_CAPACITY)
+ // || !defined(DISABLE_SATI_MODE_SENSE)
+ // || !defined(DISABLE_SATI_MODE_SELECT)
+ // || !defined(DISABLE_SATI_REASSIGN_BLOCKS)
+ // || !defined(DISABLE_SATI_START_STOP_UNIT)
+ // || !defined(DISABLE_SATI_REQUEST_SENSE)
+ // || !defined(DISABLE_SATI_WRITE_LONG)
+ // || !defined(DISABLE_SATI_LOG_SENSE)
+ // || !defined(DISABLE_SATI_UNMAP)
+// -----------------------------------------------------------------------------
+SATI_STATUS sati_translate_command_response(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ void * scsi_io,
+ void * ata_io
+)
+{
+ SATI_STATUS status = SATI_COMPLETE;
+ U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
+ U8 ata_status;
+
+ /**
+ * If the device fault bit is set in the status register, then
+ * set the sense data and return.
+ */
+ ata_status = (U8) sati_get_ata_status(register_fis);
+ if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
+ {
+ sati_scsi_sense_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_HARDWARE_ERROR,
+ SCSI_ASC_INTERNAL_TARGET_FAILURE,
+ SCSI_ASCQ_INTERNAL_TARGET_FAILURE
+ );
+
+ sequence->device->state = SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED;
+
+ // Make sure that the terminate sequence is called to allow
+ // translation logic to perform any cleanup before the IO is completed.
+ sati_sequence_terminate(sequence,
+ scsi_io,
+ ata_io);
+
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ }
+
+ // Look at the sequence type to determine the response translation method
+ // to invoke.
+ switch (sequence->type)
+ {
+#if !defined(DISABLE_SATI_TEST_UNIT_READY)
+ case SATI_SEQUENCE_TEST_UNIT_READY:
+ status = sati_test_unit_ready_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_TEST_UNIT_READY)
+
+#if !defined(DISABLE_SATI_INQUIRY) \
+ || !defined(DISABLE_SATI_READY_CAPACITY) \
+ || !defined(DISABLE_SATI_MODE_SENSE)
+
+ case SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG:
+
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ U8 error = (U8) sati_get_ata_error(register_fis);
+ status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ sati_translate_error(sequence, scsi_io, error);
+ }
+ else
+ {
+ sati_inquiry_ata_information_finish_translation(
+ sequence,
+ scsi_io,
+ ata_io
+ );
+ status = sati_check_data_io(sequence);
+ }
+ break;
+
+ case SATI_SEQUENCE_INQUIRY_STANDARD:
+ case SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES:
+ case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER:
+ case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE:
+ case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION:
+ case SATI_SEQUENCE_INQUIRY_DEVICE_ID:
+ case SATI_SEQUENCE_READ_CAPACITY_10:
+ case SATI_SEQUENCE_READ_CAPACITY_16:
+ case SATI_SEQUENCE_MODE_SENSE_6_CACHING:
+ case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL:
+ case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR:
+ case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT:
+ case SATI_SEQUENCE_MODE_SENSE_6_CONTROL:
+ case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION:
+ case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES:
+ case SATI_SEQUENCE_MODE_SENSE_10_CACHING:
+ case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL:
+ case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR:
+ case SATI_SEQUENCE_MODE_SENSE_10_CONTROL:
+ case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION:
+ case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT:
+ case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES:
+ // Did an error occur during the IO request?
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ U8 error = (U8) sati_get_ata_error(register_fis);
+ status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ sati_translate_error(sequence, scsi_io, error);
+ }
+ else
+ {
+ void * ata_data = sati_cb_get_ata_data_address(ata_io);
+
+ if(ata_data == NULL)
+ {
+ status = SATI_FAILURE;
+ }
+ else
+ {
+ sati_translate_data(sequence, ata_data, scsi_io);
+ status = sati_check_data_io(sequence);
+ }
+ }
+ break;
+#endif // !defined(DISABLE_SATI_INQUIRY)
+ // && !defined(DISABLE_SATI_READY_CAPACITY)
+ // && !defined(DISABLE_SATI_MODE_SENSE)
+
+#if !defined(DISABLE_SATI_MODE_SELECT)
+ case SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING:
+
+ status = sati_mode_select_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+
+ case SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION:
+ case SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL:
+ // Did an error occur during the IO request?
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ U8 error = (U8) sati_get_ata_error(register_fis);
+ status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ sati_translate_error(sequence, scsi_io, error);
+ }
+ else
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_MODE_SELECT)
+
+#if !defined(DISABLE_SATI_WRITE_AND_VERIFY)
+ case SATI_SEQUENCE_WRITE_AND_VERIFY:
+
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ U8 error = (U8) sati_get_ata_error(register_fis);
+ sati_translate_error(sequence, scsi_io, error);
+
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ }
+ else
+ {
+ status = sati_write_and_verify_translate_response(
+ sequence,
+ scsi_io,
+ ata_io
+ );
+ }
+ break;
+#endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY)
+
+ case SATI_SEQUENCE_READ_6:
+ case SATI_SEQUENCE_READ_10:
+ case SATI_SEQUENCE_READ_12:
+ case SATI_SEQUENCE_READ_16:
+ case SATI_SEQUENCE_WRITE_6:
+ case SATI_SEQUENCE_WRITE_10:
+ case SATI_SEQUENCE_WRITE_12:
+ case SATI_SEQUENCE_WRITE_16:
+ case SATI_SEQUENCE_VERIFY_10:
+ case SATI_SEQUENCE_VERIFY_12:
+ case SATI_SEQUENCE_VERIFY_16:
+ case SATI_SEQUENCE_SYNCHRONIZE_CACHE:
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ U8 error = (U8) sati_get_ata_error(register_fis);
+ status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ sati_translate_error(sequence, scsi_io, error);
+
+ if(sequence->state == SATI_SEQUENCE_STATE_READ_ERROR )
+ {
+ sati_scsi_read_error_sense_construct(
+ sequence,
+ scsi_io,
+ ata_io,
+ SCSI_STATUS_CHECK_CONDITION,
+ SCSI_SENSE_MEDIUM_ERROR,
+ SCSI_ASC_UNRECOVERED_READ_ERROR,
+ SCSI_ASCQ_UNRECOVERED_READ_ERROR
+ );
+ sequence->state = SATI_SEQUENCE_STATE_FINAL;
+ }
+ }
+ else
+ {
+ // We haven't satisified the transfer count from the original
+ // SCSI CDB. As a result, we need to re-issue the command
+ // with updated logical block address and transfer count.
+ if (sequence->command_specific_data.scratch)
+ {
+ /** @todo update the contents of the CDB directly? Should be
+ * done during previous command translation?
+ */
+ status = SATI_SEQUENCE_INCOMPLETE;
+ }
+ }
+ break;
+
+#if !defined(DISABLE_SATI_READ_BUFFER)
+ case SATI_SEQUENCE_READ_BUFFER:
+ status = sati_read_buffer_translate_response(
+ sequence, scsi_io, ata_io
+ );
+
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif //!defined(DISABLE_SATI_READ_BUFFER)
+
+#if !defined(DISABLE_SATI_WRITE_BUFFER)
+ case SATI_SEQUENCE_WRITE_BUFFER:
+ case SATI_SEQUENCE_WRITE_BUFFER_MICROCODE:
+ status = sati_write_buffer_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif //!defined(DISABLE_SATI_WRITE_BUFFER)
+
+#if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
+ case SATI_SEQUENCE_REASSIGN_BLOCKS:
+ status = sati_reassign_blocks_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
+
+#if !defined(DISABLE_SATI_START_STOP_UNIT)
+ case SATI_SEQUENCE_START_STOP_UNIT:
+ status = sati_start_stop_unit_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_START_STOP_UNIT)
+
+#if !defined(DISABLE_SATI_REQUEST_SENSE)
+ case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS:
+ case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE:
+ status = sati_request_sense_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_REQUEST_SENSE)
+
+#if !defined(DISABLE_SATI_WRITE_LONG)
+ case SATI_SEQUENCE_WRITE_LONG:
+ status = sati_write_long_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_WRITE_LONG)
+
+#if !defined(DISABLE_SATI_LOG_SENSE)
+ case SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE:
+ case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE:
+ case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE:
+ case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE:
+ status = sati_log_sense_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_LOG_SENSE)
+
+#if !defined(DISABLE_SATI_UNMAP)
+ case SATI_SEQUENCE_UNMAP:
+ status = sati_unmap_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ if(status == SATI_COMPLETE)
+ {
+ status = sati_check_data_io(sequence);
+ }
+ break;
+#endif // !defined(DISABLE_SATI_UNMAP)
+
+#if !defined(DISABLE_SATI_ATA_PASSTHROUGH)
+ case SATI_SEQUENCE_ATA_PASSTHROUGH_12:
+ case SATI_SEQUENCE_ATA_PASSTHROUGH_16:
+ status = sati_passthrough_translate_response(
+ sequence, scsi_io, ata_io
+ );
+ break;
+#endif // !defined(DISABLE_SATI_ATA_PASSTHROUGH)
+
+ default:
+ status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
+ break;
+ }
+
+ return status;
+}
+
+// -----------------------------------------------------------------------------
+
+#if !defined(DISABLE_SATI_TASK_MANAGEMENT)
+SATI_STATUS sati_translate_task_response(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ void * scsi_io,
+ void * ata_io
+)
+{
+ SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
+ U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
+ U8 ata_status;
+
+ /**
+ * If the device fault bit is set in the status register, then
+ * set the sense data and return.
+ */
+ ata_status = (U8) sati_get_ata_status(register_fis);
+ if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
+ {
+ sati_scsi_response_data_construct(
+ sequence,
+ scsi_io,
+ SCSI_TASK_MGMT_FUNC_FAILED
+ );
+ return SATI_FAILURE_CHECK_RESPONSE_DATA;
+ }
+
+ // Look at the sequence type to determine the response translation method
+ // to invoke.
+ switch (sequence->type)
+ {
+ case SATI_SEQUENCE_LUN_RESET:
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ sati_scsi_response_data_construct(
+ sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
+ }
+ else
+ {
+ sati_scsi_response_data_construct(
+ sequence, scsi_io, SCSI_TASK_MGMT_FUNC_COMPLETE);
+ }
+
+ status = SATI_COMPLETE;
+ break;
+
+#if !defined(DISABLE_SATI_ABORT_TASK_SET)
+ case SATI_SEQUENCE_ABORT_TASK_SET:
+ if (ata_status & ATA_STATUS_REG_ERROR_BIT)
+ {
+ sati_scsi_response_data_construct(
+ sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED);
+ }
+ else
+ {
+ void * ata_data = sati_cb_get_ata_data_address(ata_io);
+
+ if(ata_data == NULL)
+ {
+ status = SATI_FAILURE;
+ }
+ else
+ {
+ status = sati_abort_task_set_translate_data(
+ sequence,
+ ata_data,
+ scsi_io
+ );
+ }
+ }
+ break;
+#endif // !defined(DISABLE_SATI_ABORT_TASK_SET)
+
+ default:
+ status = SATI_FAILURE_INVALID_SEQUENCE_TYPE;
+ break;
+ }
+
+ return status;
+}
+#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT)
+
+#if !defined(ENABLE_MINIMUM_MEMORY_MODE)
+U32 sati_get_sat_compliance_version(
+ void
+)
+{
+ return 2; // Compliant with SAT-2.
+}
+
+U32 sati_get_sat_compliance_version_revision(
+ void
+)
+{
+ return 7; // Compliant with SAT-2 revision 7.
+}
+
+#endif // !defined(ENABLE_MINIMUM_MEMORY_MODE)
+
+U16 sati_get_number_data_bytes_set(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence
+)
+{
+ return sequence->number_data_bytes_set;
+}
+
+void sati_sequence_construct(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence
+)
+{
+ sequence->state = SATI_SEQUENCE_STATE_INITIAL;
+}
+
+void sati_sequence_terminate(
+ SATI_TRANSLATOR_SEQUENCE_T * sequence,
+ void * scsi_io,
+ void * ata_io
+)
+{
+ // Decode the sequence type to determine how to handle the termination
+ // of the the translation method.
+ switch (sequence->type)
+ {
+ case SATI_SEQUENCE_UNMAP:
+ sati_unmap_terminate(sequence,scsi_io,ata_io);
+ break;
+ }
+}
OpenPOWER on IntegriCloud