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_reassign_blocks.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 reassign blocks command.
   62  */
   63 
   64 #if !defined(DISABLE_SATI_REASSIGN_BLOCKS)
   65 
   66 #include <dev/isci/scil/sati_reassign_blocks.h>
   67 #include <dev/isci/scil/sati_callbacks.h>
   68 #include <dev/isci/scil/sati_move.h>
   69 #include <dev/isci/scil/sati_write.h>
   70 #include <dev/isci/scil/sati_translator_sequence.h>
   71 #include <dev/isci/scil/sati_util.h>
   72 #include <dev/isci/scil/intel_scsi.h>
   73 
   74 
   75 //******************************************************************************
   76 //* P R I V A T E   M E T H O D S
   77 //******************************************************************************
   78 // static SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T reassign_blocks_processing_state;
   79 
   80 /**
   81  * @brief This method copies short 24bits LBA bytes to the command register
   82  * @return Indicate if the method was successfully completed.
   83  * @retval SATI_SUCCESS This is returned in all other cases.
   84  */
   85 static
   86 void set_current_lba(U8 * lba, void  * ata_io)
   87 {
   88    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
   89 
   90    sati_set_ata_lba_low(register_fis, lba[0]);
   91    sati_set_ata_lba_mid(register_fis, lba[1]);
   92    sati_set_ata_lba_high(register_fis, lba[2]);
   93    sati_set_ata_device_head(register_fis, ATA_DEV_HEAD_REG_LBA_MODE_ENABLE | (lba[3] & 0x0F));
   94 
   95 
   96 }
   97 
   98 /**
   99  * @brief This method copies short 48bits LBA bytes to the command register
  100  * @return Indicate if the method was successfully completed.
  101  * @retval SATI_SUCCESS This is returned in all other cases.
  102  */
  103 static
  104 void set_current_long_lba(U8 * lba, void  * ata_io)
  105 {
  106    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  107 
  108    sati_set_ata_lba_low(register_fis, lba[0]);
  109    sati_set_ata_lba_mid(register_fis, lba[1]);
  110    sati_set_ata_lba_high(register_fis, lba[2]);
  111    sati_set_ata_lba_low_exp(register_fis, lba[3]);
  112    sati_set_ata_lba_mid_exp(register_fis, lba[4]);
  113    sati_set_ata_lba_high_exp(register_fis, lba[5]);
  114 }
  115 
  116 /**
  117  * @brief This method performs the SCSI VERIFY command translation
  118  *        functionality.
  119  *        This includes:
  120  *        - setting the command register
  121  *        - setting the device head register
  122  *        - filling in fields in the SATI_TRANSLATOR_SEQUENCE object.
  123  *        For more information on the parameters passed to this method,
  124  *        please reference sati_translate_command().
  125  *
  126  * @return Indicate if the method was successfully completed.
  127  * @retval SATI_SUCCESS This is returned in all other cases.
  128  */
  129 static
  130 SATI_STATUS sati_reassign_blocks_verify_command(
  131    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  132    void                       * scsi_io,
  133    void                       * ata_io
  134 )
  135 {
  136    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  137 
  138    sati_ata_non_data_command(ata_io, sequence);
  139 
  140    // Ensure the device supports the 48 bit feature set.
  141    if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
  142       sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS_EXT);
  143    else
  144       sati_set_ata_command(register_fis, ATA_READ_VERIFY_SECTORS);
  145 
  146    return SATI_SUCCESS;
  147 }
  148 
  149 /**
  150  * @brief This method performs the SCSI Write sector command translation
  151  *        functionality.
  152  *        This includes:
  153  *        - setting the command register
  154  *        - setting the device head register
  155  *        - filling in fields in the SATI_TRANSLATOR_SEQUENCE object.
  156  *        For more information on the parameters passed to this method,
  157  *        please reference sati_translate_command().
  158  *
  159  * @return Indicate if the method was successfully completed.
  160  * @retval SATI_SUCCESS This is returned in all other cases.
  161  */
  162 static
  163 SATI_STATUS sati_reassign_blocks_write_command(
  164    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  165    void                       * scsi_io,
  166    void                       * ata_io
  167 )
  168 {
  169    U8 * register_fis = sati_cb_get_h2d_register_fis_address(ata_io);
  170 
  171    sati_ata_non_data_command(ata_io, sequence);
  172    sequence->data_direction = SATI_DATA_DIRECTION_OUT;
  173 
  174 //   sati_set_ata_sector_count(register_fis, 1);
  175 //   status=sati_move_set_sector_count(sequence,scsi_io,ata_io,1,0);
  176 
  177    // Ensure the device supports the 48 bit feature set.
  178    if (sequence->device->capabilities & SATI_DEVICE_CAP_48BIT_ENABLE)
  179       sati_set_ata_command(register_fis, ATA_WRITE_DMA_EXT);
  180    else
  181       sati_set_ata_command(register_fis, ATA_WRITE_DMA);
  182 
  183    return SATI_SUCCESS; //sati_move_set_sector_count(sequence,scsi_io,ata_io,1,0);
  184 }
  185 
  186 /**
  187  * @brief This method performs the retrieving of parameter LBA praparation and setting
  188  *        processing flags before/after calling SCSI Verify sector command.
  189  * @return Indicate if the method was successfully completed.
  190  * @retval SATI_SUCCESS This is returned in all other cases.
  191  */
  192 static
  193 SATI_STATUS sati_reassign_blocks_verify_condition(
  194    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  195    void     * scsi_io,
  196    void     * ata_io
  197 )
  198 {
  199    U8 current_lba_bytes[8] = {0,0,0,0,0,0,0,0};
  200    U32 lba_offset;
  201    U8 page_size;
  202    U32 index;
  203    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  204 
  205    lba_offset = sequence->command_specific_data.reassign_blocks_process_state.lba_offset;
  206    page_size = sequence->command_specific_data.reassign_blocks_process_state.lba_size;
  207 
  208    for(index = 0; index < page_size; index++)
  209    {
  210       sati_get_data_byte(sequence, scsi_io, lba_offset+index,   &current_lba_bytes[index]);
  211    }
  212 
  213    if (page_size == 4)
  214       set_current_lba(current_lba_bytes, ata_io);
  215    else
  216       set_current_long_lba(current_lba_bytes, ata_io);
  217 
  218    status = sati_reassign_blocks_verify_command(sequence, scsi_io, ata_io);
  219    sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba++;
  220    sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_READY_TO_SEND;
  221    return  status;
  222 }
  223 
  224 /**
  225  * @brief This method performs the retrieving of parameter LBA praparation and setting
  226  *        processing flags before/after calling SCSI Write sector command.
  227  * @return Indicate if the method was successfully completed.
  228  * @retval SATI_SUCCESS This is returned in all other cases.
  229  */
  230 static
  231 SATI_STATUS sati_reassign_blocks_write_condition(
  232    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  233    void     * scsi_io,
  234    void     * ata_io
  235 )
  236 {
  237    U8 current_lba_bytes[8] = {0,0,0,0,0,0,0,0};
  238    U32 lba_offset;
  239    U8 page_size;
  240    U32 index;
  241    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  242 
  243    lba_offset = sequence->command_specific_data.reassign_blocks_process_state.lba_offset;
  244    page_size = sequence->command_specific_data.reassign_blocks_process_state.lba_size;
  245 
  246    for(index = 0; index < page_size; index++)
  247    {
  248       sati_get_data_byte(sequence, scsi_io, lba_offset+index,   &current_lba_bytes[index]);
  249    }
  250 
  251    if (page_size == 4)
  252       set_current_lba(current_lba_bytes, ata_io);
  253    else
  254       set_current_long_lba(current_lba_bytes, ata_io);
  255 
  256    status = sati_reassign_blocks_write_command(sequence, scsi_io, ata_io);
  257    sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba++;
  258    sequence->command_specific_data.reassign_blocks_process_state.ata_command_status = SATI_REASSIGN_BLOCKS_READY_TO_SEND;
  259    return  status ;
  260 }
  261 
  262 
  263 /**
  264  * @brief This method will perform the pre-processing of Reassign Blocks command and parameter.
  265  */
  266 static
  267 void  sati_reassign_blocks_initial_processing(
  268    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  269    void                       * scsi_io,
  270    void                       * ata_io
  271 )
  272 {
  273    U32 index;
  274    U8 long_lba_bit;
  275    U8 long_list_bit;
  276    U8 lba_offset;
  277    U8  page_size;
  278    U32 data_transfer_length;
  279    U8 header_bytes[4]={0,0,0,0};
  280 
  281    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  282 
  283    //A long LBA (LONGLBA) bit set to zero specifies that the REASSIGN BLOCKS defective LBA list contains four-byte LBAs.
  284    //A LONGLBA bit set to one specifies that the REASSIGN BLOCKS defective LBA list contains eight-byte LBAs.
  285    if ((sati_get_cdb_byte(cdb, 1) & SCSI_REASSIGN_BLOCKS_LONGLBA_BIT) == 0)
  286    {
  287       long_lba_bit=0;
  288       page_size = 4; //beginning of lba list
  289    }
  290    else
  291    {
  292       long_lba_bit=1;
  293       page_size = 8;
  294    }
  295 
  296    //The long list (LONGLIST) bit specifies which parameter list header
  297    if ((sati_get_cdb_byte(cdb, 1) & SCSI_REASSIGN_BLOCKS_LONGLIST_BIT) == 0)
  298    {
  299       long_list_bit=0;
  300    }
  301    else
  302    {
  303       long_list_bit=1;
  304    }
  305 
  306    sequence->allocation_length = 4; //Pre-set allocation_length so that the header can be retrieved
  307 
  308    //Get 4 bytes for headers (byte 2 & byte 3 for short header; long header all 4 bytes)
  309    for(index = 0; index < 4; index++)
  310    {
  311       sati_get_data_byte(sequence, scsi_io, index,   &header_bytes[index]);
  312    }
  313 
  314    lba_offset = 4; //beginning of lba list
  315 
  316    if (long_list_bit==0)
  317    {
  318       //Header byte 2 and 3 is the parameter list length
  319       data_transfer_length = (header_bytes[2]<<8) + header_bytes[3] + lba_offset;
  320    }
  321    else
  322    {
  323       //Header byte 0, 1, 2 and 3 contain the parameter list length
  324       data_transfer_length = (header_bytes[0]<<24) + (header_bytes[1]<<16) +
  325          (header_bytes[2]<<8) + header_bytes[3] + lba_offset;
  326    }
  327 
  328    sequence->allocation_length = data_transfer_length;
  329 
  330    //Initialized the global processing state
  331    sequence->command_specific_data.reassign_blocks_process_state.lba_size   =     page_size;
  332    sequence->command_specific_data.reassign_blocks_process_state.lba_offset =     lba_offset;
  333    sequence->command_specific_data.reassign_blocks_process_state.ata_command_sent_for_current_lba = 0;
  334    sequence->command_specific_data.reassign_blocks_process_state.block_lists_size       = data_transfer_length  -  lba_offset;
  335    sequence->command_specific_data.reassign_blocks_process_state.size_of_data_processed = 0;
  336    sequence->command_specific_data.reassign_blocks_process_state.current_lba_processed  = FALSE;
  337    sequence->command_specific_data.reassign_blocks_process_state.ata_command_status     = SATI_REASSIGN_BLOCKS_COMMAND_FAIL;
  338 }
  339 
  340 /**
  341  * @brief This method will get the data size of not yet processed data.
  342  *
  343  * @param[in] lba_process_state This parameter points to the processing state fields
  344  *            of current block lba.
  345  *
  346  * @return This method returns the sizeof not yet processed data.
  347  */
  348 static
  349 U32 sati_reassign_blocks_unprocessed_data_size(
  350    SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * lba_process_state
  351 )
  352 {
  353    U32 unprocessed_data_size;
  354 
  355    if(lba_process_state->block_lists_size >= lba_process_state->size_of_data_processed)
  356    {
  357       unprocessed_data_size = lba_process_state->block_lists_size -
  358          lba_process_state->size_of_data_processed;
  359    }
  360    else
  361    {
  362       unprocessed_data_size = 0;
  363    }
  364 
  365    return unprocessed_data_size;
  366 }
  367 
  368 
  369 /**
  370  * @brief This method will check verify the sector and issue multiple ATA set feature commands to complete the translation.
  371  *
  372  * @param[in] reassign_blocks_process_state This parameter points to the processing state fields
  373  *            of current lba block.
  374  *
  375  *
  376  * @return Indicate if the translation was successful.
  377  * @retval SATI_SUCCESS
  378  * @retval SATI_COMPLETE
  379  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  380  */
  381 static
  382 SATI_STATUS sati_reassign_blocks_process_each_lba(
  383    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  384    void                       * scsi_io,
  385    void                       * ata_io
  386    )
  387 {
  388    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  389    SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state;
  390 
  391    reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state;
  392 
  393    if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 0)&&
  394       (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_FAIL))
  395    {
  396       reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size;
  397       status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io);
  398    }
  399    else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 0)&&
  400       (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS))
  401    {
  402       // point to next lba
  403       reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size;
  404       reassign_blocks_process_state->lba_offset += reassign_blocks_process_state->lba_size;
  405       status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io);
  406    }
  407    else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 1)&&
  408       (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_FAIL))
  409    {
  410       reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size;
  411       status = sati_reassign_blocks_write_condition(sequence, scsi_io, ata_io);
  412    }
  413    else if((reassign_blocks_process_state->ata_command_sent_for_current_lba == 2) &&
  414       (reassign_blocks_process_state->ata_command_status == SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS))
  415    {
  416       reassign_blocks_process_state->size_of_data_processed += reassign_blocks_process_state->lba_size;
  417       status = sati_reassign_blocks_verify_condition(sequence, scsi_io, ata_io);
  418    }
  419    else //commands sent is 2; SATI_REASSIGN_BLOCKS_COMMAND_FAIL
  420    {
  421       status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  422    }
  423 
  424    return status;
  425 }
  426 
  427 /**
  428  * @brief This method will process the each lba.
  429  *
  430  * @param[in] reassign_blocks_process_state This parameter points to the processing state fields
  431  *            of current lba.
  432  *
  433  * @return Indicate if the translation was successful.
  434  * @retval SATI_SUCCESS
  435  * @retval SATI_COMPLETE
  436  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA
  437  */
  438 static
  439 SATI_STATUS sati_reassign_blocks_process(
  440    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  441    void                       * scsi_io,
  442    void                       * ata_io
  443 )
  444 {
  445    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  446 
  447    U32 page_size = 0; // in bytes
  448    U32 size_of_data_to_be_processed;
  449    U32 lba_offset;
  450    SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state;
  451 
  452    reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state;
  453 
  454    lba_offset = reassign_blocks_process_state->lba_offset;
  455    page_size  = reassign_blocks_process_state->lba_size;
  456 
  457 
  458    if(sati_reassign_blocks_unprocessed_data_size(reassign_blocks_process_state) < page_size)
  459    {
  460       return status;
  461    }
  462 
  463    // Any more lba blocks? If not, done.
  464    if(reassign_blocks_process_state->block_lists_size ==
  465       reassign_blocks_process_state->size_of_data_processed)
  466    {
  467       sequence->state = SATI_SEQUENCE_STATE_FINAL;
  468       status = SATI_COMPLETE;
  469    }
  470    //start processing next lba
  471    else
  472    {
  473       size_of_data_to_be_processed = reassign_blocks_process_state->block_lists_size
  474          - reassign_blocks_process_state->size_of_data_processed;
  475 
  476       status = sati_reassign_blocks_process_each_lba(sequence, scsi_io, ata_io);
  477 
  478    }
  479 
  480    return status;
  481 }
  482 
  483 //******************************************************************************
  484 //* P U B L I C   M E T H O D S
  485 //******************************************************************************
  486 
  487 /**
  488  * @brief This method will translate the SCSI Reassign Blocks command
  489  *        into corresponding ATA commands.  Depending upon the capabilities
  490  *        supported by the target different ATA commands can be selected.
  491  *        Additionally, in some cases more than a single ATA command may
  492  *        be required.
  493  *
  494  * @return Indicate if the command translation succeeded.
  495  * @retval SCI_SUCCESS This is returned if the command translation was
  496  *         successful.
  497  * @retval SCI_COMPLETE This is returned if the command translation was
  498  *         successful and no ATA commands need to be set.
  499  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
  500  *         sense data has been created as a result of something specified
  501  *         in the parameter data fields.
  502  */
  503 SATI_STATUS sati_reassign_blocks_translate_command(
  504    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  505    void                       * scsi_io,
  506    void                       * ata_io
  507 )
  508 {
  509    SATI_STATUS status = SATI_FAILURE_CHECK_RESPONSE_DATA;
  510    SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state;
  511 
  512    reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state;
  513 
  514    sequence->type = SATI_SEQUENCE_REASSIGN_BLOCKS;
  515 
  516    //Initial processing if
  517    if ( sequence->state != SATI_SEQUENCE_STATE_INCOMPLETE )
  518    {
  519       sati_reassign_blocks_initial_processing(
  520          sequence,
  521          scsi_io,
  522          ata_io
  523       );
  524    }
  525 
  526    // start processing current lba
  527    if(reassign_blocks_process_state->current_lba_processed)
  528    {
  529       reassign_blocks_process_state->ata_command_sent_for_current_lba = 0;
  530       reassign_blocks_process_state->current_lba_processed = FALSE;
  531    }
  532 
  533    status = sati_reassign_blocks_process(sequence, scsi_io, ata_io);
  534 
  535    if(reassign_blocks_process_state->block_lists_size ==
  536       reassign_blocks_process_state->size_of_data_processed)
  537    {
  538       // Done this lba
  539       sequence->state = SATI_SEQUENCE_STATE_FINAL;
  540    }
  541    else
  542    {
  543       sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
  544    }
  545 
  546    if(status == SATI_FAILURE_CHECK_RESPONSE_DATA)
  547    {
  548       sequence->state = SATI_SEQUENCE_STATE_FINAL;
  549       sati_scsi_sense_data_construct(
  550          sequence,
  551          scsi_io,
  552          SCSI_STATUS_CHECK_CONDITION,
  553          SCSI_SENSE_MEDIUM_ERROR,
  554          SCSI_ASC_UNRECOVERED_READ_ERROR,
  555          SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL
  556       );
  557    }
  558 
  559    return status;
  560 }
  561 
  562 /**
  563  * @brief This method will translate the ATA command register FIS
  564  *        response into an appropriate SCSI response for Reassign Blocks
  565  *        For more information on the parameters passed to this method,
  566  *        please reference sati_translate_response().
  567  *
  568  * @return Indicate if the response translation succeeded.
  569  * @retval SCI_SUCCESS This is returned if the data translation was
  570  *         successful.
  571  */
  572 SATI_STATUS sati_reassign_blocks_translate_response(
  573    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  574    void                       * scsi_io,
  575    void                       * ata_io
  576 )
  577 {
  578    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
  579    SATI_REASSIGN_BLOCKS_PROCESSING_STATE_T * reassign_blocks_process_state;
  580 
  581    reassign_blocks_process_state = &sequence->command_specific_data.reassign_blocks_process_state;
  582 
  583    if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
  584    {
  585       reassign_blocks_process_state->ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_FAIL;
  586 
  587       //Checking for the number of ATA commands attempted on current LBA, stop
  588       //the seaquence after 2 commands have returned errors.
  589       if(reassign_blocks_process_state->ata_command_sent_for_current_lba < 2)
  590       {
  591          sequence->state = SATI_SEQUENCE_STATE_INCOMPLETE;
  592          reassign_blocks_process_state->size_of_data_processed -= reassign_blocks_process_state->lba_size;
  593          return SATI_SEQUENCE_INCOMPLETE;
  594       }
  595       else
  596       {
  597          sati_scsi_sense_data_construct(
  598             sequence,
  599             scsi_io,
  600             SCSI_STATUS_CHECK_CONDITION,
  601             SCSI_SENSE_MEDIUM_ERROR,
  602             SCSI_ASC_UNRECOVERED_READ_ERROR,
  603             SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL
  604          );
  605       }
  606 
  607       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  608    }
  609    else
  610    {
  611       reassign_blocks_process_state->ata_command_status = SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS;
  612       if (reassign_blocks_process_state->ata_command_sent_for_current_lba != 2)
  613          reassign_blocks_process_state->current_lba_processed = TRUE;
  614 
  615       if (sequence->state == SATI_SEQUENCE_STATE_INCOMPLETE)
  616       {
  617          return SATI_SEQUENCE_INCOMPLETE;
  618       }
  619    }
  620    return SATI_COMPLETE;
  621 }
  622 
  623 #endif // !defined(DISABLE_SATI_REASSIGN_BLOCKS)
  624 

Cache object: 62f31d16235031a7dd7616f95d9dd21d


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