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_write_long.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 Write Long 10 and 16 commands based on the SAT spec.
   62  */
   63 
   64 #if !defined(DISABLE_SATI_WRITE_LONG)
   65 
   66 #include <dev/isci/scil/sati_write_long.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_move.h>
   74 
   75 #define LOGICAL_PER_PHYSICAL_SECTOR 0xF
   76 
   77 #define WR_UNCOR_BIT          0x02
   78 #define WR_UNCOR_PBLOCK_BIT   0x03
   79 #define COR_DIS_WR_UNCORR_BIT 0x06
   80 
   81 
   82 /**
   83  * @brief This method will translate the write long 10 & 16 SCSI commands into
   84  *        ATA write uncorrectable commands. For more information on the
   85  *        parameters passed to this method, please reference
   86  *        sati_translate_command().
   87  *
   88  * @return Indicate if the command translation succeeded.
   89  * @retval SCI_SUCCESS This is returned if the command translation was
   90  *         successful.
   91  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA is returned if there was
   92  *         a problem with the translation of write long.
   93  *
   94  */
   95 SATI_STATUS sati_write_long_translate_command(
   96    SATI_TRANSLATOR_SEQUENCE_T * sequence,
   97    void                       * scsi_io,
   98    void                       * ata_io
   99 )
  100 {
  101    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  102    SATI_STATUS status = SATI_FAILURE;
  103    U16 byte_transfer_length;
  104    U8 device_head  = 0;
  105 
  106    if((sequence->device->capabilities &
  107        SATI_DEVICE_CAP_WRITE_UNCORRECTABLE_ENABLE) == 0)
  108    {
  109       sati_scsi_sense_data_construct(
  110          sequence,
  111          scsi_io,
  112          SCSI_STATUS_CHECK_CONDITION,
  113          SCSI_SENSE_ILLEGAL_REQUEST,
  114          SCSI_ASC_INVALID_COMMAND_OPERATION_CODE,
  115          SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE
  116       );
  117       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  118    }
  119 
  120    //Write Long 10
  121    if(sati_get_cdb_byte(cdb, 0) == SCSI_WRITE_LONG_10)
  122    {
  123       byte_transfer_length = (sati_get_cdb_byte(cdb, 7) << 8) |
  124                              (sati_get_cdb_byte(cdb, 8));
  125 
  126       sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io);
  127    }
  128    else //Write Long 16
  129    {
  130       byte_transfer_length = (sati_get_cdb_byte(cdb, 12) << 8) |
  131                              (sati_get_cdb_byte(cdb, 13));
  132 
  133       status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io);
  134 
  135       if( status == SATI_FAILURE_CHECK_RESPONSE_DATA)
  136       {
  137          return status;
  138       }
  139    }
  140 
  141 
  142    sati_move_translate_command(sequence, scsi_io, ata_io, device_head);
  143 
  144    if( byte_transfer_length != 0 )
  145    {
  146       sati_scsi_sense_data_construct(
  147          sequence,
  148          scsi_io,
  149          SCSI_STATUS_CHECK_CONDITION,
  150          SCSI_SENSE_ILLEGAL_REQUEST,
  151          SCSI_ASC_INVALID_FIELD_IN_CDB,
  152          SCSI_ASCQ_INVALID_FIELD_IN_CDB
  153       );
  154       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  155    }
  156 
  157    switch(SATI_WRITE_LONG_GET_COR_WR_PB_BITS(cdb))
  158    {
  159       case WR_UNCOR_BIT :
  160 
  161          if( (sequence->device->capabilities &
  162               SATI_DEVICE_CAP_MULTIPLE_SECTORS_PER_PHYSCIAL_SECTOR) != 0 )
  163          {
  164             sati_scsi_sense_data_construct(
  165                sequence,
  166                scsi_io,
  167                SCSI_STATUS_CHECK_CONDITION,
  168                SCSI_SENSE_ILLEGAL_REQUEST,
  169                SCSI_ASC_INVALID_FIELD_IN_CDB,
  170                SCSI_ASCQ_INVALID_FIELD_IN_CDB
  171             );
  172             return SATI_FAILURE_CHECK_RESPONSE_DATA;
  173          }
  174          else
  175          {
  176             sati_ata_write_uncorrectable_construct(
  177                ata_io,
  178                sequence,
  179                ATA_WRITE_UNCORRECTABLE_PSEUDO
  180             );
  181             sequence->type = SATI_SEQUENCE_WRITE_LONG;
  182             status = SATI_SUCCESS;
  183          }
  184          break;
  185 
  186       case WR_UNCOR_PBLOCK_BIT :
  187 
  188          sati_ata_write_uncorrectable_construct(
  189             ata_io,
  190             sequence,
  191             ATA_WRITE_UNCORRECTABLE_PSEUDO
  192          );
  193          sequence->type = SATI_SEQUENCE_WRITE_LONG;
  194          status = SATI_SUCCESS;
  195          break;
  196 
  197       case COR_DIS_WR_UNCORR_BIT :
  198 
  199          sati_ata_write_uncorrectable_construct(
  200             ata_io,
  201             sequence,
  202             ATA_WRITE_UNCORRECTABLE_FLAGGED
  203          );
  204          sequence->type = SATI_SEQUENCE_WRITE_LONG;
  205          status = SATI_SUCCESS;
  206          break;
  207 
  208       default :
  209 
  210          sati_scsi_sense_data_construct(
  211             sequence,
  212             scsi_io,
  213             SCSI_STATUS_CHECK_CONDITION,
  214             SCSI_SENSE_ILLEGAL_REQUEST,
  215             SCSI_ASC_INVALID_FIELD_IN_CDB,
  216             SCSI_ASCQ_INVALID_FIELD_IN_CDB
  217          );
  218          return SATI_FAILURE_CHECK_RESPONSE_DATA;
  219          break;
  220    }
  221    return status;
  222 }
  223 
  224 /**
  225  * @brief This method will translate the response to the SATI Write Long
  226  *        translation. This response is only error checking the
  227  *        ATA Write Uncorrectable command.
  228  *
  229  * @return SATI_STATUS Indicates if the response translation succeeded.
  230  * @retval SCI_COMPLETE This is returned if the command translation was
  231  *         successful.
  232  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA is returned if there was
  233  *         a problem with the translation of write long.
  234  */
  235 SATI_STATUS sati_write_long_translate_response(
  236    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  237    void                       * scsi_io,
  238    void                       * ata_io
  239 )
  240 {
  241    U8 * register_fis = sati_cb_get_d2h_register_fis_address(ata_io);
  242 
  243    if (sati_get_ata_status(register_fis) & ATA_STATUS_REG_ERROR_BIT)
  244    {
  245       sati_scsi_sense_data_construct(
  246          sequence,
  247          scsi_io,
  248          SCSI_STATUS_CHECK_CONDITION,
  249          SCSI_SENSE_ABORTED_COMMAND,
  250          SCSI_ASC_COMMAND_SEQUENCE_ERROR,
  251          SCSI_ASCQ_NO_ADDITIONAL_SENSE
  252       );
  253       return SATI_FAILURE_CHECK_RESPONSE_DATA;
  254    }
  255    else
  256    {
  257       return SATI_COMPLETE;
  258    }
  259 }
  260 
  261 #endif // !defined(DISABLE_SATI_WRITE_LONG)

Cache object: 05c57291b5aabc20c2bf2b3cca75b44b


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