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 the implementation to translate 59230557Sjimharris * SCSI Request Sense command based of the SAT spec. 60230557Sjimharris */ 61230557Sjimharris 62230557Sjimharris#if !defined(DISABLE_SATI_REQUEST_SENSE) 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/sati_request_sense.h> 65230557Sjimharris#include <dev/isci/scil/sati_device.h> 66230557Sjimharris#include <dev/isci/scil/sati_util.h> 67230557Sjimharris#include <dev/isci/scil/intel_scsi.h> 68230557Sjimharris#include <dev/isci/scil/intel_ata.h> 69230557Sjimharris#include <dev/isci/scil/intel_sat.h> 70230557Sjimharris#include <dev/isci/scil/sati_callbacks.h> 71230557Sjimharris#include <dev/isci/scil/sati_mode_pages.h> 72230557Sjimharris 73230557Sjimharris#define MRIE_BYTE 3 74230557Sjimharris#define DEXCPT_BYTE 2 75230557Sjimharris 76230557Sjimharris/** 77230557Sjimharris * @brief This method will translate the SCSI request sense command 78230557Sjimharris * into corresponding ATA commands. Depending on supported and enabled 79230557Sjimharris * capabilities like SMART, different ATA commands can be selected. 80230557Sjimharris * For more information on the parameters passed to this method, 81230557Sjimharris * please reference sati_translate_command(). 82230557Sjimharris * 83230557Sjimharris * @return Indicates if the command translation succeeded. 84230557Sjimharris * @retval SATI_SUCCESS indicates that the translation was supported and occurred 85230557Sjimharris * without error. 86230557Sjimharris * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 87230557Sjimharris * the SATII is processing a format unit commmand. 88230557Sjimharris * @retval SATI_COMPLETE indicates that the translation was supported, occurred without 89230557Sjimharris * error, and no additional translation is necessary. 90230557Sjimharris */ 91230557SjimharrisSATI_STATUS sati_request_sense_translate_command( 92230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 93230557Sjimharris void * scsi_io, 94230557Sjimharris void * ata_io 95230557Sjimharris) 96230557Sjimharris{ 97230557Sjimharris U8 * cdb = sati_cb_get_cdb_address(scsi_io); 98230557Sjimharris 99230557Sjimharris //check if SATI is processing format unit command 100230557Sjimharris switch(sequence->device->state) 101230557Sjimharris { 102230557Sjimharris case SATI_DEVICE_STATE_FORMAT_UNIT_IN_PROGRESS: 103230557Sjimharris sati_scsi_sense_data_construct( 104230557Sjimharris sequence, 105230557Sjimharris scsi_io, 106230557Sjimharris SCSI_STATUS_GOOD, 107230557Sjimharris SCSI_SENSE_NOT_READY, 108230557Sjimharris SCSI_ASC_LUN_FORMAT_IN_PROGRESS, 109230557Sjimharris SCSI_ASCQ_LUN_FORMAT_IN_PROGRESS 110230557Sjimharris ); 111230557Sjimharris return SATI_COMPLETE; 112230557Sjimharris break; 113230557Sjimharris 114230557Sjimharris case SATI_DEVICE_STATE_UNIT_ATTENTION_CONDITION: 115230557Sjimharris sati_scsi_sense_data_construct( 116230557Sjimharris sequence, 117230557Sjimharris scsi_io, 118230557Sjimharris SCSI_STATUS_GOOD, 119230557Sjimharris SCSI_SENSE_UNIT_ATTENTION, 120230557Sjimharris sequence->device->unit_attention_asc, 121230557Sjimharris sequence->device->unit_attention_ascq 122230557Sjimharris ); 123230557Sjimharris return SATI_COMPLETE; 124230557Sjimharris break; 125230557Sjimharris //sending sense data status Idle, this is set by start_stop_unit 126230557Sjimharris case SATI_DEVICE_STATE_IDLE: 127230557Sjimharris sati_scsi_sense_data_construct( 128230557Sjimharris sequence, 129230557Sjimharris scsi_io, 130230557Sjimharris SCSI_STATUS_GOOD, 131230557Sjimharris SCSI_SENSE_NO_SENSE, 132230557Sjimharris SCSI_ASC_POWER_STATE_CHANGE, 133230557Sjimharris SCSI_ASCQ_IDLE_CONDITION_ACTIVATE_BY_COMMAND 134230557Sjimharris ); 135230557Sjimharris return SATI_COMPLETE; 136230557Sjimharris break; 137230557Sjimharris //sending sense data status Standby, this is set by start_stop_unit 138230557Sjimharris case SATI_DEVICE_STATE_STANDBY: 139230557Sjimharris sati_scsi_sense_data_construct( 140230557Sjimharris sequence, 141230557Sjimharris scsi_io, 142230557Sjimharris SCSI_STATUS_GOOD, 143230557Sjimharris SCSI_SENSE_NO_SENSE, 144230557Sjimharris SCSI_ASC_POWER_STATE_CHANGE, 145230557Sjimharris SCSI_ASCQ_STANDBY_CONDITION_ACTIVATE_BY_COMMAND 146230557Sjimharris ); 147230557Sjimharris return SATI_COMPLETE; 148230557Sjimharris break; 149230557Sjimharris 150230557Sjimharris case SATI_DEVICE_STATE_STOPPED: 151230557Sjimharris sati_scsi_sense_data_construct( 152230557Sjimharris sequence, 153230557Sjimharris scsi_io, 154230557Sjimharris SCSI_STATUS_GOOD, 155230557Sjimharris SCSI_SENSE_NO_SENSE, 156230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE, 157230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 158230557Sjimharris ); 159230557Sjimharris return SATI_COMPLETE; 160230557Sjimharris break; 161230557Sjimharris 162230557Sjimharris default: 163230557Sjimharris break; 164230557Sjimharris } 165230557Sjimharris 166230557Sjimharris sequence->allocation_length = sati_get_cdb_byte(cdb, 4); 167230557Sjimharris 168230557Sjimharris //Check if the device has SMART support & SMART enabled 169230557Sjimharris if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT) 170230557Sjimharris { 171230557Sjimharris if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_ENABLE) 172230557Sjimharris { 173230557Sjimharris sati_ata_smart_return_status_construct( 174230557Sjimharris ata_io, 175230557Sjimharris sequence, 176230557Sjimharris ATA_SMART_SUB_CMD_RETURN_STATUS 177230557Sjimharris ); 178230557Sjimharris 179230557Sjimharris sequence->type = SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS; 180230557Sjimharris return SATI_SUCCESS; 181230557Sjimharris } 182230557Sjimharris } 183230557Sjimharris sati_ata_check_power_mode_construct(ata_io, sequence); 184230557Sjimharris sequence->type = SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE; 185230557Sjimharris return SATI_SUCCESS; 186230557Sjimharris} 187230557Sjimharris 188230557Sjimharris/** 189230557Sjimharris * @brief This method will translate the response to the SATI Request Sense 190230557Sjimharris * translation. ATA_Check_Power_Mode and ATA_SMART_Return_Status will 191230557Sjimharris * be translated into a SCSI sense data response. 192230557Sjimharris * 193230557Sjimharris * @return SATI_STATUS Indicates if the response translation succeeded. 194230557Sjimharris * 195230557Sjimharris */ 196230557SjimharrisSATI_STATUS sati_request_sense_translate_response( 197230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 198230557Sjimharris void * scsi_io, 199230557Sjimharris void * ata_io 200230557Sjimharris) 201230557Sjimharris{ 202230557Sjimharris U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 203230557Sjimharris U32 mid_register; 204230557Sjimharris U32 high_register; 205230557Sjimharris U32 sector_count; 206230557Sjimharris SATI_STATUS status = SATI_FAILURE; 207230557Sjimharris 208230557Sjimharris if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT) 209230557Sjimharris { 210230557Sjimharris sati_scsi_sense_data_construct( 211230557Sjimharris sequence, 212230557Sjimharris scsi_io, 213230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 214230557Sjimharris SCSI_SENSE_ABORTED_COMMAND, 215230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE , 216230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 217230557Sjimharris ); 218230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 219230557Sjimharris } 220230557Sjimharris else 221230557Sjimharris { 222230557Sjimharris switch(sequence->type) 223230557Sjimharris { 224230557Sjimharris case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS: 225230557Sjimharris 226230557Sjimharris mid_register = sati_get_ata_lba_mid(register_fis); 227230557Sjimharris high_register = sati_get_ata_lba_high(register_fis); 228230557Sjimharris if(mid_register == ATA_MID_REGISTER_THRESHOLD_EXCEEDED 229230557Sjimharris && high_register == ATA_HIGH_REGISTER_THRESHOLD_EXCEEDED) 230230557Sjimharris { 231230557Sjimharris sati_request_sense_data_response_construct( 232230557Sjimharris sequence, 233230557Sjimharris scsi_io, 234230557Sjimharris SCSI_SENSE_NO_SENSE, 235230557Sjimharris SCSI_ASC_HARDWARE_IMPENDING_FAILURE, 236230557Sjimharris SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE 237230557Sjimharris ); 238230557Sjimharris status = SATI_COMPLETE; 239230557Sjimharris } 240230557Sjimharris else 241230557Sjimharris { 242230557Sjimharris sati_request_sense_data_response_construct( 243230557Sjimharris sequence, 244230557Sjimharris scsi_io, 245230557Sjimharris SCSI_SENSE_NO_SENSE, 246230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE, 247230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 248230557Sjimharris ); 249230557Sjimharris status = SATI_COMPLETE; 250230557Sjimharris } 251230557Sjimharris break; 252230557Sjimharris 253230557Sjimharris case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE: 254230557Sjimharris 255230557Sjimharris sector_count = sati_get_ata_sector_count(register_fis); 256230557Sjimharris 257230557Sjimharris switch(sector_count) 258230557Sjimharris { 259230557Sjimharris case ATA_STANDBY_POWER_MODE: 260230557Sjimharris sati_request_sense_data_response_construct( 261230557Sjimharris sequence, 262230557Sjimharris scsi_io, 263230557Sjimharris SCSI_SENSE_NO_SENSE, 264230557Sjimharris SCSI_ASC_POWER_STATE_CHANGE, 265230557Sjimharris SCSI_ASCQ_POWER_STATE_CHANGE_TO_STANDBY 266230557Sjimharris ); 267230557Sjimharris status = SATI_COMPLETE; 268230557Sjimharris break; 269230557Sjimharris 270230557Sjimharris case ATA_IDLE_POWER_MODE: 271230557Sjimharris sati_request_sense_data_response_construct( 272230557Sjimharris sequence, 273230557Sjimharris scsi_io, 274230557Sjimharris SCSI_SENSE_NO_SENSE, 275230557Sjimharris SCSI_ASC_POWER_STATE_CHANGE, 276230557Sjimharris SCSI_ASCQ_POWER_STATE_CHANGE_TO_IDLE 277230557Sjimharris ); 278230557Sjimharris status = SATI_COMPLETE; 279230557Sjimharris break; 280230557Sjimharris 281230557Sjimharris case ATA_ACTIVE_POWER_MODE: 282230557Sjimharris sati_request_sense_data_response_construct( 283230557Sjimharris sequence, 284230557Sjimharris scsi_io, 285230557Sjimharris SCSI_SENSE_NO_SENSE, 286230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE, 287230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 288230557Sjimharris ); 289230557Sjimharris status = SATI_COMPLETE; 290230557Sjimharris break; 291230557Sjimharris 292230557Sjimharris default: 293230557Sjimharris break; 294230557Sjimharris } 295230557Sjimharris break; 296230557Sjimharris 297230557Sjimharris default: 298230557Sjimharris sati_request_sense_data_response_construct( 299230557Sjimharris sequence, 300230557Sjimharris scsi_io, 301230557Sjimharris SCSI_SENSE_NO_SENSE, 302230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE, 303230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 304230557Sjimharris ); 305230557Sjimharris status = SATI_COMPLETE; 306230557Sjimharris } 307230557Sjimharris } 308230557Sjimharris 309230557Sjimharris return status; 310230557Sjimharris} 311230557Sjimharris 312230557Sjimharris/** 313230557Sjimharris * @brief This method will construct a response for the sati_request_sense 314230557Sjimharris * translation. The response will be returned in the data buffer instead 315230557Sjimharris * of the response buffer, using sense data format described in SPC-4. 316230557Sjimharris * 317230557Sjimharris */ 318230557Sjimharrisvoid sati_request_sense_data_response_construct( 319230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 320230557Sjimharris void * scsi_io, 321230557Sjimharris U8 sense_key, 322230557Sjimharris U8 additional_sense_code, 323230557Sjimharris U8 additional_sense_code_qualifier 324230557Sjimharris) 325230557Sjimharris{ 326230557Sjimharris sati_set_data_byte( 327230557Sjimharris sequence, 328230557Sjimharris scsi_io, 329230557Sjimharris 0, 330230557Sjimharris SCSI_FIXED_CURRENT_RESPONSE_CODE | SCSI_FIXED_SENSE_DATA_VALID_BIT 331230557Sjimharris ); 332230557Sjimharris 333230557Sjimharris sati_set_data_byte(sequence, scsi_io, 1, 0); 334230557Sjimharris sati_set_data_byte(sequence, scsi_io, 2, sense_key); 335230557Sjimharris sati_set_data_byte(sequence, scsi_io, 3, 0); 336230557Sjimharris sati_set_data_byte(sequence, scsi_io, 4, 0); 337230557Sjimharris sati_set_data_byte(sequence, scsi_io, 5, 0); 338230557Sjimharris sati_set_data_byte(sequence, scsi_io, 6, 0); 339230557Sjimharris sati_set_data_byte(sequence, scsi_io, 7, 0); 340230557Sjimharris sati_set_data_byte(sequence, scsi_io, 8, 0); 341230557Sjimharris sati_set_data_byte(sequence, scsi_io, 9, 0); 342230557Sjimharris sati_set_data_byte(sequence, scsi_io, 10, 0); 343230557Sjimharris sati_set_data_byte(sequence, scsi_io, 11, 0); 344230557Sjimharris sati_set_data_byte(sequence, scsi_io, 12, additional_sense_code); 345230557Sjimharris sati_set_data_byte(sequence, scsi_io, 13, additional_sense_code_qualifier); 346230557Sjimharris sati_set_data_byte(sequence, scsi_io, 14, 0); 347230557Sjimharris sati_set_data_byte(sequence, scsi_io, 15, 0); 348230557Sjimharris sati_set_data_byte(sequence, scsi_io, 16, 0); 349230557Sjimharris sati_set_data_byte(sequence, scsi_io, 17, 0); 350230557Sjimharris} 351230557Sjimharris 352230557Sjimharris#endif // !defined(DISABLE_SATI_REQUEST_SENSE) 353230557Sjimharris 354