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_sense_6.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 sense 6-byte commands.
   62  */
   63 
   64 #if !defined(DISABLE_SATI_MODE_SENSE)
   65 
   66 #include <dev/isci/scil/sati_mode_sense.h>
   67 #include <dev/isci/scil/sati_mode_sense_6.h>
   68 #include <dev/isci/scil/sati_mode_pages.h>
   69 #include <dev/isci/scil/sati_callbacks.h>
   70 #include <dev/isci/scil/sati_util.h>
   71 #include <dev/isci/scil/intel_scsi.h>
   72 #include <dev/isci/scil/intel_ata.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 builds the mode parameter header for a 6-byte SCSI
   80  *        mode sense data response.  The parameter header is 4 bytes in
   81  *        size.
   82  *        For more information on the parameters passed to this method,
   83  *        please reference sati_translate_command().
   84  *
   85  * @param[in] identify This parameter specifies the ATA remote device's
   86  *            received IDENTIFY DEVICE data.
   87  * @param[in] mode_data_length This parameter specifies the amount of data
   88  *            to be returned as part of this mode sense request.
   89  *
   90  * @return This method returns the number of bytes written into the
   91  *         data buffer.
   92  */
   93 static
   94 U32 sati_mode_sense_6_build_header(
   95    SATI_TRANSLATOR_SEQUENCE_T * sequence,
   96    void                       * scsi_io,
   97    ATA_IDENTIFY_DEVICE_DATA_T * identify,
   98    U8                           mode_data_length
   99 )
  100 {
  101    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  102 
  103    // Fill in the length of the mode parameter data returned (do not include
  104    // the size of the mode data length field in the total).
  105    sati_set_data_byte(sequence, scsi_io, 0, (U8)mode_data_length-1);
  106 
  107    // Medium Type is 0 for SBC devices
  108    sati_set_data_byte(sequence, scsi_io, 1, SCSI_MODE_HEADER_MEDIUM_TYPE_SBC);
  109 
  110    // Write Protect (WP), Rsvd, DPOFUA, Rsvd
  111    if (sequence->device->capabilities & SATI_DEVICE_CAP_DMA_FUA_ENABLE)
  112       sati_set_data_byte(sequence,scsi_io,2,SCSI_MODE_SENSE_HEADER_FUA_ENABLE);
  113    else
  114       sati_set_data_byte(sequence, scsi_io, 2, 0);
  115 
  116    // Set the block descriptor length if block descriptors are utilized.
  117    if (sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SENSE_DBD_ENABLE)
  118       sati_set_data_byte(sequence, scsi_io, 3, 0);
  119    else
  120       sati_set_data_byte(
  121          sequence, scsi_io, 3, SCSI_MODE_SENSE_STD_BLOCK_DESCRIPTOR_LENGTH
  122       );
  123 
  124    return SCSI_MODE_SENSE_6_HEADER_LENGTH;
  125 }
  126 
  127 /**
  128  * @brief This method perform the data translation common to all SCSI MODE
  129  *        SENSE 6 byte commands.  This includes building the mode page
  130  *        header and block descriptor (if requested).
  131  *        For more information on the parameters passed to this method,
  132  *        please reference sati_translate_command().
  133  *
  134  * @param[in] identify This parameter specifies the remote device's IDENTIFY
  135  *            DEVICE data to be used during translation.
  136  * @param[in] transfer_length This parameter specifies the size of the
  137  *            mode page (including header & block descriptor).
  138  *
  139  * @return This method returns the number of bytes written into the user's
  140  *         mode page data buffer.
  141  */
  142 static
  143 U32 sati_mode_sense_6_translate_data(
  144    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  145    ATA_IDENTIFY_DEVICE_DATA_T * identify,
  146    void                       * scsi_io,
  147    U8                           transfer_length
  148 )
  149 {
  150    U8  * cdb = sati_cb_get_cdb_address(scsi_io);
  151    U32   offset;
  152 
  153    offset = sati_mode_sense_6_build_header(
  154                sequence, scsi_io, identify, transfer_length
  155             );
  156 
  157    // Determine if the caller disabled block descriptors (DBD).  If not,
  158    // then generate a block descriptor.
  159    if ((sati_get_cdb_byte(cdb, 1) & SCSI_MODE_SENSE_DBD_ENABLE) == 0)
  160       offset += sati_mode_sense_build_std_block_descriptor(
  161                    sequence, scsi_io, identify, offset
  162                 );
  163 
  164    return offset;
  165 }
  166 
  167 //******************************************************************************
  168 //* P R O T E C T E D   M E T H O D S
  169 //******************************************************************************
  170 
  171 /**
  172  * @brief This method will translate the SCSI mode sense 6 byte command
  173  *        into corresponding ATA commands.  If the command is well-formed,
  174  *        then the translation will result in an ATA IDENTIFY DEVICE
  175  *        command.
  176  *        For more information on the parameters passed to this method,
  177  *        please reference sati_translate_command().
  178  *
  179  * @return Indicate if the command translation succeeded.
  180  * @retval SCI_SUCCESS This is returned if the command translation was
  181  *         successful.
  182  * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if
  183  *         sense data has been created as a result of something specified
  184  *         in the CDB.
  185  */
  186 SATI_STATUS sati_mode_sense_6_translate_command(
  187    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  188    void                       * scsi_io,
  189    void                       * ata_io
  190 )
  191 {
  192    U8 * cdb = sati_cb_get_cdb_address(scsi_io);
  193 
  194    // Set the data length based on the allocation length field in the CDB.
  195    sequence->allocation_length = sati_get_cdb_byte(cdb, 4);
  196 
  197    return sati_mode_sense_translate_command(sequence, scsi_io, ata_io, 6);
  198 }
  199 
  200 /**
  201  * @brief This method will perform data translation from the supplied ATA
  202  *        input data (i.e. an ATA IDENTIFY DEVICE block) into a CACHING
  203  *        mode page format.  The data will be written into the user's mode
  204  *        page data buffer.  This function operates specifically for MODE
  205  *        SENSE 6 commands.
  206  *        For more information on the parameters passed to this method,
  207  *        please reference sati_translate_data().
  208  *
  209  * @return none.
  210  */
  211 void sati_mode_sense_6_caching_translate_data(
  212    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  213    void                       * ata_input_data,
  214    void                       * scsi_io
  215 )
  216 {
  217    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  218                                            ata_input_data;
  219    U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  220                            + SCSI_MODE_PAGE_08_LENGTH;
  221    U32  page_offset = sati_mode_sense_6_translate_data(
  222                          sequence, identify, scsi_io, data_length
  223                       );
  224 
  225    sati_mode_sense_caching_translate_data(
  226       sequence, scsi_io, identify, page_offset
  227    );
  228 }
  229 
  230 /**
  231  * @brief This method will perform data translation from the supplied ATA
  232  *        input data (i.e. an ATA IDENTIFY DEVICE block) into a INFORMATIONAL
  233  *        EXCEPTIONS CONTROL mode page format.  The data will be written
  234  *        into the user's mode page data buffer.  This function operates
  235  *        specifically for MODE SENSE 6 commands.
  236  *        For more information on the parameters passed to this method,
  237  *        please reference sati_translate_data().
  238  *
  239  * @return none.
  240  */
  241 void sati_mode_sense_6_informational_excp_control_translate_data(
  242    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  243    void                       * ata_input_data,
  244    void                       * scsi_io
  245 )
  246 {
  247    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  248                                            ata_input_data;
  249    U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  250                            + SCSI_MODE_PAGE_1C_LENGTH;
  251    U32  page_offset = sati_mode_sense_6_translate_data(
  252                          sequence, identify, scsi_io, data_length
  253                       );
  254 
  255    sati_mode_sense_informational_excp_control_translate_data(
  256       sequence, scsi_io, identify, page_offset
  257    );
  258 }
  259 
  260 /**
  261 * @brief This method will perform data translation from the supplied ATA
  262 *        input data (i.e. an ATA IDENTIFY DEVICE block) into a DISCONNECT
  263 *        RECONNECT mode page format.  The data will be written
  264 *        into the user's mode page data buffer.  This function operates
  265 *        specifically for MODE SENSE 6 commands.
  266 *        For more information on the parameters passed to this method,
  267 *        please reference sati_translate_data().
  268 *
  269 * @return none.
  270 */
  271 void sati_mode_sense_6_disconnect_reconnect_translate_data(
  272    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  273    void                       * ata_input_data,
  274    void                       * scsi_io
  275 )
  276 {
  277    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  278       ata_input_data;
  279 
  280    U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  281       + SCSI_MODE_PAGE_02_LENGTH ;
  282 
  283    U32  page_offset = sati_mode_sense_6_translate_data(
  284                          sequence, identify, scsi_io, data_length
  285                       );
  286 
  287    sati_mode_sense_disconnect_reconnect_translate_data(
  288       sequence, scsi_io, identify, page_offset
  289    );
  290 }
  291 
  292 /**
  293 * @brief This method will perform data translation from the supplied ATA
  294 *        input data (i.e. an ATA IDENTIFY DEVICE block) into a READ WRITE ERROR
  295 *        mode page format.  The data will be written
  296 *        into the user's mode page data buffer.  This function operates
  297 *        specifically for MODE SENSE 6 commands.
  298 *        For more information on the parameters passed to this method,
  299 *        please reference sati_translate_data().
  300 *
  301 * @return none.
  302 */
  303 void sati_mode_sense_6_read_write_error_translate_data(
  304    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  305    void                       * ata_input_data,
  306    void                       * scsi_io
  307 )
  308 {
  309    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  310       ata_input_data;
  311 
  312    U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  313       + SCSI_MODE_PAGE_01_LENGTH;
  314 
  315    U32  page_offset = sati_mode_sense_6_translate_data(
  316                          sequence, identify, scsi_io, data_length
  317                       );
  318 
  319    sati_mode_sense_read_write_error_translate_data(
  320       sequence, scsi_io, identify, page_offset
  321    );
  322 }
  323 
  324 /**
  325 * @brief This method will perform data translation from the supplied ATA
  326 *        input data (i.e. an ATA IDENTIFY DEVICE block) into a CONTROL
  327 *        mode page format.  The data will be written
  328 *        into the user's mode page data buffer.  This function operates
  329 *        specifically for MODE SENSE 6 commands.
  330 *        For more information on the parameters passed to this method,
  331 *        please reference sati_translate_data().
  332 *
  333 * @return none.
  334 */
  335 void sati_mode_sense_6_control_translate_data(
  336    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  337    void                       * ata_input_data,
  338    void                       * scsi_io
  339 )
  340 {
  341    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  342       ata_input_data;
  343 
  344    U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  345       + SCSI_MODE_PAGE_0A_LENGTH;
  346 
  347    U32  page_offset = sati_mode_sense_6_translate_data(
  348                          sequence, identify, scsi_io, data_length
  349                       );
  350 
  351    sati_mode_sense_control_translate_data(
  352       sequence, scsi_io, identify, page_offset
  353    );
  354 }
  355 
  356 /**
  357 * @brief This method will perform data translation from the supplied ATA
  358 *        input data (i.e. an ATA IDENTIFY DEVICE block) into a Power
  359 *        Condition mode page format.  The data will be written
  360 *        into the user's mode page data buffer.  This function operates
  361 *        specifically for MODE SENSE 6 commands.
  362 *        For more information on the parameters passed to this method,
  363 *        please reference sati_translate_data().
  364 *
  365 * @return none.
  366 */
  367 void sati_mode_sense_6_power_condition_translate_data(
  368    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  369    void                       * ata_input_data,
  370    void                       * scsi_io
  371 )
  372 {
  373    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  374       ata_input_data;
  375 
  376    U8 data_length;
  377    U32  page_offset;
  378 
  379    data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  380          + SCSI_MODE_PAGE_1A_LENGTH;
  381 
  382    page_offset = sati_mode_sense_6_translate_data(
  383          sequence, identify, scsi_io, data_length
  384    );
  385 
  386    sati_mode_sense_power_condition_translate_data(
  387       sequence, scsi_io, identify, page_offset
  388    );
  389 }
  390 
  391 
  392 
  393 /**
  394  * @brief This method will perform data translation from the supplied ATA
  395  *        input data (i.e. an ATA IDENTIFY DEVICE block) into an ALL
  396  *        PAGES mode page format.  The ALL PAGES mode page is basically a
  397  *        conglomeration of all mode pages and sub-pages into a single
  398  *        page.  The data will be written into the user's mode page
  399  *        data buffer.  This function operates specifically for MODE
  400  *        SENSE 6 commands.
  401  *        For more information on the parameters passed to this method,
  402  *        please reference sati_translate_data().
  403  *
  404  * @return none.
  405  */
  406 void sati_mode_sense_6_all_pages_translate_data(
  407    SATI_TRANSLATOR_SEQUENCE_T * sequence,
  408    void                       * ata_input_data,
  409    void                       * scsi_io
  410 )
  411 {
  412    ATA_IDENTIFY_DEVICE_DATA_T * identify = (ATA_IDENTIFY_DEVICE_DATA_T*)
  413                                            ata_input_data;
  414    U8   data_length = (U8) sati_mode_sense_calculate_page_header(scsi_io, 6)
  415                            + SCSI_MODE_PAGE_01_LENGTH
  416                            + SCSI_MODE_PAGE_02_LENGTH
  417                            + SCSI_MODE_PAGE_08_LENGTH
  418                            + SCSI_MODE_PAGE_0A_LENGTH
  419                            + SCSI_MODE_PAGE_1C_LENGTH;
  420 
  421    U32  page_offset = sati_mode_sense_6_translate_data(
  422                          sequence, identify, scsi_io, data_length
  423                       );
  424 
  425    sati_mode_sense_all_pages_translate_data(
  426       sequence, scsi_io, identify, page_offset
  427    );
  428 }
  429 
  430 #endif // !defined(DISABLE_SATI_MODE_SENSE)
  431 

Cache object: b370d2cd2a60d3e506bec041e1f1aa0a


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