1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * @brief This file contains all of the method implementations that 59230557Sjimharris * can be utilized by a user to perform SCSI-to-ATA Translation. 60230557Sjimharris * SATI adheres to the www.t10.org SAT specification. 61230557Sjimharris * 62230557Sjimharris * For situations where compliance is not observed, the SATI will 63230557Sjimharris * return an error indication (most likely INVALID FIELD IN CDB sense data). 64230557Sjimharris */ 65230557Sjimharris 66230557Sjimharris#include <dev/isci/scil/sati.h> 67230557Sjimharris#include <dev/isci/scil/sati_callbacks.h> 68230557Sjimharris#include <dev/isci/scil/sati_util.h> 69230557Sjimharris#include <dev/isci/scil/sati_report_luns.h> 70230557Sjimharris#include <dev/isci/scil/sati_inquiry.h> 71230557Sjimharris#include <dev/isci/scil/sati_mode_sense_6.h> 72230557Sjimharris#include <dev/isci/scil/sati_mode_sense_10.h> 73230557Sjimharris#include <dev/isci/scil/sati_mode_select.h> 74230557Sjimharris#include <dev/isci/scil/sati_test_unit_ready.h> 75230557Sjimharris#include <dev/isci/scil/sati_read_capacity.h> 76230557Sjimharris#include <dev/isci/scil/sati_read.h> 77230557Sjimharris#include <dev/isci/scil/sati_write.h> 78230557Sjimharris#include <dev/isci/scil/sati_verify.h> 79230557Sjimharris#include <dev/isci/scil/sati_synchronize_cache.h> 80230557Sjimharris#include <dev/isci/scil/sati_lun_reset.h> 81230557Sjimharris#include <dev/isci/scil/sati_start_stop_unit.h> 82230557Sjimharris#include <dev/isci/scil/sati_request_sense.h> 83230557Sjimharris#include <dev/isci/scil/sati_write_long.h> 84230557Sjimharris#include <dev/isci/scil/sati_reassign_blocks.h> 85230557Sjimharris#include <dev/isci/scil/sati_log_sense.h> 86230557Sjimharris#include <dev/isci/scil/sati_abort_task_set.h> 87230557Sjimharris#include <dev/isci/scil/sati_unmap.h> 88230557Sjimharris#include <dev/isci/scil/sati_passthrough.h> 89230557Sjimharris#include <dev/isci/scil/sati_write_and_verify.h> 90230557Sjimharris#include <dev/isci/scil/sati_read_buffer.h> 91230557Sjimharris#include <dev/isci/scil/sati_write_buffer.h> 92230557Sjimharris#include <dev/isci/scil/intel_ata.h> 93230557Sjimharris#include <dev/isci/scil/intel_scsi.h> 94230557Sjimharris#include <dev/isci/scil/intel_sat.h> 95230557Sjimharris 96230557Sjimharris//****************************************************************************** 97230557Sjimharris//* P R I V A T E M E T H O D S 98230557Sjimharris//****************************************************************************** 99230557Sjimharris 100230557Sjimharris/** 101230557Sjimharris * @brief This method performs the translation of ATA error register values 102230557Sjimharris * into SCSI sense data. 103230557Sjimharris * For more information on the parameter passed to this method please 104230557Sjimharris * reference the sati_translate_response() method. 105230557Sjimharris * 106230557Sjimharris * @param[in] error This parameter specifies the contents of the ATA error 107230557Sjimharris * register to be translated. 108230557Sjimharris * 109230557Sjimharris * @return none 110230557Sjimharris */ 111230557Sjimharrisvoid sati_translate_error( 112230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 113230557Sjimharris void * scsi_io, 114230557Sjimharris U8 error 115230557Sjimharris) 116230557Sjimharris{ 117230557Sjimharris if (error & ATA_ERROR_REG_NO_MEDIA_BIT) 118230557Sjimharris { 119230557Sjimharris sati_scsi_sense_data_construct( 120230557Sjimharris sequence, 121230557Sjimharris scsi_io, 122230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 123230557Sjimharris SCSI_SENSE_NOT_READY, 124230557Sjimharris SCSI_ASC_MEDIUM_NOT_PRESENT, 125230557Sjimharris SCSI_ASCQ_MEDIUM_NOT_PRESENT 126230557Sjimharris ); 127230557Sjimharris } 128230557Sjimharris else if (error & ATA_ERROR_REG_MEDIA_CHANGE_BIT) 129230557Sjimharris { 130230557Sjimharris sati_scsi_sense_data_construct( 131230557Sjimharris sequence, 132230557Sjimharris scsi_io, 133230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 134230557Sjimharris SCSI_SENSE_UNIT_ATTENTION, 135230557Sjimharris SCSI_ASC_NOT_READY_TO_READY_CHANGE, 136230557Sjimharris SCSI_ASCQ_NOT_READY_TO_READY_CHANGE 137230557Sjimharris ); 138230557Sjimharris } 139230557Sjimharris else if (error & ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT) 140230557Sjimharris { 141230557Sjimharris sati_scsi_sense_data_construct( 142230557Sjimharris sequence, 143230557Sjimharris scsi_io, 144230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 145230557Sjimharris SCSI_SENSE_UNIT_ATTENTION, 146230557Sjimharris SCSI_ASC_MEDIUM_REMOVAL_REQUEST, 147230557Sjimharris SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST 148230557Sjimharris ); 149230557Sjimharris } 150230557Sjimharris else if (error & ATA_ERROR_REG_ID_NOT_FOUND_BIT) 151230557Sjimharris { 152230557Sjimharris sati_scsi_sense_data_construct( 153230557Sjimharris sequence, 154230557Sjimharris scsi_io, 155230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 156230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 157230557Sjimharris SCSI_ASC_LBA_OUT_OF_RANGE, 158230557Sjimharris SCSI_ASCQ_LBA_OUT_OF_RANGE 159230557Sjimharris ); 160230557Sjimharris } 161230557Sjimharris else if (error & ATA_ERROR_REG_UNCORRECTABLE_BIT) 162230557Sjimharris { 163230557Sjimharris //Mark the Sequence state as a read error so more sense data 164230557Sjimharris //can be returned later 165230557Sjimharris sequence->state = SATI_SEQUENCE_STATE_READ_ERROR; 166230557Sjimharris sati_scsi_sense_data_construct( 167230557Sjimharris sequence, 168230557Sjimharris scsi_io, 169230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 170230557Sjimharris SCSI_SENSE_MEDIUM_ERROR, 171230557Sjimharris SCSI_ASC_UNRECOVERED_READ_ERROR, 172230557Sjimharris SCSI_ASCQ_UNRECOVERED_READ_ERROR 173230557Sjimharris ); 174230557Sjimharris } 175230557Sjimharris else if ( (sequence->data_direction == SATI_DATA_DIRECTION_OUT) 176230557Sjimharris && (error & ATA_ERROR_REG_WRITE_PROTECTED_BIT) ) 177230557Sjimharris { 178230557Sjimharris sati_scsi_sense_data_construct( 179230557Sjimharris sequence, 180230557Sjimharris scsi_io, 181230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 182230557Sjimharris SCSI_SENSE_DATA_PROTECT, 183230557Sjimharris SCSI_ASC_WRITE_PROTECTED, 184230557Sjimharris SCSI_ASCQ_WRITE_PROTECTED 185230557Sjimharris ); 186230557Sjimharris } 187230557Sjimharris else if (error & ATA_ERROR_REG_ICRC_BIT) 188230557Sjimharris { 189230557Sjimharris sati_scsi_sense_data_construct( 190230557Sjimharris sequence, 191230557Sjimharris scsi_io, 192230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 193230557Sjimharris SCSI_SENSE_ABORTED_COMMAND, 194230557Sjimharris SCSI_ASC_IU_CRC_ERROR_DETECTED, 195230557Sjimharris SCSI_ASCQ_IU_CRC_ERROR_DETECTED 196230557Sjimharris ); 197230557Sjimharris } 198230557Sjimharris else // (error & ATA_ERROR_REG_ABORT_BIT) 199230557Sjimharris { 200230557Sjimharris // The ABORT bit has the lowest precedence of all errors. 201230557Sjimharris // As a result, it is at the bottom of the conditional 202230557Sjimharris // statement. 203230557Sjimharris sati_scsi_sense_data_construct( 204230557Sjimharris sequence, 205230557Sjimharris scsi_io, 206230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 207230557Sjimharris SCSI_SENSE_ABORTED_COMMAND, 208230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE, 209230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 210230557Sjimharris ); 211230557Sjimharris } 212230557Sjimharris} 213230557Sjimharris 214230557Sjimharris/** 215230557Sjimharris * @brief This method translates the supplied ATA payload data into the 216230557Sjimharris * corresponding SCSI data. This is necessary for SCSI commands 217230557Sjimharris * that have well-defined payload data associated with them (e.g. 218230557Sjimharris * READ CAPACITY). 219230557Sjimharris * 220230557Sjimharris * @param[in] sequence This parameter specifies the sequence 221230557Sjimharris * data associated with the translation. 222230557Sjimharris * @param[in] ata_io This parameter specifies the ATA payload 223230557Sjimharris * buffer location and size to be translated. 224230557Sjimharris * @param[out] scsi_output_data This parameter specifies the SCSI payload 225230557Sjimharris * memory area into which the translator is to write. 226230557Sjimharris * 227230557Sjimharris * @return none 228230557Sjimharris */ 229230557Sjimharrisstatic 230230557Sjimharrisvoid sati_translate_data( 231230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 232230557Sjimharris void * ata_input_data, 233230557Sjimharris void * scsi_io 234230557Sjimharris) 235230557Sjimharris{ 236230557Sjimharris // Update the device capabilities in the odd/crazy event something changed. 237230557Sjimharris sati_device_update_capabilities( 238230557Sjimharris sequence->device, (ATA_IDENTIFY_DEVICE_DATA_T*) ata_input_data 239230557Sjimharris ); 240230557Sjimharris 241230557Sjimharris // Look at the first byte to determine the SCSI command to translate. 242230557Sjimharris switch (sequence->type) 243230557Sjimharris { 244230557Sjimharris#if !defined(DISABLE_SATI_INQUIRY) 245230557Sjimharris case SATI_SEQUENCE_INQUIRY_STANDARD: 246230557Sjimharris sati_inquiry_standard_translate_data( 247230557Sjimharris sequence, ata_input_data, scsi_io 248230557Sjimharris ); 249230557Sjimharris break; 250230557Sjimharris 251230557Sjimharris case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER: 252230557Sjimharris sati_inquiry_serial_number_translate_data( 253230557Sjimharris sequence, ata_input_data, scsi_io 254230557Sjimharris ); 255230557Sjimharris break; 256230557Sjimharris 257230557Sjimharris case SATI_SEQUENCE_INQUIRY_DEVICE_ID: 258230557Sjimharris sati_inquiry_device_id_translate_data( 259230557Sjimharris sequence, ata_input_data, scsi_io 260230557Sjimharris ); 261230557Sjimharris break; 262230557Sjimharris 263230557Sjimharris case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE: 264230557Sjimharris sati_inquiry_block_device_translate_data( 265230557Sjimharris sequence, ata_input_data, scsi_io 266230557Sjimharris ); 267230557Sjimharris break; 268230557Sjimharris 269230557Sjimharris case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION: 270230557Sjimharris sati_inquiry_ata_information_translate_data( 271230557Sjimharris sequence, ata_input_data, scsi_io 272230557Sjimharris ); 273230557Sjimharris break; 274230557Sjimharris 275230557Sjimharris#endif // !defined(DISABLE_SATI_INQUIRY) 276230557Sjimharris 277230557Sjimharris#if !defined(DISABLE_SATI_READ_CAPACITY) 278230557Sjimharris case SATI_SEQUENCE_READ_CAPACITY_10: 279230557Sjimharris sati_read_capacity_10_translate_data(sequence, ata_input_data, scsi_io); 280230557Sjimharris break; 281230557Sjimharris 282230557Sjimharris case SATI_SEQUENCE_READ_CAPACITY_16: 283230557Sjimharris sati_read_capacity_16_translate_data(sequence, ata_input_data, scsi_io); 284230557Sjimharris break; 285230557Sjimharris#endif // !defined(DISABLE_SATI_READ_CAPACITY) 286230557Sjimharris 287230557Sjimharris#if !defined(DISABLE_SATI_MODE_SENSE) 288230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_CACHING: 289230557Sjimharris sati_mode_sense_6_caching_translate_data( 290230557Sjimharris sequence, ata_input_data, scsi_io 291230557Sjimharris ); 292230557Sjimharris break; 293230557Sjimharris 294230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL: 295230557Sjimharris sati_mode_sense_6_informational_excp_control_translate_data( 296230557Sjimharris sequence, ata_input_data, scsi_io 297230557Sjimharris ); 298230557Sjimharris break; 299230557Sjimharris 300230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR: 301230557Sjimharris sati_mode_sense_6_read_write_error_translate_data( 302230557Sjimharris sequence, ata_input_data, scsi_io 303230557Sjimharris ); 304230557Sjimharris break; 305230557Sjimharris 306230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT: 307230557Sjimharris sati_mode_sense_6_disconnect_reconnect_translate_data( 308230557Sjimharris sequence, ata_input_data, scsi_io 309230557Sjimharris ); 310230557Sjimharris break; 311230557Sjimharris 312230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_CONTROL: 313230557Sjimharris sati_mode_sense_6_control_translate_data( 314230557Sjimharris sequence, ata_input_data, scsi_io 315230557Sjimharris ); 316230557Sjimharris break; 317230557Sjimharris 318230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES: 319230557Sjimharris sati_mode_sense_6_all_pages_translate_data( 320230557Sjimharris sequence, ata_input_data, scsi_io 321230557Sjimharris ); 322230557Sjimharris break; 323230557Sjimharris 324230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION: 325230557Sjimharris sati_mode_sense_6_power_condition_translate_data( 326230557Sjimharris sequence, ata_input_data, scsi_io 327230557Sjimharris ); 328230557Sjimharris break; 329230557Sjimharris 330230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION: 331230557Sjimharris sati_mode_sense_10_power_condition_translate_data( 332230557Sjimharris sequence, ata_input_data, scsi_io 333230557Sjimharris ); 334230557Sjimharris break; 335230557Sjimharris 336230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_CACHING: 337230557Sjimharris sati_mode_sense_10_caching_translate_data( 338230557Sjimharris sequence, ata_input_data, scsi_io 339230557Sjimharris ); 340230557Sjimharris break; 341230557Sjimharris 342230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL: 343230557Sjimharris sati_mode_sense_10_informational_excp_control_translate_data( 344230557Sjimharris sequence, ata_input_data, scsi_io 345230557Sjimharris ); 346230557Sjimharris break; 347230557Sjimharris 348230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR: 349230557Sjimharris sati_mode_sense_10_read_write_error_translate_data( 350230557Sjimharris sequence, ata_input_data, scsi_io 351230557Sjimharris ); 352230557Sjimharris break; 353230557Sjimharris 354230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT: 355230557Sjimharris sati_mode_sense_10_disconnect_reconnect_translate_data( 356230557Sjimharris sequence, ata_input_data, scsi_io 357230557Sjimharris ); 358230557Sjimharris break; 359230557Sjimharris 360230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_CONTROL: 361230557Sjimharris sati_mode_sense_10_control_translate_data( 362230557Sjimharris sequence, ata_input_data, scsi_io 363230557Sjimharris ); 364230557Sjimharris break; 365230557Sjimharris 366230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES: 367230557Sjimharris sati_mode_sense_10_all_pages_translate_data( 368230557Sjimharris sequence, ata_input_data, scsi_io 369230557Sjimharris ); 370230557Sjimharris break; 371230557Sjimharris#endif // !defined(DISABLE_SATI_MODE_SENSE) 372230557Sjimharris 373230557Sjimharris default: 374230557Sjimharris break; 375230557Sjimharris } 376230557Sjimharris} 377230557Sjimharris 378230557Sjimharris//****************************************************************************** 379230557Sjimharris//* P U B L I C M E T H O D S 380230557Sjimharris//****************************************************************************** 381230557Sjimharris 382230557SjimharrisSATI_STATUS sati_translate_command( 383230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 384230557Sjimharris SATI_DEVICE_T * sati_device, 385230557Sjimharris void * scsi_io, 386230557Sjimharris void * ata_io 387230557Sjimharris) 388230557Sjimharris{ 389230557Sjimharris SATI_STATUS status = SATI_FAILURE; 390230557Sjimharris U8 * cdb = sati_cb_get_cdb_address(scsi_io); 391230557Sjimharris 392230557Sjimharris //No sense response has been set for the translation sequence yet 393230557Sjimharris sequence->is_sense_response_set = FALSE; 394230557Sjimharris // Default to no translation response required 395230557Sjimharris sequence->is_translate_response_required = FALSE; 396230557Sjimharris // Assign sati_device to sequence 397230557Sjimharris sequence->device = sati_device; 398230557Sjimharris 399230557Sjimharris /** 400230557Sjimharris * Fail any I/O request with LUN != 0 401230557Sjimharris */ 402230557Sjimharris if (sati_cb_get_lun(scsi_io) != 0) 403230557Sjimharris { 404230557Sjimharris sati_scsi_sense_data_construct( 405230557Sjimharris sequence, 406230557Sjimharris scsi_io, 407230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 408230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 409230557Sjimharris SCSI_ASC_LOGICAL_UNIT_NOT_SUPPORTED, 410230557Sjimharris 0 411230557Sjimharris ); 412230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 413230557Sjimharris } 414230557Sjimharris 415230557Sjimharris /** 416230557Sjimharris * SAT dictates: 417230557Sjimharris * - the NACA bit in the control byte (last byte) must be 0 418230557Sjimharris */ 419230557Sjimharris if ( (sati_get_cdb_byte(cdb, sati_cb_get_cdb_length(scsi_io) - 1) 420230557Sjimharris & SCSI_CONTROL_BYTE_NACA_BIT_ENABLE)) 421230557Sjimharris { 422230557Sjimharris sati_scsi_sense_data_construct( 423230557Sjimharris sequence, 424230557Sjimharris scsi_io, 425230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 426230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 427230557Sjimharris SCSI_ASC_INVALID_FIELD_IN_CDB, 428230557Sjimharris SCSI_ASCQ_INVALID_FIELD_IN_CDB 429230557Sjimharris ); 430230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 431230557Sjimharris } 432230557Sjimharris 433230557Sjimharris /** 434230557Sjimharris * Per SAT "Error and sense reporting" section. All subsequent IOs after 435230557Sjimharris * a device fault should receive INTERNAL TARGET FAILURE sense data. 436230557Sjimharris */ 437230557Sjimharris if (sati_device->state == SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED) 438230557Sjimharris { 439230557Sjimharris sati_scsi_sense_data_construct( 440230557Sjimharris sequence, 441230557Sjimharris scsi_io, 442230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 443230557Sjimharris SCSI_SENSE_HARDWARE_ERROR, 444230557Sjimharris SCSI_ASC_INTERNAL_TARGET_FAILURE, 445230557Sjimharris SCSI_ASCQ_INTERNAL_TARGET_FAILURE 446230557Sjimharris ); 447230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 448230557Sjimharris } 449230557Sjimharris 450230557Sjimharris if(sequence->state == SATI_SEQUENCE_STATE_INITIAL) 451230557Sjimharris { 452230557Sjimharris sequence->command_specific_data.scratch = 0; 453230557Sjimharris sequence->number_data_bytes_set = 0; 454230557Sjimharris } 455230557Sjimharris 456230557Sjimharris 457230557Sjimharris#ifdef SATI_TRANSPORT_SUPPORTS_SATA 458230557Sjimharris { 459230557Sjimharris U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io); 460230557Sjimharris sati_set_sata_command_flag(register_fis); 461230557Sjimharris sati_set_sata_fis_type(register_fis, SATA_FIS_TYPE_REGH2D); 462230557Sjimharris } 463230557Sjimharris#endif // SATI_TRANSPORT_SUPPORTS_SATA 464230557Sjimharris 465230557Sjimharris // Look at the first byte to determine the SCSI command to translate. 466230557Sjimharris switch (sati_get_cdb_byte(cdb, 0)) 467230557Sjimharris { 468230557Sjimharris#if !defined(DISABLE_SATI_REPORT_LUNS) 469230557Sjimharris case SCSI_REPORT_LUNS: 470230557Sjimharris status = sati_report_luns_translate_command( 471230557Sjimharris sequence, scsi_io, ata_io 472230557Sjimharris ); 473230557Sjimharris break; 474230557Sjimharris#endif // !defined(DISABLE_SATI_REPORT_LUNS) 475230557Sjimharris 476230557Sjimharris#if !defined(DISABLE_SATI_INQUIRY) 477230557Sjimharris case SCSI_INQUIRY: 478230557Sjimharris status = sati_inquiry_translate_command( 479230557Sjimharris sequence, scsi_io, ata_io 480230557Sjimharris ); 481230557Sjimharris break; 482230557Sjimharris#endif // !defined(DISABLE_SATI_INQUIRY) 483230557Sjimharris 484230557Sjimharris#if !defined(DISABLE_SATI_MODE_SENSE) 485230557Sjimharris case SCSI_MODE_SENSE_6: 486230557Sjimharris status = sati_mode_sense_6_translate_command( 487230557Sjimharris sequence, scsi_io, ata_io 488230557Sjimharris ); 489230557Sjimharris break; 490230557Sjimharris 491230557Sjimharris case SCSI_MODE_SENSE_10: 492230557Sjimharris status = sati_mode_sense_10_translate_command( 493230557Sjimharris sequence, scsi_io, ata_io 494230557Sjimharris ); 495230557Sjimharris break; 496230557Sjimharris#endif // !defined(DISABLE_SATI_MODE_SENSE) 497230557Sjimharris 498230557Sjimharris#if !defined(DISABLE_SATI_MODE_SELECT) 499230557Sjimharris case SCSI_MODE_SELECT_6: 500230557Sjimharris status = sati_mode_select_6_translate_command( 501230557Sjimharris sequence, scsi_io, ata_io 502230557Sjimharris ); 503230557Sjimharris break; 504230557Sjimharris 505230557Sjimharris case SCSI_MODE_SELECT_10: 506230557Sjimharris status = sati_mode_select_10_translate_command( 507230557Sjimharris sequence, scsi_io, ata_io 508230557Sjimharris ); 509230557Sjimharris break; 510230557Sjimharris#endif // !defined(DISABLE_SATI_MODE_SELECT) 511230557Sjimharris 512230557Sjimharris#if !defined(DISABLE_SATI_TEST_UNIT_READY) 513230557Sjimharris case SCSI_TEST_UNIT_READY: 514230557Sjimharris status = sati_test_unit_ready_translate_command( 515230557Sjimharris sequence, scsi_io, ata_io 516230557Sjimharris ); 517230557Sjimharris break; 518230557Sjimharris#endif // !defined(DISABLE_SATI_TEST_UNIT_READY) 519230557Sjimharris 520230557Sjimharris#if !defined(DISABLE_SATI_READ_CAPACITY) 521230557Sjimharris case SCSI_READ_CAPACITY_10: 522230557Sjimharris status = sati_read_capacity_10_translate_command( 523230557Sjimharris sequence, scsi_io, ata_io 524230557Sjimharris ); 525230557Sjimharris break; 526230557Sjimharris 527230557Sjimharris case SCSI_SERVICE_ACTION_IN_16: 528230557Sjimharris if ( (sati_get_cdb_byte(cdb, 1) & SCSI_SERVICE_ACTION_MASK) 529230557Sjimharris == SCSI_SERVICE_ACTION_IN_CODES_READ_CAPACITY_16) 530230557Sjimharris status = sati_read_capacity_16_translate_command( 531230557Sjimharris sequence, scsi_io, ata_io 532230557Sjimharris ); 533230557Sjimharris else 534230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 535230557Sjimharris break; 536230557Sjimharris#endif // !defined(DISABLE_SATI_READ_CAPACITY) 537230557Sjimharris 538230557Sjimharris#if !defined(DISABLE_SATI_REQUEST_SENSE) 539230557Sjimharris case SCSI_REQUEST_SENSE: 540230557Sjimharris status = sati_request_sense_translate_command( 541230557Sjimharris sequence, scsi_io, ata_io 542230557Sjimharris ); 543230557Sjimharris break; 544230557Sjimharris#endif // !defined(DISABLE_SATI_REQUEST_SENSE) 545230557Sjimharris 546230557Sjimharris case SCSI_READ_6: 547230557Sjimharris status = sati_read_6_translate_command(sequence, scsi_io, ata_io); 548230557Sjimharris break; 549230557Sjimharris 550230557Sjimharris case SCSI_READ_10: 551230557Sjimharris status = sati_read_10_translate_command(sequence, scsi_io, ata_io); 552230557Sjimharris break; 553230557Sjimharris 554230557Sjimharris case SCSI_READ_12: 555230557Sjimharris status = sati_read_12_translate_command(sequence, scsi_io, ata_io); 556230557Sjimharris break; 557230557Sjimharris 558230557Sjimharris case SCSI_READ_16: 559230557Sjimharris status = sati_read_16_translate_command(sequence, scsi_io, ata_io); 560230557Sjimharris break; 561230557Sjimharris 562230557Sjimharris case SCSI_WRITE_6: 563230557Sjimharris status = sati_write_6_translate_command(sequence, scsi_io, ata_io); 564230557Sjimharris break; 565230557Sjimharris 566230557Sjimharris case SCSI_WRITE_10: 567230557Sjimharris status = sati_write_10_translate_command(sequence, scsi_io, ata_io); 568230557Sjimharris break; 569230557Sjimharris 570230557Sjimharris case SCSI_WRITE_12: 571230557Sjimharris status = sati_write_12_translate_command(sequence, scsi_io, ata_io); 572230557Sjimharris break; 573230557Sjimharris 574230557Sjimharris case SCSI_WRITE_16: 575230557Sjimharris status = sati_write_16_translate_command(sequence, scsi_io, ata_io); 576230557Sjimharris break; 577230557Sjimharris 578230557Sjimharris#if !defined(DISABLE_SATI_VERIFY) 579230557Sjimharris case SCSI_VERIFY_10: 580230557Sjimharris status = sati_verify_10_translate_command(sequence, scsi_io, ata_io); 581230557Sjimharris break; 582230557Sjimharris 583230557Sjimharris case SCSI_VERIFY_12: 584230557Sjimharris status = sati_verify_12_translate_command(sequence, scsi_io, ata_io); 585230557Sjimharris break; 586230557Sjimharris 587230557Sjimharris case SCSI_VERIFY_16: 588230557Sjimharris status = sati_verify_16_translate_command(sequence, scsi_io, ata_io); 589230557Sjimharris break; 590230557Sjimharris#endif // !defined(DISABLE_SATI_VERIFY) 591230557Sjimharris 592230557Sjimharris#if !defined(DISABLE_SATI_WRITE_AND_VERIFY) \ 593230557Sjimharris && !defined(DISABLE_SATI_VERIFY) \ 594230557Sjimharris && !defined(DISABLE_SATI_WRITE) 595230557Sjimharris 596230557Sjimharris case SCSI_WRITE_AND_VERIFY_10: 597230557Sjimharris status = sati_write_and_verify_10_translate_command(sequence, scsi_io, ata_io); 598230557Sjimharris break; 599230557Sjimharris 600230557Sjimharris case SCSI_WRITE_AND_VERIFY_12: 601230557Sjimharris status = sati_write_and_verify_12_translate_command(sequence, scsi_io, ata_io); 602230557Sjimharris break; 603230557Sjimharris 604230557Sjimharris case SCSI_WRITE_AND_VERIFY_16: 605230557Sjimharris status = sati_write_and_verify_16_translate_command(sequence, scsi_io, ata_io); 606230557Sjimharris break; 607230557Sjimharris#endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY) 608230557Sjimharris // && !defined(DISABLE_SATI_VERIFY) 609230557Sjimharris // && !defined(DISABLE_SATI_WRITE) 610230557Sjimharris 611230557Sjimharris#if !defined(DISABLE_SATI_REASSIGN_BLOCKS) 612230557Sjimharris case SCSI_REASSIGN_BLOCKS: 613230557Sjimharris status = sati_reassign_blocks_translate_command(sequence, scsi_io, ata_io); 614230557Sjimharris break; 615230557Sjimharris#endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS) 616230557Sjimharris 617230557Sjimharris#if !defined(DISABLE_SATI_SYNCHRONIZE_CACHE) 618230557Sjimharris case SCSI_SYNCHRONIZE_CACHE_10: 619230557Sjimharris case SCSI_SYNCHRONIZE_CACHE_16: 620230557Sjimharris status = sati_synchronize_cache_translate_command(sequence, scsi_io, ata_io); 621230557Sjimharris break; 622230557Sjimharris#endif // !defined(DISABLE_SATI_SYNCHRONIZE_CACHE) 623230557Sjimharris 624230557Sjimharris#if !defined(DISABLE_SATI_START_STOP_UNIT) 625230557Sjimharris case SCSI_START_STOP_UNIT: 626230557Sjimharris status = sati_start_stop_unit_translate_command( 627230557Sjimharris sequence, scsi_io, ata_io 628230557Sjimharris ); 629230557Sjimharris break; 630230557Sjimharris#endif // !defined(DISABLE_SATI_START_STOP_UNIT) 631230557Sjimharris 632230557Sjimharris#if !defined(DISABLE_SATI_WRITE_LONG) 633230557Sjimharris case SCSI_WRITE_LONG_10: 634230557Sjimharris case SCSI_WRITE_LONG_16: 635230557Sjimharris status = sati_write_long_translate_command(sequence, scsi_io, ata_io); 636230557Sjimharris break; 637230557Sjimharris#endif // !defined(DISABLE_SATI_WRITE_LONG) 638230557Sjimharris 639230557Sjimharris#if !defined(DISABLE_SATI_LOG_SENSE) 640230557Sjimharris case SCSI_LOG_SENSE: 641230557Sjimharris status = sati_log_sense_translate_command(sequence, scsi_io, ata_io); 642230557Sjimharris break; 643230557Sjimharris#endif // !defined(DISABLE_SATI_LOG_SENSE) 644230557Sjimharris 645230557Sjimharris case SCSI_PERSISTENT_RESERVE_IN: 646230557Sjimharris case SCSI_PERSISTENT_RESERVE_OUT: 647230557Sjimharris //These commands are not supported by SATI 648230557Sjimharris sati_scsi_sense_data_construct( 649230557Sjimharris sequence, 650230557Sjimharris scsi_io, 651230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 652230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 653230557Sjimharris SCSI_ASC_INVALID_COMMAND_OPERATION_CODE, 654230557Sjimharris SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE 655230557Sjimharris ); 656230557Sjimharris //returning status now to keep sense data set above 657230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 658230557Sjimharris break; 659230557Sjimharris 660230557Sjimharris#if !defined(DISABLE_SATI_UNMAP) 661230557Sjimharris case SCSI_UNMAP: 662230557Sjimharris status = sati_unmap_translate_command(sequence, scsi_io, ata_io); 663230557Sjimharris break; 664230557Sjimharris#endif // !defined(DISABLE_SATI_UNMAP) 665230557Sjimharris 666230557Sjimharris#if !defined(DISABLE_SATI_ATA_PASSTHROUGH) 667230557Sjimharris case SCSI_ATA_PASSTHRU_12: 668230557Sjimharris status = sati_passthrough_12_translate_command(sequence, scsi_io, ata_io); 669230557Sjimharris break; 670230557Sjimharris 671230557Sjimharris case SCSI_ATA_PASSTHRU_16: 672230557Sjimharris status = sati_passthrough_16_translate_command(sequence, scsi_io, ata_io); 673230557Sjimharris break; 674230557Sjimharris 675230557Sjimharris#endif // !define(DISABLE_SATI_ATA_PASSTHRU) 676230557Sjimharris 677230557Sjimharris#if !defined(DISABLE_SATI_READ_BUFFER) 678230557Sjimharris case SCSI_READ_BUFFER: 679230557Sjimharris status = sati_read_buffer_translate_command(sequence, scsi_io, ata_io); 680230557Sjimharris break; 681230557Sjimharris#endif //!defined(DISABLE_SATI_READ_BUFFER) 682230557Sjimharris 683230557Sjimharris#if !defined(DISABLE_SATI_WRITE_BUFFER) 684230557Sjimharris case SCSI_WRITE_BUFFER: 685230557Sjimharris status = sati_write_buffer_translate_command(sequence, scsi_io, ata_io); 686230557Sjimharris break; 687230557Sjimharris#endif //!defined(DISABLE_SATI_WRITE_BUFFER) 688230557Sjimharris default: 689230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 690230557Sjimharris break; 691230557Sjimharris } 692230557Sjimharris 693230557Sjimharris if( (status == SATI_FAILURE_CHECK_RESPONSE_DATA) && 694230557Sjimharris !(sequence->is_sense_response_set) ) 695230557Sjimharris { 696230557Sjimharris sati_scsi_sense_data_construct( 697230557Sjimharris sequence, 698230557Sjimharris scsi_io, 699230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 700230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 701230557Sjimharris SCSI_ASC_INVALID_FIELD_IN_CDB, 702230557Sjimharris SCSI_ASCQ_INVALID_FIELD_IN_CDB 703230557Sjimharris ); 704230557Sjimharris } 705230557Sjimharris return status; 706230557Sjimharris} 707230557Sjimharris 708230557Sjimharris// ----------------------------------------------------------------------------- 709230557Sjimharris 710230557Sjimharris#if !defined(DISABLE_SATI_TASK_MANAGEMENT) 711230557SjimharrisSATI_STATUS sati_translate_task_management( 712230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 713230557Sjimharris SATI_DEVICE_T * sati_device, 714230557Sjimharris void * scsi_task, 715230557Sjimharris void * ata_io 716230557Sjimharris) 717230557Sjimharris{ 718230557Sjimharris SATI_STATUS status=SATI_FAILURE; 719230557Sjimharris U8 task_function = sati_cb_get_task_function(scsi_task); 720230557Sjimharris 721230557Sjimharris sequence->device = sati_device; 722230557Sjimharris 723230557Sjimharris switch (task_function) 724230557Sjimharris { 725230557Sjimharris /** 726230557Sjimharris * @todo We need to update the ABORT_TASK and ABORT_TASK_SET to be 727230557Sjimharris * SAT compliant. 728230557Sjimharris */ 729230557Sjimharris case SCSI_TASK_REQUEST_ABORT_TASK: 730230557Sjimharris case SCSI_TASK_REQUEST_LOGICAL_UNIT_RESET: 731230557Sjimharris status = sati_lun_reset_translate_command(sequence, scsi_task, ata_io); 732230557Sjimharris break; 733230557Sjimharris 734230557Sjimharris case SCSI_TASK_REQUEST_ABORT_TASK_SET: 735230557Sjimharris#if !defined(DISABLE_SATI_ABORT_TASK_SET) 736230557Sjimharris status = sati_abort_task_set_translate_command(sequence, scsi_task, ata_io); 737230557Sjimharris#else 738230557Sjimharris status = SATI_FAILURE; 739230557Sjimharris#endif 740230557Sjimharris break; 741230557Sjimharris default: 742230557Sjimharris status = SATI_FAILURE; 743230557Sjimharris break; 744230557Sjimharris } 745230557Sjimharris 746230557Sjimharris return status; 747230557Sjimharris} 748230557Sjimharris#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT) 749230557Sjimharris 750230557Sjimharris// ----------------------------------------------------------------------------- 751230557Sjimharris#if !defined(DISABLE_SATI_INQUIRY) \ 752230557Sjimharris || !defined(DISABLE_SATI_READY_CAPACITY) \ 753230557Sjimharris || !defined(DISABLE_SATI_MODE_SENSE) \ 754230557Sjimharris || !defined(DISABLE_SATI_MODE_SELECT) \ 755230557Sjimharris || !defined(DISABLE_SATI_REASSIGN_BLOCKS) \ 756230557Sjimharris || !defined(DISABLE_SATI_START_STOP_UNIT) \ 757230557Sjimharris || !defined(DISABLE_SATI_REQUEST_SENSE) \ 758230557Sjimharris || !defined(DISABLE_SATI_WRITE_LONG) \ 759230557Sjimharris || !defined(DISABLE_SATI_LOG_SENSE) \ 760230557Sjimharris || !defined(DISABLE_SATI_UNMAP) 761230557Sjimharris 762230557Sjimharrisstatic 763230557SjimharrisSATI_STATUS sati_check_data_io( 764230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence 765230557Sjimharris) 766230557Sjimharris{ 767230557Sjimharris if(sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE) 768230557Sjimharris { 769230557Sjimharris return SATI_SEQUENCE_INCOMPLETE; 770230557Sjimharris } 771230557Sjimharris else if(sequence->number_data_bytes_set < sequence->allocation_length) 772230557Sjimharris { 773230557Sjimharris return SATI_COMPLETE_IO_DONE_EARLY; 774230557Sjimharris } 775230557Sjimharris else 776230557Sjimharris { 777230557Sjimharris return SATI_COMPLETE; 778230557Sjimharris } 779230557Sjimharris} 780230557Sjimharris#endif // !defined(DISABLE_SATI_INQUIRY) 781230557Sjimharris // || !defined(DISABLE_SATI_READY_CAPACITY) 782230557Sjimharris // || !defined(DISABLE_SATI_MODE_SENSE) 783230557Sjimharris // || !defined(DISABLE_SATI_MODE_SELECT) 784230557Sjimharris // || !defined(DISABLE_SATI_REASSIGN_BLOCKS) 785230557Sjimharris // || !defined(DISABLE_SATI_START_STOP_UNIT) 786230557Sjimharris // || !defined(DISABLE_SATI_REQUEST_SENSE) 787230557Sjimharris // || !defined(DISABLE_SATI_WRITE_LONG) 788230557Sjimharris // || !defined(DISABLE_SATI_LOG_SENSE) 789230557Sjimharris // || !defined(DISABLE_SATI_UNMAP) 790230557Sjimharris// ----------------------------------------------------------------------------- 791230557SjimharrisSATI_STATUS sati_translate_command_response( 792230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 793230557Sjimharris void * scsi_io, 794230557Sjimharris void * ata_io 795230557Sjimharris) 796230557Sjimharris{ 797230557Sjimharris SATI_STATUS status = SATI_COMPLETE; 798230557Sjimharris U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 799230557Sjimharris U8 ata_status; 800230557Sjimharris 801230557Sjimharris /** 802230557Sjimharris * If the device fault bit is set in the status register, then 803230557Sjimharris * set the sense data and return. 804230557Sjimharris */ 805230557Sjimharris ata_status = (U8) sati_get_ata_status(register_fis); 806230557Sjimharris if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT) 807230557Sjimharris { 808230557Sjimharris sati_scsi_sense_data_construct( 809230557Sjimharris sequence, 810230557Sjimharris scsi_io, 811230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 812230557Sjimharris SCSI_SENSE_HARDWARE_ERROR, 813230557Sjimharris SCSI_ASC_INTERNAL_TARGET_FAILURE, 814230557Sjimharris SCSI_ASCQ_INTERNAL_TARGET_FAILURE 815230557Sjimharris ); 816230557Sjimharris 817230557Sjimharris sequence->device->state = SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED; 818230557Sjimharris 819230557Sjimharris // Make sure that the terminate sequence is called to allow 820230557Sjimharris // translation logic to perform any cleanup before the IO is completed. 821230557Sjimharris sati_sequence_terminate(sequence, 822230557Sjimharris scsi_io, 823230557Sjimharris ata_io); 824230557Sjimharris 825230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 826230557Sjimharris } 827230557Sjimharris 828230557Sjimharris // Look at the sequence type to determine the response translation method 829230557Sjimharris // to invoke. 830230557Sjimharris switch (sequence->type) 831230557Sjimharris { 832230557Sjimharris#if !defined(DISABLE_SATI_TEST_UNIT_READY) 833230557Sjimharris case SATI_SEQUENCE_TEST_UNIT_READY: 834230557Sjimharris status = sati_test_unit_ready_translate_response( 835230557Sjimharris sequence, scsi_io, ata_io 836230557Sjimharris ); 837230557Sjimharris break; 838230557Sjimharris#endif // !defined(DISABLE_SATI_TEST_UNIT_READY) 839230557Sjimharris 840230557Sjimharris#if !defined(DISABLE_SATI_INQUIRY) \ 841230557Sjimharris || !defined(DISABLE_SATI_READY_CAPACITY) \ 842230557Sjimharris || !defined(DISABLE_SATI_MODE_SENSE) 843230557Sjimharris 844230557Sjimharris case SATI_SEQUENCE_INQUIRY_EXECUTE_DEVICE_DIAG: 845230557Sjimharris 846230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 847230557Sjimharris { 848230557Sjimharris U8 error = (U8) sati_get_ata_error(register_fis); 849230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 850230557Sjimharris sati_translate_error(sequence, scsi_io, error); 851230557Sjimharris } 852230557Sjimharris else 853230557Sjimharris { 854230557Sjimharris sati_inquiry_ata_information_finish_translation( 855230557Sjimharris sequence, 856230557Sjimharris scsi_io, 857230557Sjimharris ata_io 858230557Sjimharris ); 859230557Sjimharris status = sati_check_data_io(sequence); 860230557Sjimharris } 861230557Sjimharris break; 862230557Sjimharris 863230557Sjimharris case SATI_SEQUENCE_INQUIRY_STANDARD: 864230557Sjimharris case SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES: 865230557Sjimharris case SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER: 866230557Sjimharris case SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE: 867230557Sjimharris case SATI_SEQUENCE_INQUIRY_ATA_INFORMATION: 868230557Sjimharris case SATI_SEQUENCE_INQUIRY_DEVICE_ID: 869230557Sjimharris case SATI_SEQUENCE_READ_CAPACITY_10: 870230557Sjimharris case SATI_SEQUENCE_READ_CAPACITY_16: 871230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_CACHING: 872230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL: 873230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR: 874230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT: 875230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_CONTROL: 876230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_POWER_CONDITION: 877230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES: 878230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_CACHING: 879230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL: 880230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR: 881230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_CONTROL: 882230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_POWER_CONDITION: 883230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT: 884230557Sjimharris case SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES: 885230557Sjimharris // Did an error occur during the IO request? 886230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 887230557Sjimharris { 888230557Sjimharris U8 error = (U8) sati_get_ata_error(register_fis); 889230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 890230557Sjimharris sati_translate_error(sequence, scsi_io, error); 891230557Sjimharris } 892230557Sjimharris else 893230557Sjimharris { 894230557Sjimharris void * ata_data = sati_cb_get_ata_data_address(ata_io); 895230557Sjimharris 896230557Sjimharris if(ata_data == NULL) 897230557Sjimharris { 898230557Sjimharris status = SATI_FAILURE; 899230557Sjimharris } 900230557Sjimharris else 901230557Sjimharris { 902230557Sjimharris sati_translate_data(sequence, ata_data, scsi_io); 903230557Sjimharris status = sati_check_data_io(sequence); 904230557Sjimharris } 905230557Sjimharris } 906230557Sjimharris break; 907230557Sjimharris#endif // !defined(DISABLE_SATI_INQUIRY) 908230557Sjimharris // && !defined(DISABLE_SATI_READY_CAPACITY) 909230557Sjimharris // && !defined(DISABLE_SATI_MODE_SENSE) 910230557Sjimharris 911230557Sjimharris#if !defined(DISABLE_SATI_MODE_SELECT) 912230557Sjimharris case SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING: 913230557Sjimharris 914230557Sjimharris status = sati_mode_select_translate_response( 915230557Sjimharris sequence, scsi_io, ata_io 916230557Sjimharris ); 917230557Sjimharris if(status == SATI_COMPLETE) 918230557Sjimharris { 919230557Sjimharris status = sati_check_data_io(sequence); 920230557Sjimharris } 921230557Sjimharris break; 922230557Sjimharris 923230557Sjimharris case SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION: 924230557Sjimharris case SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL: 925230557Sjimharris // Did an error occur during the IO request? 926230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 927230557Sjimharris { 928230557Sjimharris U8 error = (U8) sati_get_ata_error(register_fis); 929230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 930230557Sjimharris sati_translate_error(sequence, scsi_io, error); 931230557Sjimharris } 932230557Sjimharris else 933230557Sjimharris { 934230557Sjimharris status = sati_check_data_io(sequence); 935230557Sjimharris } 936230557Sjimharris break; 937230557Sjimharris#endif // !defined(DISABLE_SATI_MODE_SELECT) 938230557Sjimharris 939230557Sjimharris#if !defined(DISABLE_SATI_WRITE_AND_VERIFY) 940230557Sjimharris case SATI_SEQUENCE_WRITE_AND_VERIFY: 941230557Sjimharris 942230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 943230557Sjimharris { 944230557Sjimharris U8 error = (U8) sati_get_ata_error(register_fis); 945230557Sjimharris sati_translate_error(sequence, scsi_io, error); 946230557Sjimharris 947230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 948230557Sjimharris } 949230557Sjimharris else 950230557Sjimharris { 951230557Sjimharris status = sati_write_and_verify_translate_response( 952230557Sjimharris sequence, 953230557Sjimharris scsi_io, 954230557Sjimharris ata_io 955230557Sjimharris ); 956230557Sjimharris } 957230557Sjimharris break; 958230557Sjimharris#endif // !defined(DISABLE_SATI_WRITE_AND_VERIFY) 959230557Sjimharris 960230557Sjimharris case SATI_SEQUENCE_READ_6: 961230557Sjimharris case SATI_SEQUENCE_READ_10: 962230557Sjimharris case SATI_SEQUENCE_READ_12: 963230557Sjimharris case SATI_SEQUENCE_READ_16: 964230557Sjimharris case SATI_SEQUENCE_WRITE_6: 965230557Sjimharris case SATI_SEQUENCE_WRITE_10: 966230557Sjimharris case SATI_SEQUENCE_WRITE_12: 967230557Sjimharris case SATI_SEQUENCE_WRITE_16: 968230557Sjimharris case SATI_SEQUENCE_VERIFY_10: 969230557Sjimharris case SATI_SEQUENCE_VERIFY_12: 970230557Sjimharris case SATI_SEQUENCE_VERIFY_16: 971230557Sjimharris case SATI_SEQUENCE_SYNCHRONIZE_CACHE: 972230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 973230557Sjimharris { 974230557Sjimharris U8 error = (U8) sati_get_ata_error(register_fis); 975230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 976230557Sjimharris sati_translate_error(sequence, scsi_io, error); 977230557Sjimharris 978230557Sjimharris if(sequence->state == SATI_SEQUENCE_STATE_READ_ERROR ) 979230557Sjimharris { 980230557Sjimharris sati_scsi_read_error_sense_construct( 981230557Sjimharris sequence, 982230557Sjimharris scsi_io, 983230557Sjimharris ata_io, 984230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 985230557Sjimharris SCSI_SENSE_MEDIUM_ERROR, 986230557Sjimharris SCSI_ASC_UNRECOVERED_READ_ERROR, 987230557Sjimharris SCSI_ASCQ_UNRECOVERED_READ_ERROR 988230557Sjimharris ); 989230557Sjimharris sequence->state = SATI_SEQUENCE_STATE_FINAL; 990230557Sjimharris } 991230557Sjimharris } 992230557Sjimharris else 993230557Sjimharris { 994230557Sjimharris // We haven't satisified the transfer count from the original 995230557Sjimharris // SCSI CDB. As a result, we need to re-issue the command 996230557Sjimharris // with updated logical block address and transfer count. 997230557Sjimharris if (sequence->command_specific_data.scratch) 998230557Sjimharris { 999230557Sjimharris /** @todo update the contents of the CDB directly? Should be 1000230557Sjimharris * done during previous command translation? 1001230557Sjimharris */ 1002230557Sjimharris status = SATI_SEQUENCE_INCOMPLETE; 1003230557Sjimharris } 1004230557Sjimharris } 1005230557Sjimharris break; 1006230557Sjimharris 1007230557Sjimharris#if !defined(DISABLE_SATI_READ_BUFFER) 1008230557Sjimharris case SATI_SEQUENCE_READ_BUFFER: 1009230557Sjimharris status = sati_read_buffer_translate_response( 1010230557Sjimharris sequence, scsi_io, ata_io 1011230557Sjimharris ); 1012230557Sjimharris 1013230557Sjimharris if(status == SATI_COMPLETE) 1014230557Sjimharris { 1015230557Sjimharris status = sati_check_data_io(sequence); 1016230557Sjimharris } 1017230557Sjimharris break; 1018230557Sjimharris#endif //!defined(DISABLE_SATI_READ_BUFFER) 1019230557Sjimharris 1020230557Sjimharris#if !defined(DISABLE_SATI_WRITE_BUFFER) 1021230557Sjimharris case SATI_SEQUENCE_WRITE_BUFFER: 1022230557Sjimharris case SATI_SEQUENCE_WRITE_BUFFER_MICROCODE: 1023230557Sjimharris status = sati_write_buffer_translate_response( 1024230557Sjimharris sequence, scsi_io, ata_io 1025230557Sjimharris ); 1026230557Sjimharris break; 1027230557Sjimharris#endif //!defined(DISABLE_SATI_WRITE_BUFFER) 1028230557Sjimharris 1029230557Sjimharris#if !defined(DISABLE_SATI_REASSIGN_BLOCKS) 1030230557Sjimharris case SATI_SEQUENCE_REASSIGN_BLOCKS: 1031230557Sjimharris status = sati_reassign_blocks_translate_response( 1032230557Sjimharris sequence, scsi_io, ata_io 1033230557Sjimharris ); 1034230557Sjimharris if(status == SATI_COMPLETE) 1035230557Sjimharris { 1036230557Sjimharris status = sati_check_data_io(sequence); 1037230557Sjimharris } 1038230557Sjimharris break; 1039230557Sjimharris#endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS) 1040230557Sjimharris 1041230557Sjimharris#if !defined(DISABLE_SATI_START_STOP_UNIT) 1042230557Sjimharris case SATI_SEQUENCE_START_STOP_UNIT: 1043230557Sjimharris status = sati_start_stop_unit_translate_response( 1044230557Sjimharris sequence, scsi_io, ata_io 1045230557Sjimharris ); 1046230557Sjimharris if(status == SATI_COMPLETE) 1047230557Sjimharris { 1048230557Sjimharris status = sati_check_data_io(sequence); 1049230557Sjimharris } 1050230557Sjimharris break; 1051230557Sjimharris#endif // !defined(DISABLE_SATI_START_STOP_UNIT) 1052230557Sjimharris 1053230557Sjimharris#if !defined(DISABLE_SATI_REQUEST_SENSE) 1054230557Sjimharris case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS: 1055230557Sjimharris case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE: 1056230557Sjimharris status = sati_request_sense_translate_response( 1057230557Sjimharris sequence, scsi_io, ata_io 1058230557Sjimharris ); 1059230557Sjimharris if(status == SATI_COMPLETE) 1060230557Sjimharris { 1061230557Sjimharris status = sati_check_data_io(sequence); 1062230557Sjimharris } 1063230557Sjimharris break; 1064230557Sjimharris#endif // !defined(DISABLE_SATI_REQUEST_SENSE) 1065230557Sjimharris 1066230557Sjimharris#if !defined(DISABLE_SATI_WRITE_LONG) 1067230557Sjimharris case SATI_SEQUENCE_WRITE_LONG: 1068230557Sjimharris status = sati_write_long_translate_response( 1069230557Sjimharris sequence, scsi_io, ata_io 1070230557Sjimharris ); 1071230557Sjimharris if(status == SATI_COMPLETE) 1072230557Sjimharris { 1073230557Sjimharris status = sati_check_data_io(sequence); 1074230557Sjimharris } 1075230557Sjimharris break; 1076230557Sjimharris#endif // !defined(DISABLE_SATI_WRITE_LONG) 1077230557Sjimharris 1078230557Sjimharris#if !defined(DISABLE_SATI_LOG_SENSE) 1079230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE: 1080230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE: 1081230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE: 1082230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE: 1083230557Sjimharris status = sati_log_sense_translate_response( 1084230557Sjimharris sequence, scsi_io, ata_io 1085230557Sjimharris ); 1086230557Sjimharris if(status == SATI_COMPLETE) 1087230557Sjimharris { 1088230557Sjimharris status = sati_check_data_io(sequence); 1089230557Sjimharris } 1090230557Sjimharris break; 1091230557Sjimharris#endif // !defined(DISABLE_SATI_LOG_SENSE) 1092230557Sjimharris 1093230557Sjimharris#if !defined(DISABLE_SATI_UNMAP) 1094230557Sjimharris case SATI_SEQUENCE_UNMAP: 1095230557Sjimharris status = sati_unmap_translate_response( 1096230557Sjimharris sequence, scsi_io, ata_io 1097230557Sjimharris ); 1098230557Sjimharris break; 1099230557Sjimharris#endif // !defined(DISABLE_SATI_UNMAP) 1100230557Sjimharris 1101230557Sjimharris#if !defined(DISABLE_SATI_ATA_PASSTHROUGH) 1102230557Sjimharris case SATI_SEQUENCE_ATA_PASSTHROUGH_12: 1103230557Sjimharris case SATI_SEQUENCE_ATA_PASSTHROUGH_16: 1104230557Sjimharris status = sati_passthrough_translate_response( 1105230557Sjimharris sequence, scsi_io, ata_io 1106230557Sjimharris ); 1107230557Sjimharris break; 1108230557Sjimharris#endif // !defined(DISABLE_SATI_ATA_PASSTHROUGH) 1109230557Sjimharris 1110230557Sjimharris default: 1111230557Sjimharris status = SATI_FAILURE_INVALID_SEQUENCE_TYPE; 1112230557Sjimharris break; 1113230557Sjimharris } 1114230557Sjimharris 1115230557Sjimharris return status; 1116230557Sjimharris} 1117230557Sjimharris 1118230557Sjimharris// ----------------------------------------------------------------------------- 1119230557Sjimharris 1120230557Sjimharris#if !defined(DISABLE_SATI_TASK_MANAGEMENT) 1121230557SjimharrisSATI_STATUS sati_translate_task_response( 1122230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 1123230557Sjimharris void * scsi_io, 1124230557Sjimharris void * ata_io 1125230557Sjimharris) 1126230557Sjimharris{ 1127230557Sjimharris SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA; 1128230557Sjimharris U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 1129230557Sjimharris U8 ata_status; 1130230557Sjimharris 1131230557Sjimharris /** 1132230557Sjimharris * If the device fault bit is set in the status register, then 1133230557Sjimharris * set the sense data and return. 1134230557Sjimharris */ 1135230557Sjimharris ata_status = (U8) sati_get_ata_status(register_fis); 1136230557Sjimharris if (ata_status & ATA_STATUS_REG_DEVICE_FAULT_BIT) 1137230557Sjimharris { 1138230557Sjimharris sati_scsi_response_data_construct( 1139230557Sjimharris sequence, 1140230557Sjimharris scsi_io, 1141230557Sjimharris SCSI_TASK_MGMT_FUNC_FAILED 1142230557Sjimharris ); 1143230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 1144230557Sjimharris } 1145230557Sjimharris 1146230557Sjimharris // Look at the sequence type to determine the response translation method 1147230557Sjimharris // to invoke. 1148230557Sjimharris switch (sequence->type) 1149230557Sjimharris { 1150230557Sjimharris case SATI_SEQUENCE_LUN_RESET: 1151230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 1152230557Sjimharris { 1153230557Sjimharris sati_scsi_response_data_construct( 1154230557Sjimharris sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED); 1155230557Sjimharris } 1156230557Sjimharris else 1157230557Sjimharris { 1158230557Sjimharris sati_scsi_response_data_construct( 1159230557Sjimharris sequence, scsi_io, SCSI_TASK_MGMT_FUNC_COMPLETE); 1160230557Sjimharris } 1161230557Sjimharris 1162230557Sjimharris status = SATI_COMPLETE; 1163230557Sjimharris break; 1164230557Sjimharris 1165230557Sjimharris#if !defined(DISABLE_SATI_ABORT_TASK_SET) 1166230557Sjimharris case SATI_SEQUENCE_ABORT_TASK_SET: 1167230557Sjimharris if (ata_status & ATA_STATUS_REG_ERROR_BIT) 1168230557Sjimharris { 1169230557Sjimharris sati_scsi_response_data_construct( 1170230557Sjimharris sequence, scsi_io, SCSI_TASK_MGMT_FUNC_FAILED); 1171230557Sjimharris } 1172230557Sjimharris else 1173230557Sjimharris { 1174230557Sjimharris void * ata_data = sati_cb_get_ata_data_address(ata_io); 1175230557Sjimharris 1176230557Sjimharris if(ata_data == NULL) 1177230557Sjimharris { 1178230557Sjimharris status = SATI_FAILURE; 1179230557Sjimharris } 1180230557Sjimharris else 1181230557Sjimharris { 1182230557Sjimharris status = sati_abort_task_set_translate_data( 1183230557Sjimharris sequence, 1184230557Sjimharris ata_data, 1185230557Sjimharris scsi_io 1186230557Sjimharris ); 1187230557Sjimharris } 1188230557Sjimharris } 1189230557Sjimharris break; 1190230557Sjimharris#endif // !defined(DISABLE_SATI_ABORT_TASK_SET) 1191230557Sjimharris 1192230557Sjimharris default: 1193230557Sjimharris status = SATI_FAILURE_INVALID_SEQUENCE_TYPE; 1194230557Sjimharris break; 1195230557Sjimharris } 1196230557Sjimharris 1197230557Sjimharris return status; 1198230557Sjimharris} 1199230557Sjimharris#endif // !defined(DISABLE_SATI_TASK_MANAGEMENT) 1200230557Sjimharris 1201230557Sjimharris#if !defined(ENABLE_MINIMUM_MEMORY_MODE) 1202230557SjimharrisU32 sati_get_sat_compliance_version( 1203230557Sjimharris void 1204230557Sjimharris) 1205230557Sjimharris{ 1206230557Sjimharris return 2; // Compliant with SAT-2. 1207230557Sjimharris} 1208230557Sjimharris 1209230557SjimharrisU32 sati_get_sat_compliance_version_revision( 1210230557Sjimharris void 1211230557Sjimharris) 1212230557Sjimharris{ 1213230557Sjimharris return 7; // Compliant with SAT-2 revision 7. 1214230557Sjimharris} 1215230557Sjimharris 1216230557Sjimharris#endif // !defined(ENABLE_MINIMUM_MEMORY_MODE) 1217230557Sjimharris 1218230557SjimharrisU16 sati_get_number_data_bytes_set( 1219230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence 1220230557Sjimharris) 1221230557Sjimharris{ 1222230557Sjimharris return sequence->number_data_bytes_set; 1223230557Sjimharris} 1224230557Sjimharris 1225230557Sjimharrisvoid sati_sequence_construct( 1226230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence 1227230557Sjimharris) 1228230557Sjimharris{ 1229230557Sjimharris sequence->state = SATI_SEQUENCE_STATE_INITIAL; 1230230557Sjimharris} 1231230557Sjimharris 1232230557Sjimharrisvoid sati_sequence_terminate( 1233230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 1234230557Sjimharris void * scsi_io, 1235230557Sjimharris void * ata_io 1236230557Sjimharris) 1237230557Sjimharris{ 1238230557Sjimharris // Decode the sequence type to determine how to handle the termination 1239240518Seadler // of the translation method. 1240230557Sjimharris switch (sequence->type) 1241230557Sjimharris { 1242230557Sjimharris case SATI_SEQUENCE_UNMAP: 1243230557Sjimharris sati_unmap_terminate(sequence,scsi_io,ata_io); 1244230557Sjimharris break; 1245230557Sjimharris } 1246230557Sjimharris} 1247