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 method definitions to translate 59230557Sjimharris* SCSI Log Sense command based of the SATv2 spec. 60230557Sjimharris*/ 61230557Sjimharris 62230557Sjimharris#if !defined(DISABLE_SATI_LOG_SENSE) 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/sati_log_sense.h> 65230557Sjimharris#include <dev/isci/scil/sati_callbacks.h> 66230557Sjimharris#include <dev/isci/scil/sati_util.h> 67230557Sjimharris 68230557Sjimharris//****************************************************************************** 69230557Sjimharris//* P R I V A T E M E T H O D S 70230557Sjimharris//****************************************************************************** 71230557Sjimharris 72230557Sjimharris/** 73230557Sjimharris * @brief This method constructs the SATI supported log page. This is a log 74230557Sjimharris * containing the page codes of all the SATI supported log pages. 75230557Sjimharris * 76230557Sjimharris * @return n/a 77230557Sjimharris * 78230557Sjimharris */ 79230557Sjimharrisstatic 80230557Sjimharrisvoid sati_supported_log_page_construct( 81230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 82230557Sjimharris void * scsi_io 83230557Sjimharris) 84230557Sjimharris{ 85230557Sjimharris U32 next_byte; 86230557Sjimharris //set SPF = 0 and PAGE_CODE = 0 87230557Sjimharris sati_set_data_byte(sequence, scsi_io, 0, 0x00); 88230557Sjimharris 89230557Sjimharris //set SUBPAGE_CODE = 0 90230557Sjimharris sati_set_data_byte(sequence, scsi_io, 1, 0x00); 91230557Sjimharris 92230557Sjimharris //set the Page Length to (n-3) or 2 because only two log pages are supported 93230557Sjimharris sati_set_data_byte(sequence, scsi_io, 2, 0x00); 94230557Sjimharris sati_set_data_byte(sequence, scsi_io, 3, 0x02); 95230557Sjimharris 96230557Sjimharris //specify the next byte to be set 97230557Sjimharris next_byte = 4; 98230557Sjimharris 99230557Sjimharris if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT) 100230557Sjimharris { 101230557Sjimharris sati_set_data_byte( 102230557Sjimharris sequence, 103230557Sjimharris scsi_io, 104230557Sjimharris next_byte, 105230557Sjimharris SCSI_LOG_PAGE_INFORMATION_EXCEPTION 106230557Sjimharris ); 107230557Sjimharris next_byte = 5; 108230557Sjimharris } 109230557Sjimharris 110230557Sjimharris if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT) 111230557Sjimharris { 112230557Sjimharris sati_set_data_byte( 113230557Sjimharris sequence, 114230557Sjimharris scsi_io, 115230557Sjimharris next_byte, 116230557Sjimharris SCSI_LOG_PAGE_SELF_TEST 117230557Sjimharris ); 118230557Sjimharris } 119230557Sjimharris} 120230557Sjimharris 121230557Sjimharris/** 122230557Sjimharris * @brief This method sets bytes 4-19 of the self-test log parameter to zero. 123230557Sjimharris * 124230557Sjimharris * @return n/a 125230557Sjimharris * 126230557Sjimharris */ 127230557Sjimharrisstatic 128230557Sjimharrisvoid sati_set_parameters_to_zero( 129230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 130230557Sjimharris void * scsi_io 131230557Sjimharris) 132230557Sjimharris{ 133230557Sjimharris sati_set_data_byte(sequence, scsi_io, 8, 0x00); //log_parameter byte 4 134230557Sjimharris sati_set_data_byte(sequence, scsi_io, 9, 0x00); //log_parameter byte 5 135230557Sjimharris sati_set_data_byte(sequence, scsi_io, 10, 0x00); //log_parameter byte 6 136230557Sjimharris sati_set_data_byte(sequence, scsi_io, 11, 0x00); //log_parameter byte 7 137230557Sjimharris sati_set_data_byte(sequence, scsi_io, 12, 0x00); //log_parameter byte 8 138230557Sjimharris sati_set_data_byte(sequence, scsi_io, 13, 0x00); //log_parameter byte 9 139230557Sjimharris sati_set_data_byte(sequence, scsi_io, 14, 0x00); //log_parameter byte 10 140230557Sjimharris sati_set_data_byte(sequence, scsi_io, 15, 0x00); //log_parameter byte 11 141230557Sjimharris sati_set_data_byte(sequence, scsi_io, 16, 0x00); //log_parameter byte 12 142230557Sjimharris sati_set_data_byte(sequence, scsi_io, 17, 0x00); //log_parameter byte 13 143230557Sjimharris sati_set_data_byte(sequence, scsi_io, 18, 0x00); //log_parameter byte 14 144230557Sjimharris sati_set_data_byte(sequence, scsi_io, 19, 0x00); //log_parameter byte 15 145230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, 0x00); //log_parameter byte 16 146230557Sjimharris sati_set_data_byte(sequence, scsi_io, 21, 0x00); //log_parameter byte 17 147230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x00); //log_parameter byte 18 148230557Sjimharris sati_set_data_byte(sequence, scsi_io, 23, 0x00); //log_parameter byte 19 149230557Sjimharris} 150230557Sjimharris 151230557Sjimharris/** 152230557Sjimharris * @brief This method translates the ATA Extended SMART self-test log into 153230557Sjimharris * SCSI Sense Key, Additional Sense Code, and Additional Sense code 154230557Sjimharris * qualifiers based on the self test status byte in the appropriate 155230557Sjimharris * descriptor entry. 156230557Sjimharris * 157230557Sjimharris * @return n/a 158230557Sjimharris * 159230557Sjimharris */ 160230557Sjimharrisstatic 161230557Sjimharrisvoid sati_translate_sense_values( 162230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 163230557Sjimharris void * scsi_io, 164230557Sjimharris U8 self_test_status_byte 165230557Sjimharris) 166230557Sjimharris{ 167230557Sjimharris //byte 17 168230557Sjimharris sati_set_data_byte( 169230557Sjimharris sequence, 170230557Sjimharris scsi_io, 171230557Sjimharris 21, 172230557Sjimharris SCSI_DIAGNOSTIC_FAILURE_ON_COMPONENT 173230557Sjimharris ); 174230557Sjimharris 175230557Sjimharris switch(self_test_status_byte) 176230557Sjimharris { 177230557Sjimharris case 1: 178230557Sjimharris //byte 16 179230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND); 180230557Sjimharris 181230557Sjimharris //byte 18 182230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x81); 183230557Sjimharris break; 184230557Sjimharris 185230557Sjimharris case 2: 186230557Sjimharris //byte 16 187230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND); 188230557Sjimharris 189230557Sjimharris //byte 18 190230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x82); 191230557Sjimharris break; 192230557Sjimharris 193230557Sjimharris case 3: 194230557Sjimharris //byte 16 195230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND); 196230557Sjimharris 197230557Sjimharris //byte 18 198230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x83); 199230557Sjimharris break; 200230557Sjimharris 201230557Sjimharris case 4: 202230557Sjimharris //byte 16 203230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR); 204230557Sjimharris 205230557Sjimharris //byte 18 206230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x84); 207230557Sjimharris break; 208230557Sjimharris 209230557Sjimharris case 5: 210230557Sjimharris //byte 16 211230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR); 212230557Sjimharris 213230557Sjimharris //byte 18 214230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x85); 215230557Sjimharris break; 216230557Sjimharris 217230557Sjimharris case 6: 218230557Sjimharris //byte 16 219230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR); 220230557Sjimharris 221230557Sjimharris //byte 18 222230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x86); 223230557Sjimharris break; 224230557Sjimharris 225230557Sjimharris case 7: 226230557Sjimharris //byte 16 227230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_MEDIUM_ERROR); 228230557Sjimharris 229230557Sjimharris //byte 18 230230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x87); 231230557Sjimharris break; 232230557Sjimharris 233230557Sjimharris case 8: 234230557Sjimharris //byte 16 235230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR); 236230557Sjimharris 237230557Sjimharris //byte 18 238230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x88); 239230557Sjimharris break; 240230557Sjimharris 241230557Sjimharris default: 242230557Sjimharris //byte 16 243230557Sjimharris sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_NO_SENSE); 244230557Sjimharris //byte 17 245230557Sjimharris sati_set_data_byte(sequence, scsi_io, 21, SCSI_ASC_NO_ADDITIONAL_SENSE); 246230557Sjimharris //byte 18 247230557Sjimharris sati_set_data_byte(sequence, scsi_io, 22, 0x00); 248230557Sjimharris break; 249230557Sjimharris } 250230557Sjimharris 251230557Sjimharris} 252230557Sjimharris 253230557Sjimharris/** 254230557Sjimharris * @brief This method retrieves the correct self-test results by checking the 255230557Sjimharris * descriptor index in the extended SMART self-test log. The index is 256230557Sjimharris * used to determine the appropriate descriptor entry. 257230557Sjimharris * 258230557Sjimharris * @return n/a 259230557Sjimharris * 260230557Sjimharris */ 261230557Sjimharrisstatic 262230557Sjimharrisvoid sati_get_self_test_results( 263230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 264230557Sjimharris void * scsi_io, 265230557Sjimharris ATA_EXTENDED_SMART_SELF_TEST_LOG_T * ata_log 266230557Sjimharris) 267230557Sjimharris{ 268230557Sjimharris U16 descriptor_index = *((U16 *)(&ata_log->self_test_descriptor_index[0])); 269230557Sjimharris 270230557Sjimharris /* 271230557Sjimharris * SATv2 wants data from descriptor N where N is equal to 272230557Sjimharris * (descriptor_index - parameter_code) + 1. Since parameter 273230557Sjimharris * code is always 0x0001 just checking descriptor_index. 274230557Sjimharris */ 275230557Sjimharris 276230557Sjimharris if(descriptor_index <= 0) 277230557Sjimharris { 278230557Sjimharris sati_set_parameters_to_zero(sequence, scsi_io); 279230557Sjimharris } 280230557Sjimharris else 281230557Sjimharris { 282230557Sjimharris sati_set_data_byte( 283230557Sjimharris sequence, 284230557Sjimharris scsi_io, 285230557Sjimharris 8, 286230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.status_byte 287230557Sjimharris ); 288230557Sjimharris 289230557Sjimharris //Sef-test number unspecified per satv2 290230557Sjimharris sati_set_data_byte(sequence, scsi_io, 9, 0x00); 291230557Sjimharris sati_set_data_byte( 292230557Sjimharris sequence, 293230557Sjimharris scsi_io, 294230557Sjimharris 10, 295230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.time_stamp_high 296230557Sjimharris ); 297230557Sjimharris 298230557Sjimharris sati_set_data_byte( 299230557Sjimharris sequence, 300230557Sjimharris scsi_io, 301230557Sjimharris 11, 302230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.time_stamp_low 303230557Sjimharris ); 304230557Sjimharris 305230557Sjimharris //set to zero because it's a 48bit address 306230557Sjimharris sati_set_data_byte(sequence, scsi_io, 12, 0x00); 307230557Sjimharris sati_set_data_byte(sequence, scsi_io, 13, 0x00); 308230557Sjimharris 309230557Sjimharris sati_set_data_byte( 310230557Sjimharris sequence, 311230557Sjimharris scsi_io, 312230557Sjimharris 14, 313230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_high_ext 314230557Sjimharris ); 315230557Sjimharris 316230557Sjimharris sati_set_data_byte( 317230557Sjimharris sequence, 318230557Sjimharris scsi_io, 319230557Sjimharris 15, 320230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_mid_ext 321230557Sjimharris ); 322230557Sjimharris 323230557Sjimharris sati_set_data_byte( 324230557Sjimharris sequence, 325230557Sjimharris scsi_io, 326230557Sjimharris 16, 327230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_low_ext 328230557Sjimharris ); 329230557Sjimharris 330230557Sjimharris sati_set_data_byte( 331230557Sjimharris sequence, 332230557Sjimharris scsi_io, 333230557Sjimharris 17, 334230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_high 335230557Sjimharris ); 336230557Sjimharris 337230557Sjimharris sati_set_data_byte( 338230557Sjimharris sequence, 339230557Sjimharris scsi_io, 340230557Sjimharris 18, 341230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_mid 342230557Sjimharris ); 343230557Sjimharris 344230557Sjimharris sati_set_data_byte( 345230557Sjimharris sequence, 346230557Sjimharris scsi_io, 347230557Sjimharris 19, 348230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_low 349230557Sjimharris ); 350230557Sjimharris 351230557Sjimharris sati_translate_sense_values( 352230557Sjimharris sequence, 353230557Sjimharris scsi_io, 354230557Sjimharris ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.status_byte 355230557Sjimharris ); 356230557Sjimharris } 357230557Sjimharris} 358230557Sjimharris 359230557Sjimharris/** 360230557Sjimharris* @brief This method will construct the first eight bytes of the SCSI self test 361230557Sjimharris* log page for both cases when SATI sends a ATA read log ext and a smart 362230557Sjimharris* read log command. 363230557Sjimharris* 364230557Sjimharris* @return n/a 365230557Sjimharris* 366230557Sjimharris*/ 367230557Sjimharrisstatic 368230557Sjimharrisvoid sati_self_test_log_header_construct( 369230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 370230557Sjimharris void * scsi_io 371230557Sjimharris) 372230557Sjimharris{ 373230557Sjimharris //PAGE CODE for Self-Test Log Page 374230557Sjimharris sati_set_data_byte(sequence, scsi_io, 0, 0x10); 375230557Sjimharris sati_set_data_byte(sequence, scsi_io, 1, 0x00); 376230557Sjimharris 377230557Sjimharris //PAGE LENGTH is 0x14 instead of 0x190, not returning 20/0x190 log perameters 378230557Sjimharris sati_set_data_byte(sequence, scsi_io, 2, 0x00); 379230557Sjimharris sati_set_data_byte(sequence, scsi_io, 3, 0x14); 380230557Sjimharris 381230557Sjimharris /* 382230557Sjimharris * Log PARAMETER 0x0001 383230557Sjimharris * Only sending one log parameter per self-test request. 384230557Sjimharris */ 385230557Sjimharris sati_set_data_byte(sequence, scsi_io, 4, 0x00); //log_parameter byte 0 386230557Sjimharris sati_set_data_byte(sequence, scsi_io, 5, 0x01); //log_parameter byte 1 387230557Sjimharris 388230557Sjimharris //Set to 0x03 per SATv2 spec 389230557Sjimharris sati_set_data_byte(sequence, scsi_io, 6, 0x03); //log_parameter byte 2 390230557Sjimharris 391230557Sjimharris //Parameter Length set to 0x10 per SATv2 spec 392230557Sjimharris sati_set_data_byte(sequence, scsi_io, 7, 0x10); //log_parameter byte 3 393230557Sjimharris} 394230557Sjimharris 395230557Sjimharris/** 396230557Sjimharris * @brief This method will construct the SCSI self test log page from 397230557Sjimharris * the Extended SMART self-test log response recieved from the 398230557Sjimharris * ATA device. The response is from a ATA_Read_Log_EXT command 399230557Sjimharris * issued by SATI. 400230557Sjimharris * 401230557Sjimharris * @return n/a 402230557Sjimharris * 403230557Sjimharris */ 404230557Sjimharrisstatic 405230557Sjimharrisvoid sati_extended_self_test_log_page_construct( 406230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 407230557Sjimharris void * scsi_io, 408230557Sjimharris void * ata_data 409230557Sjimharris) 410230557Sjimharris{ 411230557Sjimharris ATA_EXTENDED_SMART_SELF_TEST_LOG_T * ata_log = 412230557Sjimharris (ATA_EXTENDED_SMART_SELF_TEST_LOG_T*) ata_data; 413230557Sjimharris 414230557Sjimharris sati_self_test_log_header_construct(sequence, scsi_io); 415230557Sjimharris 416230557Sjimharris //bytes 4-19 417230557Sjimharris if( (ata_log->self_test_descriptor_index[0] == 0) && 418230557Sjimharris (ata_log->self_test_descriptor_index[1] == 0)) 419230557Sjimharris { 420230557Sjimharris sati_set_parameters_to_zero(sequence, scsi_io); 421230557Sjimharris } 422230557Sjimharris else 423230557Sjimharris { 424230557Sjimharris sati_get_self_test_results(sequence, scsi_io, ata_log); 425230557Sjimharris } 426230557Sjimharris} 427230557Sjimharris 428230557Sjimharris/** 429230557Sjimharris* @brief This method will construct the SCSI self test log page from 430230557Sjimharris* the SMART self-test log response recieved from the ATA device. 431230557Sjimharris* The response is from a ATA_SMART_Read_Log command issued by SATI. 432230557Sjimharris* 433230557Sjimharris* @return n/a 434230557Sjimharris* 435230557Sjimharris*/ 436230557Sjimharrisstatic 437230557Sjimharrisvoid sati_self_test_log_page_construct( 438230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 439230557Sjimharris void * scsi_io, 440230557Sjimharris void * ata_data 441230557Sjimharris) 442230557Sjimharris{ 443230557Sjimharris ATA_SMART_SELF_TEST_LOG_T * ata_log = 444230557Sjimharris (ATA_SMART_SELF_TEST_LOG_T*) ata_data; 445230557Sjimharris 446230557Sjimharris sati_self_test_log_header_construct(sequence, scsi_io); 447230557Sjimharris 448230557Sjimharris //first descriptor entry(index == 0) is always used because scsi_parameter_code == 1 449230557Sjimharris sati_set_data_byte( 450230557Sjimharris sequence, 451230557Sjimharris scsi_io, 452230557Sjimharris 8, 453230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.status_byte 454230557Sjimharris ); 455230557Sjimharris 456230557Sjimharris //Sef-test number unspecified per satv2 457230557Sjimharris sati_set_data_byte(sequence, scsi_io, 9, 0x00); 458230557Sjimharris 459230557Sjimharris sati_set_data_byte( 460230557Sjimharris sequence, 461230557Sjimharris scsi_io, 462230557Sjimharris 10, 463230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.time_stamp_high 464230557Sjimharris ); 465230557Sjimharris 466230557Sjimharris sati_set_data_byte( 467230557Sjimharris sequence, 468230557Sjimharris scsi_io, 469230557Sjimharris 11, 470230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.time_stamp_low 471230557Sjimharris ); 472230557Sjimharris 473230557Sjimharris //set to zero because it's a 28bit address 474230557Sjimharris sati_set_data_byte(sequence, scsi_io, 12, 0x00); 475230557Sjimharris sati_set_data_byte(sequence, scsi_io, 13, 0x00); 476230557Sjimharris sati_set_data_byte(sequence, scsi_io, 14, 0x00); 477230557Sjimharris sati_set_data_byte(sequence, scsi_io, 15, 0x00); 478230557Sjimharris 479230557Sjimharris sati_set_data_byte( 480230557Sjimharris sequence, 481230557Sjimharris scsi_io, 482230557Sjimharris 16, 483230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_low_ext 484230557Sjimharris ); 485230557Sjimharris 486230557Sjimharris sati_set_data_byte( 487230557Sjimharris sequence, 488230557Sjimharris scsi_io, 489230557Sjimharris 17, 490230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_high 491230557Sjimharris ); 492230557Sjimharris 493230557Sjimharris sati_set_data_byte( 494230557Sjimharris sequence, 495230557Sjimharris scsi_io, 496230557Sjimharris 18, 497230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_mid 498230557Sjimharris ); 499230557Sjimharris 500230557Sjimharris sati_set_data_byte( 501230557Sjimharris sequence, 502230557Sjimharris scsi_io, 503230557Sjimharris 19, 504230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_low 505230557Sjimharris ); 506230557Sjimharris 507230557Sjimharris sati_translate_sense_values( 508230557Sjimharris sequence, 509230557Sjimharris scsi_io, 510230557Sjimharris ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.status_byte 511230557Sjimharris ); 512230557Sjimharris} 513230557Sjimharris 514230557Sjimharris/** 515230557Sjimharris* @brief This method will construct the SCSI information exception log page from 516230557Sjimharris* the ATA SMART response recieved from the ATA device. The response is 517230557Sjimharris* from a ATA SMART return status command issued by SATI. 518230557Sjimharris* 519230557Sjimharris* @return n/a 520230557Sjimharris* 521230557Sjimharris*/ 522230557Sjimharrisstatic 523230557Sjimharrisvoid sati_information_exception_log_page_contruct( 524230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 525230557Sjimharris void * scsi_io, 526230557Sjimharris void * ata_io 527230557Sjimharris) 528230557Sjimharris{ 529230557Sjimharris U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 530230557Sjimharris U32 mid_register = sati_get_ata_lba_mid(register_fis); 531230557Sjimharris U32 high_register = sati_get_ata_lba_high(register_fis); 532230557Sjimharris 533230557Sjimharris //Information Exception Page code 534230557Sjimharris sati_set_data_byte( 535230557Sjimharris sequence, 536230557Sjimharris scsi_io, 537230557Sjimharris 0, 538230557Sjimharris SCSI_LOG_PAGE_INFORMATION_EXCEPTION 539230557Sjimharris ); 540230557Sjimharris 541230557Sjimharris //Sub-page code 542230557Sjimharris sati_set_data_byte(sequence, scsi_io, 1, 0x00); 543230557Sjimharris 544230557Sjimharris //Page length of log parameters 545230557Sjimharris sati_set_data_byte(sequence, scsi_io, 2, 0x00); 546230557Sjimharris sati_set_data_byte(sequence, scsi_io, 3, 0x08); 547230557Sjimharris 548230557Sjimharris //parameter code 549230557Sjimharris sati_set_data_byte(sequence, scsi_io, 4, 0x00); 550230557Sjimharris sati_set_data_byte(sequence, scsi_io, 5, 0x00); 551230557Sjimharris 552230557Sjimharris //Format and Linking 553230557Sjimharris sati_set_data_byte(sequence, scsi_io, 6, 0x03); 554230557Sjimharris //Parameter Length 555230557Sjimharris sati_set_data_byte(sequence, scsi_io, 7, 0x04); 556230557Sjimharris 557230557Sjimharris if(mid_register == ATA_MID_REGISTER_THRESHOLD_EXCEEDED 558230557Sjimharris && high_register == ATA_HIGH_REGISTER_THRESHOLD_EXCEEDED) 559230557Sjimharris { 560230557Sjimharris sati_set_data_byte( 561230557Sjimharris sequence, 562230557Sjimharris scsi_io, 563230557Sjimharris 8, 564230557Sjimharris SCSI_ASC_HARDWARE_IMPENDING_FAILURE 565230557Sjimharris ); 566230557Sjimharris 567230557Sjimharris sati_set_data_byte( 568230557Sjimharris sequence, 569230557Sjimharris scsi_io, 570230557Sjimharris 9, 571230557Sjimharris SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE 572230557Sjimharris ); 573230557Sjimharris } 574230557Sjimharris else 575230557Sjimharris { 576230557Sjimharris sati_set_data_byte(sequence, scsi_io, 8, SCSI_ASC_NO_ADDITIONAL_SENSE); 577230557Sjimharris sati_set_data_byte(sequence, scsi_io, 9, SCSI_ASCQ_NO_ADDITIONAL_SENSE); 578230557Sjimharris } 579230557Sjimharris //setting most recent temperature reading to 0xFF(not supported) for now. 580230557Sjimharris sati_set_data_byte(sequence, scsi_io, 10, 0xFF); 581230557Sjimharris} 582230557Sjimharris 583230557Sjimharris//****************************************************************************** 584230557Sjimharris//* P U B L I C M E T H O D S 585230557Sjimharris//****************************************************************************** 586230557Sjimharris 587230557Sjimharris/** 588230557Sjimharris * @brief This method will translate the SCSI Log Sense command into ATA commands 589230557Sjimharris * specified by SATv2. ATA commands Read Log EXT and SMART Read Log will 590230557Sjimharris * be issued by this translation. 591230557Sjimharris * 592230557Sjimharris * @return SATI_STATUS Indicates if the command translation succeeded. 593230557Sjimharris * 594230557Sjimharris */ 595230557SjimharrisSATI_STATUS sati_log_sense_translate_command( 596230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 597230557Sjimharris void * scsi_io, 598230557Sjimharris void * ata_io 599230557Sjimharris) 600230557Sjimharris{ 601230557Sjimharris U8 * cdb = sati_cb_get_cdb_address(scsi_io); 602230557Sjimharris SATI_STATUS status = SATI_FAILURE; 603230557Sjimharris 604230557Sjimharris if(SATI_LOG_SENSE_GET_PC_FIELD(cdb) == 1 && 605230557Sjimharris (sati_get_cdb_byte(cdb, 3) == 0)) 606230557Sjimharris { 607230557Sjimharris sequence->allocation_length = (sati_get_cdb_byte(cdb, 7) << 8) | 608230557Sjimharris (sati_get_cdb_byte(cdb, 8)); 609230557Sjimharris 610230557Sjimharris switch(SATI_LOG_SENSE_GET_PAGE_CODE(cdb)) 611230557Sjimharris { 612230557Sjimharris //Return Supported Log Pages log page 613230557Sjimharris case SCSI_LOG_PAGE_SUPPORTED_PAGES : 614230557Sjimharris sati_supported_log_page_construct(sequence, scsi_io); 615230557Sjimharris sequence->type = SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE; 616230557Sjimharris status = SATI_COMPLETE; 617230557Sjimharris break; 618230557Sjimharris 619230557Sjimharris //Return Self-Test Results log page 620230557Sjimharris case SCSI_LOG_PAGE_SELF_TEST : 621230557Sjimharris 622230557Sjimharris if((sequence->device->capabilities & 623230557Sjimharris SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT) == 0) 624230557Sjimharris { 625230557Sjimharris sati_scsi_sense_data_construct( 626230557Sjimharris sequence, 627230557Sjimharris scsi_io, 628230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 629230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 630230557Sjimharris SCSI_ASC_INVALID_FIELD_IN_CDB, 631230557Sjimharris SCSI_ASCQ_INVALID_FIELD_IN_CDB 632230557Sjimharris ); 633230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 634230557Sjimharris } 635230557Sjimharris else 636230557Sjimharris { 637230557Sjimharris //check if 48-bit Address feature set is supported 638230557Sjimharris if((sequence->device->capabilities & 639230557Sjimharris SATI_DEVICE_CAP_48BIT_ENABLE)) 640230557Sjimharris { 641230557Sjimharris //ATA Read Log Ext with log address set to 0x07 642230557Sjimharris sati_ata_read_log_ext_construct( 643230557Sjimharris ata_io, 644230557Sjimharris sequence, 645230557Sjimharris ATA_LOG_PAGE_EXTENDED_SMART_SELF_TEST, 646230557Sjimharris sizeof(ATA_EXTENDED_SMART_SELF_TEST_LOG_T) 647230557Sjimharris ); 648230557Sjimharris sequence->type = 649230557Sjimharris SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE; 650230557Sjimharris status = SATI_SUCCESS; 651230557Sjimharris } 652230557Sjimharris else 653230557Sjimharris { 654230557Sjimharris //ATA Smart Read Log with log address set to 0x06 655230557Sjimharris sati_ata_smart_read_log_construct( 656230557Sjimharris ata_io, 657230557Sjimharris sequence, 658230557Sjimharris ATA_LOG_PAGE_SMART_SELF_TEST, 659230557Sjimharris sizeof(ATA_SMART_SELF_TEST_LOG_T) 660230557Sjimharris ); 661230557Sjimharris sequence->type = SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE; 662230557Sjimharris status = SATI_SUCCESS; 663230557Sjimharris } 664230557Sjimharris } 665230557Sjimharris break; 666230557Sjimharris 667230557Sjimharris //Return Informational Exceptions log page 668230557Sjimharris case SCSI_LOG_PAGE_INFORMATION_EXCEPTION : 669230557Sjimharris if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT) 670230557Sjimharris { 671230557Sjimharris if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_ENABLE) 672230557Sjimharris { 673230557Sjimharris sati_ata_smart_return_status_construct( 674230557Sjimharris ata_io, 675230557Sjimharris sequence, 676230557Sjimharris ATA_SMART_SUB_CMD_RETURN_STATUS 677230557Sjimharris ); 678230557Sjimharris sequence->type = 679230557Sjimharris SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE; 680230557Sjimharris status = SATI_SUCCESS; 681230557Sjimharris } 682230557Sjimharris else 683230557Sjimharris { 684230557Sjimharris sati_scsi_sense_data_construct( 685230557Sjimharris sequence, 686230557Sjimharris scsi_io, 687230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 688230557Sjimharris SCSI_SENSE_ABORTED_COMMAND, 689230557Sjimharris SCSI_ASC_ATA_DEVICE_FEATURE_NOT_ENABLED, 690230557Sjimharris SCSI_ASCQ_ATA_DEVICE_FEATURE_NOT_ENABLED 691230557Sjimharris ); 692230557Sjimharris 693230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 694230557Sjimharris } 695230557Sjimharris } 696230557Sjimharris else 697230557Sjimharris { 698230557Sjimharris sati_scsi_sense_data_construct( 699230557Sjimharris sequence, 700230557Sjimharris scsi_io, 701230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 702230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 703230557Sjimharris SCSI_ASC_INVALID_FIELD_IN_CDB, 704230557Sjimharris SCSI_ASCQ_INVALID_FIELD_IN_CDB 705230557Sjimharris ); 706230557Sjimharris 707230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 708230557Sjimharris } 709230557Sjimharris break; 710230557Sjimharris default : 711230557Sjimharris //UNSPECIFIED SATv2r9 712230557Sjimharris sati_scsi_sense_data_construct( 713230557Sjimharris sequence, 714230557Sjimharris scsi_io, 715230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 716230557Sjimharris SCSI_SENSE_ILLEGAL_REQUEST, 717230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE , 718230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 719230557Sjimharris ); 720230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 721230557Sjimharris break; 722230557Sjimharris } 723230557Sjimharris } 724230557Sjimharris return status; 725230557Sjimharris} 726230557Sjimharris 727230557Sjimharris/** 728230557Sjimharris * @brief This method will translate the response to the SATI Log Sense 729230557Sjimharris * translation. ATA command responses will be translated into the 730230557Sjimharris * correct SCSI log pages to be returned by SATI. 731230557Sjimharris * 732230557Sjimharris * @return SATI_STATUS Indicates if the response translation succeeded. 733230557Sjimharris * 734230557Sjimharris */ 735230557SjimharrisSATI_STATUS sati_log_sense_translate_response( 736230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 737230557Sjimharris void * scsi_io, 738230557Sjimharris void * ata_io 739230557Sjimharris) 740230557Sjimharris{ 741230557Sjimharris U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io); 742230557Sjimharris SATI_STATUS status = SATI_FAILURE; 743230557Sjimharris 744230557Sjimharris if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT) 745230557Sjimharris { 746230557Sjimharris sati_scsi_sense_data_construct( 747230557Sjimharris sequence, 748230557Sjimharris scsi_io, 749230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 750230557Sjimharris SCSI_SENSE_ABORTED_COMMAND, 751230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE , 752230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 753230557Sjimharris ); 754230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 755230557Sjimharris } 756230557Sjimharris else 757230557Sjimharris { 758230557Sjimharris 759230557Sjimharris void * ata_data = sati_cb_get_ata_data_address(ata_io); 760230557Sjimharris 761230557Sjimharris if(ata_data == NULL) 762230557Sjimharris { 763230557Sjimharris return SATI_FAILURE; 764230557Sjimharris } 765230557Sjimharris 766230557Sjimharris switch(sequence->type) 767230557Sjimharris { 768230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE: 769230557Sjimharris sati_extended_self_test_log_page_construct( 770230557Sjimharris sequence, scsi_io, ata_data 771230557Sjimharris ); 772230557Sjimharris 773230557Sjimharris status = SATI_COMPLETE; 774230557Sjimharris break; 775230557Sjimharris 776230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE: 777230557Sjimharris sati_self_test_log_page_construct(sequence, scsi_io, ata_data); 778230557Sjimharris status = SATI_COMPLETE; 779230557Sjimharris break; 780230557Sjimharris 781230557Sjimharris case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE: 782230557Sjimharris //This function needs a d->h register fis, not ata data 783230557Sjimharris sati_information_exception_log_page_contruct( 784230557Sjimharris sequence, scsi_io, ata_io 785230557Sjimharris ); 786230557Sjimharris 787230557Sjimharris status = SATI_COMPLETE; 788230557Sjimharris break; 789230557Sjimharris 790230557Sjimharris default: 791230557Sjimharris sati_scsi_sense_data_construct( 792230557Sjimharris sequence, 793230557Sjimharris scsi_io, 794230557Sjimharris SCSI_STATUS_CHECK_CONDITION, 795230557Sjimharris SCSI_SENSE_ABORTED_COMMAND, 796230557Sjimharris SCSI_ASC_NO_ADDITIONAL_SENSE , 797230557Sjimharris SCSI_ASCQ_NO_ADDITIONAL_SENSE 798230557Sjimharris ); 799230557Sjimharris status = SATI_FAILURE_CHECK_RESPONSE_DATA; 800230557Sjimharris break; 801230557Sjimharris } 802230557Sjimharris } 803230557Sjimharris return status; 804230557Sjimharris} 805230557Sjimharris 806230557Sjimharris#endif // !defined(DISABLE_SATI_LOG_SENSE) 807230557Sjimharris 808