The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/isci/scil/sati_log_sense.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
    3  *
    4  * This file is provided under a dual BSD/GPLv2 license.  When using or
    5  * redistributing this file, you may do so under either license.
    6  *
    7  * GPL LICENSE SUMMARY
    8  *
    9  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
   10  *
   11  * This program is free software; you can redistribute it and/or modify
   12  * it under the terms of version 2 of the GNU General Public License as
   13  * published by the Free Software Foundation.
   14  *
   15  * This program is distributed in the hope that it will be useful, but
   16  * WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18  * General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License
   21  * along with this program; if not, write to the Free Software
   22  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
   23  * The full GNU General Public License is included in this distribution
   24  * in the file called LICENSE.GPL.
   25  *
   26  * BSD LICENSE
   27  *
   28  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
   29  * All rights reserved.
   30  *
   31  * Redistribution and use in source and binary forms, with or without
   32  * modification, are permitted provided that the following conditions
   33  * are met:
   34  *
   35  *   * Redistributions of source code must retain the above copyright
   36  *     notice, this list of conditions and the following disclaimer.
   37  *   * Redistributions in binary form must reproduce the above copyright
   38  *     notice, this list of conditions and the following disclaimer in
   39  *     the documentation and/or other materials provided with the
   40  *     distribution.
   41  *
   42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   45  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   46  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   47  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   48  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   49  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   50  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   51  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   52  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   53  */
   54 
   55 #include <sys/cdefs.h>
   56 __FBSDID("$FreeBSD$");
   57 
   58 /**
   59 * @file
   60 * @brief This file contains the method definitions to translate
   61 *        SCSI Log Sense command based of the SATv2 spec.
   62 */
   63 
   64 #if !defined(DISABLE_SATI_LOG_SENSE)
   65 
   66 #include <dev/isci/scil/sati_log_sense.h>
   67 #include <dev/isci/scil/sati_callbacks.h>
   68 #include <dev/isci/scil/sati_util.h>
   69 
   70 //******************************************************************************
   71 //* P R I V A T E   M E T H O D S
   72 //******************************************************************************
   73 
   74 /**
   75  * @brief This method constructs the SATI supported log page. This is a log
   76  *        containing the page codes of all the SATI supported log pages.
   77  *
   78  * @return n/a
   79  *
   80  */
   81 static
   82 void sati_supported_log_page_construct(
   83    SATI_TRANSLATOR_SEQUENCE_T  * sequence,
   84    void                        * scsi_io
   85 )
   86 {
   87    U32 next_byte;
   88    //set SPF = 0 and PAGE_CODE = 0
   89    sati_set_data_byte(sequence, scsi_io, 0, 0x00);
   90 
   91    //set SUBPAGE_CODE = 0
   92    sati_set_data_byte(sequence, scsi_io, 1, 0x00);
   93 
   94    //set the Page Length to (n-3) or 2 because only two log pages are supported
   95    sati_set_data_byte(sequence, scsi_io, 2, 0x00);
   96    sati_set_data_byte(sequence, scsi_io, 3, 0x02);
   97 
   98    //specify the next byte to be set
   99    next_byte = 4;
  100 
  101    if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT)
  102    {
  103       sati_set_data_byte(
  104          sequence,
  105          scsi_io,
  106          next_byte,
  107          SCSI_LOG_PAGE_INFORMATION_EXCEPTION
  108       );
  109       next_byte = 5;
  110    }
  111 
  112    if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT)
  113    {
  114       sati_set_data_byte(
  115          sequence,
  116          scsi_io,
  117          next_byte,
  118          SCSI_LOG_PAGE_SELF_TEST
  119       );
  120    }
  121 }
  122 
  123 /**
  124  * @brief This method sets bytes 4-19 of the self-test log parameter to zero.
  125  *
  126  * @return n/a
  127  *
  128  */
  129 static
  130 void sati_set_parameters_to_zero(
  131    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  132    void                       * scsi_io
  133 )
  134 {
  135       sati_set_data_byte(sequence, scsi_io, 8, 0x00);   //log_parameter byte 4
  136       sati_set_data_byte(sequence, scsi_io, 9, 0x00);   //log_parameter byte 5
  137       sati_set_data_byte(sequence, scsi_io, 10, 0x00);  //log_parameter byte 6
  138       sati_set_data_byte(sequence, scsi_io, 11, 0x00);  //log_parameter byte 7
  139       sati_set_data_byte(sequence, scsi_io, 12, 0x00);  //log_parameter byte 8
  140       sati_set_data_byte(sequence, scsi_io, 13, 0x00);  //log_parameter byte 9
  141       sati_set_data_byte(sequence, scsi_io, 14, 0x00);  //log_parameter byte 10
  142       sati_set_data_byte(sequence, scsi_io, 15, 0x00);  //log_parameter byte 11
  143       sati_set_data_byte(sequence, scsi_io, 16, 0x00);  //log_parameter byte 12
  144       sati_set_data_byte(sequence, scsi_io, 17, 0x00);  //log_parameter byte 13
  145       sati_set_data_byte(sequence, scsi_io, 18, 0x00);  //log_parameter byte 14
  146       sati_set_data_byte(sequence, scsi_io, 19, 0x00);  //log_parameter byte 15
  147       sati_set_data_byte(sequence, scsi_io, 20, 0x00);  //log_parameter byte 16
  148       sati_set_data_byte(sequence, scsi_io, 21, 0x00);  //log_parameter byte 17
  149       sati_set_data_byte(sequence, scsi_io, 22, 0x00);  //log_parameter byte 18
  150       sati_set_data_byte(sequence, scsi_io, 23, 0x00);  //log_parameter byte 19
  151 }
  152 
  153 /**
  154  * @brief This method translates the ATA Extended SMART self-test log into
  155  *        SCSI Sense Key, Additional Sense Code, and Additional Sense code
  156  *        qualifiers based on the self test status byte in the appropriate
  157  *        descriptor entry.
  158  *
  159  * @return n/a
  160  *
  161  */
  162 static
  163 void sati_translate_sense_values(
  164    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  165    void                       * scsi_io,
  166    U8                           self_test_status_byte
  167 )
  168 {
  169    //byte 17
  170    sati_set_data_byte(
  171       sequence,
  172       scsi_io,
  173       21,
  174       SCSI_DIAGNOSTIC_FAILURE_ON_COMPONENT
  175    );
  176 
  177    switch(self_test_status_byte)
  178    {
  179       case 1:
  180          //byte 16
  181          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND);
  182 
  183          //byte 18
  184          sati_set_data_byte(sequence, scsi_io, 22, 0x81);
  185          break;
  186 
  187       case 2:
  188          //byte 16
  189          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND);
  190 
  191          //byte 18
  192          sati_set_data_byte(sequence, scsi_io, 22, 0x82);
  193          break;
  194 
  195       case 3:
  196          //byte 16
  197          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_ABORTED_COMMAND);
  198 
  199          //byte 18
  200          sati_set_data_byte(sequence, scsi_io, 22, 0x83);
  201          break;
  202 
  203       case 4:
  204          //byte 16
  205          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
  206 
  207          //byte 18
  208          sati_set_data_byte(sequence, scsi_io, 22, 0x84);
  209          break;
  210 
  211       case 5:
  212          //byte 16
  213          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
  214 
  215          //byte 18
  216          sati_set_data_byte(sequence, scsi_io, 22, 0x85);
  217          break;
  218 
  219       case 6:
  220          //byte 16
  221          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
  222 
  223          //byte 18
  224          sati_set_data_byte(sequence, scsi_io, 22, 0x86);
  225          break;
  226 
  227       case 7:
  228          //byte 16
  229          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_MEDIUM_ERROR);
  230 
  231          //byte 18
  232          sati_set_data_byte(sequence, scsi_io, 22, 0x87);
  233          break;
  234 
  235       case 8:
  236          //byte 16
  237          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_HARDWARE_ERROR);
  238 
  239          //byte 18
  240          sati_set_data_byte(sequence, scsi_io, 22, 0x88);
  241          break;
  242 
  243       default:
  244          //byte 16
  245          sati_set_data_byte(sequence, scsi_io, 20, SCSI_SENSE_NO_SENSE);
  246          //byte 17
  247          sati_set_data_byte(sequence, scsi_io, 21, SCSI_ASC_NO_ADDITIONAL_SENSE);
  248          //byte 18
  249          sati_set_data_byte(sequence, scsi_io, 22, 0x00);
  250          break;
  251    }
  252 
  253 }
  254 
  255 /**
  256  * @brief This method retrieves the correct self-test results by checking the
  257  *        descriptor index in the extended SMART self-test log. The index is
  258  *        used to determine the appropriate descriptor entry.
  259  *
  260  * @return n/a
  261  *
  262  */
  263 static
  264 void sati_get_self_test_results(
  265    SATI_TRANSLATOR_SEQUENCE_T          * sequence,
  266    void                                * scsi_io,
  267    ATA_EXTENDED_SMART_SELF_TEST_LOG_T  * ata_log
  268 )
  269 {
  270    U16 descriptor_index = *((U16 *)(&ata_log->self_test_descriptor_index[0]));
  271 
  272    /*
  273     * SATv2 wants data from descriptor N where N is equal to
  274     * (descriptor_index - parameter_code) + 1. Since parameter
  275     * code is always 0x0001 just checking descriptor_index.
  276     */
  277 
  278    if(descriptor_index <= 0)
  279    {
  280       sati_set_parameters_to_zero(sequence, scsi_io);
  281    }
  282    else
  283    {
  284       sati_set_data_byte(
  285        sequence,
  286        scsi_io,
  287        8,
  288        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.status_byte
  289       );
  290 
  291       //Sef-test number unspecified per satv2
  292       sati_set_data_byte(sequence, scsi_io, 9, 0x00);
  293       sati_set_data_byte(
  294        sequence,
  295        scsi_io,
  296        10,
  297        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.time_stamp_high
  298       );
  299 
  300       sati_set_data_byte(
  301        sequence,
  302        scsi_io,
  303        11,
  304        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.time_stamp_low
  305       );
  306 
  307       //set to zero because it's a 48bit address
  308       sati_set_data_byte(sequence, scsi_io, 12, 0x00);
  309       sati_set_data_byte(sequence, scsi_io, 13, 0x00);
  310 
  311       sati_set_data_byte(
  312        sequence,
  313        scsi_io,
  314        14,
  315        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_high_ext
  316       );
  317 
  318       sati_set_data_byte(
  319        sequence,
  320        scsi_io,
  321        15,
  322        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_mid_ext
  323       );
  324 
  325       sati_set_data_byte(
  326        sequence,
  327        scsi_io,
  328        16,
  329        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_low_ext
  330       );
  331 
  332       sati_set_data_byte(
  333        sequence,
  334        scsi_io,
  335        17,
  336        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_high
  337       );
  338 
  339       sati_set_data_byte(
  340        sequence,
  341        scsi_io,
  342        18,
  343        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_mid
  344       );
  345 
  346       sati_set_data_byte(
  347        sequence,
  348        scsi_io,
  349        19,
  350        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.failing_lba_low
  351       );
  352 
  353       sati_translate_sense_values(
  354        sequence,
  355        scsi_io,
  356        ata_log->descriptor_entrys[descriptor_index].DESCRIPTOR_ENTRY.status_byte
  357       );
  358    }
  359 }
  360 
  361 /**
  362 * @brief This method will construct the first eight bytes of the SCSI self test
  363 *        log page for both cases when SATI sends a ATA read log ext and a smart
  364 *        read log command.
  365 *
  366 * @return n/a
  367 *
  368 */
  369 static
  370 void sati_self_test_log_header_construct(
  371    SATI_TRANSLATOR_SEQUENCE_T  * sequence,
  372    void                        * scsi_io
  373 )
  374 {
  375    //PAGE CODE for Self-Test Log Page
  376    sati_set_data_byte(sequence, scsi_io, 0, 0x10);
  377    sati_set_data_byte(sequence, scsi_io, 1, 0x00);
  378 
  379    //PAGE LENGTH is 0x14 instead of 0x190, not returning 20/0x190 log perameters
  380    sati_set_data_byte(sequence, scsi_io, 2, 0x00);
  381    sati_set_data_byte(sequence, scsi_io, 3, 0x14);
  382 
  383    /*
  384     * Log PARAMETER 0x0001
  385     * Only sending one log parameter per self-test request.
  386     */
  387    sati_set_data_byte(sequence, scsi_io, 4, 0x00);       //log_parameter byte 0
  388    sati_set_data_byte(sequence, scsi_io, 5, 0x01);       //log_parameter byte 1
  389 
  390    //Set to 0x03 per SATv2 spec
  391    sati_set_data_byte(sequence, scsi_io, 6, 0x03);       //log_parameter byte 2
  392 
  393    //Parameter Length set to 0x10 per SATv2 spec
  394    sati_set_data_byte(sequence, scsi_io, 7, 0x10);       //log_parameter byte 3
  395 }
  396 
  397 /**
  398  * @brief This method will construct the SCSI self test log page from
  399  *        the Extended SMART self-test log response received from the
  400  *        ATA device. The response is from a ATA_Read_Log_EXT command
  401  *        issued by SATI.
  402  *
  403  * @return n/a
  404  *
  405  */
  406 static
  407 void sati_extended_self_test_log_page_construct(
  408    SATI_TRANSLATOR_SEQUENCE_T  * sequence,
  409    void                        * scsi_io,
  410    void                        * ata_data
  411 )
  412 {
  413    ATA_EXTENDED_SMART_SELF_TEST_LOG_T * ata_log =
  414                   (ATA_EXTENDED_SMART_SELF_TEST_LOG_T*) ata_data;
  415 
  416    sati_self_test_log_header_construct(sequence, scsi_io);
  417 
  418    //bytes 4-19
  419    if( (ata_log->self_test_descriptor_index[0] == 0) &&
  420        (ata_log->self_test_descriptor_index[1] == 0))
  421    {
  422       sati_set_parameters_to_zero(sequence, scsi_io);
  423    }
  424    else
  425    {
  426       sati_get_self_test_results(sequence, scsi_io, ata_log);
  427    }
  428 }
  429 
  430 /**
  431 * @brief This method will construct the SCSI self test log page from
  432 *        the SMART self-test log response received from the ATA device.
  433 *        The response is from a ATA_SMART_Read_Log command issued by SATI.
  434 *
  435 * @return n/a
  436 *
  437 */
  438 static
  439 void sati_self_test_log_page_construct(
  440    SATI_TRANSLATOR_SEQUENCE_T  * sequence,
  441    void                        * scsi_io,
  442    void                        * ata_data
  443 )
  444 {
  445    ATA_SMART_SELF_TEST_LOG_T * ata_log =
  446                         (ATA_SMART_SELF_TEST_LOG_T*) ata_data;
  447 
  448    sati_self_test_log_header_construct(sequence, scsi_io);
  449 
  450    //first descriptor entry(index == 0) is always used because scsi_parameter_code == 1
  451    sati_set_data_byte(
  452       sequence,
  453       scsi_io,
  454       8,
  455       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.status_byte
  456    );
  457 
  458    //Sef-test number unspecified per satv2
  459    sati_set_data_byte(sequence, scsi_io, 9, 0x00);
  460 
  461    sati_set_data_byte(
  462       sequence,
  463       scsi_io,
  464       10,
  465       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.time_stamp_high
  466    );
  467 
  468    sati_set_data_byte(
  469       sequence,
  470       scsi_io,
  471       11,
  472       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.time_stamp_low
  473    );
  474 
  475    //set to zero because it's a 28bit address
  476    sati_set_data_byte(sequence, scsi_io, 12, 0x00);
  477    sati_set_data_byte(sequence, scsi_io, 13, 0x00);
  478    sati_set_data_byte(sequence, scsi_io, 14, 0x00);
  479    sati_set_data_byte(sequence, scsi_io, 15, 0x00);
  480 
  481    sati_set_data_byte(
  482       sequence,
  483       scsi_io,
  484       16,
  485       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_low_ext
  486    );
  487 
  488    sati_set_data_byte(
  489       sequence,
  490       scsi_io,
  491       17,
  492       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_high
  493    );
  494 
  495    sati_set_data_byte(
  496       sequence,
  497       scsi_io,
  498       18,
  499       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_mid
  500    );
  501 
  502    sati_set_data_byte(
  503       sequence,
  504       scsi_io,
  505       19,
  506       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.failing_lba_low
  507    );
  508 
  509    sati_translate_sense_values(
  510       sequence,
  511       scsi_io,
  512       ata_log->descriptor_entrys[0].SMART_DESCRIPTOR_ENTRY.status_byte
  513    );
  514 }
  515 
  516 /**
  517 * @brief This method will construct the SCSI information exception log page from
  518 *        the ATA SMART response received from the ATA device. The response is
  519 *         from a ATA SMART return status command issued by SATI.
  520 *
  521 * @return n/a
  522 *
  523 */
  524 static
  525 void sati_information_exception_log_page_contruct(
  526    SATI_TRANSLATOR_SEQUENCE_T  * sequence,
  527    void                        * scsi_io,
  528    void                        * ata_io
  529 )
  530 {
  531    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
  532    U32 mid_register = sati_get_ata_lba_mid(register_fis);
  533    U32 high_register = sati_get_ata_lba_high(register_fis);
  534 
  535    //Information Exception Page code
  536    sati_set_data_byte(
  537       sequence,
  538       scsi_io,
  539       0,
  540       SCSI_LOG_PAGE_INFORMATION_EXCEPTION
  541    );
  542 
  543    //Sub-page code
  544    sati_set_data_byte(sequence, scsi_io, 1, 0x00);
  545 
  546    //Page length of log parameters
  547    sati_set_data_byte(sequence, scsi_io, 2, 0x00);
  548    sati_set_data_byte(sequence, scsi_io, 3, 0x08);
  549 
  550    //parameter code
  551    sati_set_data_byte(sequence, scsi_io, 4, 0x00);
  552    sati_set_data_byte(sequence, scsi_io, 5, 0x00);
  553 
  554    //Format and Linking
  555    sati_set_data_byte(sequence, scsi_io, 6, 0x03);
  556    //Parameter Length
  557    sati_set_data_byte(sequence, scsi_io, 7, 0x04);
  558 
  559    if(mid_register == ATA_MID_REGISTER_THRESHOLD_EXCEEDED
  560       && high_register == ATA_HIGH_REGISTER_THRESHOLD_EXCEEDED)
  561    {
  562       sati_set_data_byte(
  563          sequence,
  564          scsi_io,
  565          8,
  566          SCSI_ASC_HARDWARE_IMPENDING_FAILURE
  567       );
  568 
  569       sati_set_data_byte(
  570          sequence,
  571          scsi_io,
  572          9,
  573          SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE
  574       );
  575    }
  576    else
  577    {
  578       sati_set_data_byte(sequence, scsi_io, 8, SCSI_ASC_NO_ADDITIONAL_SENSE);
  579       sati_set_data_byte(sequence, scsi_io, 9, SCSI_ASCQ_NO_ADDITIONAL_SENSE);
  580    }
  581    //setting most recent temperature reading to 0xFF(not supported) for now.
  582    sati_set_data_byte(sequence, scsi_io, 10, 0xFF);
  583 }
  584 
  585 //******************************************************************************
  586 //* P U B L I C   M E T H O D S
  587 //******************************************************************************
  588 
  589 /**
  590  * @brief This method will translate the SCSI Log Sense command into ATA commands
  591  *        specified by SATv2. ATA commands Read Log EXT and SMART Read Log will
  592  *        be issued by this translation.
  593  *
  594  * @return SATI_STATUS Indicates if the command translation succeeded.
  595  *
  596  */
  597 SATI_STATUS sati_log_sense_translate_command(
  598    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  599    void                       * scsi_io,
  600    void                       * ata_io
  601 )
  602 {
  603    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  604    SATI_STATUS status = SATI_FAILURE;
  605 
  606    if(SATI_LOG_SENSE_GET_PC_FIELD(cdb) == 1 &&
  607       (sati_get_cdb_byte(cdb, 3) == 0))
  608    {
  609       sequence->allocation_length = (sati_get_cdb_byte(cdb, 7) << 8) |
  610                                     (sati_get_cdb_byte(cdb, 8));
  611 
  612       switch(SATI_LOG_SENSE_GET_PAGE_CODE(cdb))
  613       {
  614          //Return Supported Log Pages log page
  615          case SCSI_LOG_PAGE_SUPPORTED_PAGES :
  616             sati_supported_log_page_construct(sequence, scsi_io);
  617             sequence->type = SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE;
  618             status = SATI_COMPLETE;
  619             break;
  620 
  621          //Return Self-Test Results log page
  622          case SCSI_LOG_PAGE_SELF_TEST :
  623 
  624             if((sequence->device->capabilities &
  625                SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT) == 0)
  626             {
  627                sati_scsi_sense_data_construct(
  628                   sequence,
  629                   scsi_io,
  630                   SCSI_STATUS_CHECK_CONDITION,
  631                   SCSI_SENSE_ILLEGAL_REQUEST,
  632                   SCSI_ASC_INVALID_FIELD_IN_CDB,
  633                   SCSI_ASCQ_INVALID_FIELD_IN_CDB
  634                );
  635                status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  636             }
  637             else
  638             {
  639                //check if 48-bit Address feature set is supported
  640                if((sequence->device->capabilities &
  641                   SATI_DEVICE_CAP_48BIT_ENABLE))
  642                {
  643                   //ATA Read Log Ext with log address set to 0x07
  644                   sati_ata_read_log_ext_construct(
  645                                      ata_io,
  646                                      sequence,
  647                                      ATA_LOG_PAGE_EXTENDED_SMART_SELF_TEST,
  648                                      sizeof(ATA_EXTENDED_SMART_SELF_TEST_LOG_T)
  649                   );
  650                   sequence->type =
  651                             SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE;
  652                   status = SATI_SUCCESS;
  653                }
  654                else
  655                {
  656                   //ATA Smart Read Log with log address set to 0x06
  657                   sati_ata_smart_read_log_construct(
  658                                        ata_io,
  659                                        sequence,
  660                                        ATA_LOG_PAGE_SMART_SELF_TEST,
  661                                        sizeof(ATA_SMART_SELF_TEST_LOG_T)
  662                   );
  663                   sequence->type = SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE;
  664                   status = SATI_SUCCESS;
  665                }
  666             }
  667             break;
  668 
  669          //Return Informational Exceptions log page
  670          case SCSI_LOG_PAGE_INFORMATION_EXCEPTION :
  671             if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT)
  672             {
  673                if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_ENABLE)
  674                {
  675                   sati_ata_smart_return_status_construct(
  676                                        ata_io,
  677                                        sequence,
  678                                        ATA_SMART_SUB_CMD_RETURN_STATUS
  679                   );
  680                   sequence->type =
  681                                 SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE;
  682                   status = SATI_SUCCESS;
  683                }
  684                else
  685                {
  686                   sati_scsi_sense_data_construct(
  687                      sequence,
  688                      scsi_io,
  689                      SCSI_STATUS_CHECK_CONDITION,
  690                      SCSI_SENSE_ABORTED_COMMAND,
  691                      SCSI_ASC_ATA_DEVICE_FEATURE_NOT_ENABLED,
  692                      SCSI_ASCQ_ATA_DEVICE_FEATURE_NOT_ENABLED
  693                   );
  694 
  695                   status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  696                }
  697             }
  698             else
  699             {
  700                sati_scsi_sense_data_construct(
  701                   sequence,
  702                   scsi_io,
  703                   SCSI_STATUS_CHECK_CONDITION,
  704                   SCSI_SENSE_ILLEGAL_REQUEST,
  705                   SCSI_ASC_INVALID_FIELD_IN_CDB,
  706                   SCSI_ASCQ_INVALID_FIELD_IN_CDB
  707                );
  708 
  709                status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  710             }
  711             break;
  712          default :
  713             //UNSPECIFIED SATv2r9
  714             sati_scsi_sense_data_construct(
  715                sequence,
  716                scsi_io,
  717                SCSI_STATUS_CHECK_CONDITION,
  718                SCSI_SENSE_ILLEGAL_REQUEST,
  719                SCSI_ASC_NO_ADDITIONAL_SENSE ,
  720                SCSI_ASCQ_NO_ADDITIONAL_SENSE
  721             );
  722             status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  723             break;
  724       }
  725    }
  726    return status;
  727 }
  728 
  729 /**
  730  * @brief This method will translate the response to the SATI Log Sense
  731  *        translation. ATA command responses will be translated into the
  732  *        correct SCSI log pages to be returned by SATI.
  733  *
  734  * @return SATI_STATUS Indicates if the response translation succeeded.
  735  *
  736  */
  737 SATI_STATUS sati_log_sense_translate_response(
  738    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  739    void                       * scsi_io,
  740    void                       * ata_io
  741 )
  742 {
  743    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
  744    SATI_STATUS status = SATI_FAILURE;
  745 
  746    if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
  747    {
  748       sati_scsi_sense_data_construct(
  749          sequence,
  750          scsi_io,
  751          SCSI_STATUS_CHECK_CONDITION,
  752          SCSI_SENSE_ABORTED_COMMAND,
  753          SCSI_ASC_NO_ADDITIONAL_SENSE ,
  754          SCSI_ASCQ_NO_ADDITIONAL_SENSE
  755       );
  756       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  757    }
  758    else
  759    {
  760 
  761       void * ata_data = sati_cb_get_ata_data_address(ata_io);
  762 
  763       if(ata_data == NULL)
  764       {
  765          return SATI_FAILURE;
  766       }
  767 
  768       switch(sequence->type)
  769       {
  770          case SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE:
  771             sati_extended_self_test_log_page_construct(
  772                                  sequence, scsi_io, ata_data
  773             );
  774 
  775             status = SATI_COMPLETE;
  776             break;
  777 
  778          case SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE:
  779             sati_self_test_log_page_construct(sequence, scsi_io, ata_data);
  780             status = SATI_COMPLETE;
  781             break;
  782 
  783          case SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE:
  784             //This function needs a d->h register fis, not ata data
  785             sati_information_exception_log_page_contruct(
  786                                  sequence, scsi_io, ata_io
  787             );
  788 
  789             status = SATI_COMPLETE;
  790             break;
  791 
  792          default:
  793             sati_scsi_sense_data_construct(
  794                sequence,
  795                scsi_io,
  796                SCSI_STATUS_CHECK_CONDITION,
  797                SCSI_SENSE_ABORTED_COMMAND,
  798                SCSI_ASC_NO_ADDITIONAL_SENSE ,
  799                SCSI_ASCQ_NO_ADDITIONAL_SENSE
  800             );
  801             status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  802             break;
  803       }
  804    }
  805    return status;
  806 }
  807 
  808 #endif // !defined(DISABLE_SATI_LOG_SENSE)
  809 

Cache object: e686d97590b2fb4a72404b768bfa6443


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.