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_request_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 implementation to translate
   61  *        SCSI Request Sense command based of the SAT spec.
   62  */
   63 
   64 #if !defined(DISABLE_SATI_REQUEST_SENSE)
   65 
   66 #include <dev/isci/scil/sati_request_sense.h>
   67 #include <dev/isci/scil/sati_device.h>
   68 #include <dev/isci/scil/sati_util.h>
   69 #include <dev/isci/scil/intel_scsi.h>
   70 #include <dev/isci/scil/intel_ata.h>
   71 #include <dev/isci/scil/intel_sat.h>
   72 #include <dev/isci/scil/sati_callbacks.h>
   73 #include <dev/isci/scil/sati_mode_pages.h>
   74 
   75 #define MRIE_BYTE 3
   76 #define DEXCPT_BYTE 2
   77 
   78 /**
   79  * @brief This method will translate the SCSI request sense command
   80  *        into corresponding ATA commands.  Depending on supported and enabled
   81  *        capabilities like SMART, different ATA commands can be selected.
   82  *        For more information on the parameters passed to this method,
   83  *        please reference sati_translate_command().
   84  *
   85  * @return Indicates if the command translation succeeded.
   86  * @retval SATI_SUCCESS indicates that the translation was supported and occurred
   87  *         without error.
   88  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
   89  *         the SATII is processing a format unit command.
   90  * @retval SATI_COMPLETE indicates that the translation was supported, occurred without
   91  *         error, and no additional translation is necessary.
   92  */
   93 SATI_STATUS sati_request_sense_translate_command(
   94    SATI_TRANSLATOR_SEQUENCE_T * sequence,
   95    void                       * scsi_io,
   96    void                       * ata_io
   97 )
   98 {
   99    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  100 
  101    //check if SATI is processing format unit command
  102    switch(sequence->device->state)
  103    {
  104       case SATI_DEVICE_STATE_FORMAT_UNIT_IN_PROGRESS:
  105          sati_scsi_sense_data_construct(
  106             sequence,
  107             scsi_io,
  108             SCSI_STATUS_GOOD,
  109             SCSI_SENSE_NOT_READY,
  110             SCSI_ASC_LUN_FORMAT_IN_PROGRESS,
  111             SCSI_ASCQ_LUN_FORMAT_IN_PROGRESS
  112          );
  113          return SATI_COMPLETE;
  114       break;
  115 
  116       case SATI_DEVICE_STATE_UNIT_ATTENTION_CONDITION:
  117          sati_scsi_sense_data_construct(
  118             sequence,
  119             scsi_io,
  120             SCSI_STATUS_GOOD,
  121             SCSI_SENSE_UNIT_ATTENTION,
  122             sequence->device->unit_attention_asc,
  123             sequence->device->unit_attention_ascq
  124          );
  125          return SATI_COMPLETE;
  126       break;
  127       //sending sense data status Idle, this is set by start_stop_unit
  128       case SATI_DEVICE_STATE_IDLE:
  129          sati_scsi_sense_data_construct(
  130             sequence,
  131             scsi_io,
  132             SCSI_STATUS_GOOD,
  133             SCSI_SENSE_NO_SENSE,
  134             SCSI_ASC_POWER_STATE_CHANGE,
  135             SCSI_ASCQ_IDLE_CONDITION_ACTIVATE_BY_COMMAND
  136          );
  137          return SATI_COMPLETE;
  138       break;
  139       //sending sense data status Standby, this is set by start_stop_unit
  140       case SATI_DEVICE_STATE_STANDBY:
  141          sati_scsi_sense_data_construct(
  142             sequence,
  143             scsi_io,
  144             SCSI_STATUS_GOOD,
  145             SCSI_SENSE_NO_SENSE,
  146             SCSI_ASC_POWER_STATE_CHANGE,
  147             SCSI_ASCQ_STANDBY_CONDITION_ACTIVATE_BY_COMMAND
  148          );
  149          return SATI_COMPLETE;
  150       break;
  151 
  152       case SATI_DEVICE_STATE_STOPPED:
  153          sati_scsi_sense_data_construct(
  154             sequence,
  155             scsi_io,
  156             SCSI_STATUS_GOOD,
  157             SCSI_SENSE_NO_SENSE,
  158             SCSI_ASC_NO_ADDITIONAL_SENSE,
  159             SCSI_ASCQ_NO_ADDITIONAL_SENSE
  160          );
  161          return SATI_COMPLETE;
  162       break;
  163 
  164       default:
  165       break;
  166    }
  167 
  168    sequence->allocation_length = sati_get_cdb_byte(cdb, 4);
  169 
  170    //Check if the device has SMART support & SMART enabled
  171    if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_SUPPORT)
  172    {
  173        if(sequence->device->capabilities & SATI_DEVICE_CAP_SMART_ENABLE)
  174        {
  175             sati_ata_smart_return_status_construct(
  176                            ata_io,
  177                            sequence,
  178                            ATA_SMART_SUB_CMD_RETURN_STATUS
  179             );
  180 
  181             sequence->type = SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS;
  182             return SATI_SUCCESS;
  183         }
  184    }
  185    sati_ata_check_power_mode_construct(ata_io, sequence);
  186    sequence->type = SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE;
  187    return SATI_SUCCESS;
  188 }
  189 
  190 /**
  191  * @brief This method will translate the response to the SATI Request Sense
  192  *        translation. ATA_Check_Power_Mode and ATA_SMART_Return_Status will
  193  *        be translated into a SCSI sense data response.
  194  *
  195  * @return SATI_STATUS Indicates if the response translation succeeded.
  196  *
  197  */
  198 SATI_STATUS sati_request_sense_translate_response(
  199    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  200    void                       * scsi_io,
  201    void                       * ata_io
  202 )
  203 {
  204    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
  205    U32 mid_register;
  206    U32 high_register;
  207    U32 sector_count;
  208    SATI_STATUS status = SATI_FAILURE;
  209 
  210    if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
  211    {
  212       sati_scsi_sense_data_construct(
  213          sequence,
  214          scsi_io,
  215          SCSI_STATUS_CHECK_CONDITION,
  216          SCSI_SENSE_ABORTED_COMMAND,
  217          SCSI_ASC_NO_ADDITIONAL_SENSE ,
  218          SCSI_ASCQ_NO_ADDITIONAL_SENSE
  219       );
  220       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  221    }
  222    else
  223    {
  224       switch(sequence->type)
  225       {
  226          case SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS:
  227 
  228             mid_register = sati_get_ata_lba_mid(register_fis);
  229             high_register = sati_get_ata_lba_high(register_fis);
  230             if(mid_register == ATA_MID_REGISTER_THRESHOLD_EXCEEDED
  231                && high_register == ATA_HIGH_REGISTER_THRESHOLD_EXCEEDED)
  232             {
  233                sati_request_sense_data_response_construct(
  234                   sequence,
  235                   scsi_io,
  236                   SCSI_SENSE_NO_SENSE,
  237                   SCSI_ASC_HARDWARE_IMPENDING_FAILURE,
  238                   SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE
  239                );
  240                status = SATI_COMPLETE;
  241             }
  242             else
  243             {
  244                sati_request_sense_data_response_construct(
  245                   sequence,
  246                   scsi_io,
  247                   SCSI_SENSE_NO_SENSE,
  248                   SCSI_ASC_NO_ADDITIONAL_SENSE,
  249                   SCSI_ASCQ_NO_ADDITIONAL_SENSE
  250                );
  251                status = SATI_COMPLETE;
  252             }
  253          break;
  254 
  255          case SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE:
  256 
  257             sector_count = sati_get_ata_sector_count(register_fis);
  258 
  259             switch(sector_count)
  260             {
  261                 case ATA_STANDBY_POWER_MODE:
  262                    sati_request_sense_data_response_construct(
  263                       sequence,
  264                       scsi_io,
  265                       SCSI_SENSE_NO_SENSE,
  266                       SCSI_ASC_POWER_STATE_CHANGE,
  267                       SCSI_ASCQ_POWER_STATE_CHANGE_TO_STANDBY
  268                    );
  269                    status = SATI_COMPLETE;
  270                 break;
  271 
  272                 case ATA_IDLE_POWER_MODE:
  273                    sati_request_sense_data_response_construct(
  274                       sequence,
  275                       scsi_io,
  276                       SCSI_SENSE_NO_SENSE,
  277                       SCSI_ASC_POWER_STATE_CHANGE,
  278                       SCSI_ASCQ_POWER_STATE_CHANGE_TO_IDLE
  279                    );
  280                    status = SATI_COMPLETE;
  281                 break;
  282 
  283                 case ATA_ACTIVE_POWER_MODE:
  284                    sati_request_sense_data_response_construct(
  285                       sequence,
  286                       scsi_io,
  287                       SCSI_SENSE_NO_SENSE,
  288                       SCSI_ASC_NO_ADDITIONAL_SENSE,
  289                       SCSI_ASCQ_NO_ADDITIONAL_SENSE
  290                    );
  291                    status = SATI_COMPLETE;
  292                 break;
  293 
  294                 default:
  295                 break;
  296              }
  297          break;
  298 
  299          default:
  300             sati_request_sense_data_response_construct(
  301                sequence,
  302                scsi_io,
  303                SCSI_SENSE_NO_SENSE,
  304                SCSI_ASC_NO_ADDITIONAL_SENSE,
  305                SCSI_ASCQ_NO_ADDITIONAL_SENSE
  306             );
  307             status = SATI_COMPLETE;
  308       }
  309    }
  310 
  311    return status;
  312 }
  313 
  314 /**
  315  * @brief This method will construct a response for the sati_request_sense
  316  *        translation. The response will be returned in the data buffer instead
  317  *        of the response buffer, using sense data format described in SPC-4.
  318  *
  319  */
  320 void sati_request_sense_data_response_construct(
  321    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  322    void                       * scsi_io,
  323    U8                           sense_key,
  324    U8                           additional_sense_code,
  325    U8                           additional_sense_code_qualifier
  326 )
  327 {
  328    sati_set_data_byte(
  329       sequence,
  330       scsi_io,
  331       0,
  332       SCSI_FIXED_CURRENT_RESPONSE_CODE | SCSI_FIXED_SENSE_DATA_VALID_BIT
  333    );
  334 
  335    sati_set_data_byte(sequence, scsi_io, 1, 0);
  336    sati_set_data_byte(sequence, scsi_io, 2, sense_key);
  337    sati_set_data_byte(sequence, scsi_io, 3, 0);
  338    sati_set_data_byte(sequence, scsi_io, 4, 0);
  339    sati_set_data_byte(sequence, scsi_io, 5, 0);
  340    sati_set_data_byte(sequence, scsi_io, 6, 0);
  341    sati_set_data_byte(sequence, scsi_io, 7, 0);
  342    sati_set_data_byte(sequence, scsi_io, 8, 0);
  343    sati_set_data_byte(sequence, scsi_io, 9, 0);
  344    sati_set_data_byte(sequence, scsi_io, 10, 0);
  345    sati_set_data_byte(sequence, scsi_io, 11, 0);
  346    sati_set_data_byte(sequence, scsi_io, 12, additional_sense_code);
  347    sati_set_data_byte(sequence, scsi_io, 13, additional_sense_code_qualifier);
  348    sati_set_data_byte(sequence, scsi_io, 14, 0);
  349    sati_set_data_byte(sequence, scsi_io, 15, 0);
  350    sati_set_data_byte(sequence, scsi_io, 16, 0);
  351    sati_set_data_byte(sequence, scsi_io, 17, 0);
  352 }
  353 
  354 #endif // !defined(DISABLE_SATI_REQUEST_SENSE)
  355 

Cache object: 9fc5b488ffd70140da7ff547b24d463e


[ 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.