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_mode_select.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 implementations required to
   61  *        translate the SCSI mode select (6 and 10-byte) commands with 5
   62  *        supported mode parameter pages (0x01, 0x02, 0x08, 0x0A, 0x1C).
   63  */
   64 
   65 #if !defined(DISABLE_SATI_MODE_SELECT)
   66 
   67 #include <dev/isci/scil/sati_mode_select.h>
   68 #include <dev/isci/scil/sati_mode_pages.h>
   69 #include <dev/isci/scil/sati_callbacks.h>
   70 #include <dev/isci/scil/sci_object.h>
   71 #include <dev/isci/scil/sati_translator_sequence.h>
   72 #include <dev/isci/scil/sati_util.h>
   73 
   74 //******************************************************************************
   75 //* P R I V A T E   M E T H O D S
   76 //******************************************************************************
   77 
   78 /**
   79  * @brief This method will get medium type parameter field per CDB size.
   80  *
   81  * @param[in] scsi_io This parameter specifies the user's SCSI IO object
   82  *            for which to calculate the mode page header.
   83  * @param[in] cdb_size This parameter specifies the number of bytes
   84  *            associated with the CDB for which to calculate the header.
   85  *
   86  * @return This method returns the medium type for the mode page header.
   87  */
   88 static
   89 U8 sati_mode_select_get_medium_type(
   90    U8 * mode_parameters,
   91    U32  cdb_size
   92 )
   93 {
   94    U8  medium_type =0xFF;
   95    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T * mode_parameters_6;
   96    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T * mode_parameters_10;
   97 
   98    if(cdb_size == 6)
   99    {
  100       mode_parameters_6 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T *) mode_parameters;
  101       medium_type = mode_parameters_6->medium_type;
  102    }
  103    else if(cdb_size == 10)
  104    {
  105       mode_parameters_10 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T *) mode_parameters;
  106       medium_type = mode_parameters_10->medium_type;
  107    }
  108 
  109    return medium_type;
  110 }
  111 
  112 /**
  113  * @brief This method will retrieve Block Descriptor Length.
  114  *
  115  * @param[in] mode_parameters This parameter contains the address to the mode parameters.
  116  * @param[in] cdb_size This parameter specifies the number of bytes
  117  *            associated with the CDB for which to process the block descriptor.
  118  *
  119  * @return This method returns the size, in bytes, for the mode parameter block descriptor.
  120  */
  121 static
  122 U32 sati_mode_select_get_mode_block_descriptor_length(
  123    U8 * mode_parameters,
  124    U32  cdb_size
  125 )
  126 {
  127    U32 mode_block_descriptor_length = 0;
  128    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T * mode_parameters_6;
  129    SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T * mode_parameters_10;
  130 
  131    if(cdb_size == 6)
  132    {
  133       mode_parameters_6 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T *) mode_parameters;
  134       mode_block_descriptor_length = mode_parameters_6->block_descriptor_length;
  135    }
  136    else if(cdb_size == 10)
  137    {
  138       mode_parameters_10 = (SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T *) mode_parameters;
  139       //Long LBA bit is the bit0 of the byte
  140       //Spec says another way to get the block descriptor length to multiply the block number
  141       //   with block length (8 or 16), but we can get it directly.
  142       mode_block_descriptor_length =(((U16)mode_parameters_10->block_descriptor_length[0]) << 8) +
  143          mode_parameters_10->block_descriptor_length[1];
  144 
  145    }
  146 
  147    return mode_block_descriptor_length;
  148 
  149 }
  150 
  151 /**
  152  * @brief This method will find the starting byte location for a page.
  153  *
  154  * @param[in] block_descriptor_length This parameter passes in the length of
  155  *            block descriptor.
  156  * @param[in] cdb_size This parameter specifies the number of bytes
  157  *            associated with the CDB for which to calculate the header.
  158  *
  159  * @return This method returns the offset, for the mode page.
  160  */
  161 static
  162 U32 sati_mode_select_get_mode_page_offset(
  163     U32 block_descriptor_length,
  164     U32 cdb_size
  165     )
  166 {
  167    U32 mode_page_offset;
  168 
  169    if(cdb_size == 6)
  170    {
  171       mode_page_offset =  sizeof(SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_6_T) +  block_descriptor_length;
  172    }
  173    else if(cdb_size == 10)
  174    {
  175       mode_page_offset =  sizeof(SCSI_MODE_SELECT_MODE_PARAMETER_HEADER_10_T) +  block_descriptor_length;
  176    }
  177    else
  178    {
  179       mode_page_offset = 0;
  180    }
  181 
  182    return mode_page_offset;
  183 }
  184 
  185 /**
  186  * @brief This method will set the initial Mode Select processing state.
  187  */
  188 static
  189 void  sati_mode_select_initialize_mode_sel_processing_state(
  190    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  191    void                       * scsi_io,
  192    void                       * ata_io,
  193    U32 data_transfer_length,
  194    U32 mode_page_offset
  195    )
  196 {
  197    sequence->command_specific_data.process_state.ata_command_sent_for_cmp = 0;
  198    sequence->command_specific_data.process_state.mode_page_offset=mode_page_offset;
  199    sequence->command_specific_data.process_state.mode_pages_size = data_transfer_length  -  mode_page_offset;
  200    sequence->command_specific_data.process_state.size_of_data_processed = 0;
  201    sequence->command_specific_data.process_state.current_mode_page_processed = FALSE;
  202 }
  203 
  204 /**
  205  * @brief This method will get mode page size.
  206  *
  207  * @param[in] page_code This parameter contains page code for the current mode page.
  208  *
  209  * @return This method returns the size of current mode page.
  210  */
  211 static
  212 U32 sati_mode_select_get_mode_page_size(
  213    U8 page_code
  214 )
  215 {
  216    U32 page_size=0;
  217 
  218    switch (page_code)
  219    {
  220    case SCSI_MODE_PAGE_READ_WRITE_ERROR:
  221       page_size=SCSI_MODE_PAGE_01_LENGTH;
  222       break;
  223 
  224    case SCSI_MODE_PAGE_DISCONNECT_RECONNECT:
  225       page_size=SCSI_MODE_PAGE_02_LENGTH;
  226       break;
  227 
  228    case SCSI_MODE_PAGE_CACHING:
  229       page_size=SCSI_MODE_PAGE_08_LENGTH;
  230       break;
  231 
  232    case SCSI_MODE_PAGE_CONTROL:
  233       page_size=SCSI_MODE_PAGE_0A_LENGTH;
  234       break;
  235 
  236    case SCSI_MODE_PAGE_INFORMATIONAL_EXCP_CONTROL:
  237       page_size=SCSI_MODE_PAGE_1C_LENGTH;
  238       break;
  239 
  240    case SCSI_MODE_PAGE_POWER_CONDITION:
  241       page_size=SCSI_MODE_PAGE_1A_LENGTH;
  242       break;
  243    default:
  244       page_size=0;
  245       break;
  246    }
  247 
  248    return page_size;
  249 }
  250 
  251 /**
  252  * @brief This method will check the validity of parameter data of Read Write Error Recovery
  253  *            page and further processing the page data if necessary.
  254  *
  255  * @param[in] page_size This parameter specifies page size of current mode page.
  256  *
  257  * @return Indicate if the translation was successful.
  258  * @retval SATI_SUCCESS
  259  * @retval SATI_COMPLETE
  260  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  261  */
  262 static
  263 SATI_STATUS sati_mode_select_process_mode_page_read_write_error_recovery(
  264    SATI_TRANSLATOR_SEQUENCE_T* sequence,
  265    void     *  scsi_io,
  266    U32   page_size
  267    )
  268 {
  269    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  270 
  271    U8 current_mode_page[SCSI_MODE_PAGE_01_LENGTH]={0,0,0,0,0,0,0,0,0,0,0,0};
  272    U32 mode_page_offset;
  273 
  274    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
  275 
  276    //Check all the defined bits for this page
  277    //SPF(0b); Page length 0x0A;AWRE 1; ARRE 0; Error recovery bits 0; RC 0;
  278    //Recovery time limit last two bytes 0
  279 
  280    sati_get_data_byte(sequence, scsi_io, mode_page_offset,   &current_mode_page[0]);
  281    sati_get_data_byte(sequence, scsi_io, mode_page_offset+1, &current_mode_page[1]);
  282    sati_get_data_byte(sequence, scsi_io, mode_page_offset+2, &current_mode_page[2]);
  283    sati_get_data_byte(sequence, scsi_io, mode_page_offset+10, &current_mode_page[10]);
  284    sati_get_data_byte(sequence, scsi_io, mode_page_offset+11, &current_mode_page[11]);
  285 
  286    if ( ((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
  287       (current_mode_page[1] != (SCSI_MODE_PAGE_01_LENGTH - 2)) ||
  288       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_01_AWRE_MASK) == 0) ||
  289       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_01_ARRE_MASK) != 0) ||
  290       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_01_RC_ERBITS_MASK) != 0) ||
  291       (current_mode_page[10] != 0 ) ||
  292       (current_mode_page[11] != 0 ) )
  293    {
  294       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  295       return status;
  296    }
  297 
  298    //no need to send any command
  299    {
  300       sequence->command_specific_data.process_state.size_of_data_processed += page_size;
  301       sequence->command_specific_data.process_state.mode_page_offset += page_size;
  302       sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
  303    }
  304 
  305    status = SATI_COMPLETE;
  306 
  307    return status;
  308 }
  309 
  310 /**
  311  * @brief This method will check the validity of parameter data of Disconnect Reconnect mode
  312  *            page and further processing the page data if necessary.
  313  *
  314  * @param[in] page_size This parameter specifies page size of current mode page.
  315  *
  316  * @return Indicate if the translation was successful.
  317  * @retval SATI_SUCCESS
  318  * @retval SATI_COMPLETE
  319  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  320  */
  321 static
  322 SATI_STATUS sati_mode_select_process_mode_page_disconnect_reconnect(
  323    SATI_MODE_SELECT_PROCESSING_STATE_T * mode_select_process_state,
  324    U32 page_size
  325    )
  326 {
  327    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  328 
  329    // No need to check data for valid or invalid this page (undefined)
  330    // No ata command to send
  331    {
  332       mode_select_process_state->size_of_data_processed += page_size;
  333       mode_select_process_state->mode_page_offset += page_size;
  334       mode_select_process_state->current_mode_page_processed = TRUE;
  335    }
  336 
  337    // No further interaction with remote devices
  338    status = SATI_COMPLETE;
  339 
  340    return status;
  341 }
  342 
  343 /**
  344  * @brief This method will check the validity of parameter data of Caching mode
  345  *            page and issue multiple ATA set feature commands to complete the translation.
  346  *
  347  * @param[in] page_size This parameter specifies page size of current mode page.
  348  *
  349  * @return Indicate if the translation was successful.
  350  * @retval SATI_SUCCESS
  351  * @retval SATI_COMPLETE
  352  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  353  */
  354 static
  355 SATI_STATUS sati_mode_select_process_mode_page_caching(
  356    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  357    void * scsi_io,
  358    void * ata_io,
  359    U32 page_size
  360    )
  361 {
  362    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  363 
  364    //SCSI_MODE_PAGE_08_LENGTH 0x14= 20
  365    U8 current_mode_page[SCSI_MODE_PAGE_08_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  366    U32 mode_page_offset;
  367    U32 index;
  368 
  369    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
  370    sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING;
  371 
  372    for(index = 0; index < SCSI_MODE_PAGE_08_LENGTH; index++)
  373    {
  374       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
  375    }
  376 
  377    //Check for data validity
  378    //SPF(0b); Page length 0x12;Byte2 to Byte15 all 0 with exception DRA and WCE changeable
  379 
  380    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
  381       (current_mode_page[1] != (SCSI_MODE_PAGE_08_LENGTH-2)) ||
  382       ((current_mode_page[2] | SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT)!=SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT) ||
  383       (current_mode_page[3] != 0 ) ||
  384       (current_mode_page[4] != 0 ) ||
  385       (current_mode_page[5] != 0 ) ||
  386       (current_mode_page[6] != 0 ) ||
  387       (current_mode_page[7] != 0 ) ||
  388       (current_mode_page[8] != 0 ) ||
  389       (current_mode_page[9] != 0 ) ||
  390       (current_mode_page[10] != 0 ) ||
  391       (current_mode_page[11] != 0 ) ||
  392       ((current_mode_page[12] & SCSI_MODE_SELECT_MODE_PAGE_08_FSW_LBCSS_NVDIS) != 0) ||
  393       (current_mode_page[13] != 0 ) ||
  394       (current_mode_page[14] != 0 ) ||
  395       (current_mode_page[15] != 0 ))
  396    {
  397       //parameter data passed in containing data that doesn't meet the SAT-2 requirement
  398       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  399    }
  400 
  401    if(sequence->command_specific_data.process_state.ata_command_sent_for_cmp == 0)
  402    {
  403       //byte2 bit2 WCE==0 disable write cache WCE==1 enable write cache
  404       //SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT ==0x4,
  405 
  406       if ( (current_mode_page[2] & SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT) == 0)
  407          sati_ata_set_features_construct(ata_io, sequence, ATA_SET_FEATURES_SUB_CMD_DISABLE_CACHE);
  408       else
  409          sati_ata_set_features_construct(ata_io, sequence, ATA_SET_FEATURES_SUB_CMD_ENABLE_CACHE);
  410 
  411    }
  412    else if(sequence->command_specific_data.process_state.ata_command_sent_for_cmp == 1)
  413    {
  414       // DRA bit is set to 0, enable Read look ahead AAh;
  415       // DRA bit is set to 1, disable with set feature command 55h
  416       // SCSI_MODE_PAGE_CACHE_PAGE_DRA_BIT== 0x20
  417 
  418       if ( (current_mode_page[12] & SCSI_MODE_PAGE_CACHE_PAGE_DRA_BIT) == 0)
  419          sati_ata_set_features_construct(ata_io, sequence,ATA_SET_FEATURES_SUB_CMD_ENABLE_READ_AHEAD);
  420       else
  421          sati_ata_set_features_construct(ata_io, sequence,ATA_SET_FEATURES_SUB_CMD_DISABLE_READ_AHEAD);
  422 
  423       sequence->command_specific_data.process_state.size_of_data_processed += page_size;
  424       sequence->command_specific_data.process_state.mode_page_offset += page_size;
  425       sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
  426 
  427 
  428    }
  429    // No more ata commands to send
  430 
  431    sequence->command_specific_data.process_state.ata_command_sent_for_cmp++;
  432 
  433    status = SATI_SUCCESS;
  434 
  435    return status;
  436 }
  437 
  438 /**
  439  * @brief This method will check the validity of parameter data of Control mode
  440  *            page and further processing the page data if necessary.
  441  *
  442  * @param[in] mode_select_process_state This parameter points to the processing state fields
  443  *            of current mode page.
  444  * @param[in] page_size This parameter specifies page size of current mode page.
  445  *
  446  * @return Indicate if the translation was successful.
  447  * @retval SATI_SUCCESS
  448  * @retval SATI_COMPLETE
  449  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  450  */
  451 static
  452 SATI_STATUS sati_mode_select_process_mode_page_control(
  453          SATI_TRANSLATOR_SEQUENCE_T* sequence,
  454          void     *  scsi_io,
  455          void     *  ata_io,
  456          U32 page_size
  457       )
  458 {
  459    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  460 
  461    //SCSI_MODE_PAGE_0A_LENGTH 12
  462    U8 current_mode_page[SCSI_MODE_PAGE_0A_LENGTH]={0,0,0,0,0,0,0,0,0,0};
  463    U32 mode_page_offset;
  464    U32 index;
  465 
  466    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
  467 
  468    for(index = 0; index < SCSI_MODE_PAGE_0A_LENGTH; index++)
  469    {
  470       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
  471    }
  472 
  473    //bit 1 and 2 of byte3 Qerr full task management model etc. then both bits 0
  474    //byte 8 and 9 busy time out period variable if not ffff setable?
  475    //check for page data validity
  476    //Byte2: 0000???0b  Byte3: Queued Algorithm Modifier should be set to 1 QErr?
  477    //Byte4: ??000???   Byte5: ?0???000
  478 
  479    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
  480       (current_mode_page[1] != (SCSI_MODE_PAGE_0A_LENGTH - 2)) ||
  481       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_0A_TST_TMF_RLEC) != 0) ||
  482       ((current_mode_page[3] & SCSI_MODE_SELECT_MODE_PAGE_0A_MODIFIER) != 0) ||
  483       ((current_mode_page[4] & SCSI_MODE_SELECT_MODE_PAGE_0A_UA_SWP ) != 0) ||
  484       ((current_mode_page[5] & SCSI_MODE_SELECT_MODE_PAGE_0A_TAS_AUTO ) != 0 ) )
  485    {
  486       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  487    }
  488 
  489    if ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_D_SENSE) != 0)
  490        sequence->device->descriptor_sense_enable = SCSI_MODE_PAGE_CONTROL_D_SENSE_ENABLE;
  491    else
  492        sequence->device->descriptor_sense_enable = SCSI_MODE_PAGE_CONTROL_D_SENSE_DISABLE;
  493 
  494    // no ata command need to be comfirmed
  495    {
  496       sequence->command_specific_data.process_state.size_of_data_processed += page_size;
  497       sequence->command_specific_data.process_state.mode_page_offset += page_size;
  498       sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
  499    }
  500 
  501    status = SATI_COMPLETE;
  502 
  503    return status;
  504 }
  505 
  506 /**
  507  * @brief This method will check the validity of parameter data of Information Exception Control
  508  *            mode page and further processing the page data if necessary.
  509  *
  510  * @param[in] page_size This parameter specifies page size of current mode page.
  511  *
  512  * @return Indicate if the translation was successful.
  513  * @retval SATI_SUCCESS
  514  * @retval SATI_COMPLETE
  515  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  516  */
  517 static
  518 SATI_STATUS sati_mode_select_process_mode_page_informational_exception_control(
  519    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  520    void     *  scsi_io,
  521    void     *  ata_io,
  522    U32 page_size
  523    )
  524 {
  525    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  526 
  527    //SCSI_MODE_PAGE_1C_LENGTH 12
  528    U8 current_mode_page[SCSI_MODE_PAGE_1C_LENGTH]={0,0,0,0,0,0,0,0,0,0,0,0};
  529    U32 mode_page_offset;
  530    U32 index;
  531 
  532    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
  533    sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL;
  534 
  535    for(index = 0; index < 4; index++)
  536    {
  537       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
  538    }
  539 
  540    //Check for data validity
  541    //SPF(0b); Page length 0x0A; Byte2 0????0?? Byte3: ????1100
  542    //SCSI_MODE_SELECT_MODE_PAGE_MRIE_BYTE same as REPORT_INFO_EXCEPTION_CONDITION_ON_REQUEST 0x6
  543    //SCSI_MODE_PAGE_DEXCPT_ENABLE
  544 
  545    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
  546       (current_mode_page[1] != (SCSI_MODE_PAGE_1C_LENGTH - 2)) ||
  547       ((current_mode_page[2] & SCSI_MODE_SELECT_MODE_PAGE_1C_PERF_TEST)!= 0 ) ||
  548       ((current_mode_page[3] & SCSI_MODE_SELECT_MODE_PAGE_MRIE_MASK) !=
  549       SCSI_MODE_SELECT_MODE_PAGE_MRIE_BYTE ))
  550    {
  551       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  552    }
  553 
  554    // DEXCPT bit is set to 0, enable SMART reporting D8h;
  555    // DEXCPT bit is set to 1, disable SMART reporting D9h
  556    // SCSI_MODE_PAGE_DEXCPT_ENABLE== 0x08
  557 
  558    if ( (current_mode_page[2] & SCSI_MODE_PAGE_DEXCPT_ENABLE) == 0)
  559       sati_ata_smart_return_status_construct(ata_io, sequence, ATA_SMART_SUB_CMD_ENABLE);
  560    else
  561       sati_ata_smart_return_status_construct(ata_io, sequence, ATA_SMART_SUB_CMD_DISABLE);
  562 
  563    sequence->command_specific_data.process_state.size_of_data_processed += page_size;
  564    sequence->command_specific_data.process_state.mode_page_offset += page_size;
  565    sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
  566    // No more ata commands to send
  567 
  568    status = SATI_SUCCESS;
  569 
  570    return status;
  571 }
  572 
  573 /**
  574  * @brief This method will check the validity of parameter data of Power Condition mode
  575  *            page and issue multiple ATA set feature commands to complete the translation.
  576  *
  577  * @param[in] mode_select_process_state This parameter points to the processing state fields
  578  *            of current mode page.
  579  * @param[in] page_size This parameter specifies page size of current mode page.
  580  *
  581  * @return Indicate if the translation was successful.
  582  * @retval SATI_SUCCESS
  583  * @retval SATI_COMPLETE
  584  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  585  */
  586 static
  587 SATI_STATUS sati_mode_select_process_mode_page_power_condition(
  588    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  589    void * scsi_io,
  590    void * ata_io,
  591    U32 page_size
  592    )
  593 {
  594    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  595 
  596    //SCSI_MODE_PAGE_1A_LENGTH 10
  597    U8 current_mode_page[SCSI_MODE_PAGE_1A_LENGTH] = {0,0,0,0,0,0,0,0,0,0};
  598    U32 mode_page_offset;
  599    U32 index;
  600 
  601    U32 timer = 0;
  602    U16 count = 0;
  603 
  604    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
  605 
  606    sequence->type = SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION;
  607 
  608    for(index = 0; index < SCSI_MODE_PAGE_1A_LENGTH; index++)
  609    {
  610       sati_get_data_byte(sequence, scsi_io, mode_page_offset+index, &current_mode_page[index]);
  611    }
  612 
  613    //Check for data validity
  614    //SPF(0b); Page length 0x0A;
  615 
  616    if (((current_mode_page[0] & SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK)!= 0) ||
  617       (current_mode_page[1] != (SCSI_MODE_PAGE_1A_LENGTH - 2) ) ||
  618       ((current_mode_page[3] & SCSI_MODE_PAGE_POWER_CONDITION_IDLE)!= 0)
  619       )
  620    {
  621       //parameter data passed in containing data that doesn't meet the SAT-2 requirement
  622       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  623    }
  624 
  625    // STANDBY bit is set to 0, do nothing since the standby timer can't be set;
  626    // STANDBY bit is set to 1, translate the standby timer
  627    // SCSI_MODE_PAGE_POWER_CONDITION_STANDBY== 0x01
  628    if (current_mode_page[3] & SCSI_MODE_PAGE_POWER_CONDITION_STANDBY)
  629    {
  630       timer = (current_mode_page[8]<<24) + (current_mode_page[9]<<16) + (current_mode_page[10]<<8) + current_mode_page[11];
  631 
  632       //If the ATA IDENTIFY DEVICE data word 49, bit 13 is set to one,
  633       if (sequence->device->capabilities & SATI_DEVICE_CAP_STANDBY_ENABLE)
  634       {
  635          if (timer == 0)
  636          {
  637             //TPV=0 send ATA STANDBY_IMMEDIATE
  638             sati_ata_standby_immediate_construct(ata_io, sequence);
  639             sequence->command_specific_data.translated_command = ATA_STANDBY_IMMED;
  640          }
  641          else if ((timer > 0) && (timer <= 12000))
  642          {
  643             //1 to 12 000 INT((z - 1) / 50) + 1
  644             count = (U16)((timer -1) / 50) + 1;
  645             sati_ata_standby_construct(ata_io, sequence, count);
  646          }
  647          else if ((timer > 12000) && (timer <= 12600))
  648          {
  649             //12 001 to 12 600 FCh
  650             sati_ata_standby_construct(ata_io, sequence, 0xFC);
  651          }
  652          else if ((timer > 12600) && (timer <= 12750))
  653          {
  654             //12 601 to 12 750 FFh
  655             sati_ata_standby_construct(ata_io, sequence, 0xFF);
  656          }
  657          else if ((timer > 12750) && (timer < 18000))
  658          {
  659             //12 751 to 17 999 F1h
  660             sati_ata_standby_construct(ata_io, sequence, 0xF1);
  661          }
  662          else if ((timer >= 18000) && (timer <= 198000))
  663          {
  664             //18 000 to 198 000 INT(z / 18 000) + 240
  665             count = (U16)(timer / 18000) + 240;
  666             sati_ata_standby_construct(ata_io, sequence, count);
  667          }
  668          else
  669          {
  670             //All other values FDh
  671             sati_ata_standby_construct(ata_io, sequence, 0xFD);
  672          }
  673          status = SATI_SUCCESS ;
  674       }
  675       else
  676       {
  677          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  678          //If the ATA IDENTIFY DEVICE data word 49, bit 13 is set to 0
  679       }
  680    }
  681    else
  682    {
  683       status = SATI_COMPLETE;
  684    }
  685 
  686    sequence->command_specific_data.process_state.size_of_data_processed += page_size;
  687    sequence->command_specific_data.process_state.mode_page_offset += page_size;
  688    sequence->command_specific_data.process_state.current_mode_page_processed = TRUE;
  689 
  690    return status;
  691 }
  692 
  693 /**
  694  * @brief This method will process the mode page.
  695  *
  696  *
  697  * @return Indicate if the translation was successful.
  698  * @retval SATI_SUCCESS
  699  * @retval SATI_COMPLETE
  700  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  701  */
  702 static
  703 SATI_STATUS sati_mode_select_process_mode_page(
  704    SATI_TRANSLATOR_SEQUENCE_T* sequence,
  705    void                      * scsi_io,
  706    void                      * ata_io
  707 )
  708 {
  709    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  710 
  711    U8 page_code;
  712    U32 page_size = 0; // in bytes
  713    U32 size_of_data_to_be_processed;
  714 
  715    U8 page_code_byte;
  716    U32 mode_page_offset;
  717 
  718    mode_page_offset = sequence->command_specific_data.process_state.mode_page_offset;
  719 
  720    sati_get_data_byte(sequence, scsi_io, mode_page_offset, &page_code_byte);
  721 
  722    // No more pages.
  723    if(sequence->command_specific_data.process_state.mode_pages_size >
  724       sequence->command_specific_data.process_state.size_of_data_processed)
  725    {
  726       //SCSI_MODE_SENSE_PAGE_CODE_ENABLE==0x3f same for Mode Select
  727       page_code = page_code_byte & SCSI_MODE_SENSE_PAGE_CODE_ENABLE;
  728       page_size = sati_mode_select_get_mode_page_size(page_code);
  729       size_of_data_to_be_processed = sequence->command_specific_data.process_state.mode_pages_size
  730          - sequence->command_specific_data.process_state.size_of_data_processed;
  731 
  732       if( page_size == 0 )
  733       {
  734          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  735       }
  736       else
  737       {
  738          // process mode page
  739          switch(page_code)
  740          {
  741          case SCSI_MODE_PAGE_READ_WRITE_ERROR:
  742             status = sati_mode_select_process_mode_page_read_write_error_recovery(
  743                         sequence,
  744                         scsi_io,
  745                         page_size
  746                      );
  747             break;
  748 
  749          case SCSI_MODE_PAGE_DISCONNECT_RECONNECT:
  750             status = sati_mode_select_process_mode_page_disconnect_reconnect(
  751                         &sequence->command_specific_data.process_state,
  752                         page_size
  753                      );
  754             break;
  755 
  756          case SCSI_MODE_PAGE_CACHING:
  757             status = sati_mode_select_process_mode_page_caching(
  758                         sequence,
  759                         scsi_io,
  760                         ata_io,
  761                         page_size
  762                      );
  763             break;
  764 
  765          case SCSI_MODE_PAGE_CONTROL:
  766             status = sati_mode_select_process_mode_page_control(
  767                         sequence,
  768                         scsi_io,
  769                         ata_io,
  770                         page_size
  771                      );
  772             break;
  773 
  774          case SCSI_MODE_PAGE_INFORMATIONAL_EXCP_CONTROL:
  775             status = sati_mode_select_process_mode_page_informational_exception_control(
  776                         sequence,
  777                         scsi_io,
  778                         ata_io,
  779                         page_size
  780                      );
  781             break;
  782 
  783          case SCSI_MODE_PAGE_POWER_CONDITION:
  784             status = sati_mode_select_process_mode_page_power_condition(
  785                         sequence,
  786                         scsi_io,
  787                         ata_io,
  788                         page_size
  789                      );
  790 
  791             break;
  792 
  793          default:
  794             break;
  795          }
  796 
  797       }
  798    }
  799 
  800    return status;
  801 }
  802 
  803 //******************************************************************************
  804 //* P U B L I C   M E T H O D S
  805 //******************************************************************************
  806 
  807 /**
  808  * @brief This method will translate the SCSI Mode Select 6 byte or 10 byte command
  809  *        into corresponding ATA commands.  Depending upon the capabilities
  810  *        supported by the target different ATA commands can be selected.
  811  *        Additionally, in some cases more than a single ATA command may
  812  *        be required.
  813  *
  814  * @return Indicate if the command translation succeeded.
  815  * @retval SCI_SUCCESS This is returned if the command translation was
  816  *         successful.
  817  * @retval SCI_COMPLETE This is returned if the command translation was
  818  *         successful and no ATA commands need to be set.
  819  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
  820  *         sense data has been created as a result of something specified
  821  *         in the parameter data fields.
  822  */
  823 static
  824 SATI_STATUS sati_mode_select_translate_command(
  825    SATI_TRANSLATOR_SEQUENCE_T   * sequence,
  826    void                         * scsi_io,
  827    void                         * ata_io,
  828    U32                          cdb_size
  829 )
  830 {
  831    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  832    U32 mode_page_offset;
  833    U32 block_descriptor_length;
  834    U32 index;
  835    U16 data_transfer_length;
  836    U8 current_mode_parameters[8]={0,0,0,0,0,0,0,0};
  837    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  838 
  839    // cdb_size must be 6 or 10
  840    if(FALSE == (cdb_size == 6 || cdb_size == 10))
  841    {
  842       return status;
  843    }
  844 
  845    if(sequence->state == SATI_SEQUENCE_STATE_INITIAL)
  846    {
  847       sequence->command_specific_data.process_state.ata_command_sent_for_cmp = 0;
  848       sequence->state = SATI_SEQUENCE_STATE_TRANSLATE_DATA;
  849    }
  850 
  851    //First, initializes mode_sel_processing_state
  852    if ( sequence->command_specific_data.process_state.ata_command_sent_for_cmp == 0 )
  853    {
  854       if (cdb_size == 6)
  855       {
  856          //CDB byte 4 is the parameter length
  857          data_transfer_length = sati_get_cdb_byte(cdb, 4);
  858       }
  859       else
  860       {
  861          //CDB byte 7 and 8 for Mode Select 10
  862          data_transfer_length = (sati_get_cdb_byte(cdb, 7) << 8) + sati_get_cdb_byte(cdb, 8);
  863       }
  864 
  865       sequence->allocation_length = data_transfer_length;
  866 
  867       //Get 8 bytes for headers (4 bytes for Mode Select 6 and 8 bytes for Mode Select 10)
  868       for( index = 0; index < 8; index++ )
  869       {
  870          sati_get_data_byte(sequence, scsi_io, index, &current_mode_parameters[index]);
  871       }
  872 
  873       //medium type should be 0
  874       if ( sati_mode_select_get_medium_type(current_mode_parameters, cdb_size) != 0 )
  875       {
  876          sati_scsi_sense_data_construct(
  877             sequence,
  878             scsi_io,
  879             SCSI_STATUS_CHECK_CONDITION,
  880             SCSI_SENSE_ILLEGAL_REQUEST,
  881             SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
  882             SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
  883          );
  884          return status;
  885       }
  886 
  887       block_descriptor_length = sati_mode_select_get_mode_block_descriptor_length(
  888                                    current_mode_parameters,
  889                                    cdb_size
  890                                 );
  891 
  892       mode_page_offset = sati_mode_select_get_mode_page_offset(
  893                             block_descriptor_length,
  894                             cdb_size
  895                          );
  896 
  897       if(mode_page_offset > data_transfer_length)
  898       {
  899          sequence->state = SATI_SEQUENCE_STATE_FINAL;
  900          status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  901       }
  902       else
  903       {
  904          sati_mode_select_initialize_mode_sel_processing_state(
  905             sequence,
  906             scsi_io,
  907             ata_io,
  908             data_transfer_length,
  909             mode_page_offset
  910          );
  911 
  912       }
  913     }
  914 
  915    // move to next mode page
  916    if(sequence->command_specific_data.process_state.current_mode_page_processed)
  917    {
  918       sequence->command_specific_data.process_state.ata_command_sent_for_cmp = 0;
  919       sequence->command_specific_data.process_state.current_mode_page_processed = FALSE;
  920    }
  921 
  922    status = sati_mode_select_process_mode_page(sequence, scsi_io, ata_io);
  923 
  924    if(sequence->command_specific_data.process_state.current_mode_page_processed != FALSE)
  925    {
  926       // Done this page
  927       sequence->state = SATI_SEQUENCE_STATE_FINAL;
  928    }
  929    else
  930    {
  931       sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
  932    }
  933 
  934    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
  935    {
  936       sequence->state = SATI_SEQUENCE_STATE_FINAL;
  937       sati_scsi_sense_data_construct(
  938          sequence,
  939          scsi_io,
  940          SCSI_STATUS_CHECK_CONDITION,
  941          SCSI_SENSE_ILLEGAL_REQUEST,
  942          SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
  943          SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
  944       );
  945    }
  946 
  947    return status;
  948 }
  949 
  950 /**
  951  * @brief This method will call Mode Select 6 Translation command
  952  *        For more information on the parameters passed to this method,
  953  *        please reference sati_translate_command().
  954  *
  955  * @return Indicate if the command translation succeeded.
  956  * @retval SCI_SUCCESS This is returned if the command translation was
  957  *         successful.
  958  * @retval SCI_COMPLETE This is returned if the command translation was
  959  *         successful and no ATA commands need to be set.
  960  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
  961  *         sense data has been created as a result of something specified
  962  *         in the parameter data fields.
  963  */
  964 SATI_STATUS sati_mode_select_6_translate_command(
  965    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  966    void                       * scsi_io,
  967    void                       * ata_io
  968 )
  969 {
  970    SATI_STATUS status=SATI_FAILURE;
  971    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  972 
  973    //PF bit needs to be 1 byte1 bit ???1????
  974    if ((sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SELECT_PF_MASK) == !SCSI_MODE_SELECT_PF_BIT)
  975    {
  976       sati_scsi_sense_data_construct(
  977          sequence,
  978          scsi_io,
  979          SCSI_STATUS_CHECK_CONDITION,
  980          SCSI_SENSE_ILLEGAL_REQUEST,
  981          SCSI_ASC_INVALID_FIELD_IN_CDB,
  982          SCSI_ASCQ_INVALID_FIELD_IN_CDB
  983       );
  984       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  985       return status;
  986    }
  987 
  988    status=sati_mode_select_translate_command(
  989              sequence,
  990              scsi_io,
  991              ata_io,
  992              6
  993           );
  994 
  995    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
  996    {
  997       sati_scsi_sense_data_construct(
  998          sequence,
  999          scsi_io,
 1000          SCSI_STATUS_CHECK_CONDITION,
 1001          SCSI_SENSE_ILLEGAL_REQUEST,
 1002          SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
 1003          SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
 1004       );
 1005    }
 1006    return status;
 1007 
 1008 }
 1009 
 1010 /**
 1011  * @brief This method will call Mode Select 10 translation command
 1012  *        For more information on the parameters passed to this method,
 1013  *        please reference sati_translate_command().
 1014  *
 1015  * @return Indicate if the command translation succeeded.
 1016  * @retval SCI_SUCCESS This is returned if the command translation was
 1017  *         successful.
 1018  * @retval SCI_COMPLETE This is returned if the command translation was
 1019  *         successful and no ATA commands need to be set.
 1020  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
 1021  *         sense data has been created as a result of something specified
 1022  *         in the parameter data fields.
 1023  */
 1024 SATI_STATUS sati_mode_select_10_translate_command(
 1025    SATI_TRANSLATOR_SEQUENCE_T * sequence,
 1026    void                       * scsi_io,
 1027    void                       * ata_io
 1028 )
 1029 {
 1030    SATI_STATUS status=SATI_FAILURE;
 1031    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
 1032 
 1033    //PF bit needs to be 1 byte1 bit ???1????
 1034    if ((sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SELECT_PF_MASK) == !SCSI_MODE_SELECT_PF_BIT)
 1035    {
 1036       sati_scsi_sense_data_construct(
 1037          sequence,
 1038          scsi_io,
 1039          SCSI_STATUS_CHECK_CONDITION,
 1040          SCSI_SENSE_ILLEGAL_REQUEST,
 1041          SCSI_ASC_INVALID_FIELD_IN_CDB,
 1042          SCSI_ASCQ_INVALID_FIELD_IN_CDB
 1043       );
 1044       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
 1045       return status;
 1046    }
 1047 
 1048    status=sati_mode_select_translate_command(
 1049              sequence,
 1050              scsi_io,
 1051              ata_io,
 1052              10
 1053           );
 1054 
 1055    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
 1056    {
 1057       sati_scsi_sense_data_construct(
 1058          sequence,
 1059          scsi_io,
 1060          SCSI_STATUS_CHECK_CONDITION,
 1061          SCSI_SENSE_ILLEGAL_REQUEST,
 1062          SCSI_ASC_INVALID_FIELD_IN_PARM_LIST,
 1063          SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST
 1064       );
 1065    }
 1066    return status;
 1067 }
 1068 
 1069 /**
 1070 * @brief This method will conduct error handling for the ATA Set Features command
 1071 *        that is issued during a Mode Select translation for the Caching Mode
 1072 *        page.
 1073 *
 1074 *
 1075 * @return Indicate if the command translation succeeded.
 1076 *
 1077 * @retval SCI_COMPLETE This is returned if the command translation was
 1078 *         successful and no additional ATA commands need to be set.
 1079 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
 1080 *         sense data has been created as a result of an error returned
 1081 */
 1082 SATI_STATUS sati_mode_select_translate_response(
 1083 SATI_TRANSLATOR_SEQUENCE_T * sequence,
 1084 void                       * scsi_io,
 1085 void                       * ata_io
 1086 )
 1087 {
 1088    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
 1089    SATI_STATUS status = SATI_FAILURE;
 1090 
 1091    if(sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
 1092    {
 1093       sati_scsi_sense_data_construct(
 1094          sequence,
 1095          scsi_io,
 1096          SCSI_STATUS_CHECK_CONDITION,
 1097          SCSI_SENSE_ABORTED_COMMAND,
 1098          SCSI_ASC_NO_ADDITIONAL_SENSE,
 1099          SCSI_ASCQ_NO_ADDITIONAL_SENSE
 1100       );
 1101       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
 1102    }
 1103    else
 1104    {
 1105       if (sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
 1106       {
 1107          status = SATI_SEQUENCE_INCOMPLETE;
 1108       }
 1109       else
 1110       {
 1111          status = SATI_COMPLETE;
 1112       }
 1113    }
 1114    return status;
 1115 }
 1116 
 1117 #endif // !defined(DISABLE_SATI_MODE_SELECT)

Cache object: 40b61d89dd09a5c463b13b381ce5026b


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